This commit is contained in:
jiangh277 2025-08-05 19:01:41 +08:00
parent eba0eb085e
commit 75e61a1bf4
14 changed files with 71 additions and 92 deletions

View File

@ -49,7 +49,7 @@ public class StoryController {
@GetMapping("/{storyId}") @GetMapping("/{storyId}")
public ResponseEntity<Story> getStoryById(@PathVariable String storyId) { public ResponseEntity<Story> getStoryById(@PathVariable String storyId) {
log.info("获取故事详情, ID: {}", storyId); log.info("获取故事详情, ID: {}", storyId);
Story story = storyService.getStoryById(storyId); Story story = storyService.getStoryByInstanceId(storyId);
return ResponseEntity.success(story); return ResponseEntity.success(story);
} }

View File

@ -52,9 +52,9 @@ public class StoryItemController {
} }
@GetMapping("/list") @GetMapping("/list")
public ResponseEntity<List<StoryItem>> getItemsByMasterItem(@RequestParam String masterItemId) { public ResponseEntity<List<StoryItem>> getItemsByMasterItem(@RequestParam String storyInstanceId) {
log.info("查询 StoryItem 列表,masterItemId: {}", masterItemId); log.info("查询 StoryItem 列表,storyInstanceId: {}", storyInstanceId);
List<StoryItem> items = storyItemService.getItemsByMasterItem(masterItemId); List<StoryItem> items = storyItemService.getItemsByMasterItem(storyInstanceId);
return ResponseEntity.success(items); return ResponseEntity.success(items);
} }
@GetMapping("/images/{itemId}") @GetMapping("/images/{itemId}")
@ -63,4 +63,10 @@ public class StoryItemController {
List<String> images = storyItemService.getStoryItemImages(itemId); List<String> images = storyItemService.getStoryItemImages(itemId);
return ResponseEntity.success(images); return ResponseEntity.success(images);
} }
@GetMapping("/count/{storyInstanceId}")
public ResponseEntity<Integer> getStoryItemCount(@PathVariable String storyInstanceId) {
log.info("获取 StoryItem 子项数量storyInstanceId: {}", storyInstanceId);
Integer count = storyItemService.getStoryItemCount(storyInstanceId);
return ResponseEntity.success(count);
}
} }

View File

@ -14,4 +14,6 @@ public interface CommonRelationMapper {
List<String> getStoryItemsByImageInstanceId(String imageInstanceId); List<String> getStoryItemsByImageInstanceId(String imageInstanceId);
void deleteImageStoryItemRelation(String imageInstanceId, String storyItemId); void deleteImageStoryItemRelation(String imageInstanceId, String storyItemId);
void deleteRelationByRelaId(String relaId);
void deleteRelationBySubRelaId(String subRelaId);
} }

View File

@ -9,10 +9,10 @@ import java.util.List;
public interface StoryItemMapper { public interface StoryItemMapper {
void insert(StoryItem storyItem); void insert(StoryItem storyItem);
void update(StoryItem storyItem); void update(StoryItem storyItem);
void deleteById(String itemId); void deleteByItemId(String itemId);
StoryItem selectById(String itemId); StoryItem selectById(String itemId);
List<StoryItem> selectByMasterItem(String masterItemId); List<StoryItem> selectByMasterItem(String masterItemId);
List<String> selectImagesByItemId(String itemId); List<String> selectImagesByItemId(String itemId);
List<StoryItem> selectByMasterItemWithSubItems(String masterItemId); List<StoryItem> selectStoryItemByStoryInstanceId(String storyInstanceId);
int countByStoryId(String storyInstanceId);
} }

View File

@ -10,7 +10,7 @@ public interface StoryMapper {
void insert(Story story); void insert(Story story);
void update(Story story); void update(Story story);
void deleteByInstanceId(String instanceId); void deleteByInstanceId(String instanceId);
Story selectById(String instanceId); Story selectByInstanceId(String instanceId);
List<Story> selectByOwnerId(String ownerId); List<Story> selectByOwnerId(String ownerId);
} }

View File

