diff --git a/timeline-story-service/src/main/java/com/timeline/story/controller/StoryItemController.java b/timeline-story-service/src/main/java/com/timeline/story/controller/StoryItemController.java index 8e7ba87..8987b61 100644 --- a/timeline-story-service/src/main/java/com/timeline/story/controller/StoryItemController.java +++ b/timeline-story-service/src/main/java/com/timeline/story/controller/StoryItemController.java @@ -8,10 +8,12 @@ import com.timeline.story.vo.StoryItemAddVo; import com.timeline.story.vo.StoryItemVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.openfeign.SpringQueryMap; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; +import java.util.Map; @RestController @RequestMapping("/story/item") @@ -53,9 +55,9 @@ public class StoryItemController { } @GetMapping("/list") - public ResponseEntity> getItemsByMasterItem(@RequestParam String storyInstanceId) { - log.info("查询 StoryItem 列表,storyInstanceId: {}", storyInstanceId); - List items = storyItemService.getItemsByMasterItem(storyInstanceId); + public ResponseEntity getItemsByMasterItem(@SpringQueryMap StoryItemVo storyItemVo) { + log.info("查询 StoryItem 列表,storyInstanceId: {}, current: {}, pageSize:{}", storyItemVo.getStoryInstanceId(), storyItemVo.getCurrent(), storyItemVo.getPageSize()); + Map items = storyItemService.getItemsByMasterItem(storyItemVo); return ResponseEntity.success(items); } @GetMapping("/images/{itemId}") diff --git a/timeline-story-service/src/main/java/com/timeline/story/controller/StoryPermissionController.java b/timeline-story-service/src/main/java/com/timeline/story/controller/StoryPermissionController.java new file mode 100644 index 0000000..344d80b --- /dev/null +++ b/timeline-story-service/src/main/java/com/timeline/story/controller/StoryPermissionController.java @@ -0,0 +1,73 @@ +package com.timeline.story.controller; + +import com.timeline.common.response.ResponseEntity; +import com.timeline.story.entity.StoryPermission; +import com.timeline.story.service.StoryPermissionService; +import com.timeline.story.vo.StoryPermissionVo; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/story/permission") +@Slf4j +public class StoryPermissionController { + + @Autowired + private StoryPermissionService storyPermissionService; + + @PostMapping + public ResponseEntity createPermission(@RequestBody StoryPermissionVo permissionVo) { + log.info("创建权限: {}", permissionVo); + storyPermissionService.createPermission(permissionVo); + return ResponseEntity.success("权限创建成功"); + } + + @PutMapping + public ResponseEntity updatePermission(@RequestBody StoryPermissionVo permissionVo) { + log.info("更新权限: {}", permissionVo); + storyPermissionService.updatePermission(permissionVo); + return ResponseEntity.success("权限更新成功"); + } + + @DeleteMapping("/{permissionId}") + public ResponseEntity deletePermission(@PathVariable String permissionId) { + log.info("删除权限: {}", permissionId); + storyPermissionService.deletePermission(permissionId); + return ResponseEntity.success("权限删除成功"); + } + + @GetMapping("/{permissionId}") + public ResponseEntity getPermissionById(@PathVariable String permissionId) { + log.info("获取权限详情: {}", permissionId); + StoryPermission permission = storyPermissionService.getPermissionById(permissionId); + return ResponseEntity.success(permission); + } + + @GetMapping("/story/{storyInstanceId}") + public ResponseEntity> getPermissionsByStoryId(@PathVariable String storyInstanceId) { + log.info("获取故事情限列表: {}", storyInstanceId); + List permissions = storyPermissionService.getPermissionsByStoryId(storyInstanceId); + return ResponseEntity.success(permissions); + } + + @GetMapping("/user/{userId}") + public ResponseEntity> getPermissionsByUserId(@PathVariable String userId) { + log.info("获取用户权限列表: {}", userId); + List permissions = storyPermissionService.getPermissionsByUserId(userId); + return ResponseEntity.success(permissions); + } + + @GetMapping("/check") + public ResponseEntity checkUserPermission( + @RequestParam String storyInstanceId, + @RequestParam String userId, + @RequestParam Integer requiredPermissionType) { + log.info("检查用户权限: storyInstanceId={}, userId={}, requiredPermissionType={}", + storyInstanceId, userId, requiredPermissionType); + boolean hasPermission = storyPermissionService.checkUserPermission(storyInstanceId, userId, requiredPermissionType); + return ResponseEntity.success(hasPermission); + } +} diff --git a/timeline-story-service/src/main/java/com/timeline/story/dao/StoryItemMapper.java b/timeline-story-service/src/main/java/com/timeline/story/dao/StoryItemMapper.java index aa39770..c65eda7 100644 --- a/timeline-story-service/src/main/java/com/timeline/story/dao/StoryItemMapper.java +++ b/timeline-story-service/src/main/java/com/timeline/story/dao/StoryItemMapper.java @@ -4,6 +4,7 @@ import com.timeline.story.entity.StoryItem; import org.apache.ibatis.annotations.Mapper; import java.util.List; +import java.util.Map; @Mapper public interface StoryItemMapper { @@ -13,6 +14,6 @@ public interface StoryItemMapper { StoryItem selectById(String itemId); List selectByMasterItem(String masterItemId); List selectImagesByItemId(String itemId); - List selectStoryItemByStoryInstanceId(String storyInstanceId); + List selectStoryItemByStoryInstanceId(Map map); int countByStoryId(String storyInstanceId); } diff --git a/timeline-story-service/src/main/java/com/timeline/story/dao/StoryPermissionMapper.java b/timeline-story-service/src/main/java/com/timeline/story/dao/StoryPermissionMapper.java new file mode 100644 index 0000000..ae19265 --- /dev/null +++ b/timeline-story-service/src/main/java/com/timeline/story/dao/StoryPermissionMapper.java @@ -0,0 +1,18 @@ +package com.timeline.story.dao; + +import com.timeline.story.entity.StoryPermission; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface StoryPermissionMapper { + void insert(StoryPermission permission); + void update(StoryPermission permission); + void deleteByPermissionId(String permissionId); + StoryPermission selectByPermissionId(String permissionId); + List selectByStoryInstanceId(String storyInstanceId); + List selectByUserId(String userId); + StoryPermission selectByStoryAndUser(String storyInstanceId, String userId); + List selectByStoryAndPermissionType(String storyInstanceId, Integer permissionType); +} diff --git a/timeline-story-service/src/main/java/com/timeline/story/entity/Story.java b/timeline-story-service/src/main/java/com/timeline/story/entity/Story.java index 50ba5d9..9d5efac 100644 --- a/timeline-story-service/src/main/java/com/timeline/story/entity/Story.java +++ b/timeline-story-service/src/main/java/com/timeline/story/entity/Story.java @@ -19,4 +19,9 @@ public class Story { private String ownerId; private String status; private String logo; + // 新增字段:创建人名称和修改人名称 + private String ownerName; + private String updateName; + // 新增字段:故事项数量 + private Integer itemCount; } diff --git a/timeline-story-service/src/main/java/com/timeline/story/entity/StoryPermission.java b/timeline-story-service/src/main/java/com/timeline/story/entity/StoryPermission.java new file mode 100644 index 0000000..4843f70 --- /dev/null +++ b/timeline-story-service/src/main/java/com/timeline/story/entity/StoryPermission.java @@ -0,0 +1,20 @@ +package com.timeline.story.entity; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class StoryPermission { + private Integer id; + private String permissionId; + private String storyInstanceId; + private String userId; + private Integer permissionType; // 1-创建者,2-仅查看,3-可新增,4-可管理 + private Integer isDeleted; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updateTime; +} diff --git a/timeline-story-service/src/main/java/com/timeline/story/service/StoryItemService.java b/timeline-story-service/src/main/java/com/timeline/story/service/StoryItemService.java index e9bca22..51c6463 100644 --- a/timeline-story-service/src/main/java/com/timeline/story/service/StoryItemService.java +++ b/timeline-story-service/src/main/java/com/timeline/story/service/StoryItemService.java @@ -7,6 +7,7 @@ import com.timeline.story.vo.StoryItemWithCoverVo; import org.springframework.web.multipart.MultipartFile; import java.util.List; +import java.util.Map; public interface StoryItemService { void createStoryItem(StoryItemAddVo storyItemVo, List images); @@ -14,7 +15,7 @@ public interface StoryItemService { void updateItem(String itemId, String description, String location); void deleteItem(String itemId); StoryItem getItemById(String itemId); - List getItemsByMasterItem(String masterItemId); + Map getItemsByMasterItem(StoryItemVo storyItemVo); List getStoryItemImages(String storyItemId); Integer getStoryItemCount(String instanceId); diff --git a/timeline-story-service/src/main/java/com/timeline/story/service/StoryPermissionService.java b/timeline-story-service/src/main/java/com/timeline/story/service/StoryPermissionService.java new file mode 100644 index 0000000..831cbf2 --- /dev/null +++ b/timeline-story-service/src/main/java/com/timeline/story/service/StoryPermissionService.java @@ -0,0 +1,18 @@ +package com.timeline.story.service; + +import com.timeline.story.entity.StoryPermission; +import com.timeline.story.vo.StoryPermissionVo; + +import java.util.List; + +public interface StoryPermissionService { + void createPermission(StoryPermissionVo permissionVo); + void updatePermission(StoryPermissionVo permissionVo); + void deletePermission(String permissionId); + StoryPermission getPermissionById(String permissionId); + List getPermissionsByStoryId(String storyInstanceId); + List getPermissionsByUserId(String userId); + StoryPermission getPermissionByStoryAndUser(String storyInstanceId, String userId); + boolean checkUserPermission(String storyInstanceId, String userId, Integer requiredPermissionType); + List getPermissionsByStoryAndType(String storyInstanceId, Integer permissionType); +} diff --git a/timeline-story-service/src/main/java/com/timeline/story/service/impl/StoryItemServiceImpl.java b/timeline-story-service/src/main/java/com/timeline/story/service/impl/StoryItemServiceImpl.java index 5e6404e..0c7a18f 100644 --- a/timeline-story-service/src/main/java/com/timeline/story/service/impl/StoryItemServiceImpl.java +++ b/timeline-story-service/src/main/java/com/timeline/story/service/impl/StoryItemServiceImpl.java @@ -1,6 +1,7 @@ package com.timeline.story.service.impl; import com.timeline.common.constants.CommonConstants; +import com.timeline.common.utils.PageUtils; import com.timeline.story.dao.CommonRelationMapper; import com.timeline.common.dto.CommonRelationDTO; import com.timeline.common.exception.CustomException; @@ -21,7 +22,9 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.time.LocalDateTime; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Slf4j @Service @@ -126,8 +129,12 @@ public class StoryItemServiceImpl implements StoryItemService { } @Override - public List getItemsByMasterItem(String storyInstanceId) { - return storyItemMapper.selectStoryItemByStoryInstanceId(storyInstanceId); + public Map getItemsByMasterItem(StoryItemVo storyItemVo) { + HashMap map = new HashMap<>(); + map.put("storyInstanceId", storyItemVo.getStoryInstanceId()); + Map resultMap = PageUtils.pageQuery(storyItemVo.getCurrent(), storyItemVo.getPageSize(), StoryItemMapper.class, "selectStoryItemByStoryInstanceId", + map, "list"); + return resultMap; } @Override diff --git a/timeline-story-service/src/main/java/com/timeline/story/service/impl/StoryPermissionServiceImpl.java b/timeline-story-service/src/main/java/com/timeline/story/service/impl/StoryPermissionServiceImpl.java new file mode 100644 index 0000000..7a7402a --- /dev/null +++ b/timeline-story-service/src/main/java/com/timeline/story/service/impl/StoryPermissionServiceImpl.java @@ -0,0 +1,111 @@ +package com.timeline.story.service.impl; + +import com.timeline.common.constants.CommonConstants; +import com.timeline.common.exception.CustomException; +import com.timeline.common.response.ResponseEnum; +import com.timeline.common.utils.IdUtils; +import com.timeline.story.dao.StoryPermissionMapper; +import com.timeline.story.entity.StoryPermission; +import com.timeline.story.service.StoryPermissionService; +import com.timeline.story.vo.StoryPermissionVo; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; + +@Slf4j +@Service +public class StoryPermissionServiceImpl implements StoryPermissionService { + + @Autowired + private StoryPermissionMapper storyPermissionMapper; + + @Override + public void createPermission(StoryPermissionVo permissionVo) { + try { + StoryPermission permission = new StoryPermission(); + BeanUtils.copyProperties(permissionVo, permission); + permission.setPermissionId(IdUtils.randomUuidUpper()); + permission.setCreateTime(LocalDateTime.now()); + permission.setUpdateTime(LocalDateTime.now()); + permission.setIsDeleted(CommonConstants.NOT_DELETED); + storyPermissionMapper.insert(permission); + } catch (Exception e) { + log.error("创建权限失败", e); + throw new CustomException(ResponseEnum.INTERNAL_SERVER_ERROR, "创建权限失败"); + } + } + + @Override + public void updatePermission(StoryPermissionVo permissionVo) { + try { + StoryPermission permission = storyPermissionMapper.selectByPermissionId(permissionVo.getPermissionId()); + if (permission == null) { + throw new CustomException(ResponseEnum.NOT_FOUND, "权限记录不存在"); + } + BeanUtils.copyProperties(permissionVo, permission); + permission.setUpdateTime(LocalDateTime.now()); + storyPermissionMapper.update(permission); + } catch (CustomException e) { + throw e; + } catch (Exception e) { + log.error("更新权限失败", e); + throw new CustomException(ResponseEnum.INTERNAL_SERVER_ERROR, "更新权限失败"); + } + } + + @Override + public void deletePermission(String permissionId) { + try { + StoryPermission permission = storyPermissionMapper.selectByPermissionId(permissionId); + if (permission == null) { + throw new CustomException(ResponseEnum.NOT_FOUND, "权限记录不存在"); + } + storyPermissionMapper.deleteByPermissionId(permissionId); + } catch (CustomException e) { + throw e; + } catch (Exception e) { + log.error("删除权限失败", e); + throw new CustomException(ResponseEnum.INTERNAL_SERVER_ERROR, "删除权限失败"); + } + } + + @Override + public StoryPermission getPermissionById(String permissionId) { + return storyPermissionMapper.selectByPermissionId(permissionId); + } + + @Override + public List getPermissionsByStoryId(String storyInstanceId) { + return storyPermissionMapper.selectByStoryInstanceId(storyInstanceId); + } + + @Override + public List getPermissionsByUserId(String userId) { + return storyPermissionMapper.selectByUserId(userId); + } + + @Override + public StoryPermission getPermissionByStoryAndUser(String storyInstanceId, String userId) { + return storyPermissionMapper.selectByStoryAndUser(storyInstanceId, userId); + } + + @Override + public boolean checkUserPermission(String storyInstanceId, String userId, Integer requiredPermissionType) { + StoryPermission permission = storyPermissionMapper.selectByStoryAndUser(storyInstanceId, userId); + if (permission == null) { + return false; + } + + // 权限类型数字越大权限越高 + return permission.getPermissionType() >= requiredPermissionType; + } + + @Override + public List getPermissionsByStoryAndType(String storyInstanceId, Integer permissionType) { + return storyPermissionMapper.selectByStoryAndPermissionType(storyInstanceId, permissionType); + } +} diff --git a/timeline-story-service/src/main/java/com/timeline/story/service/impl/StoryServiceImpl.java b/timeline-story-service/src/main/java/com/timeline/story/service/impl/StoryServiceImpl.java index abbc3e3..20f9ece 100644 --- a/timeline-story-service/src/main/java/com/timeline/story/service/impl/StoryServiceImpl.java +++ b/timeline-story-service/src/main/java/com/timeline/story/service/impl/StoryServiceImpl.java @@ -4,7 +4,9 @@ import com.timeline.common.exception.CustomException; import com.timeline.common.response.ResponseEnum; import com.timeline.story.entity.Story; import com.timeline.story.dao.StoryMapper; +import com.timeline.story.service.StoryPermissionService; import com.timeline.story.service.StoryService; +import com.timeline.story.vo.StoryPermissionVo; import com.timeline.story.vo.StoryVo; import com.timeline.common.utils.IdUtils; import lombok.extern.slf4j.Slf4j; @@ -21,6 +23,8 @@ public class StoryServiceImpl implements StoryService { @Autowired private StoryMapper storyMapper; + @Autowired + private StoryPermissionService storyPermissionService; @Override public void createStory(StoryVo storyVo) { try { @@ -35,6 +39,12 @@ public class StoryServiceImpl implements StoryService { story.setLogo(storyVo.getLogo()); story.setIsDelete(0); storyMapper.insert(story); + // 自动添加创建者权限 + StoryPermissionVo permissionVo = new StoryPermissionVo(); + permissionVo.setStoryInstanceId(story.getInstanceId()); + permissionVo.setUserId(storyVo.getOwnerId()); + permissionVo.setPermissionType(1); // 创建者权限 + storyPermissionService.createPermission(permissionVo); } catch (Exception e) { log.error("创建故事失败", e); throw new CustomException(500, "创建故事失败: " + e.toString()); @@ -54,6 +64,11 @@ public class StoryServiceImpl implements StoryService { story.setStatus(storyVo.getStatus()); story.setUpdateTime(LocalDateTime.now()); story.setLogo(storyVo.getLogo()); + + // 如果传入了 updateId,则更新 updateId todo: 使用线程获取用户ID + if (storyVo.getOwnerId() != null && !storyVo.getOwnerId().isEmpty()) { + story.setUpdateId(storyVo.getOwnerId()); + } storyMapper.update(story); } diff --git a/timeline-story-service/src/main/java/com/timeline/story/vo/StoryItemVo.java b/timeline-story-service/src/main/java/com/timeline/story/vo/StoryItemVo.java index 31ccad4..57e218c 100644 --- a/timeline-story-service/src/main/java/com/timeline/story/vo/StoryItemVo.java +++ b/timeline-story-service/src/main/java/com/timeline/story/vo/StoryItemVo.java @@ -1,12 +1,12 @@ package com.timeline.story.vo; +import com.timeline.common.vo.CommonVo; import lombok.Data; import java.time.LocalDateTime; @Data - -public class StoryItemVo { +public class StoryItemVo extends CommonVo { private String instanceId; private String masterItemId; private String title; diff --git a/timeline-story-service/src/main/java/com/timeline/story/vo/StoryPermissionVo.java b/timeline-story-service/src/main/java/com/timeline/story/vo/StoryPermissionVo.java new file mode 100644 index 0000000..b964c74 --- /dev/null +++ b/timeline-story-service/src/main/java/com/timeline/story/vo/StoryPermissionVo.java @@ -0,0 +1,13 @@ +package com.timeline.story.vo; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class StoryPermissionVo { + private String permissionId; + private String storyInstanceId; + private String userId; + private Integer permissionType; // 1-创建者,2-仅查看,3-可新增,4-可管理 +} diff --git a/timeline-story-service/src/main/resources/com/timeline/story/dao/StoryItemMapper.xml b/timeline-story-service/src/main/resources/com/timeline/story/dao/StoryItemMapper.xml index ddeee54..90f8533 100644 --- a/timeline-story-service/src/main/resources/com/timeline/story/dao/StoryItemMapper.xml +++ b/timeline-story-service/src/main/resources/com/timeline/story/dao/StoryItemMapper.xml @@ -37,7 +37,7 @@ - SELECT * FROM story WHERE instance_id = #{instanceId} + SELECT + s.*, + u1.user_name as owner_name, + u2.user_name as update_name, + (SELECT COUNT(*) FROM story_item si WHERE si.story_instance_id = s.instance_id AND si.is_delete = 0) as item_count + + FROM story s + + LEFT JOIN user u1 ON s.owner_id = u1.user_id AND u1.is_deleted = 0 + LEFT JOIN user u2 ON s.update_id = u2.user_id AND u2.is_deleted = 0 + WHERE s.instance_id = #{instanceId} diff --git a/timeline-story-service/src/main/resources/com/timeline/story/dao/StoryPermissionMapper.xml b/timeline-story-service/src/main/resources/com/timeline/story/dao/StoryPermissionMapper.xml new file mode 100644 index 0000000..2b00acc --- /dev/null +++ b/timeline-story-service/src/main/resources/com/timeline/story/dao/StoryPermissionMapper.xml @@ -0,0 +1,46 @@ + + + + + + + INSERT INTO story_permission (permission_id, story_instance_id, user_id, permission_type) + VALUES (#{permissionId}, #{storyInstanceId}, #{userId}, #{permissionType}) + + + + UPDATE story_permission + SET permission_type = #{permissionType}, + update_time = NOW() + WHERE permission_id = #{permissionId} AND is_deleted = 0 + + + + UPDATE story_permission + SET is_deleted = 1 + WHERE permission_id = #{permissionId} + + + + + + + + + + + +