@ -6,8 +6,9 @@ import java.time.LocalDateTime;
@Data @Data
public class StoryItem { public class StoryItem {
private String itemId; private String instanceId;
private String masterItem; private String storyInstanceId;
private String masterItemId;
private String title; private String title;
private String description; private String description;
private String location; private String location;
@ -18,7 +19,6 @@ public class StoryItem {
private LocalDateTime updateTime; private LocalDateTime updateTime;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime storyItemTime; private LocalDateTime storyItemTime;
private Integer isRoot;
private Integer isDelete; private Integer isDelete;
private String coverInstanceId; private String coverInstanceId;
private StoryItem[] subItems; private StoryItem[] subItems;

View File

@ -16,4 +16,6 @@ public interface StoryItemService {
StoryItem getItemById(String itemId); StoryItem getItemById(String itemId);
List<StoryItem> getItemsByMasterItem(String masterItemId); List<StoryItem> getItemsByMasterItem(String masterItemId);
List<String> getStoryItemImages(String storyItemId); List<String> getStoryItemImages(String storyItemId);
Integer getStoryItemCount(String instanceId);
} }

View File

@ -9,7 +9,7 @@ public interface StoryService {
void createStory(StoryVo storyVo); void createStory(StoryVo storyVo);
void updateStory(StoryVo storyVo, String storyId); void updateStory(StoryVo storyVo, String storyId);
void deleteStory(String storyId); void deleteStory(String storyId);
Story getStoryById(String storyId); Story getStoryByInstanceId(String storyId);
List<Story> getStoriesByOwnerId(String ownerId); List<Story> getStoriesByOwnerId(String ownerId);
} }

View File

@ -37,13 +37,12 @@ public class StoryItemServiceImpl implements StoryItemService {
public void createItem(StoryItemVo storyItemVo) { public void createItem(StoryItemVo storyItemVo) {
try { try {
StoryItem item = new StoryItem(); StoryItem item = new StoryItem();
item.setItemId(IdUtils.randomUuidUpper()); item.setInstanceId(IdUtils.randomUuidUpper());
item.setMasterItem(storyItemVo.getMasterItemId()); item.setMasterItemId(storyItemVo.getMasterItemId());
item.setDescription(storyItemVo.getDescription()); item.setDescription(storyItemVo.getDescription());
item.setTitle(storyItemVo.getTitle()); item.setTitle(storyItemVo.getTitle());
item.setLocation(storyItemVo.getLocation()); item.setLocation(storyItemVo.getLocation());
item.setCreateId("createId"); item.setCreateId("createId");
item.setIsRoot(storyItemVo.getIsRoot());
item.setIsDelete(0); item.setIsDelete(0);
item.setCreateTime(LocalDateTime.now()); item.setCreateTime(LocalDateTime.now());
item.setUpdateTime(LocalDateTime.now()); item.setUpdateTime(LocalDateTime.now());
@ -65,22 +64,16 @@ public class StoryItemServiceImpl implements StoryItemService {
// 2. 创建 StoryItem 实体 // 2. 创建 StoryItem 实体
StoryItem item = new StoryItem(); StoryItem item = new StoryItem();
item.setItemId(IdUtils.randomUuidUpper()); item.setInstanceId(IdUtils.randomUuidUpper());
item.setMasterItem(storyItemVo.getMasterItemId()); item.setStoryInstanceId(storyItemVo.getStoryInstanceId());
item.setMasterItemId(storyItemVo.getMasterItemId());
item.setTitle(storyItemVo.getTitle()); item.setTitle(storyItemVo.getTitle());
item.setDescription(storyItemVo.getDescription()); item.setDescription(storyItemVo.getDescription());
item.setLocation(storyItemVo.getLocation()); item.setLocation(storyItemVo.getLocation());
item.setCreateId("createId"); item.setCreateId("createId");
item.setStoryItemTime(storyItemVo.getStoryItemTime()); item.setStoryItemTime(storyItemVo.getStoryItemTime());
item.setIsRoot(storyItemVo.getIsRoot());
item.setIsDelete(0); item.setIsDelete(0);
item.setCoverInstanceId(coverKey); item.setCoverInstanceId(coverKey);
if (storyItemVo.getIsRoot() == CommonConstants.STORY_ITEM_IS_ROOT){
item.setIsRoot(CommonConstants.STORY_ITEM_IS_ROOT);
} else {
item.setIsRoot(CommonConstants.STORY_ITEM_IS_NOT_ROOT);
}
// 3. 上传所有图片并建立关联 // 3. 上传所有图片并建立关联
for (MultipartFile image : images) { for (MultipartFile image : images) {
@ -88,10 +81,10 @@ public class StoryItemServiceImpl implements StoryItemService {
String key = response.getData(); String key = response.getData();
log.info("上传成功文件instanceId:{}", key); log.info("上传成功文件instanceId:{}", key);
// 4. 保存封面与 StoryItem 的关联关系 // 4. 保存封面与 StoryItem 的关联关系
buildStoryItemImageRelation(item.getItemId(), key); buildStoryItemImageRelation(item.getInstanceId(), key);
} }
// 4. 记录封面与 StoryItem 的关联关系 // 4. 记录封面与 StoryItem 的关联关系
buildStoryItemImageRelation(item.getItemId(), coverKey); buildStoryItemImageRelation(item.getInstanceId(), coverKey);
// 3. 插入到 story_item // 3. 插入到 story_item
storyItemMapper.insert(item); storyItemMapper.insert(item);
} catch (Exception e) { } catch (Exception e) {
@ -139,7 +132,8 @@ public class StoryItemServiceImpl implements StoryItemService {
if (item == null) { if (item == null) {
throw new RuntimeException("StoryItem 不存在"); throw new RuntimeException("StoryItem 不存在");
} }
storyItemMapper.deleteById(itemId); storyItemMapper.deleteByItemId(itemId);
commonRelationMapper.deleteRelationByRelaId(itemId);
} catch (Exception e) { } catch (Exception e) {
log.error("删除 StoryItem 失败", e); log.error("删除 StoryItem 失败", e);
throw new RuntimeException("删除 StoryItem 失败"); throw new RuntimeException("删除 StoryItem 失败");
@ -152,8 +146,8 @@ public class StoryItemServiceImpl implements StoryItemService {
} }
@Override @Override
public List<StoryItem> getItemsByMasterItem(String masterItemId) { public List<StoryItem> getItemsByMasterItem(String storyInstanceId) {
return storyItemMapper.selectByMasterItemWithSubItems(masterItemId); return storyItemMapper.selectStoryItemByStoryInstanceId(storyInstanceId);
} }
@Override @Override
@ -161,6 +155,11 @@ public class StoryItemServiceImpl implements StoryItemService {
return storyItemMapper.selectImagesByItemId(storyItemId); return storyItemMapper.selectImagesByItemId(storyItemId);
} }
@Override
public Integer getStoryItemCount(String instanceId) {
return storyItemMapper.countByStoryId(instanceId);
}
private void buildStoryItemImageRelation(String storyItemId, String imageIds) { private void buildStoryItemImageRelation(String storyItemId, String imageIds) {
CommonRelationDTO relationDTO = new CommonRelationDTO(); CommonRelationDTO relationDTO = new CommonRelationDTO();
relationDTO.setRelaId(storyItemId); relationDTO.setRelaId(storyItemId);

View File

@ -44,7 +44,7 @@ public class StoryServiceImpl implements StoryService {
@Override @Override
public void updateStory(StoryVo storyVo, String storyId) { public void updateStory(StoryVo storyVo, String storyId) {
Story story = storyMapper.selectById(storyId); Story story = storyMapper.selectByInstanceId(storyId);
if (story == null) { if (story == null) {
throw new CustomException(ResponseEnum.NOT_FOUND); throw new CustomException(ResponseEnum.NOT_FOUND);
} }
@ -60,7 +60,7 @@ public class StoryServiceImpl implements StoryService {
@Override @Override
public void deleteStory(String storyId) { public void deleteStory(String storyId) {
Story story = storyMapper.selectById(storyId); Story story = storyMapper.selectByInstanceId(storyId);
if (story == null) { if (story == null) {
throw new CustomException(ResponseEnum.NOT_FOUND); throw new CustomException(ResponseEnum.NOT_FOUND);
} }
@ -68,8 +68,8 @@ public class StoryServiceImpl implements StoryService {
} }
@Override @Override
public Story getStoryById(String storyId) { public Story getStoryByInstanceId(String storyId) {
Story story = storyMapper.selectById(storyId); Story story = storyMapper.selectByInstanceId(storyId);
if (story == null) { if (story == null) {
throw new CustomException(ResponseEnum.NOT_FOUND); throw new CustomException(ResponseEnum.NOT_FOUND);
} }

View File

@ -13,6 +13,6 @@ public class StoryItemVo {
private String description; private String description;
private String location; private String location;
private LocalDateTime storyItemTime; private LocalDateTime storyItemTime;
private Integer isRoot; private String storyInstanceId;
} }

View File

@ -30,4 +30,16 @@
INSERT INTO common_relation (rela_id, sub_rela_id, rela_type, user_id) INSERT INTO common_relation (rela_id, sub_rela_id, rela_type, user_id)
VALUES (#{relaId}, #{subRelaId}, #{relationType}, #{userId}) VALUES (#{relaId}, #{subRelaId}, #{relationType}, #{userId})
</insert> </insert>
<update id="deleteRelationByRelaId">
UPDATE common_relation
SET is_delete = 1
WHERE rela_id = #{relaId}
</update>
<update id="deleteRelationBySubRelaId">
UPDATE common_relation
SET is_delete = 1
WHERE sub_rela_id = #{subRelaId}
</update>
</mapper> </mapper>

View File

@ -5,8 +5,8 @@
<mapper namespace="com.timeline.story.dao.StoryItemMapper"> <mapper namespace="com.timeline.story.dao.StoryItemMapper">
<insert id="insert"> <insert id="insert">
INSERT INTO story_item (item_id, master_item, description, location, title, create_id, is_root, is_delete, story_item_time, cover_instance_id) INSERT INTO story_item (instance_id, master_item_id, description, location, title, create_id, story_instance_id, is_delete, story_item_time, cover_instance_id)
VALUES (#{itemId}, #{masterItem}, #{description}, #{location}, #{title},#{createId}, #{isRoot}, #{isDelete}, #{storyItemTime}, #{coverInstanceId}) VALUES (#{instanceId}, #{masterItemId}, #{description}, #{location}, #{title},#{createId}, #{storyInstanceId}, #{isDelete}, #{storyItemTime}, #{coverInstanceId})
</insert> </insert>
<update id="update"> <update id="update">
@ -15,74 +15,32 @@
location = #{location}, location = #{location},
create_id = #{createId}, create_id = #{createId},
update_time = NOW() update_time = NOW()
WHERE item_id = #{itemId} WHERE instance_id = #{instanceId}
</update> </update>
<delete id="deleteById"> <delete id="deleteByItemId">
DELETE FROM story_item WHERE item_id = #{itemId} UPDATE story_item
SET is_delete = 1
WHERE instance_id = #{instanceId}
</delete> </delete>
<select id="selectById" resultType="com.timeline.story.entity.StoryItem"> <select id="selectById" resultType="com.timeline.story.entity.StoryItem">
SELECT * FROM story_item WHERE item_id = #{itemId} SELECT * FROM story_item WHERE instance_id = #{instanceId}
</select> </select>
<select id="selectByMasterItem" resultType="com.timeline.story.entity.StoryItem"> <select id="selectByMasterItem" resultType="com.timeline.story.entity.StoryItem">
SELECT * FROM story_item WHERE master_item = #{masterItemId} AND is_delete = 0 SELECT * FROM story_item WHERE master_item_id = #{masterItemId} AND is_delete = 0
</select> </select>
<select id="selectImagesByItemId" resultType="java.lang.String"> <select id="selectImagesByItemId" resultType="java.lang.String">
SELECT sub_rela_id FROM common_relation WHERE rela_id = #{itemId} AND rela_type = 5 AND is_delete = 0 SELECT sub_rela_id FROM common_relation WHERE rela_id = #{instanceId} AND rela_type = 5 AND is_delete = 0
</select> </select>
<select id="selectByMasterItemWithSubItems" resultType="com.timeline.story.entity.StoryItem"> <select id="selectStoryItemByStoryInstanceId" resultType="com.timeline.story.entity.StoryItem">
WITH RECURSIVE StoryItemTree AS ( SELECT * FROM story_item WHERE story_instance_id = #{storyInstanceId} AND is_delete = 0
SELECT
item_id,
master_item,
title,
description,
location,
create_id,
create_time,
update_time,
story_item_time,
is_root,
is_delete,
cover_instance_id,
0 AS level,
CAST(item_id AS CHAR(255)) AS path
FROM
story_item
WHERE
master_item = #{masterItemId}
AND is_delete = 0
UNION ALL
SELECT
si.item_id,
si.master_item,
si.title,
si.description,
si.location,
si.create_id,
si.create_time,
si.update_time,
si.story_item_time,
si.is_root,
si.is_delete,
si.cover_instance_id,
t.level + 1,
CONCAT(t.path, '->', si.item_id)
FROM
story_item si
INNER JOIN
StoryItemTree t ON si.master_item = t.item_id
WHERE
si.is_delete = 0
)
SELECT * FROM StoryItemTree
ORDER BY story_item_time ASC; ORDER BY story_item_time ASC;
</select> </select>
<select id="countByStoryId" resultType="int">
SELECT COUNT(*) FROM story_item WHERE story_instance_id = #{storyInstanceId} AND is_delete = 0
</select>
</mapper> </mapper>

View File

@ -24,7 +24,7 @@
UPDATE story SET story.is_delete = 1 WHERE instance_id = #{instanceId} UPDATE story SET story.is_delete = 1 WHERE instance_id = #{instanceId}
</delete> </delete>
<select id="selectById" resultType="com.timeline.story.entity.Story"> <select id="selectByInstanceId" resultType="com.timeline.story.entity.Story">
SELECT * FROM story WHERE instance_id = #{instanceId} SELECT * FROM story WHERE instance_id = #{instanceId}
</select> </select>