Bladeren bron

[feat]
对原有的写游记模块,增加@用户,#话题,关联群聊的功能

chenchen 1 maand geleden
bovenliggende
commit
c07a924f01
56 gewijzigde bestanden met toevoegingen van 3150 en 151 verwijderingen
  1. 144 147
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/WebSiteTourismTravelNotesPublishController.java
  2. 26 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/TourismProjectTravelNotesWriteToWebDto.java
  3. 34 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/model/TourShortImGroup.java
  4. 21 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/model/TourShortTopic.java
  5. 29 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/model/TourShortUser.java
  6. 21 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/TourTravelNotesPublishService.java
  7. 6 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/impl/BasicToWebServiceImpl.java
  8. 352 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/impl/TourTravelNotesPublishServiceImpl.java
  9. 31 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/TourShortImGroupVo.java
  10. 22 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/TourShortTopicVo.java
  11. 37 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/TourShortUserVo.java
  12. 179 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourTravelNotesImgController.java
  13. 179 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourTravelNotesMentionUserController.java
  14. 179 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourTravelNotesTopicController.java
  15. 179 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourTravelNotesTopicRelationController.java
  16. 11 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourFansMapper.java
  17. 12 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourImGroupMapper.java
  18. 33 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourTravelNotesImgMapper.java
  19. 33 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourTravelNotesMentionUserMapper.java
  20. 43 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourTravelNotesTopicMapper.java
  21. 33 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourTravelNotesTopicRelationMapper.java
  22. 17 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourFansMapper.xml
  23. 18 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourImGroupMapper.xml
  24. 47 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourTravelNotesImgMapper.xml
  25. 57 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourTravelNotesMentionUserMapper.xml
  26. 89 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourTravelNotesTopicMapper.xml
  27. 57 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourTravelNotesTopicRelationMapper.xml
  28. 8 3
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourismProjectTravelNotesWriteMapper.xml
  29. 39 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourTravelNotesImgDto.java
  30. 47 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourTravelNotesMentionUserDto.java
  31. 43 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourTravelNotesTopicDto.java
  32. 47 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourTravelNotesTopicRelationDto.java
  33. 6 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourismProjectTravelNotesWriteDto.java
  34. 33 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourTravelNotesImg.java
  35. 39 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourTravelNotesMentionUser.java
  36. 53 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourTravelNotesTopic.java
  37. 39 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourTravelNotesTopicRelation.java
  38. 13 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourismProjectTravelNotesWrite.java
  39. 11 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourFansService.java
  40. 10 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourImGroupService.java
  41. 68 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourTravelNotesImgService.java
  42. 68 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourTravelNotesMentionUserService.java
  43. 68 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourTravelNotesTopicRelationService.java
  44. 76 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourTravelNotesTopicService.java
  45. 7 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourFansServiceImpl.java
  46. 7 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourImGroupServiceImpl.java
  47. 98 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourTravelNotesImgServiceImpl.java
  48. 98 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourTravelNotesMentionUserServiceImpl.java
  49. 98 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourTravelNotesTopicRelationServiceImpl.java
  50. 109 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourTravelNotesTopicServiceImpl.java
  51. 33 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourTravelNotesImgVo.java
  52. 39 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourTravelNotesMentionUserVo.java
  53. 39 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourTravelNotesTopicRelationVo.java
  54. 43 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourTravelNotesTopicVo.java
  55. 19 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourismProjectTravelNotesWriteVo.java
  56. 3 1
      common/common-core/src/main/java/com/tourism/common/core/constant/ErrorCodeEnum.java

+ 144 - 147
application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/WebSiteTourismTravelNotesPublishController.java

@@ -12,19 +12,25 @@ import com.tourism.common.core.util.MyModelUtil;
 import com.tourism.common.core.util.MyPageUtil;
 import com.tourism.common.core.validator.UpdateGroup;
 import com.tourism.common.huaweicloud.moderation.service.HuaweiCloudModerationService;
+import com.tourism.common.huaweicloud.obs.util.MergeAvatarsFlexUtils;
 import com.tourism.common.log.annotation.OperationLog;
 import com.tourism.common.log.model.constant.SysOperationLogType;
 import com.tourism.common.sequence.wrapper.IdGeneratorWrapper;
 import com.tourism.webadmin.app.website.dto.TourismProjectTravelNotesWriteDetailPageDto;
 import com.tourism.webadmin.app.website.dto.TourismProjectTravelNotesWriteToWebDto;
 import com.tourism.webadmin.app.website.dto.WebsiteTourUserDto;
-import com.tourism.webadmin.app.website.vo.TourWriteBelongTabVo;
-import com.tourism.webadmin.app.website.vo.TourismProjectTravelNotesWriteCovertVo;
+import com.tourism.webadmin.app.website.model.TourShortImGroup;
+import com.tourism.webadmin.app.website.model.TourShortTopic;
+import com.tourism.webadmin.app.website.model.TourShortUser;
+import com.tourism.webadmin.app.website.service.TourTravelNotesPublishService;
+import com.tourism.webadmin.app.website.vo.*;
+import com.tourism.webadmin.back.dto.TourTravelNotesMentionUserDto;
 import com.tourism.webadmin.back.dto.TourismTravelNotesContentWriteDto;
 import com.tourism.webadmin.back.model.*;
 import com.tourism.webadmin.back.model.constant.AuditState;
 import com.tourism.webadmin.back.model.constant.UnmountState;
 import com.tourism.webadmin.back.service.*;
+import com.tourism.webadmin.back.vo.TourTravelNotesTopicVo;
 import com.tourism.webadmin.back.vo.TourismProjectTravelNotesWriteVo;
 import com.tourism.webadmin.back.vo.TourismTravelNotesContentWriteVo;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -37,8 +43,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Tag(name = "门户网站发布游记接口")
@@ -63,6 +68,18 @@ public class WebSiteTourismTravelNotesPublishController {
     private HuaweiCloudModerationService huaweiCloudModerationService;
     @Autowired
     private ApplicationConfig applicationConfig;
+    @Autowired
+    private TourFansService tourFansService;
+    @Autowired
+    private TourTravelNotesTopicService tourTravelNotesTopicService;
+    @Autowired
+    private TourImGroupService tourImGroupService;
+    @Autowired
+    private TourImMemberService tourImMemberService;
+    @Autowired
+    private MergeAvatarsFlexUtils mergeAvatarsFlexUtils;
+    @Autowired
+    private TourTravelNotesPublishService tourTravelNotesPublishService;
 
     /**
      * 获取草稿id
@@ -84,54 +101,31 @@ public class WebSiteTourismTravelNotesPublishController {
     @PostMapping("/saveDraft")
     public ResponseResult<Void> saveDraft(@RequestBody TourismProjectTravelNotesWriteToWebDto tourismProjectTravelNotesWriteDto) {
 
-
-        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite =
-                tourismProjectTravelNotesWriteService.getById(tourismProjectTravelNotesWriteDto.getId());
-
-        TourismProjectTravelNotesWrite tourismProjectTravelNotesWriteSave =
-                MyModelUtil.copyTo(tourismProjectTravelNotesWriteDto,TourismProjectTravelNotesWrite.class);
-
-        //将从表中的数据进行过滤,筛选出cover为1的图片为封面图,第一段落为项目简述
-        List<TourismTravelNotesContentWriteDto> travelNotesContent = tourismProjectTravelNotesWriteDto.getTravelNotesContent();
-
-        //循环遍历查询内容是否超过5000长度
-        for(TourismTravelNotesContentWriteDto i:travelNotesContent){
-            if(StringUtils.isNotBlank(i.getContent()) && i.getContent().length()>5000)
-                return ResponseResult.error(ErrorCodeEnum.CONTENT_OUT_LIMIT);
-        }
-        List<TourismTravelNotesContentWriteDto> coverImageList = travelNotesContent.stream().filter(item -> item.getType().equals("image") && item.getCover() != null && item.getCover() == 1).collect(Collectors.toList());
-        List<TourismTravelNotesContentWriteDto> coverImageList1 = travelNotesContent.stream().filter(item -> item.getType().equals("image")).collect(Collectors.toList());
-        if(CollectionUtils.isEmpty(coverImageList)){
-            if(CollectionUtils.isNotEmpty(coverImageList1)){
-                tourismProjectTravelNotesWriteSave.setTourismUrl(coverImageList1.get(0).getContent());
-            }
-        }else{
-            tourismProjectTravelNotesWriteSave.setTourismUrl(coverImageList.get(0).getContent());
+        //先校验提及的用户id是否符合互关的状态
+        List<TourTravelNotesMentionUserDto> mentions = tourismProjectTravelNotesWriteDto.getMentions();
+        List<TourTravelNotesMentionUserDto> mentionsUserIdList = mentions.stream().filter(item -> item.getUserId() != null).collect(Collectors.toList());
+        Long userId = TokenData.takeFromRequest().getUserId();
+        List<TourShortUser> fouceEachFriendsByName = tourFansService.getFouceEachFriendsByName(userId, "");
+        List<TourShortUser> fouceEachFriedsUserIdList = fouceEachFriendsByName.stream().filter(i -> i.getUserId() != null).collect(Collectors.toList());
+        if(!(fouceEachFriedsUserIdList).containsAll(mentionsUserIdList)){
+            return ResponseResult.error(ErrorCodeEnum.MENTION_USER_ERROR,"提及的用户与本人不符合互关的状态");
         }
 
-        //判断是新增还是更新
-        if(tourismProjectTravelNotesWrite == null){
-            //草稿为下架状态
-            tourismProjectTravelNotesWriteSave.setUnmountState(UnmountState.DELIST);
-            tourismProjectTravelNotesWriteService.saveNew(tourismProjectTravelNotesWriteSave);
-        }else {
-            //草稿为下架状态
-            tourismProjectTravelNotesWriteSave.setUnmountState(UnmountState.DELIST);
-            tourismProjectTravelNotesWriteService.updateById(tourismProjectTravelNotesWriteSave);
+        //校验dto中的群聊是否为本人参与的群聊
+        List<TourShortImGroup> takePartImGroupListByName = tourImGroupService.getTakePartImGroupListByName(userId, "");
+        List<Long> takePartImGroupIdList = takePartImGroupListByName.stream().mapToLong(TourShortImGroup::getId).boxed().collect(Collectors.toList());
+        if(!takePartImGroupIdList.contains(tourismProjectTravelNotesWriteDto.getTourImGroupId())){
+            return ResponseResult.error(ErrorCodeEnum.MENTION_GROUP_ERROR,"本人未参与到关联的群聊中");
         }
 
-        //判断内容是否为空
-        if(tourismProjectTravelNotesWriteDto.getTravelNotesContent() != null) {
-            List<TourismTravelNotesContentWriteDto> travelNotesContentWriteList = tourismProjectTravelNotesWriteDto.getTravelNotesContent();
-            List<TourismTravelNotesContentWrite> tourismTravelNotesContentWriteList = MyModelUtil.copyCollectionTo(travelNotesContentWriteList, TourismTravelNotesContentWrite.class);
-            for (TourismTravelNotesContentWrite item : tourismTravelNotesContentWriteList) {
-                item.setAssociationId(tourismProjectTravelNotesWriteSave.getId());
-                item.setId(null);
-            }
-            tourismTravelNotesContentWriteService.removeByAssociationId(tourismProjectTravelNotesWriteSave.getId());
-            //查询关联数据的id,根据id进行更新数据表的数据
-            tourismTravelNotesContentWriteService.saveNewBatch(tourismTravelNotesContentWriteList);
+        //循环遍历查询内容是否超过5000长度
+        List<TourismTravelNotesContentWriteDto> travelNotesContent = tourismProjectTravelNotesWriteDto.getTravelNotesContent();
+        for (TourismTravelNotesContentWriteDto i : travelNotesContent) {
+            if (StringUtils.isNotBlank(i.getContent()) && i.getContent().length() > 5000)
+                return ResponseResult.error(ErrorCodeEnum.CONTENT_OUT_LIMIT);
         }
+        
+        tourTravelNotesPublishService.saveDraft(tourismProjectTravelNotesWriteDto);
         return ResponseResult.success();
     }
 
@@ -147,22 +141,8 @@ public class WebSiteTourismTravelNotesPublishController {
         if (pageDto.getType() == null) {
             return ResponseResult.success(null);
         }
-        Long userId = TokenData.takeFromRequest().getUserId();
-        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite = new TourismProjectTravelNotesWrite();
-        tourismProjectTravelNotesWrite.setCreateUserId(userId);
-        tourismProjectTravelNotesWrite.setState(pageDto.getType());
-        MyOrderParam myOrderParam = new MyOrderParam();
-        myOrderParam.add(new MyOrderParam.OrderInfo("updateTime",false,null));
-        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourismProjectTravelNotesWrite.class);
-        if(pageDto.getPageSize() != null && pageDto.getPageNum() != null){
-            PageMethod.startPage(pageDto.getPageNum(), pageDto.getPageSize(), true);
-        }
-        //查询已发布状态的状态,则需要state为3并且上下架状态为上架
-        if(pageDto.getType() == 3){
-            tourismProjectTravelNotesWrite.setUnmountState(UnmountState.LISTING);
-        }
-        List<TourismProjectTravelNotesWrite> tourismProjectTravelNotesWriteList =
-                tourismProjectTravelNotesWriteService.getTourismProjectTravelNotesWriteList(tourismProjectTravelNotesWrite, orderBy);
+
+        List<TourismProjectTravelNotesWrite> tourismProjectTravelNotesWriteList = tourTravelNotesPublishService.getDraftList(pageDto);
 
         MyPageData<TourismProjectTravelNotesWriteCovertVo> tourismProjectTravelNotesWriteVoMyPageData = MyPageUtil.makeResponseData(tourismProjectTravelNotesWriteList, TourismProjectTravelNotesWriteCovertVo.class);
         List<TourismProjectTravelNotesWriteCovertVo> dataList = tourismProjectTravelNotesWriteVoMyPageData.getDataList();
@@ -218,8 +198,7 @@ public class WebSiteTourismTravelNotesPublishController {
                 return ResponseResult.error(ErrorCodeEnum.DATA_NOT_FOUND);
             }
         }
-        tourismProjectTravelNotesWriteService.remove(Long.valueOf(writeId));
-        tourismTravelNotesContentWriteService.removeByAssociationId(Long.valueOf(writeId));
+        tourTravelNotesPublishService.removeByDraftId(writeId);
         return ResponseResult.success();
     }
 
@@ -232,92 +211,25 @@ public class WebSiteTourismTravelNotesPublishController {
     @PostMapping("/publishDraft")
     @Transactional
     public ResponseResult<Void> publishDraft(@RequestBody TourismProjectTravelNotesWriteToWebDto tourismProjectTravelNotesWriteDto) {
-        String errorMessage = MyCommonUtil.getModelValidationError(tourismProjectTravelNotesWriteDto,UpdateGroup.class);
-        if (errorMessage != null) {
-            return ResponseResult.success(null);
-        }
-        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite =
-                MyModelUtil.copyTo(tourismProjectTravelNotesWriteDto, TourismProjectTravelNotesWrite.class);
-
-        //校验该游记是否为审核中和已发布状态
-        TourismProjectTravelNotesWrite tourismProjectTravelNotesWriteVerify =
-                tourismProjectTravelNotesWriteService.getById(tourismProjectTravelNotesWriteDto.getId());
-
-        if(tourismProjectTravelNotesWriteVerify != null){
-            if(tourismProjectTravelNotesWriteVerify.getState() .equals(AuditState.UNAUDITSTATE)) {
-                return ResponseResult.error(ErrorCodeEnum.INVALID_STATUS_ARGUMENT, "该游记状态为:正在审核中,请撤销后进行操作");
-            }else if(tourismProjectTravelNotesWriteVerify.getState() .equals(AuditState.SUCCEEDAUDIT)){
-                return ResponseResult.error(ErrorCodeEnum.INVALID_STATUS_ARGUMENT, "该游记状态为:已发布成功,请下架后进行操作");
-            }
-        }
-        //将从表中的数据进行过滤,筛选出cover为1的图片为封面图,第一段落为项目简述
-        List<TourismTravelNotesContentWriteDto> travelNotesContent = tourismProjectTravelNotesWriteDto.getTravelNotesContent();
 
-        //循环遍历查询内容是否超过5000长度
-        for(TourismTravelNotesContentWriteDto i:travelNotesContent){
-            if(StringUtils.isNotBlank(i.getContent()) && i.getContent().length()>5000)
-                return ResponseResult.error(ErrorCodeEnum.CONTENT_OUT_LIMIT);
-        }
-        List<TourismTravelNotesContentWriteDto> coverImageList = travelNotesContent.stream().filter(item -> item.getType().equals("image") && item.getCover() != null && item.getCover() == 1).collect(Collectors.toList());
-        List<TourismTravelNotesContentWriteDto> coverImageList1 = travelNotesContent.stream().filter(item -> item.getType().equals("image")).collect(Collectors.toList());
-        if(CollectionUtils.isEmpty(coverImageList)){
-            if(CollectionUtils.isEmpty(coverImageList1)){
-                return ResponseResult.error(ErrorCodeEnum.NOT_COVER);
-            }else {
-                tourismProjectTravelNotesWrite.setTourismUrl(coverImageList1.get(0).getContent());
-            }
-        }else{
-            tourismProjectTravelNotesWrite.setTourismUrl(coverImageList.get(0).getContent());
-        }
-        List<TourismTravelNotesContentWriteDto> sectionContent = travelNotesContent.stream().filter(item -> item.getType().equals("sectionContent")).collect(Collectors.toList());
-        if(CollectionUtils.isNotEmpty(sectionContent)){
-            tourismProjectTravelNotesWrite.setRemarks(sectionContent.get(0).getContent());
+        //先校验提及的用户id是否符合互关的状态
+        List<TourTravelNotesMentionUserDto> mentions = tourismProjectTravelNotesWriteDto.getMentions();
+        List<TourTravelNotesMentionUserDto> mentionsUserIdList = mentions.stream().filter(item -> item.getUserId() != null).collect(Collectors.toList());
+        Long userId = TokenData.takeFromRequest().getUserId();
+        List<TourShortUser> fouceEachFriendsByName = tourFansService.getFouceEachFriendsByName(userId, "");
+        List<TourShortUser> fouceEachFriedsUserIdList = fouceEachFriendsByName.stream().filter(i -> i.getUserId() != null).collect(Collectors.toList());
+        if(!(fouceEachFriedsUserIdList).containsAll(mentionsUserIdList)){
+            return ResponseResult.error(ErrorCodeEnum.MENTION_USER_ERROR,"提及的用户与本人不符合互关的状态");
         }
 
-        // 文案审核
-        List<String> imageList = travelNotesContent.stream().filter(e -> e.getType().equals("image")).map(TourismTravelNotesContentWriteDto::getContent).collect(Collectors.toList());
-        imageList.add(tourismProjectTravelNotesWrite.getTravelNotesBanner());
-        Boolean imageResult = huaweiCloudModerationService.runImageModeration(imageList);
-        // 图片审核
-        List<String> titleList = travelNotesContent.stream().filter(e -> e.getType().equals("sectionTitle")).map(TourismTravelNotesContentWriteDto::getContent).collect(Collectors.toList());
-        List<String> contentList = travelNotesContent.stream().filter(e -> e.getType().equals("sectionContent")).map(TourismTravelNotesContentWriteDto::getContent).collect(Collectors.toList());
-        titleList.addAll(contentList);
-        Boolean textResult = huaweiCloudModerationService.runTextModeration(titleList);
-        String auditReson = "";
-        if(imageResult && textResult){
-            tourismProjectTravelNotesWrite.setAutoAuditStatus(1);
-            auditReson = "图文审核通过";
-        }else {
-            tourismProjectTravelNotesWrite.setAutoAuditStatus(2);
-            if(!imageResult){
-                auditReson = "图片审核未通过:可能设计暴恐、色情、违禁、辱骂等内容;";
-            }
-            if(!textResult){
-                auditReson += "文案审核未通过:可能设计暴恐、色情、违禁、辱骂等内容;";
-            }
-        }
-        tourismProjectTravelNotesWrite.setAutoRejectReason(auditReson);
-
-        tourismProjectTravelNotesWrite.setState(AuditState.UNAUDITSTATE);
-        //对dto的id进行判断,如果数据表中查不到该id,则为新增;否则为修改
-        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite1 =
-                tourismProjectTravelNotesWriteService.getById(tourismProjectTravelNotesWriteDto.getId());
-        if(tourismProjectTravelNotesWrite1 == null) {
-            tourismProjectTravelNotesWriteService.saveNew(tourismProjectTravelNotesWrite);
-        }else{
-            if(!tourismProjectTravelNotesWrite1.getCreateUserId().equals(TokenData.takeFromRequest().getUserId())){
-                return ResponseResult.error(ErrorCodeEnum.DATA_SAVE_FAILED);
-            }
-            tourismProjectTravelNotesWriteService.updateById(tourismProjectTravelNotesWrite);
+        //校验dto中的群聊是否为本人参与的群聊
+        List<TourShortImGroup> takePartImGroupListByName = tourImGroupService.getTakePartImGroupListByName(userId, "");
+        List<Long> takePartImGroupIdList = takePartImGroupListByName.stream().mapToLong(TourShortImGroup::getId).boxed().collect(Collectors.toList());
+        if(!takePartImGroupIdList.contains(tourismProjectTravelNotesWriteDto.getTourImGroupId())){
+            return ResponseResult.error(ErrorCodeEnum.MENTION_GROUP_ERROR,"本人未参与到关联的群聊中");
         }
-        tourismTravelNotesContentWriteService.removeByAssociationId(tourismProjectTravelNotesWriteDto.getId());
-        List<TourismTravelNotesContentWrite> tourismTravelNotesContentWriteList =
-                MyModelUtil.copyCollectionTo(tourismProjectTravelNotesWriteDto.getTravelNotesContent(), TourismTravelNotesContentWrite.class);
-        for (TourismTravelNotesContentWrite item : tourismTravelNotesContentWriteList) {
-            item.setAssociationId(tourismProjectTravelNotesWrite.getId());
-            item.setId(null);
-        }
-        tourismTravelNotesContentWriteService.saveNewBatch(tourismTravelNotesContentWriteList);
+
+        tourTravelNotesPublishService.publishDraft(tourismProjectTravelNotesWriteDto);
         return ResponseResult.success();
     }
 
@@ -485,6 +397,91 @@ public class WebSiteTourismTravelNotesPublishController {
         return ResponseResult.success(newDirectoryInfoList);
     }
 
+    /**
+     * 根据名称查询互关的好友信息
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.LIST)
+    @GetMapping("/getFouceEachFriendsByName")
+    public ResponseResult<List<TourShortUserVo>> getFouceEachFriendsByName(String name) {
+        //limit20
+        PageMethod.startPage(1, 20, true);
+        Long userId = TokenData.takeFromRequest().getUserId();
+        List<TourShortUser> tourShortUserList = tourFansService.getFouceEachFriendsByName(userId, name);
+        List<TourShortUserVo> tourShortUserVoList = MyModelUtil.copyCollectionTo(tourShortUserList, TourShortUserVo.class);
+        return ResponseResult.success(tourShortUserVoList);
+    }
+
+    /**
+     * 模糊搜索话题列表
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.LIST)
+    @GetMapping("/getTopicListByName")
+    public ResponseResult<List<TourShortTopicVo>> getTopicListByName(String name) {
+        //limit20
+        PageMethod.startPage(1, 20, true);
+        TourTravelNotesTopic tourTravelNotesTopic = new TourTravelNotesTopic();
+        tourTravelNotesTopic.setName(name);
+        List<TourShortTopic> tourTravelNotesTopicListByName = tourTravelNotesTopicService.getTourTravelNotesTopicListByName(name);
+        List<TourShortTopicVo> tourTravelNotesTopicVoList = MyModelUtil.copyCollectionTo(tourTravelNotesTopicListByName, TourShortTopicVo.class);
+        return ResponseResult.success(tourTravelNotesTopicVoList);
+    }
+
+    /**
+     * 模糊搜索自己参与的群聊列表
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.LIST)
+    @GetMapping("/getTakePartImGroupListByName")
+    public ResponseResult<List<TourShortImGroupVo>> getTakePartImGroupListByName(String name) {
+        //limit20
+        PageMethod.startPage(1, 20, true);
+        Long localUserId = TokenData.takeFromRequest().getUserId();
+        List<TourShortImGroup> takePartImGroupListByName = tourImGroupService.getTakePartImGroupListByName(localUserId,name);
+
+        //根据群聊id,填充每个群聊的人数以及每个群聊的头像
+        Set<Long> set = new HashSet();
+        set.addAll(takePartImGroupListByName.stream()
+                .filter(t -> t.getId() != null)  // 过滤掉 id 为 null 的元素
+                .map(TourShortImGroup::getId)    // 提取 id
+                .collect(Collectors.toSet()));
+
+        //查询群聊中有哪些群成员id
+        List<TourImMember> tourImMemberList = tourImMemberService.getInList("groupId", set);
+        // 根据群 ID 对群成员进行分组,并且每个群组最多取前 9 个成员
+        Map<Long, List<TourImMember>> groupedMembers = tourImMemberList.stream()
+                .collect(Collectors.groupingBy(
+                        TourImMember::getGroupId,
+                        Collectors.collectingAndThen(
+                                Collectors.toList(),
+                                members -> members.stream().limit(9).collect(Collectors.toList())  // 限制每个群组的成员为前 9 个
+                        )
+                ));
+        // 提取 userId 并去重
+        Set<Long> uniqueUserIds = tourImMemberList.stream().map(TourImMember::getUserId).collect(Collectors.toSet());  // 使用 Set 自动去重
+        // 根据userId获取用户头像
+        List<TourUser> userIdList = tourUserService.getInList("userId", uniqueUserIds);
+        // 使用 Stream 提取 userId 和 headImageUrl,生成 Map
+        Map<Long, String> userHeadImageMap = userIdList.stream()
+                .collect(Collectors.toMap(TourUser::getUserId, TourUser::getHeadImageUrl));
+        //根据群成员id来查询群成员的头像
+        for(TourShortImGroup i:takePartImGroupListByName){
+                i.setCount(tourImMemberList.stream().filter(e -> e.getGroupId().equals(i.getId())).collect(Collectors.toList()).size());
+            if(StringUtils.isBlank(i.getGroupAvatarUrl())){
+                //没有设置头像,则进行拼头像
+                List<TourImMember> tourImMembers = groupedMembers.get(i.getId());
+                List<String> avatarUrls = tourImMembers.stream().map(TourImMember::getUserId).map(userId -> userHeadImageMap.get(userId)).collect(Collectors.toList());
+                i.setGroupAvatarUrl(mergeAvatarsFlexUtils.mergeAndUploadAvatars(avatarUrls));
+            }
+        }
+
+        List<TourShortImGroupVo> tourShortImGroupVo = MyModelUtil.copyCollectionTo(takePartImGroupListByName, TourShortImGroupVo.class);
+        return ResponseResult.success(tourShortImGroupVo);
+    }
 
 
 }

+ 26 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/TourismProjectTravelNotesWriteToWebDto.java

@@ -1,7 +1,9 @@
 package com.tourism.webadmin.app.website.dto;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.tourism.common.core.validator.ConstDictRef;
 import com.tourism.common.core.validator.UpdateGroup;
+import com.tourism.webadmin.back.dto.TourTravelNotesMentionUserDto;
 import com.tourism.webadmin.back.dto.TourismTravelNotesContentWriteDto;
 import com.tourism.webadmin.back.model.constant.*;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -230,4 +232,28 @@ public class TourismProjectTravelNotesWriteToWebDto {
      */
     @Schema(description = "游玩人数。")
     private String travelNumber;
+
+    /**
+     * 上传的图片集。
+     */
+    @Schema(description = "上传的图片集。")
+    private List<String> imgUrls;
+
+    /**
+     * 游记内容提及的用户信息。
+     */
+    @Schema(description = "游记内容提及的用户信息。")
+    private List<TourTravelNotesMentionUserDto> mentions;
+
+    /**
+     * 游记内容提及的用户信息。
+     */
+    @Schema(description = "游记内容提及的用户信息。")
+    private List<String> topics;
+
+    /**
+     * 群聊id。
+     */
+    @Schema(description = "群聊id。")
+    private Long tourImGroupId;
 }

+ 34 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/model/TourShortImGroup.java

@@ -0,0 +1,34 @@
+package com.tourism.webadmin.app.website.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+@TableName(value = "tour_im_group")
+public class TourShortImGroup {
+    /**
+     * 群聊id。
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 群聊名称。
+     */
+    @TableId(value = "group_name")
+    private String groupName;
+
+    /**
+     * 群聊头像。
+     */
+    @TableId(value = "group_avatar")
+    private String groupAvatarUrl;
+
+    /**
+     * 群成员人数。
+     */
+    @Schema(description = "群成员人数")
+    private Integer count;
+}

+ 21 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/model/TourShortTopic.java

@@ -0,0 +1,21 @@
+package com.tourism.webadmin.app.website.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+@Data
+@TableName(value = "tour_travel_notes_topic")
+public class TourShortTopic {
+    /**
+     * 话题名称。
+     */
+    @TableId(value = "topic_name")
+    private String topicName;
+
+    /**
+     * 浏览量。
+     */
+    @TableId(value = "total_view_count")
+    private String totalViewCount;
+}

+ 29 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/model/TourShortUser.java

@@ -0,0 +1,29 @@
+package com.tourism.webadmin.app.website.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@TableName(value = "tour_user")
+public class TourShortUser {
+    /**
+     * 主键Id。
+     */
+    @TableId(value = "user_id")
+    private Long userId;
+
+    /**
+     * 昵称。
+     */
+    @TableId(value = "show_name")
+    private String showName;
+
+    /**
+     * 用户头像的Url。
+     */
+    @TableId(value = "head_image_url")
+    private String headImageUrl;
+}

+ 21 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/TourTravelNotesPublishService.java

@@ -0,0 +1,21 @@
+package com.tourism.webadmin.app.website.service;
+
+import com.tourism.common.core.object.ResponseResult;
+import com.tourism.webadmin.app.website.dto.TourismProjectTravelNotesWriteDetailPageDto;
+import com.tourism.webadmin.app.website.dto.TourismProjectTravelNotesWriteToWebDto;
+import com.tourism.webadmin.app.website.vo.HouseFilterListsVo;
+import com.tourism.webadmin.back.model.TourismProjectTravelNotesWrite;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+public interface TourTravelNotesPublishService {
+
+    void saveDraft(TourismProjectTravelNotesWriteToWebDto tourismProjectTravelNotesWriteDto);
+
+    void removeByDraftId(String writeId);
+
+    List<TourismProjectTravelNotesWrite> getDraftList(TourismProjectTravelNotesWriteDetailPageDto pageDto);
+
+    ResponseResult<Void> publishDraft(TourismProjectTravelNotesWriteToWebDto tourismProjectTravelNotesWriteDto);
+}

+ 6 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/impl/BasicToWebServiceImpl.java

@@ -243,6 +243,12 @@ public class BasicToWebServiceImpl implements BasicToWebService
             writeVo.setHomeHotPicturesAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), writeVo.getTourismUrl()));
             writeVo.setTravelNotesBannerAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), writeVo.getTravelNotesBanner()));
         }
+
+        DirectoryInfo directoryInfo = directoryInfoService.getById(writeVo.getEndPlace());
+        if(directoryInfo.getParentId() != null) {
+            DirectoryInfo directoryInfo1 = directoryInfoService.getById(directoryInfo.getParentId());
+            writeVo.setEndArea(directoryInfo1.getMenuName());
+        }
         return writeVo;
     }
 

+ 352 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/impl/TourTravelNotesPublishServiceImpl.java

@@ -0,0 +1,352 @@
+package com.tourism.webadmin.app.website.service.impl;
+
+import com.github.pagehelper.page.PageMethod;
+import com.tourism.common.additional.utils.StringUtils;
+import com.tourism.common.core.constant.ErrorCodeEnum;
+import com.tourism.common.core.object.MyOrderParam;
+import com.tourism.common.core.object.ResponseResult;
+import com.tourism.common.core.object.TokenData;
+import com.tourism.common.core.util.MyCommonUtil;
+import com.tourism.common.core.util.MyModelUtil;
+import com.tourism.common.core.validator.UpdateGroup;
+import com.tourism.webadmin.app.website.dto.TourismProjectTravelNotesWriteDetailPageDto;
+import com.tourism.webadmin.app.website.dto.TourismProjectTravelNotesWriteToWebDto;
+import com.tourism.webadmin.app.website.service.TourTravelNotesPublishService;
+import com.tourism.webadmin.back.dto.TourismTravelNotesContentWriteDto;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.back.model.constant.AuditState;
+import com.tourism.webadmin.back.model.constant.UnmountState;
+import com.tourism.webadmin.back.service.*;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import com.tourism.common.huaweicloud.moderation.service.HuaweiCloudModerationService;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service("TourTravelNotesPublishService")
+public class TourTravelNotesPublishServiceImpl implements TourTravelNotesPublishService {
+
+
+    @Autowired
+    private TourismProjectTravelNotesWriteService tourismProjectTravelNotesWriteService;
+    @Autowired
+    private TourismTravelNotesContentWriteService tourismTravelNotesContentWriteService;
+    @Autowired
+    private TourTravelNotesMentionUserService tourTravelNotesMentionUserService;
+    @Autowired
+    private TourTravelNotesTopicRelationService tourTravelNotesTopicRelationService;
+    @Autowired
+    private HuaweiCloudModerationService huaweiCloudModerationService;
+    @Autowired
+    private TourTravelNotesImgService tourTravelNotesImgService;
+
+
+    @Override
+    @Transactional
+    public void saveDraft(TourismProjectTravelNotesWriteToWebDto tourismProjectTravelNotesWriteDto) {
+
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite =
+                tourismProjectTravelNotesWriteService.getById(tourismProjectTravelNotesWriteDto.getId());
+
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWriteSave =
+                MyModelUtil.copyTo(tourismProjectTravelNotesWriteDto, TourismProjectTravelNotesWrite.class);
+
+        //判断imgUrls是否为空,不为空的话,则把第一张图作为列表图
+        if (CollectionUtils.isNotEmpty(tourismProjectTravelNotesWriteDto.getImgUrls())) {
+            tourismProjectTravelNotesWriteSave.setTourismUrl(tourismProjectTravelNotesWriteDto.getImgUrls().get(0));
+        }
+
+        List<TourTravelNotesTopicRelation> tourTravelNotesTopicRelationList = new ArrayList<>();
+        List<TourTravelNotesImg> tourTravelNotesImgList = new ArrayList<>();
+        //判断是新增还是更新
+        if (tourismProjectTravelNotesWrite == null) {
+            //新增
+            //草稿为下架状态
+            tourismProjectTravelNotesWriteSave.setUnmountState(UnmountState.DELIST);
+            TourismProjectTravelNotesWrite tourismProjectTravelNotesWriteNew = tourismProjectTravelNotesWriteService.saveNew(tourismProjectTravelNotesWriteSave);
+
+            //对游记提及的关联用户信息进行关联游记id
+            tourismProjectTravelNotesWriteDto.getMentions().forEach(item -> {
+                item.setTravelNotesId(tourismProjectTravelNotesWriteNew.getId());
+            });
+
+            //对游记中提及的话题进行关联游记id
+            tourismProjectTravelNotesWriteDto.getTopics().forEach(j->{
+                TourTravelNotesTopicRelation tourTravelNotesTopicRelation = new TourTravelNotesTopicRelation();
+                tourTravelNotesTopicRelation.setTopicName(j);
+                tourTravelNotesTopicRelation.setTravelNotesId(tourismProjectTravelNotesWriteNew.getId());
+                tourTravelNotesTopicRelationList.add(tourTravelNotesTopicRelation);
+            });
+
+            //构建游记中的图片数据
+            tourismProjectTravelNotesWriteDto.getImgUrls().forEach(y->{
+                TourTravelNotesImg tourTravelNotesImg = new TourTravelNotesImg();
+                tourTravelNotesImg.setImgUrl(y);
+                tourTravelNotesImg.setTravelNotesId(tourismProjectTravelNotesWriteNew.getId());
+                tourTravelNotesImgList.add(tourTravelNotesImg);
+            });
+        } else {
+            //修改
+            //草稿为下架状态
+            tourismProjectTravelNotesWriteSave.setUnmountState(UnmountState.DELIST);
+            tourismProjectTravelNotesWriteService.updateById(tourismProjectTravelNotesWriteSave);
+            //对游记提及的关联用户信息进行关联游记id
+            tourismProjectTravelNotesWriteDto.getMentions().forEach(item -> {
+                item.setTravelNotesId(tourismProjectTravelNotesWriteSave.getId());
+            });
+            TourTravelNotesMentionUser tourTravelNotesMentionUser = new TourTravelNotesMentionUser();
+            tourTravelNotesMentionUser.setTravelNotesId(tourismProjectTravelNotesWriteSave.getId());
+            tourTravelNotesMentionUserService.removeBy(tourTravelNotesMentionUser);
+            //移除原来关联的话题
+            TourTravelNotesTopicRelation tourTravelNotesTopicRelation = new TourTravelNotesTopicRelation();
+            tourTravelNotesTopicRelation.setTravelNotesId(tourismProjectTravelNotesWriteSave.getId());
+            tourTravelNotesTopicRelationService.removeBy(tourTravelNotesTopicRelation);
+
+            //对游记中提及的话题进行关联游记id
+            tourismProjectTravelNotesWriteDto.getTopics().forEach(j->{
+                TourTravelNotesTopicRelation tourTravelNotesTopicRelationNew = new TourTravelNotesTopicRelation();
+                tourTravelNotesTopicRelationNew.setTopicName(j);
+                tourTravelNotesTopicRelationNew.setTravelNotesId(tourismProjectTravelNotesWriteSave.getId());
+                tourTravelNotesTopicRelationList.add(tourTravelNotesTopicRelationNew);
+            });
+
+            //移除原来图片中的地址数据
+            TourTravelNotesImg tourTravelNotesImg = new TourTravelNotesImg();
+            tourTravelNotesImg.setTravelNotesId(tourismProjectTravelNotesWriteSave.getId());
+            tourTravelNotesImgService.removeBy(tourTravelNotesImg);
+
+            //构建现有的游记图片数据
+            tourismProjectTravelNotesWriteDto.getImgUrls().forEach(y->{
+                TourTravelNotesImg tourTravelNotesImgNew = new TourTravelNotesImg();
+                tourTravelNotesImg.setImgUrl(y);
+                tourTravelNotesImg.setTravelNotesId(tourismProjectTravelNotesWriteSave.getId());
+                tourTravelNotesImgList.add(tourTravelNotesImgNew);
+            });
+        }
+        //保存游记中提及的用户
+        List<TourTravelNotesMentionUser> tourTravelNotesMentionUserList = MyModelUtil.copyCollectionTo(tourismProjectTravelNotesWriteDto.getMentions(), TourTravelNotesMentionUser.class);
+        tourTravelNotesMentionUserService.saveBatch(tourTravelNotesMentionUserList);
+        //保存游记中提及的话题
+        tourTravelNotesTopicRelationService.saveNewBatch(tourTravelNotesTopicRelationList);
+        //保存游记中的图片
+        tourTravelNotesImgService.saveNewBatch(tourTravelNotesImgList);
+
+        //判断内容是否为空
+        if (tourismProjectTravelNotesWriteDto.getTravelNotesContent() != null) {
+            List<TourismTravelNotesContentWriteDto> travelNotesContentWriteList = tourismProjectTravelNotesWriteDto.getTravelNotesContent();
+            List<TourismTravelNotesContentWrite> tourismTravelNotesContentWriteList = MyModelUtil.copyCollectionTo(travelNotesContentWriteList, TourismTravelNotesContentWrite.class);
+            for (TourismTravelNotesContentWrite item : tourismTravelNotesContentWriteList) {
+                item.setAssociationId(tourismProjectTravelNotesWriteSave.getId());
+                item.setId(null);
+            }
+            tourismTravelNotesContentWriteService.removeByAssociationId(tourismProjectTravelNotesWriteSave.getId());
+            //查询关联数据的id,根据id进行更新数据表的数据
+            tourismTravelNotesContentWriteService.saveNewBatch(tourismTravelNotesContentWriteList);
+        }
+
+
+    }
+
+    @Override
+    @Transactional
+    public void removeByDraftId(String writeId){
+        //删除游记主表
+        tourismProjectTravelNotesWriteService.remove(Long.valueOf(writeId));
+        //删除游记内容表
+        tourismTravelNotesContentWriteService.removeByAssociationId(Long.valueOf(writeId));
+        //删除游记中提及的用户关系表
+        TourTravelNotesMentionUser tourTravelNotesMentionUser = new TourTravelNotesMentionUser();
+        tourTravelNotesMentionUser.setTravelNotesId(Long.valueOf(writeId));
+        tourTravelNotesMentionUserService.removeBy(tourTravelNotesMentionUser);
+        //删除游记中提及的话题关系表
+        TourTravelNotesTopicRelation tourTravelNotesTopicRelation = new TourTravelNotesTopicRelation();
+        tourTravelNotesTopicRelation.setTravelNotesId(Long.valueOf(writeId));
+        tourTravelNotesTopicRelationService.removeBy(tourTravelNotesTopicRelation);
+    }
+
+    @Override
+    public List<TourismProjectTravelNotesWrite> getDraftList(TourismProjectTravelNotesWriteDetailPageDto pageDto){
+
+        Long userId = TokenData.takeFromRequest().getUserId();
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite = new TourismProjectTravelNotesWrite();
+        tourismProjectTravelNotesWrite.setCreateUserId(userId);
+        tourismProjectTravelNotesWrite.setState(pageDto.getType());
+        MyOrderParam myOrderParam = new MyOrderParam();
+        myOrderParam.add(new MyOrderParam.OrderInfo("updateTime",false,null));
+        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourismProjectTravelNotesWrite.class);
+        if(pageDto.getPageSize() != null && pageDto.getPageNum() != null){
+            PageMethod.startPage(pageDto.getPageNum(), pageDto.getPageSize(), true);
+        }
+        //查询已发布状态的状态,则需要state为3并且上下架状态为上架
+        if(pageDto.getType() == 3){
+            tourismProjectTravelNotesWrite.setUnmountState(UnmountState.LISTING);
+        }
+        List<TourismProjectTravelNotesWrite> tourismProjectTravelNotesWriteList =
+                tourismProjectTravelNotesWriteService.getTourismProjectTravelNotesWriteList(tourismProjectTravelNotesWrite, orderBy);
+
+        return tourismProjectTravelNotesWriteList;
+    }
+
+    @Override
+    @Transactional
+    public ResponseResult<Void> publishDraft(TourismProjectTravelNotesWriteToWebDto tourismProjectTravelNotesWriteDto){
+        String errorMessage = MyCommonUtil.getModelValidationError(tourismProjectTravelNotesWriteDto, UpdateGroup.class);
+        if (errorMessage != null) {
+            return ResponseResult.success(null);
+        }
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite =
+                MyModelUtil.copyTo(tourismProjectTravelNotesWriteDto, TourismProjectTravelNotesWrite.class);
+
+        //校验该游记是否为审核中和已发布状态
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWriteVerify =
+                tourismProjectTravelNotesWriteService.getById(tourismProjectTravelNotesWriteDto.getId());
+
+        if(tourismProjectTravelNotesWriteVerify != null){
+            if(tourismProjectTravelNotesWriteVerify.getState() .equals(AuditState.UNAUDITSTATE)) {
+                return ResponseResult.error(ErrorCodeEnum.INVALID_STATUS_ARGUMENT, "该游记状态为:正在审核中,请撤销后进行操作");
+            }else if(tourismProjectTravelNotesWriteVerify.getState() .equals(AuditState.SUCCEEDAUDIT)){
+                return ResponseResult.error(ErrorCodeEnum.INVALID_STATUS_ARGUMENT, "该游记状态为:已发布成功,请下架后进行操作");
+            }
+        }
+        //将从表中的数据进行过滤,筛选出cover为1的图片为封面图,第一段落为项目简述
+        List<TourismTravelNotesContentWriteDto> travelNotesContent = tourismProjectTravelNotesWriteDto.getTravelNotesContent();
+
+        //循环遍历查询内容是否超过5000长度
+        for(TourismTravelNotesContentWriteDto i:travelNotesContent){
+            if(StringUtils.isNotBlank(i.getContent()) && i.getContent().length()>5000)
+                return ResponseResult.error(ErrorCodeEnum.CONTENT_OUT_LIMIT);
+        }
+
+        //判断imgUrls是否为空,不为空的话,则把第一张图作为列表图
+        if (CollectionUtils.isNotEmpty(tourismProjectTravelNotesWriteDto.getImgUrls())) {
+            tourismProjectTravelNotesWrite.setTourismUrl(tourismProjectTravelNotesWriteDto.getImgUrls().get(0));
+        }
+
+        List<TourismTravelNotesContentWriteDto> sectionContent = travelNotesContent.stream().filter(item -> item.getType().equals("sectionContent")).collect(Collectors.toList());
+        if(CollectionUtils.isNotEmpty(sectionContent)){
+            tourismProjectTravelNotesWrite.setRemarks(sectionContent.get(0).getContent());
+        }
+
+        // 文案审核
+        List<String> imageList = travelNotesContent.stream().filter(e -> e.getType().equals("image")).map(TourismTravelNotesContentWriteDto::getContent).collect(Collectors.toList());
+        imageList.add(tourismProjectTravelNotesWrite.getTravelNotesBanner());
+        Boolean imageResult = huaweiCloudModerationService.runImageModeration(imageList);
+        // 图片审核
+        List<String> titleList = travelNotesContent.stream().filter(e -> e.getType().equals("sectionTitle")).map(TourismTravelNotesContentWriteDto::getContent).collect(Collectors.toList());
+        List<String> contentList = travelNotesContent.stream().filter(e -> e.getType().equals("sectionContent")).map(TourismTravelNotesContentWriteDto::getContent).collect(Collectors.toList());
+        titleList.addAll(contentList);
+        Boolean textResult = huaweiCloudModerationService.runTextModeration(titleList);
+        String auditReson = "";
+        if(imageResult && textResult){
+            tourismProjectTravelNotesWrite.setAutoAuditStatus(1);
+            auditReson = "图文审核通过";
+        }else {
+            tourismProjectTravelNotesWrite.setAutoAuditStatus(2);
+            if(!imageResult){
+                auditReson = "图片审核未通过:可能设计暴恐、色情、违禁、辱骂等内容;";
+            }
+            if(!textResult){
+                auditReson += "文案审核未通过:可能设计暴恐、色情、违禁、辱骂等内容;";
+            }
+        }
+        tourismProjectTravelNotesWrite.setAutoRejectReason(auditReson);
+
+        tourismProjectTravelNotesWrite.setState(AuditState.UNAUDITSTATE);
+
+        List<TourTravelNotesTopicRelation> tourTravelNotesTopicRelationList = new ArrayList<>();
+        List<TourTravelNotesImg> tourTravelNotesImgList = new ArrayList<>();
+
+        //对dto的id进行判断,如果数据表中查不到该id,则为新增;否则为修改
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite1 =
+                tourismProjectTravelNotesWriteService.getById(tourismProjectTravelNotesWriteDto.getId());
+        if(tourismProjectTravelNotesWrite1 == null) {
+            tourismProjectTravelNotesWriteService.saveNew(tourismProjectTravelNotesWrite);
+
+            //对游记提及的关联用户信息进行关联游记id
+            tourismProjectTravelNotesWriteDto.getMentions().forEach(item -> {
+                item.setTravelNotesId(tourismProjectTravelNotesWrite.getId());
+            });
+
+            //对游记中提及的话题进行关联游记id
+            tourismProjectTravelNotesWriteDto.getTopics().forEach(j->{
+                TourTravelNotesTopicRelation tourTravelNotesTopicRelation = new TourTravelNotesTopicRelation();
+                tourTravelNotesTopicRelation.setTopicName(j);
+                tourTravelNotesTopicRelation.setTravelNotesId(tourismProjectTravelNotesWrite.getId());
+                tourTravelNotesTopicRelationList.add(tourTravelNotesTopicRelation);
+            });
+
+            //构建游记中的图片数据
+            tourismProjectTravelNotesWriteDto.getImgUrls().forEach(y->{
+                TourTravelNotesImg tourTravelNotesImg = new TourTravelNotesImg();
+                tourTravelNotesImg.setImgUrl(y);
+                tourTravelNotesImg.setTravelNotesId(tourismProjectTravelNotesWrite.getId());
+                tourTravelNotesImgList.add(tourTravelNotesImg);
+            });
+
+        }else{
+            if(!tourismProjectTravelNotesWrite1.getCreateUserId().equals(TokenData.takeFromRequest().getUserId())){
+                return ResponseResult.error(ErrorCodeEnum.DATA_SAVE_FAILED);
+            }
+            tourismProjectTravelNotesWriteService.updateById(tourismProjectTravelNotesWrite);
+
+            //删除游记中提及的用户关系表
+            TourTravelNotesMentionUser tourTravelNotesMentionUser = new TourTravelNotesMentionUser();
+            tourTravelNotesMentionUser.setTravelNotesId(tourismProjectTravelNotesWrite.getId());
+            tourTravelNotesMentionUserService.removeBy(tourTravelNotesMentionUser);
+            //删除游记中提及的话题关系表
+            TourTravelNotesTopicRelation tourTravelNotesTopicRelation = new TourTravelNotesTopicRelation();
+            tourTravelNotesTopicRelation.setTravelNotesId(tourismProjectTravelNotesWrite.getId());
+            tourTravelNotesTopicRelationService.removeBy(tourTravelNotesTopicRelation);
+
+            //对游记提及的关联用户信息进行关联游记id
+            tourismProjectTravelNotesWriteDto.getMentions().forEach(item -> {
+                item.setTravelNotesId(tourismProjectTravelNotesWrite.getId());
+            });
+
+            //对游记中提及的话题进行关联游记id
+            tourismProjectTravelNotesWriteDto.getTopics().forEach(j->{
+                TourTravelNotesTopicRelation tourTravelNotesTopicRelationNew = new TourTravelNotesTopicRelation();
+                tourTravelNotesTopicRelationNew.setTopicName(j);
+                tourTravelNotesTopicRelationNew.setTravelNotesId(tourismProjectTravelNotesWrite.getId());
+                tourTravelNotesTopicRelationList.add(tourTravelNotesTopicRelationNew);
+            });
+
+            //移除原来图片中的地址数据
+            TourTravelNotesImg tourTravelNotesImg = new TourTravelNotesImg();
+            tourTravelNotesImg.setTravelNotesId(tourismProjectTravelNotesWrite.getId());
+            tourTravelNotesImgService.removeBy(tourTravelNotesImg);
+
+            //构建现有的游记图片数据
+            tourismProjectTravelNotesWriteDto.getImgUrls().forEach(y->{
+                TourTravelNotesImg tourTravelNotesImgNew = new TourTravelNotesImg();
+                tourTravelNotesImg.setImgUrl(y);
+                tourTravelNotesImg.setTravelNotesId(tourismProjectTravelNotesWrite.getId());
+                tourTravelNotesImgList.add(tourTravelNotesImgNew);
+            });
+        }
+
+        //保存游记中提及的用户
+        List<TourTravelNotesMentionUser> tourTravelNotesMentionUserList = MyModelUtil.copyCollectionTo(tourismProjectTravelNotesWriteDto.getMentions(), TourTravelNotesMentionUser.class);
+        tourTravelNotesMentionUserService.saveBatch(tourTravelNotesMentionUserList);
+        //保存游记中提及的话题
+        tourTravelNotesTopicRelationService.saveNewBatch(tourTravelNotesTopicRelationList);
+        //保存游记中的图片
+        tourTravelNotesImgService.saveNewBatch(tourTravelNotesImgList);
+
+        tourismTravelNotesContentWriteService.removeByAssociationId(tourismProjectTravelNotesWriteDto.getId());
+        List<TourismTravelNotesContentWrite> tourismTravelNotesContentWriteList =
+                MyModelUtil.copyCollectionTo(tourismProjectTravelNotesWriteDto.getTravelNotesContent(), TourismTravelNotesContentWrite.class);
+        for (TourismTravelNotesContentWrite item : tourismTravelNotesContentWriteList) {
+            item.setAssociationId(tourismProjectTravelNotesWrite.getId());
+            item.setId(null);
+        }
+        tourismTravelNotesContentWriteService.saveNewBatch(tourismTravelNotesContentWriteList);
+
+        return ResponseResult.success();
+    }
+}

+ 31 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/TourShortImGroupVo.java

@@ -0,0 +1,31 @@
+package com.tourism.webadmin.app.website.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+public class TourShortImGroupVo {
+    /**
+     * 群聊id。
+     */
+    @Schema(description = "群聊id")
+    private String id;
+
+    /**
+     * 群聊名称。
+     */
+    @Schema(description = "群聊名称")
+    private String groupName;
+
+    /**
+     * 群聊头像。
+     */
+    @Schema(description = "群聊头像的Url")
+    private String groupAvatarUrl;
+
+    /**
+     * 群成员人数。
+     */
+    @Schema(description = "群成员人数")
+    private Integer count;
+}

+ 22 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/TourShortTopicVo.java

@@ -0,0 +1,22 @@
+package com.tourism.webadmin.app.website.vo;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+@TableName(value = "tour_travel_notes_topic")
+public class TourShortTopicVo {
+    /**
+     * 话题名称。
+     */
+    @Schema(description = "话题名称")
+    private String topicName;
+
+    /**
+     * 浏览量。
+     */
+    @Schema(description = "浏览量")
+    private String totalViewCount;
+}

+ 37 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/TourShortUserVo.java

@@ -0,0 +1,37 @@
+package com.tourism.webadmin.app.website.vo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.tourism.common.core.annotation.RelationConstDict;
+import com.tourism.common.core.annotation.RelationGlobalDict;
+import com.tourism.common.core.annotation.UploadFlagColumn;
+import com.tourism.common.core.upload.UploadStoreTypeEnum;
+import com.tourism.common.core.util.MyCommonUtil;
+import com.tourism.webadmin.upms.model.constant.SysUserStatus;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.Map;
+
+@Data
+public class TourShortUserVo {
+    /**
+     * 主键Id。
+     */
+    @Schema(description = "主键Id")
+    private String userId;
+
+    /**
+     * 昵称。
+     */
+    @Schema(description = "昵称")
+    private String showName;
+
+    /**
+     * 用户头像的Url。
+     */
+    @Schema(description = "用户头像的Url")
+    private String headImageUrl;
+}

+ 179 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourTravelNotesImgController.java

@@ -0,0 +1,179 @@
+package com.tourism.webadmin.back.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.tourism.common.log.annotation.OperationLog;
+import com.tourism.common.log.model.constant.SysOperationLogType;
+import com.github.pagehelper.page.PageMethod;
+import com.tourism.webadmin.back.vo.*;
+import com.tourism.webadmin.back.dto.*;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.back.service.*;
+import com.tourism.common.core.object.*;
+import com.tourism.common.core.util.*;
+import com.tourism.common.core.constant.*;
+import com.tourism.common.core.annotation.MyRequestBody;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+/**
+ * 游记中的图片操作控制器类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Tag(name = "游记中的图片管理接口")
+@Slf4j
+@RestController
+@RequestMapping("/admin/app/tourTravelNotesImg")
+public class TourTravelNotesImgController {
+
+    @Autowired
+    private TourTravelNotesImgService tourTravelNotesImgService;
+
+    /**
+     * 新增游记中的图片数据。
+     *
+     * @param tourTravelNotesImgDto 新增对象。
+     * @return 应答结果对象,包含新增对象主键Id。
+     */
+    @ApiOperationSupport(ignoreParameters = {"tourTravelNotesImgDto.id"})
+    @SaCheckPermission("tourTravelNotesImg.add")
+    @OperationLog(type = SysOperationLogType.ADD)
+    @PostMapping("/add")
+    public ResponseResult<Long> add(@MyRequestBody TourTravelNotesImgDto tourTravelNotesImgDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourTravelNotesImgDto, false);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        TourTravelNotesImg tourTravelNotesImg = MyModelUtil.copyTo(tourTravelNotesImgDto, TourTravelNotesImg.class);
+        tourTravelNotesImg = tourTravelNotesImgService.saveNew(tourTravelNotesImg);
+        return ResponseResult.success(tourTravelNotesImg.getId());
+    }
+
+    /**
+     * 更新游记中的图片数据。
+     *
+     * @param tourTravelNotesImgDto 更新对象。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesImg.update")
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/update")
+    public ResponseResult<Void> update(@MyRequestBody TourTravelNotesImgDto tourTravelNotesImgDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourTravelNotesImgDto, true);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        TourTravelNotesImg tourTravelNotesImg = MyModelUtil.copyTo(tourTravelNotesImgDto, TourTravelNotesImg.class);
+        TourTravelNotesImg originalTourTravelNotesImg = tourTravelNotesImgService.getById(tourTravelNotesImg.getId());
+        if (originalTourTravelNotesImg == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        if (!tourTravelNotesImgService.update(tourTravelNotesImg, originalTourTravelNotesImg)) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 删除游记中的图片数据。
+     *
+     * @param id 删除对象主键Id。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesImg.delete")
+    @OperationLog(type = SysOperationLogType.DELETE)
+    @PostMapping("/delete")
+    public ResponseResult<Void> delete(@MyRequestBody Long id) {
+        if (MyCommonUtil.existBlankArgument(id)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        return this.doDelete(id);
+    }
+
+    /**
+     * 批量删除游记中的图片数据。
+     *
+     * @param idList 待删除对象的主键Id列表。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesImg.delete")
+    @OperationLog(type = SysOperationLogType.DELETE_BATCH)
+    @PostMapping("/deleteBatch")
+    public ResponseResult<Void> deleteBatch(@MyRequestBody List<Long> idList) {
+        if (MyCommonUtil.existBlankArgument(idList)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        for (Long id : idList) {
+            ResponseResult<Void> responseResult = this.doDelete(id);
+            if (!responseResult.isSuccess()) {
+                return responseResult;
+            }
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 列出符合过滤条件的游记中的图片列表。
+     *
+     * @param tourTravelNotesImgDtoFilter 过滤对象。
+     * @param orderParam 排序参数。
+     * @param pageParam 分页参数。
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @SaCheckPermission("tourTravelNotesImg.view")
+    @PostMapping("/list")
+    public ResponseResult<MyPageData<TourTravelNotesImgVo>> list(
+            @MyRequestBody TourTravelNotesImgDto tourTravelNotesImgDtoFilter,
+            @MyRequestBody MyOrderParam orderParam,
+            @MyRequestBody MyPageParam pageParam) {
+        if (pageParam != null) {
+            PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
+        }
+        TourTravelNotesImg tourTravelNotesImgFilter = MyModelUtil.copyTo(tourTravelNotesImgDtoFilter, TourTravelNotesImg.class);
+        String orderBy = MyOrderParam.buildOrderBy(orderParam, TourTravelNotesImg.class);
+        List<TourTravelNotesImg> tourTravelNotesImgList =
+                tourTravelNotesImgService.getTourTravelNotesImgListWithRelation(tourTravelNotesImgFilter, orderBy);
+        return ResponseResult.success(MyPageUtil.makeResponseData(tourTravelNotesImgList, TourTravelNotesImgVo.class));
+    }
+
+    /**
+     * 查看指定游记中的图片对象详情。
+     *
+     * @param id 指定对象主键Id。
+     * @return 应答结果对象,包含对象详情。
+     */
+    @SaCheckPermission("tourTravelNotesImg.view")
+    @GetMapping("/view")
+    public ResponseResult<TourTravelNotesImgVo> view(@RequestParam Long id) {
+        TourTravelNotesImg tourTravelNotesImg = tourTravelNotesImgService.getByIdWithRelation(id, MyRelationParam.full());
+        if (tourTravelNotesImg == null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        TourTravelNotesImgVo tourTravelNotesImgVo = MyModelUtil.copyTo(tourTravelNotesImg, TourTravelNotesImgVo.class);
+        return ResponseResult.success(tourTravelNotesImgVo);
+    }
+
+    private ResponseResult<Void> doDelete(Long id) {
+        String errorMessage;
+        // 验证关联Id的数据合法性
+        TourTravelNotesImg originalTourTravelNotesImg = tourTravelNotesImgService.getById(id);
+        if (originalTourTravelNotesImg == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        if (!tourTravelNotesImgService.remove(id)) {
+            errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        return ResponseResult.success();
+    }
+}

+ 179 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourTravelNotesMentionUserController.java

@@ -0,0 +1,179 @@
+package com.tourism.webadmin.back.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.tourism.common.log.annotation.OperationLog;
+import com.tourism.common.log.model.constant.SysOperationLogType;
+import com.github.pagehelper.page.PageMethod;
+import com.tourism.webadmin.back.vo.*;
+import com.tourism.webadmin.back.dto.*;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.back.service.*;
+import com.tourism.common.core.object.*;
+import com.tourism.common.core.util.*;
+import com.tourism.common.core.constant.*;
+import com.tourism.common.core.annotation.MyRequestBody;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+/**
+ * 游记提及的用户操作控制器类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Tag(name = "游记提及的用户管理接口")
+@Slf4j
+@RestController
+@RequestMapping("/admin/app/tourTravelNotesMentionUser")
+public class TourTravelNotesMentionUserController {
+
+    @Autowired
+    private TourTravelNotesMentionUserService tourTravelNotesMentionUserService;
+
+    /**
+     * 新增游记提及的用户数据。
+     *
+     * @param tourTravelNotesMentionUserDto 新增对象。
+     * @return 应答结果对象,包含新增对象主键Id。
+     */
+    @ApiOperationSupport(ignoreParameters = {"tourTravelNotesMentionUserDto.id"})
+    @SaCheckPermission("tourTravelNotesMentionUser.add")
+    @OperationLog(type = SysOperationLogType.ADD)
+    @PostMapping("/add")
+    public ResponseResult<Long> add(@MyRequestBody TourTravelNotesMentionUserDto tourTravelNotesMentionUserDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourTravelNotesMentionUserDto, false);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        TourTravelNotesMentionUser tourTravelNotesMentionUser = MyModelUtil.copyTo(tourTravelNotesMentionUserDto, TourTravelNotesMentionUser.class);
+        tourTravelNotesMentionUser = tourTravelNotesMentionUserService.saveNew(tourTravelNotesMentionUser);
+        return ResponseResult.success(tourTravelNotesMentionUser.getId());
+    }
+
+    /**
+     * 更新游记提及的用户数据。
+     *
+     * @param tourTravelNotesMentionUserDto 更新对象。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesMentionUser.update")
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/update")
+    public ResponseResult<Void> update(@MyRequestBody TourTravelNotesMentionUserDto tourTravelNotesMentionUserDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourTravelNotesMentionUserDto, true);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        TourTravelNotesMentionUser tourTravelNotesMentionUser = MyModelUtil.copyTo(tourTravelNotesMentionUserDto, TourTravelNotesMentionUser.class);
+        TourTravelNotesMentionUser originalTourTravelNotesMentionUser = tourTravelNotesMentionUserService.getById(tourTravelNotesMentionUser.getId());
+        if (originalTourTravelNotesMentionUser == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        if (!tourTravelNotesMentionUserService.update(tourTravelNotesMentionUser, originalTourTravelNotesMentionUser)) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 删除游记提及的用户数据。
+     *
+     * @param id 删除对象主键Id。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesMentionUser.delete")
+    @OperationLog(type = SysOperationLogType.DELETE)
+    @PostMapping("/delete")
+    public ResponseResult<Void> delete(@MyRequestBody Long id) {
+        if (MyCommonUtil.existBlankArgument(id)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        return this.doDelete(id);
+    }
+
+    /**
+     * 批量删除游记提及的用户数据。
+     *
+     * @param idList 待删除对象的主键Id列表。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesMentionUser.delete")
+    @OperationLog(type = SysOperationLogType.DELETE_BATCH)
+    @PostMapping("/deleteBatch")
+    public ResponseResult<Void> deleteBatch(@MyRequestBody List<Long> idList) {
+        if (MyCommonUtil.existBlankArgument(idList)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        for (Long id : idList) {
+            ResponseResult<Void> responseResult = this.doDelete(id);
+            if (!responseResult.isSuccess()) {
+                return responseResult;
+            }
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 列出符合过滤条件的游记提及的用户列表。
+     *
+     * @param tourTravelNotesMentionUserDtoFilter 过滤对象。
+     * @param orderParam 排序参数。
+     * @param pageParam 分页参数。
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @SaCheckPermission("tourTravelNotesMentionUser.view")
+    @PostMapping("/list")
+    public ResponseResult<MyPageData<TourTravelNotesMentionUserVo>> list(
+            @MyRequestBody TourTravelNotesMentionUserDto tourTravelNotesMentionUserDtoFilter,
+            @MyRequestBody MyOrderParam orderParam,
+            @MyRequestBody MyPageParam pageParam) {
+        if (pageParam != null) {
+            PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
+        }
+        TourTravelNotesMentionUser tourTravelNotesMentionUserFilter = MyModelUtil.copyTo(tourTravelNotesMentionUserDtoFilter, TourTravelNotesMentionUser.class);
+        String orderBy = MyOrderParam.buildOrderBy(orderParam, TourTravelNotesMentionUser.class);
+        List<TourTravelNotesMentionUser> tourTravelNotesMentionUserList =
+                tourTravelNotesMentionUserService.getTourTravelNotesMentionUserListWithRelation(tourTravelNotesMentionUserFilter, orderBy);
+        return ResponseResult.success(MyPageUtil.makeResponseData(tourTravelNotesMentionUserList, TourTravelNotesMentionUserVo.class));
+    }
+
+    /**
+     * 查看指定游记提及的用户对象详情。
+     *
+     * @param id 指定对象主键Id。
+     * @return 应答结果对象,包含对象详情。
+     */
+    @SaCheckPermission("tourTravelNotesMentionUser.view")
+    @GetMapping("/view")
+    public ResponseResult<TourTravelNotesMentionUserVo> view(@RequestParam Long id) {
+        TourTravelNotesMentionUser tourTravelNotesMentionUser = tourTravelNotesMentionUserService.getByIdWithRelation(id, MyRelationParam.full());
+        if (tourTravelNotesMentionUser == null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        TourTravelNotesMentionUserVo tourTravelNotesMentionUserVo = MyModelUtil.copyTo(tourTravelNotesMentionUser, TourTravelNotesMentionUserVo.class);
+        return ResponseResult.success(tourTravelNotesMentionUserVo);
+    }
+
+    private ResponseResult<Void> doDelete(Long id) {
+        String errorMessage;
+        // 验证关联Id的数据合法性
+        TourTravelNotesMentionUser originalTourTravelNotesMentionUser = tourTravelNotesMentionUserService.getById(id);
+        if (originalTourTravelNotesMentionUser == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        if (!tourTravelNotesMentionUserService.remove(id)) {
+            errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        return ResponseResult.success();
+    }
+}

+ 179 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourTravelNotesTopicController.java

@@ -0,0 +1,179 @@
+package com.tourism.webadmin.back.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.tourism.common.log.annotation.OperationLog;
+import com.tourism.common.log.model.constant.SysOperationLogType;
+import com.github.pagehelper.page.PageMethod;
+import com.tourism.webadmin.back.vo.*;
+import com.tourism.webadmin.back.dto.*;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.back.service.*;
+import com.tourism.common.core.object.*;
+import com.tourism.common.core.util.*;
+import com.tourism.common.core.constant.*;
+import com.tourism.common.core.annotation.MyRequestBody;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+/**
+ * 游记话题操作控制器类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Tag(name = "游记话题管理接口")
+@Slf4j
+@RestController
+@RequestMapping("/admin/app/tourTravelNotesTopic")
+public class TourTravelNotesTopicController {
+
+    @Autowired
+    private TourTravelNotesTopicService tourTravelNotesTopicService;
+
+    /**
+     * 新增游记话题数据。
+     *
+     * @param tourTravelNotesTopicDto 新增对象。
+     * @return 应答结果对象,包含新增对象主键Id。
+     */
+    @ApiOperationSupport(ignoreParameters = {"tourTravelNotesTopicDto.id"})
+    @SaCheckPermission("tourTravelNotesTopic.add")
+    @OperationLog(type = SysOperationLogType.ADD)
+    @PostMapping("/add")
+    public ResponseResult<Long> add(@MyRequestBody TourTravelNotesTopicDto tourTravelNotesTopicDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourTravelNotesTopicDto, false);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        TourTravelNotesTopic tourTravelNotesTopic = MyModelUtil.copyTo(tourTravelNotesTopicDto, TourTravelNotesTopic.class);
+        tourTravelNotesTopic = tourTravelNotesTopicService.saveNew(tourTravelNotesTopic);
+        return ResponseResult.success(tourTravelNotesTopic.getId());
+    }
+
+    /**
+     * 更新游记话题数据。
+     *
+     * @param tourTravelNotesTopicDto 更新对象。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesTopic.update")
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/update")
+    public ResponseResult<Void> update(@MyRequestBody TourTravelNotesTopicDto tourTravelNotesTopicDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourTravelNotesTopicDto, true);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        TourTravelNotesTopic tourTravelNotesTopic = MyModelUtil.copyTo(tourTravelNotesTopicDto, TourTravelNotesTopic.class);
+        TourTravelNotesTopic originalTourTravelNotesTopic = tourTravelNotesTopicService.getById(tourTravelNotesTopic.getId());
+        if (originalTourTravelNotesTopic == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        if (!tourTravelNotesTopicService.update(tourTravelNotesTopic, originalTourTravelNotesTopic)) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 删除游记话题数据。
+     *
+     * @param id 删除对象主键Id。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesTopic.delete")
+    @OperationLog(type = SysOperationLogType.DELETE)
+    @PostMapping("/delete")
+    public ResponseResult<Void> delete(@MyRequestBody Long id) {
+        if (MyCommonUtil.existBlankArgument(id)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        return this.doDelete(id);
+    }
+
+    /**
+     * 批量删除游记话题数据。
+     *
+     * @param idList 待删除对象的主键Id列表。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesTopic.delete")
+    @OperationLog(type = SysOperationLogType.DELETE_BATCH)
+    @PostMapping("/deleteBatch")
+    public ResponseResult<Void> deleteBatch(@MyRequestBody List<Long> idList) {
+        if (MyCommonUtil.existBlankArgument(idList)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        for (Long id : idList) {
+            ResponseResult<Void> responseResult = this.doDelete(id);
+            if (!responseResult.isSuccess()) {
+                return responseResult;
+            }
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 列出符合过滤条件的游记话题列表。
+     *
+     * @param tourTravelNotesTopicDtoFilter 过滤对象。
+     * @param orderParam 排序参数。
+     * @param pageParam 分页参数。
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @SaCheckPermission("tourTravelNotesTopic.view")
+    @PostMapping("/list")
+    public ResponseResult<MyPageData<TourTravelNotesTopicVo>> list(
+            @MyRequestBody TourTravelNotesTopicDto tourTravelNotesTopicDtoFilter,
+            @MyRequestBody MyOrderParam orderParam,
+            @MyRequestBody MyPageParam pageParam) {
+        if (pageParam != null) {
+            PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
+        }
+        TourTravelNotesTopic tourTravelNotesTopicFilter = MyModelUtil.copyTo(tourTravelNotesTopicDtoFilter, TourTravelNotesTopic.class);
+        String orderBy = MyOrderParam.buildOrderBy(orderParam, TourTravelNotesTopic.class);
+        List<TourTravelNotesTopic> tourTravelNotesTopicList =
+                tourTravelNotesTopicService.getTourTravelNotesTopicListWithRelation(tourTravelNotesTopicFilter, orderBy);
+        return ResponseResult.success(MyPageUtil.makeResponseData(tourTravelNotesTopicList, TourTravelNotesTopicVo.class));
+    }
+
+    /**
+     * 查看指定游记话题对象详情。
+     *
+     * @param id 指定对象主键Id。
+     * @return 应答结果对象,包含对象详情。
+     */
+    @SaCheckPermission("tourTravelNotesTopic.view")
+    @GetMapping("/view")
+    public ResponseResult<TourTravelNotesTopicVo> view(@RequestParam Long id) {
+        TourTravelNotesTopic tourTravelNotesTopic = tourTravelNotesTopicService.getByIdWithRelation(id, MyRelationParam.full());
+        if (tourTravelNotesTopic == null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        TourTravelNotesTopicVo tourTravelNotesTopicVo = MyModelUtil.copyTo(tourTravelNotesTopic, TourTravelNotesTopicVo.class);
+        return ResponseResult.success(tourTravelNotesTopicVo);
+    }
+
+    private ResponseResult<Void> doDelete(Long id) {
+        String errorMessage;
+        // 验证关联Id的数据合法性
+        TourTravelNotesTopic originalTourTravelNotesTopic = tourTravelNotesTopicService.getById(id);
+        if (originalTourTravelNotesTopic == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        if (!tourTravelNotesTopicService.remove(id)) {
+            errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        return ResponseResult.success();
+    }
+}

+ 179 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourTravelNotesTopicRelationController.java

@@ -0,0 +1,179 @@
+package com.tourism.webadmin.back.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.tourism.common.log.annotation.OperationLog;
+import com.tourism.common.log.model.constant.SysOperationLogType;
+import com.github.pagehelper.page.PageMethod;
+import com.tourism.webadmin.back.vo.*;
+import com.tourism.webadmin.back.dto.*;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.back.service.*;
+import com.tourism.common.core.object.*;
+import com.tourism.common.core.util.*;
+import com.tourism.common.core.constant.*;
+import com.tourism.common.core.annotation.MyRequestBody;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+/**
+ * 游记与话题关联操作控制器类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Tag(name = "游记与话题关联管理接口")
+@Slf4j
+@RestController
+@RequestMapping("/admin/app/tourTravelNotesTopicRelation")
+public class TourTravelNotesTopicRelationController {
+
+    @Autowired
+    private TourTravelNotesTopicRelationService tourTravelNotesTopicRelationService;
+
+    /**
+     * 新增游记与话题关联数据。
+     *
+     * @param tourTravelNotesTopicRelationDto 新增对象。
+     * @return 应答结果对象,包含新增对象主键Id。
+     */
+    @ApiOperationSupport(ignoreParameters = {"tourTravelNotesTopicRelationDto.id"})
+    @SaCheckPermission("tourTravelNotesTopicRelation.add")
+    @OperationLog(type = SysOperationLogType.ADD)
+    @PostMapping("/add")
+    public ResponseResult<Long> add(@MyRequestBody TourTravelNotesTopicRelationDto tourTravelNotesTopicRelationDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourTravelNotesTopicRelationDto, false);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        TourTravelNotesTopicRelation tourTravelNotesTopicRelation = MyModelUtil.copyTo(tourTravelNotesTopicRelationDto, TourTravelNotesTopicRelation.class);
+        tourTravelNotesTopicRelation = tourTravelNotesTopicRelationService.saveNew(tourTravelNotesTopicRelation);
+        return ResponseResult.success(tourTravelNotesTopicRelation.getId());
+    }
+
+    /**
+     * 更新游记与话题关联数据。
+     *
+     * @param tourTravelNotesTopicRelationDto 更新对象。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesTopicRelation.update")
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/update")
+    public ResponseResult<Void> update(@MyRequestBody TourTravelNotesTopicRelationDto tourTravelNotesTopicRelationDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourTravelNotesTopicRelationDto, true);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        TourTravelNotesTopicRelation tourTravelNotesTopicRelation = MyModelUtil.copyTo(tourTravelNotesTopicRelationDto, TourTravelNotesTopicRelation.class);
+        TourTravelNotesTopicRelation originalTourTravelNotesTopicRelation = tourTravelNotesTopicRelationService.getById(tourTravelNotesTopicRelation.getId());
+        if (originalTourTravelNotesTopicRelation == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        if (!tourTravelNotesTopicRelationService.update(tourTravelNotesTopicRelation, originalTourTravelNotesTopicRelation)) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 删除游记与话题关联数据。
+     *
+     * @param id 删除对象主键Id。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesTopicRelation.delete")
+    @OperationLog(type = SysOperationLogType.DELETE)
+    @PostMapping("/delete")
+    public ResponseResult<Void> delete(@MyRequestBody Long id) {
+        if (MyCommonUtil.existBlankArgument(id)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        return this.doDelete(id);
+    }
+
+    /**
+     * 批量删除游记与话题关联数据。
+     *
+     * @param idList 待删除对象的主键Id列表。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourTravelNotesTopicRelation.delete")
+    @OperationLog(type = SysOperationLogType.DELETE_BATCH)
+    @PostMapping("/deleteBatch")
+    public ResponseResult<Void> deleteBatch(@MyRequestBody List<Long> idList) {
+        if (MyCommonUtil.existBlankArgument(idList)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        for (Long id : idList) {
+            ResponseResult<Void> responseResult = this.doDelete(id);
+            if (!responseResult.isSuccess()) {
+                return responseResult;
+            }
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 列出符合过滤条件的游记与话题关联列表。
+     *
+     * @param tourTravelNotesTopicRelationDtoFilter 过滤对象。
+     * @param orderParam 排序参数。
+     * @param pageParam 分页参数。
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @SaCheckPermission("tourTravelNotesTopicRelation.view")
+    @PostMapping("/list")
+    public ResponseResult<MyPageData<TourTravelNotesTopicRelationVo>> list(
+            @MyRequestBody TourTravelNotesTopicRelationDto tourTravelNotesTopicRelationDtoFilter,
+            @MyRequestBody MyOrderParam orderParam,
+            @MyRequestBody MyPageParam pageParam) {
+        if (pageParam != null) {
+            PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
+        }
+        TourTravelNotesTopicRelation tourTravelNotesTopicRelationFilter = MyModelUtil.copyTo(tourTravelNotesTopicRelationDtoFilter, TourTravelNotesTopicRelation.class);
+        String orderBy = MyOrderParam.buildOrderBy(orderParam, TourTravelNotesTopicRelation.class);
+        List<TourTravelNotesTopicRelation> tourTravelNotesTopicRelationList =
+                tourTravelNotesTopicRelationService.getTourTravelNotesTopicRelationListWithRelation(tourTravelNotesTopicRelationFilter, orderBy);
+        return ResponseResult.success(MyPageUtil.makeResponseData(tourTravelNotesTopicRelationList, TourTravelNotesTopicRelationVo.class));
+    }
+
+    /**
+     * 查看指定游记与话题关联对象详情。
+     *
+     * @param id 指定对象主键Id。
+     * @return 应答结果对象,包含对象详情。
+     */
+    @SaCheckPermission("tourTravelNotesTopicRelation.view")
+    @GetMapping("/view")
+    public ResponseResult<TourTravelNotesTopicRelationVo> view(@RequestParam Long id) {
+        TourTravelNotesTopicRelation tourTravelNotesTopicRelation = tourTravelNotesTopicRelationService.getByIdWithRelation(id, MyRelationParam.full());
+        if (tourTravelNotesTopicRelation == null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        TourTravelNotesTopicRelationVo tourTravelNotesTopicRelationVo = MyModelUtil.copyTo(tourTravelNotesTopicRelation, TourTravelNotesTopicRelationVo.class);
+        return ResponseResult.success(tourTravelNotesTopicRelationVo);
+    }
+
+    private ResponseResult<Void> doDelete(Long id) {
+        String errorMessage;
+        // 验证关联Id的数据合法性
+        TourTravelNotesTopicRelation originalTourTravelNotesTopicRelation = tourTravelNotesTopicRelationService.getById(id);
+        if (originalTourTravelNotesTopicRelation == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        if (!tourTravelNotesTopicRelationService.remove(id)) {
+            errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        return ResponseResult.success();
+    }
+}

+ 11 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourFansMapper.java

@@ -1,6 +1,8 @@
 package com.tourism.webadmin.back.dao;
 
 import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.webadmin.app.website.model.TourShortUser;
+import com.tourism.webadmin.app.website.vo.TourShortUserVo;
 import com.tourism.webadmin.back.model.TourFans;
 import org.apache.ibatis.annotations.Param;
 
@@ -30,4 +32,13 @@ public interface TourFansMapper extends BaseDaoMapper<TourFans> {
      */
     List<TourFans> getTourFansList(
             @Param("tourFansFilter") TourFans tourFansFilter, @Param("orderBy") String orderBy);
+
+    /**
+     * 获取过滤后的对象列表。
+     *
+     * @param name 模糊查询的昵称。
+     * @return 对象列表。
+     */
+    List<TourShortUser> getFouceEachFriendsByName(
+            @Param("userId") Long userId,@Param("name") String name);
 }

+ 12 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourImGroupMapper.java

@@ -1,6 +1,8 @@
 package com.tourism.webadmin.back.dao;
 
 import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.webadmin.app.website.model.TourShortImGroup;
+import com.tourism.webadmin.app.website.vo.TourShortImGroupVo;
 import com.tourism.webadmin.back.model.TourImGroup;
 import com.tourism.webadmin.back.model.TourImGroupInvitation;
 import com.tourism.webadmin.back.model.TourImMember;
@@ -50,4 +52,14 @@ public interface TourImGroupMapper extends BaseDaoMapper<TourImGroup> {
             @Param("tourImMemberFilter") TourImMember tourImMemberFilter,
             @Param("tourImMessageFilter") TourImMessage tourImMessageFilter,
             @Param("orderBy") String orderBy);
+
+    /**
+     * 获取过滤后的对象列表。
+     *
+     * @param userId 用户id。
+     * @param name 昵称。
+     * @return 对象列表。
+     */
+    List<TourShortImGroup> getTakePartImGroupListByName(
+            @Param("userId") Long userId,@Param("name") String name);
 }

+ 33 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourTravelNotesImgMapper.java

@@ -0,0 +1,33 @@
+package com.tourism.webadmin.back.dao;
+
+import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.webadmin.back.model.TourTravelNotesImg;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.*;
+
+/**
+ * 游记中的图片数据操作访问接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public interface TourTravelNotesImgMapper extends BaseDaoMapper<TourTravelNotesImg> {
+
+    /**
+     * 批量插入对象列表。
+     *
+     * @param tourTravelNotesImgList 新增对象列表。
+     */
+    void insertList(List<TourTravelNotesImg> tourTravelNotesImgList);
+
+    /**
+     * 获取过滤后的对象列表。
+     *
+     * @param tourTravelNotesImgFilter 主表过滤对象。
+     * @param orderBy 排序字符串,order by从句的参数。
+     * @return 对象列表。
+     */
+    List<TourTravelNotesImg> getTourTravelNotesImgList(
+            @Param("tourTravelNotesImgFilter") TourTravelNotesImg tourTravelNotesImgFilter, @Param("orderBy") String orderBy);
+}

+ 33 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourTravelNotesMentionUserMapper.java

@@ -0,0 +1,33 @@
+package com.tourism.webadmin.back.dao;
+
+import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.webadmin.back.model.TourTravelNotesMentionUser;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.*;
+
+/**
+ * 游记提及的用户数据操作访问接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public interface TourTravelNotesMentionUserMapper extends BaseDaoMapper<TourTravelNotesMentionUser> {
+
+    /**
+     * 批量插入对象列表。
+     *
+     * @param tourTravelNotesMentionUserList 新增对象列表。
+     */
+    void insertList(List<TourTravelNotesMentionUser> tourTravelNotesMentionUserList);
+
+    /**
+     * 获取过滤后的对象列表。
+     *
+     * @param tourTravelNotesMentionUserFilter 主表过滤对象。
+     * @param orderBy 排序字符串,order by从句的参数。
+     * @return 对象列表。
+     */
+    List<TourTravelNotesMentionUser> getTourTravelNotesMentionUserList(
+            @Param("tourTravelNotesMentionUserFilter") TourTravelNotesMentionUser tourTravelNotesMentionUserFilter, @Param("orderBy") String orderBy);
+}

+ 43 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourTravelNotesTopicMapper.java

@@ -0,0 +1,43 @@
+package com.tourism.webadmin.back.dao;
+
+import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.webadmin.app.website.model.TourShortTopic;
+import com.tourism.webadmin.back.model.TourTravelNotesTopic;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.*;
+
+/**
+ * 游记话题数据操作访问接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public interface TourTravelNotesTopicMapper extends BaseDaoMapper<TourTravelNotesTopic> {
+
+    /**
+     * 批量插入对象列表。
+     *
+     * @param tourTravelNotesTopicList 新增对象列表。
+     */
+    void insertList(List<TourTravelNotesTopic> tourTravelNotesTopicList);
+
+    /**
+     * 获取过滤后的对象列表。
+     *
+     * @param tourTravelNotesTopicFilter 主表过滤对象。
+     * @param orderBy 排序字符串,order by从句的参数。
+     * @return 对象列表。
+     */
+    List<TourTravelNotesTopic> getTourTravelNotesTopicList(
+            @Param("tourTravelNotesTopicFilter") TourTravelNotesTopic tourTravelNotesTopicFilter, @Param("orderBy") String orderBy);
+
+    /**
+     * 获取过滤后的对象列表。
+     *
+     * @param name 话题名称。
+     * @return 对象列表。
+     */
+    List<TourShortTopic> getTourTravelNotesTopicListByName(
+            @Param("name") String name);
+}

+ 33 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourTravelNotesTopicRelationMapper.java

@@ -0,0 +1,33 @@
+package com.tourism.webadmin.back.dao;
+
+import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.webadmin.back.model.TourTravelNotesTopicRelation;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.*;
+
+/**
+ * 游记与话题关联数据操作访问接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public interface TourTravelNotesTopicRelationMapper extends BaseDaoMapper<TourTravelNotesTopicRelation> {
+
+    /**
+     * 批量插入对象列表。
+     *
+     * @param tourTravelNotesTopicRelationList 新增对象列表。
+     */
+    void insertList(List<TourTravelNotesTopicRelation> tourTravelNotesTopicRelationList);
+
+    /**
+     * 获取过滤后的对象列表。
+     *
+     * @param tourTravelNotesTopicRelationFilter 主表过滤对象。
+     * @param orderBy 排序字符串,order by从句的参数。
+     * @return 对象列表。
+     */
+    List<TourTravelNotesTopicRelation> getTourTravelNotesTopicRelationList(
+            @Param("tourTravelNotesTopicRelationFilter") TourTravelNotesTopicRelation tourTravelNotesTopicRelationFilter, @Param("orderBy") String orderBy);
+}

+ 17 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourFansMapper.xml

@@ -60,4 +60,21 @@
             ORDER BY ${orderBy}
         </if>
     </select>
+
+    <select id="getFouceEachFriendsByName" resultType="com.tourism.webadmin.app.website.model.TourShortUser" parameterType="String">
+        SELECT user.user_id, user.show_name, user.head_image_url
+        FROM tour_user AS user
+        WHERE user.user_id IN (
+        SELECT DISTINCT tf1.attention_id
+        FROM tour_fans tf1
+        INNER JOIN tour_fans tf2 ON tf1.create_user_id = tf2.attention_id
+        WHERE tf1.create_user_id = #{userId}
+        AND tf2.attention_id = #{userId}
+        AND tf1.delete_flag = 1
+        AND tf2.delete_flag = 1
+        )
+        <if test="name != null and name != ''">
+            AND user.show_name LIKE CONCAT('%', #{name}, '%')
+        </if>
+    </select>
 </mapper>

+ 18 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourImGroupMapper.xml

@@ -155,4 +155,22 @@
             ORDER BY ${orderBy}
         </if>
     </select>
+
+    <select id="getTakePartImGroupListByName" resultType="com.tourism.webadmin.app.website.model.TourShortImGroup">
+        SELECT
+            g.id,
+            g.group_name,
+            g.group_avatar
+        FROM
+            tour_im_group g
+                INNER JOIN
+            tour_im_member m
+            ON
+                g.id = m.group_id
+        WHERE
+            m.user_id = #{userId} and g.data_state = 1 and m.data_state = 1 and g.notice_type = 2
+        <if test="name != null and name != ''">
+        AND g.group_name LIKE CONCAT('%', #{name}, '%')
+        </if>
+    </select>
 </mapper>

+ 47 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourTravelNotesImgMapper.xml

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.tourism.webadmin.back.dao.TourTravelNotesImgMapper">
+    <resultMap id="BaseResultMap" type="com.tourism.webadmin.back.model.TourTravelNotesImg">
+        <id column="id" jdbcType="BIGINT" property="id"/>
+        <result column="img_url" jdbcType="VARCHAR" property="imgUrl"/>
+        <result column="travel_notes_id" jdbcType="BIGINT" property="travelNotesId"/>
+    </resultMap>
+
+    <insert id="insertList">
+        INSERT INTO tour_travel_notes_img
+            (id,
+            img_url,
+            travel_notes_id)
+        VALUES
+        <foreach collection="list" index="index" item="item" separator="," >
+            (#{item.id},
+            #{item.imgUrl},
+            #{item.travelNotesId})
+        </foreach>
+    </insert>
+
+    <!-- 如果有逻辑删除字段过滤,请写到这里 -->
+    <sql id="filterRef">
+        <!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
+        <include refid="com.tourism.webadmin.back.dao.TourTravelNotesImgMapper.inputFilterRef"/>
+    </sql>
+
+    <!-- 这里仅包含调用接口输入的主表过滤条件 -->
+    <sql id="inputFilterRef">
+        <if test="tourTravelNotesImgFilter != null">
+            <if test="tourTravelNotesImgFilter.travelNotesId != null">
+                AND tour_travel_notes_img.travel_notes_id = #{tourTravelNotesImgFilter.travelNotesId}
+            </if>
+        </if>
+    </sql>
+
+    <select id="getTourTravelNotesImgList" resultMap="BaseResultMap" parameterType="com.tourism.webadmin.back.model.TourTravelNotesImg">
+        SELECT * FROM tour_travel_notes_img
+        <where>
+            <include refid="filterRef"/>
+        </where>
+        <if test="orderBy != null and orderBy != ''">
+            ORDER BY ${orderBy}
+        </if>
+    </select>
+</mapper>

+ 57 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourTravelNotesMentionUserMapper.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.tourism.webadmin.back.dao.TourTravelNotesMentionUserMapper">
+    <resultMap id="BaseResultMap" type="com.tourism.webadmin.back.model.TourTravelNotesMentionUser">
+        <id column="id" jdbcType="BIGINT" property="id"/>
+        <result column="travel_notes_id" jdbcType="BIGINT" property="travelNotesId"/>
+        <result column="user_name" jdbcType="VARCHAR" property="userName"/>
+        <result column="user_id" jdbcType="BIGINT" property="userId"/>
+    </resultMap>
+
+    <insert id="insertList">
+        INSERT INTO tour_travel_notes_mention_user
+            (id,
+            travel_notes_id,
+            user_name,
+            user_id)
+        VALUES
+        <foreach collection="list" index="index" item="item" separator="," >
+            (#{item.id},
+            #{item.travelNotesId},
+            #{item.userName},
+            #{item.userId})
+        </foreach>
+    </insert>
+
+    <!-- 如果有逻辑删除字段过滤,请写到这里 -->
+    <sql id="filterRef">
+        <!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
+        <include refid="com.tourism.webadmin.back.dao.TourTravelNotesMentionUserMapper.inputFilterRef"/>
+    </sql>
+
+    <!-- 这里仅包含调用接口输入的主表过滤条件 -->
+    <sql id="inputFilterRef">
+        <if test="tourTravelNotesMentionUserFilter != null">
+            <if test="tourTravelNotesMentionUserFilter.travelNotesId != null">
+                AND tour_travel_notes_mention_user.travel_notes_id = #{tourTravelNotesMentionUserFilter.travelNotesId}
+            </if>
+            <if test="tourTravelNotesMentionUserFilter.userName != null and tourTravelNotesMentionUserFilter.userName != ''">
+                <bind name = "safeTourTravelNotesMentionUserUserName" value = "'%' + tourTravelNotesMentionUserFilter.userName + '%'" />
+                AND tour_travel_notes_mention_user.user_name LIKE #{safeTourTravelNotesMentionUserUserName}
+            </if>
+            <if test="tourTravelNotesMentionUserFilter.userId != null">
+                AND tour_travel_notes_mention_user.user_id = #{tourTravelNotesMentionUserFilter.userId}
+            </if>
+        </if>
+    </sql>
+
+    <select id="getTourTravelNotesMentionUserList" resultMap="BaseResultMap" parameterType="com.tourism.webadmin.back.model.TourTravelNotesMentionUser">
+        SELECT * FROM tour_travel_notes_mention_user
+        <where>
+            <include refid="filterRef"/>
+        </where>
+        <if test="orderBy != null and orderBy != ''">
+            ORDER BY ${orderBy}
+        </if>
+    </select>
+</mapper>

+ 89 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourTravelNotesTopicMapper.xml

@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.tourism.webadmin.back.dao.TourTravelNotesTopicMapper">
+    <resultMap id="BaseResultMap" type="com.tourism.webadmin.back.model.TourTravelNotesTopic">
+        <id column="id" jdbcType="BIGINT" property="id"/>
+        <result column="name" jdbcType="VARCHAR" property="name"/>
+        <result column="enable" jdbcType="TINYINT" property="enable"/>
+        <result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
+        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+        <result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
+        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+        <result column="data_state" jdbcType="TINYINT" property="dataState"/>
+    </resultMap>
+
+    <insert id="insertList">
+        INSERT INTO tour_travel_notes_topic
+            (id,
+            name,
+            enable,
+            create_user_id,
+            create_time,
+            update_user_id,
+            update_time,
+            data_state)
+        VALUES
+        <foreach collection="list" index="index" item="item" separator="," >
+            (#{item.id},
+            #{item.name},
+            #{item.enable},
+            #{item.createUserId},
+            #{item.createTime},
+            #{item.updateUserId},
+            #{item.updateTime},
+            #{item.dataState})
+        </foreach>
+    </insert>
+
+    <!-- 如果有逻辑删除字段过滤,请写到这里 -->
+    <sql id="filterRef">
+        <!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
+        <include refid="com.tourism.webadmin.back.dao.TourTravelNotesTopicMapper.inputFilterRef"/>
+        AND tour_travel_notes_topic.data_state = ${@com.tourism.common.core.constant.GlobalDeletedFlag@NORMAL}
+    </sql>
+
+    <!-- 这里仅包含调用接口输入的主表过滤条件 -->
+    <sql id="inputFilterRef">
+        <if test="tourTravelNotesTopicFilter != null">
+            <if test="tourTravelNotesTopicFilter.name != null and tourTravelNotesTopicFilter.name != ''">
+                <bind name = "safeTourTravelNotesTopicName" value = "'%' + tourTravelNotesTopicFilter.name + '%'" />
+                AND tour_travel_notes_topic.name LIKE #{safeTourTravelNotesTopicName}
+            </if>
+            <if test="tourTravelNotesTopicFilter.enable != null">
+                AND tour_travel_notes_topic.enable = #{tourTravelNotesTopicFilter.enable}
+            </if>
+        </if>
+    </sql>
+
+    <select id="getTourTravelNotesTopicList" resultMap="BaseResultMap" parameterType="com.tourism.webadmin.back.model.TourTravelNotesTopic">
+        SELECT * FROM tour_travel_notes_topic
+        <where>
+            <include refid="filterRef"/>
+        </where>
+        <if test="orderBy != null and orderBy != ''">
+            ORDER BY ${orderBy}
+        </if>
+    </select>
+
+    <select id="getTourTravelNotesTopicListByName" resultType="com.tourism.webadmin.app.website.model.TourShortTopic" parameterType="String">
+        SELECT
+            tnt.name AS topic_name,
+            SUM(tntp.page_view_count) AS total_view_count
+        FROM
+            tour_travel_notes_topic tnt
+                JOIN
+            tour_travel_notes_topic_relation tnttr ON tnt.id = tnttr.topic_id
+                JOIN
+            tour_tourism_project_travel_notes tntp ON tnttr.travel_notes_id = tntp.id
+        where tnt.enable = 1 and tnt.data_state = 1 and tntp.data_state = 1
+        <where>
+            <if test="name != null and name != ''">
+            and tnt.name LIKE CONCAT('%', #{name}, '%')
+            </if>
+        </where>
+        GROUP BY
+            tnt.name
+        ORDER BY
+            total_view_count DESC;
+    </select>
+</mapper>

+ 57 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourTravelNotesTopicRelationMapper.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.tourism.webadmin.back.dao.TourTravelNotesTopicRelationMapper">
+    <resultMap id="BaseResultMap" type="com.tourism.webadmin.back.model.TourTravelNotesTopicRelation">
+        <id column="id" jdbcType="BIGINT" property="id"/>
+        <result column="travel_notes_id" jdbcType="BIGINT" property="travelNotesId"/>
+        <result column="topic_id" jdbcType="BIGINT" property="topicId"/>
+        <result column="topic_name" jdbcType="VARCHAR" property="topicName"/>
+    </resultMap>
+
+    <insert id="insertList">
+        INSERT INTO tour_travel_notes_topic_relation
+            (id,
+            travel_notes_id,
+            topic_id,
+            topic_name)
+        VALUES
+        <foreach collection="list" index="index" item="item" separator="," >
+            (#{item.id},
+            #{item.travelNotesId},
+            #{item.topicId},
+            #{item.topicName})
+        </foreach>
+    </insert>
+
+    <!-- 如果有逻辑删除字段过滤,请写到这里 -->
+    <sql id="filterRef">
+        <!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
+        <include refid="com.tourism.webadmin.back.dao.TourTravelNotesTopicRelationMapper.inputFilterRef"/>
+    </sql>
+
+    <!-- 这里仅包含调用接口输入的主表过滤条件 -->
+    <sql id="inputFilterRef">
+        <if test="tourTravelNotesTopicRelationFilter != null">
+            <if test="tourTravelNotesTopicRelationFilter.travelNotesId != null">
+                AND tour_travel_notes_topic_relation.travel_notes_id = #{tourTravelNotesTopicRelationFilter.travelNotesId}
+            </if>
+            <if test="tourTravelNotesTopicRelationFilter.topicId != null">
+                AND tour_travel_notes_topic_relation.topic_id = #{tourTravelNotesTopicRelationFilter.topicId}
+            </if>
+            <if test="tourTravelNotesTopicRelationFilter.topicName != null and tourTravelNotesTopicRelationFilter.topicName != ''">
+                <bind name = "safeTourTravelNotesTopicRelationTopicName" value = "'%' + tourTravelNotesTopicRelationFilter.topicName + '%'" />
+                AND tour_travel_notes_topic_relation.topic_name LIKE #{safeTourTravelNotesTopicRelationTopicName}
+            </if>
+        </if>
+    </sql>
+
+    <select id="getTourTravelNotesTopicRelationList" resultMap="BaseResultMap" parameterType="com.tourism.webadmin.back.model.TourTravelNotesTopicRelation">
+        SELECT * FROM tour_travel_notes_topic_relation
+        <where>
+            <include refid="filterRef"/>
+        </where>
+        <if test="orderBy != null and orderBy != ''">
+            ORDER BY ${orderBy}
+        </if>
+    </select>
+</mapper>

+ 8 - 3
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourismProjectTravelNotesWriteMapper.xml

@@ -32,6 +32,7 @@
         <result column="auto_reject_reason" jdbcType="VARCHAR" property="autoRejectReason"/>
         <result column="travel_mode" jdbcType="TINYINT" property="travelMode"/>
         <result column="travel_number" jdbcType="VARCHAR" property="travelNumber"/>
+        <result column="tour_im_group_id" jdbcType="BIGINT" property="tourImGroupId"/>
     </resultMap>
 
     <insert id="insertList">
@@ -65,7 +66,8 @@
             auto_audit_status,
             auto_reject_reason,
             travel_mode,
-            travel_number)
+            travel_number,
+            tour_im_group_id)
         VALUES
         <foreach collection="list" index="index" item="item" separator="," >
             (#{item.id},
@@ -97,7 +99,8 @@
             #{item.autoAuditStatus},
             #{item.autoRejectReason},
             #{item.travelMode},
-            #{item.travelNumber})
+            #{item.travelNumber},
+            #{item.tourImGroupId})
         </foreach>
     </insert>
 
@@ -165,10 +168,12 @@
                 <bind name = "safeTourismProjectTravelNotesWriteSearchString" value = "'%' + tourismProjectTravelNotesWriteFilter.searchString + '%'" />
                 AND CONCAT(IFNULL(tour_tourism_project_travel_notes_writer.project_title,''), IFNULL(tour_tourism_project_travel_notes_writer.count_times,''), IFNULL(tour_tourism_project_travel_notes_writer.role,''), IFNULL(tour_tourism_project_travel_notes_writer.average_cost,''), IFNULL(tour_tourism_project_travel_notes_writer.reason,'')) LIKE #{safeTourismProjectTravelNotesWriteSearchString}
             </if>
-
             <if test="tourismProjectTravelNotesWriteFilter.unmountState != null">
                 AND tour_tourism_project_travel_notes_writer.unmount_state = #{tourismProjectTravelNotesWriteFilter.unmountState}
             </if>
+            <if test="tourismProjectTravelNotesWriteFilter.tourImGroupId != null">
+                AND tour_tourism_project_travel_notes_writer.tour_im_group_id = #{tourismProjectTravelNotesWriteFilter.tourImGroupId}
+            </if>
             <if test="tourismProjectTravelNotesWriteFilter.directoryInfoIds != null and tourismProjectTravelNotesWriteFilter.directoryInfoIds.size() > 0">
                 AND tour_tourism_project_travel_notes_writer.end_place IN
                 <foreach item="id" index="index" collection="tourismProjectTravelNotesWriteFilter.directoryInfoIds" open="(" separator="," close=")">

+ 39 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourTravelNotesImgDto.java

@@ -0,0 +1,39 @@
+package com.tourism.webadmin.back.dto;
+
+import com.tourism.common.core.validator.UpdateGroup;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.*;
+
+/**
+ * 游记中的图片Dto对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "游记中的图片Dto对象")
+@Data
+public class TourTravelNotesImgDto {
+
+    /**
+     * id。
+     */
+    @Schema(description = "id。", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "数据验证失败,id不能为空!", groups = {UpdateGroup.class})
+    private Long id;
+
+    /**
+     * 图片地址。
+     */
+    @Schema(description = "图片地址。")
+    private String imgUrl;
+
+    /**
+     * 游记id。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "游记id。可支持等于操作符的列表数据过滤。")
+    private Long travelNotesId;
+}

+ 47 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourTravelNotesMentionUserDto.java

@@ -0,0 +1,47 @@
+package com.tourism.webadmin.back.dto;
+
+import com.tourism.common.core.validator.UpdateGroup;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.*;
+
+/**
+ * 游记提及的用户Dto对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "游记提及的用户Dto对象")
+@Data
+public class TourTravelNotesMentionUserDto {
+
+    /**
+     * 主键id。
+     */
+    @Schema(description = "主键id。", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "数据验证失败,主键id不能为空!", groups = {UpdateGroup.class})
+    private Long id;
+
+    /**
+     * 游记id。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "游记id。可支持等于操作符的列表数据过滤。")
+    private Long travelNotesId;
+
+    /**
+     * 写游记提到的用户昵称。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "写游记提到的用户昵称。可支持等于操作符的列表数据过滤。")
+    private String userName;
+
+    /**
+     * 写游记提到的用户id。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "写游记提到的用户id。可支持等于操作符的列表数据过滤。")
+    private Long userId;
+}

+ 43 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourTravelNotesTopicDto.java

@@ -0,0 +1,43 @@
+package com.tourism.webadmin.back.dto;
+
+import com.tourism.common.core.validator.UpdateGroup;
+import com.tourism.common.core.validator.ConstDictRef;
+import com.tourism.webadmin.back.model.constant.Enable;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.*;
+
+/**
+ * 游记话题Dto对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "游记话题Dto对象")
+@Data
+public class TourTravelNotesTopicDto {
+
+    /**
+     * 主键id。
+     */
+    @Schema(description = "主键id。", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "数据验证失败,主键id不能为空!", groups = {UpdateGroup.class})
+    private Long id;
+
+    /**
+     * 话题名称。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "话题名称。可支持等于操作符的列表数据过滤。")
+    private String name;
+
+    /**
+     * 是否启用,0否,1是。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "是否启用,0否,1是。可支持等于操作符的列表数据过滤。")
+    @ConstDictRef(constDictClass = Enable.class, message = "数据验证失败,是否启用,0否,1是为无效值!")
+    private Integer enable;
+}

+ 47 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourTravelNotesTopicRelationDto.java

@@ -0,0 +1,47 @@
+package com.tourism.webadmin.back.dto;
+
+import com.tourism.common.core.validator.UpdateGroup;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.*;
+
+/**
+ * 游记与话题关联Dto对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "游记与话题关联Dto对象")
+@Data
+public class TourTravelNotesTopicRelationDto {
+
+    /**
+     * 主键id。
+     */
+    @Schema(description = "主键id。", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "数据验证失败,主键id不能为空!", groups = {UpdateGroup.class})
+    private Long id;
+
+    /**
+     * 游记id。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "游记id。可支持等于操作符的列表数据过滤。")
+    private Long travelNotesId;
+
+    /**
+     * 话题id。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "话题id。可支持等于操作符的列表数据过滤。")
+    private Long topicId;
+
+    /**
+     * 话题名称。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "话题名称。可支持等于操作符的列表数据过滤。")
+    private String topicName;
+}

+ 6 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourismProjectTravelNotesWriteDto.java

@@ -229,4 +229,10 @@ public class TourismProjectTravelNotesWriteDto {
     @Schema(description = "游玩人数。")
     private String travelNumber;
 
+    /**
+     * 群聊id。
+     */
+    @Schema(description = "群聊id。")
+    private Long tourImGroupId;
+
 }

+ 33 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourTravelNotesImg.java

@@ -0,0 +1,33 @@
+package com.tourism.webadmin.back.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+
+/**
+ * 游记中的图片实体对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Data
+@TableName(value = "tour_travel_notes_img")
+public class TourTravelNotesImg {
+
+    /**
+     * id。
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 图片地址。
+     */
+    @TableField(value = "img_url")
+    private String imgUrl;
+
+    /**
+     * 游记id。
+     */
+    @TableField(value = "travel_notes_id")
+    private Long travelNotesId;
+}

+ 39 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourTravelNotesMentionUser.java

@@ -0,0 +1,39 @@
+package com.tourism.webadmin.back.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+
+/**
+ * 游记提及的用户实体对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Data
+@TableName(value = "tour_travel_notes_mention_user")
+public class TourTravelNotesMentionUser {
+
+    /**
+     * 主键id。
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 游记id。
+     */
+    @TableField(value = "travel_notes_id")
+    private Long travelNotesId;
+
+    /**
+     * 写游记提到的用户昵称。
+     */
+    @TableField(value = "user_name")
+    private String userName;
+
+    /**
+     * 写游记提到的用户id。
+     */
+    @TableField(value = "user_id")
+    private Long userId;
+}

+ 53 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourTravelNotesTopic.java

@@ -0,0 +1,53 @@
+package com.tourism.webadmin.back.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.tourism.webadmin.back.model.constant.Enable;
+import com.tourism.common.core.annotation.*;
+import com.tourism.common.core.base.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Map;
+
+/**
+ * 游记话题实体对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName(value = "tour_travel_notes_topic")
+public class TourTravelNotesTopic extends BaseModel {
+
+    /**
+     * 主键id。
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 话题名称。
+     */
+    @TableField(value = "name")
+    private String name;
+
+    /**
+     * 是否启用,0否,1是。
+     */
+    @TableField(value = "enable")
+    private Integer enable;
+
+    /**
+     * 逻辑删除标记字段(1: 正常 -1: 已删除)。
+     */
+    @TableLogic
+    @TableField(value = "data_state")
+    private Integer dataState;
+
+    @RelationConstDict(
+            masterIdField = "enable",
+            constantDictClass = Enable.class)
+    @TableField(exist = false)
+    private Map<String, Object> enableDictMap;
+}

+ 39 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourTravelNotesTopicRelation.java

@@ -0,0 +1,39 @@
+package com.tourism.webadmin.back.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+
+/**
+ * 游记与话题关联实体对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Data
+@TableName(value = "tour_travel_notes_topic_relation")
+public class TourTravelNotesTopicRelation {
+
+    /**
+     * 主键id。
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 游记id。
+     */
+    @TableField(value = "travel_notes_id")
+    private Long travelNotesId;
+
+    /**
+     * 话题id。
+     */
+    @TableField(value = "topic_id")
+    private Long topicId;
+
+    /**
+     * 话题名称。
+     */
+    @TableField(value = "topic_name")
+    private String topicName;
+}

+ 13 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourismProjectTravelNotesWrite.java

@@ -270,4 +270,17 @@ public class TourismProjectTravelNotesWrite extends BaseModel {
      */
     @TableField(value = "travel_number")
     private String travelNumber;
+
+    /**
+     * 群聊id。
+     */
+    @TableField(value = "tour_im_group_id")
+    private Long tourImGroupId;
+
+    @RelationOneToOne(
+            masterIdField = "tour_im_group",
+            slaveModelClass = TourImGroup.class,
+            slaveIdField = "id")
+    @TableField(exist = false)
+    private TourImGroup tourImGroup;
 }

+ 11 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourFansService.java

@@ -1,5 +1,7 @@
 package com.tourism.webadmin.back.service;
 
+import com.tourism.webadmin.app.website.model.TourShortUser;
+import com.tourism.webadmin.app.website.vo.TourShortUserVo;
 import com.tourism.webadmin.back.model.*;
 import com.tourism.common.core.object.CallResult;
 import com.tourism.common.core.base.service.IBaseService;
@@ -85,4 +87,13 @@ public interface TourFansService extends IBaseService<TourFans, Long> {
      * @return 验证结果。如果失败,包含具体的错误信息和导致错误的数据对象。
      */
     CallResult verifyImportList(List<TourFans> dataList, Set<String> ignoreFieldSet);
+
+    /**
+     * 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
+     * 如果需要同时获取关联数据,请移步(getTourFansListWithRelation)方法。
+     *
+     * @param name  模糊搜索的昵称。
+     * @return 查询结果集。
+     */
+    List<TourShortUser> getFouceEachFriendsByName(Long userId, String name);
 }

+ 10 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourImGroupService.java

@@ -1,6 +1,8 @@
 package com.tourism.webadmin.back.service;
 
 import com.alibaba.fastjson.JSONObject;
+import com.tourism.webadmin.app.website.model.TourShortImGroup;
+import com.tourism.webadmin.app.website.vo.TourShortImGroupVo;
 import com.tourism.webadmin.back.model.*;
 import com.tourism.common.core.object.CallResult;
 import com.tourism.common.core.base.service.IBaseService;
@@ -117,4 +119,12 @@ public interface TourImGroupService extends IBaseService<TourImGroup, Long> {
      * @return 验证结果。如果失败,包含具体的错误信息和导致错误的数据对象。
      */
     CallResult verifyImportList(List<TourImGroup> dataList, Set<String> ignoreFieldSet);
+
+    /**
+     * 获取自己参与的群聊列表
+     *
+     * @param userId  用户id。
+     * @return 查询结果集。
+     */
+    List<TourShortImGroup> getTakePartImGroupListByName(Long userId,String name);
 }

+ 68 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourTravelNotesImgService.java

@@ -0,0 +1,68 @@
+package com.tourism.webadmin.back.service;
+
+import com.tourism.webadmin.back.model.*;
+import com.tourism.common.core.base.service.IBaseService;
+
+import java.util.*;
+
+/**
+ * 游记中的图片数据操作服务接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public interface TourTravelNotesImgService extends IBaseService<TourTravelNotesImg, Long> {
+
+    /**
+     * 保存新增对象。
+     *
+     * @param tourTravelNotesImg 新增对象。
+     * @return 返回新增对象。
+     */
+    TourTravelNotesImg saveNew(TourTravelNotesImg tourTravelNotesImg);
+
+    /**
+     * 利用数据库的insertList语法,批量插入对象列表。
+     *
+     * @param tourTravelNotesImgList 新增对象列表。
+     */
+    void saveNewBatch(List<TourTravelNotesImg> tourTravelNotesImgList);
+
+    /**
+     * 更新数据对象。
+     *
+     * @param tourTravelNotesImg         更新的对象。
+     * @param originalTourTravelNotesImg 原有数据对象。
+     * @return 成功返回true,否则false。
+     */
+    boolean update(TourTravelNotesImg tourTravelNotesImg, TourTravelNotesImg originalTourTravelNotesImg);
+
+    /**
+     * 删除指定数据。
+     *
+     * @param id 主键Id。
+     * @return 成功返回true,否则false。
+     */
+    boolean remove(Long id);
+
+    /**
+     * 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
+     * 如果需要同时获取关联数据,请移步(getTourTravelNotesImgListWithRelation)方法。
+     *
+     * @param filter  过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<TourTravelNotesImg> getTourTravelNotesImgList(TourTravelNotesImg filter, String orderBy);
+
+    /**
+     * 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
+     * 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
+     * 如果仅仅需要获取主表数据,请移步(getTourTravelNotesImgList),以便获取更好的查询性能。
+     *
+     * @param filter 主表过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<TourTravelNotesImg> getTourTravelNotesImgListWithRelation(TourTravelNotesImg filter, String orderBy);
+}

+ 68 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourTravelNotesMentionUserService.java

@@ -0,0 +1,68 @@
+package com.tourism.webadmin.back.service;
+
+import com.tourism.webadmin.back.model.*;
+import com.tourism.common.core.base.service.IBaseService;
+
+import java.util.*;
+
+/**
+ * 游记提及的用户数据操作服务接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public interface TourTravelNotesMentionUserService extends IBaseService<TourTravelNotesMentionUser, Long> {
+
+    /**
+     * 保存新增对象。
+     *
+     * @param tourTravelNotesMentionUser 新增对象。
+     * @return 返回新增对象。
+     */
+    TourTravelNotesMentionUser saveNew(TourTravelNotesMentionUser tourTravelNotesMentionUser);
+
+    /**
+     * 利用数据库的insertList语法,批量插入对象列表。
+     *
+     * @param tourTravelNotesMentionUserList 新增对象列表。
+     */
+    void saveNewBatch(List<TourTravelNotesMentionUser> tourTravelNotesMentionUserList);
+
+    /**
+     * 更新数据对象。
+     *
+     * @param tourTravelNotesMentionUser         更新的对象。
+     * @param originalTourTravelNotesMentionUser 原有数据对象。
+     * @return 成功返回true,否则false。
+     */
+    boolean update(TourTravelNotesMentionUser tourTravelNotesMentionUser, TourTravelNotesMentionUser originalTourTravelNotesMentionUser);
+
+    /**
+     * 删除指定数据。
+     *
+     * @param id 主键Id。
+     * @return 成功返回true,否则false。
+     */
+    boolean remove(Long id);
+
+    /**
+     * 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
+     * 如果需要同时获取关联数据,请移步(getTourTravelNotesMentionUserListWithRelation)方法。
+     *
+     * @param filter  过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<TourTravelNotesMentionUser> getTourTravelNotesMentionUserList(TourTravelNotesMentionUser filter, String orderBy);
+
+    /**
+     * 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
+     * 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
+     * 如果仅仅需要获取主表数据,请移步(getTourTravelNotesMentionUserList),以便获取更好的查询性能。
+     *
+     * @param filter 主表过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<TourTravelNotesMentionUser> getTourTravelNotesMentionUserListWithRelation(TourTravelNotesMentionUser filter, String orderBy);
+}

+ 68 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourTravelNotesTopicRelationService.java

@@ -0,0 +1,68 @@
+package com.tourism.webadmin.back.service;
+
+import com.tourism.webadmin.back.model.*;
+import com.tourism.common.core.base.service.IBaseService;
+
+import java.util.*;
+
+/**
+ * 游记与话题关联数据操作服务接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public interface TourTravelNotesTopicRelationService extends IBaseService<TourTravelNotesTopicRelation, Long> {
+
+    /**
+     * 保存新增对象。
+     *
+     * @param tourTravelNotesTopicRelation 新增对象。
+     * @return 返回新增对象。
+     */
+    TourTravelNotesTopicRelation saveNew(TourTravelNotesTopicRelation tourTravelNotesTopicRelation);
+
+    /**
+     * 利用数据库的insertList语法,批量插入对象列表。
+     *
+     * @param tourTravelNotesTopicRelationList 新增对象列表。
+     */
+    void saveNewBatch(List<TourTravelNotesTopicRelation> tourTravelNotesTopicRelationList);
+
+    /**
+     * 更新数据对象。
+     *
+     * @param tourTravelNotesTopicRelation         更新的对象。
+     * @param originalTourTravelNotesTopicRelation 原有数据对象。
+     * @return 成功返回true,否则false。
+     */
+    boolean update(TourTravelNotesTopicRelation tourTravelNotesTopicRelation, TourTravelNotesTopicRelation originalTourTravelNotesTopicRelation);
+
+    /**
+     * 删除指定数据。
+     *
+     * @param id 主键Id。
+     * @return 成功返回true,否则false。
+     */
+    boolean remove(Long id);
+
+    /**
+     * 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
+     * 如果需要同时获取关联数据,请移步(getTourTravelNotesTopicRelationListWithRelation)方法。
+     *
+     * @param filter  过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<TourTravelNotesTopicRelation> getTourTravelNotesTopicRelationList(TourTravelNotesTopicRelation filter, String orderBy);
+
+    /**
+     * 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
+     * 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
+     * 如果仅仅需要获取主表数据,请移步(getTourTravelNotesTopicRelationList),以便获取更好的查询性能。
+     *
+     * @param filter 主表过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<TourTravelNotesTopicRelation> getTourTravelNotesTopicRelationListWithRelation(TourTravelNotesTopicRelation filter, String orderBy);
+}

+ 76 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourTravelNotesTopicService.java

@@ -0,0 +1,76 @@
+package com.tourism.webadmin.back.service;
+
+import com.tourism.webadmin.app.website.model.TourShortTopic;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.common.core.base.service.IBaseService;
+
+import java.util.*;
+
+/**
+ * 游记话题数据操作服务接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public interface TourTravelNotesTopicService extends IBaseService<TourTravelNotesTopic, Long> {
+
+    /**
+     * 保存新增对象。
+     *
+     * @param tourTravelNotesTopic 新增对象。
+     * @return 返回新增对象。
+     */
+    TourTravelNotesTopic saveNew(TourTravelNotesTopic tourTravelNotesTopic);
+
+    /**
+     * 利用数据库的insertList语法,批量插入对象列表。
+     *
+     * @param tourTravelNotesTopicList 新增对象列表。
+     */
+    void saveNewBatch(List<TourTravelNotesTopic> tourTravelNotesTopicList);
+
+    /**
+     * 更新数据对象。
+     *
+     * @param tourTravelNotesTopic         更新的对象。
+     * @param originalTourTravelNotesTopic 原有数据对象。
+     * @return 成功返回true,否则false。
+     */
+    boolean update(TourTravelNotesTopic tourTravelNotesTopic, TourTravelNotesTopic originalTourTravelNotesTopic);
+
+    /**
+     * 删除指定数据。
+     *
+     * @param id 主键Id。
+     * @return 成功返回true,否则false。
+     */
+    boolean remove(Long id);
+
+    /**
+     * 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
+     * 如果需要同时获取关联数据,请移步(getTourTravelNotesTopicListWithRelation)方法。
+     *
+     * @param filter  过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<TourTravelNotesTopic> getTourTravelNotesTopicList(TourTravelNotesTopic filter, String orderBy);
+
+    /**
+     * 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
+     * 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
+     * 如果仅仅需要获取主表数据,请移步(getTourTravelNotesTopicList),以便获取更好的查询性能。
+     *
+     * @param filter 主表过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<TourTravelNotesTopic> getTourTravelNotesTopicListWithRelation(TourTravelNotesTopic filter, String orderBy);
+
+    /**
+     *
+     * @param name 话题名称。
+     * @return 查询结果集。
+     */
+    List<TourShortTopic> getTourTravelNotesTopicListByName(String name);
+}

+ 7 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourFansServiceImpl.java

@@ -3,6 +3,8 @@ package com.tourism.webadmin.back.service.impl;
 import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.tourism.common.core.object.TokenData;
+import com.tourism.webadmin.app.website.model.TourShortUser;
+import com.tourism.webadmin.app.website.vo.TourShortUserVo;
 import com.tourism.webadmin.back.service.*;
 import com.tourism.webadmin.back.dao.*;
 import com.tourism.webadmin.back.model.*;
@@ -169,4 +171,9 @@ public class TourFansServiceImpl extends BaseService<TourFans, Long> implements
         tourFans.setDeleteFlag(GlobalDeletedFlag.NORMAL);
         return tourFans;
     }
+
+    @Override
+    public List<TourShortUser> getFouceEachFriendsByName(Long userId, String name) {
+        return tourFansMapper.getFouceEachFriendsByName(userId,name);
+    }
 }

+ 7 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourImGroupServiceImpl.java

@@ -4,6 +4,8 @@ import cn.hutool.core.collection.CollUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.TypeReference;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.tourism.webadmin.app.website.model.TourShortImGroup;
+import com.tourism.webadmin.app.website.vo.TourShortImGroupVo;
 import com.tourism.webadmin.back.model.constant.IsTrue;
 import com.tourism.webadmin.back.service.*;
 import com.tourism.webadmin.back.dao.*;
@@ -265,4 +267,9 @@ public class TourImGroupServiceImpl extends BaseService<TourImGroup, Long> imple
         MyModelUtil.setDefaultValue(tourImGroup, "bannedStatus", IsTrue.FALSE);
         return tourImGroup;
     }
+
+    @Override
+    public List<TourShortImGroup> getTakePartImGroupListByName(Long userId,String name) {
+        return tourImGroupMapper.getTakePartImGroupListByName(userId,name);
+    }
 }

+ 98 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourTravelNotesImgServiceImpl.java

@@ -0,0 +1,98 @@
+package com.tourism.webadmin.back.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.tourism.webadmin.back.service.*;
+import com.tourism.webadmin.back.dao.*;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.config.DataSourceType;
+import com.tourism.common.core.annotation.MyDataSource;
+import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.common.core.object.MyRelationParam;
+import com.tourism.common.core.base.service.BaseService;
+import com.tourism.common.sequence.wrapper.IdGeneratorWrapper;
+import com.github.pagehelper.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * 游记中的图片数据操作服务类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Slf4j
+@Service("tourTravelNotesImgService")
+public class TourTravelNotesImgServiceImpl extends BaseService<TourTravelNotesImg, Long> implements TourTravelNotesImgService {
+
+    @Autowired
+    private IdGeneratorWrapper idGenerator;
+    @Autowired
+    private TourTravelNotesImgMapper tourTravelNotesImgMapper;
+
+    /**
+     * 返回当前Service的主表Mapper对象。
+     *
+     * @return 主表Mapper对象。
+     */
+    @Override
+    protected BaseDaoMapper<TourTravelNotesImg> mapper() {
+        return tourTravelNotesImgMapper;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public TourTravelNotesImg saveNew(TourTravelNotesImg tourTravelNotesImg) {
+        tourTravelNotesImgMapper.insert(this.buildDefaultValue(tourTravelNotesImg));
+        return tourTravelNotesImg;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void saveNewBatch(List<TourTravelNotesImg> tourTravelNotesImgList) {
+        if (CollUtil.isNotEmpty(tourTravelNotesImgList)) {
+            tourTravelNotesImgList.forEach(this::buildDefaultValue);
+            tourTravelNotesImgMapper.insertList(tourTravelNotesImgList);
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean update(TourTravelNotesImg tourTravelNotesImg, TourTravelNotesImg originalTourTravelNotesImg) {
+        // 这里重点提示,在执行主表数据更新之前,如果有哪些字段不支持修改操作,请用原有数据对象字段替换当前数据字段。
+        UpdateWrapper<TourTravelNotesImg> uw = this.createUpdateQueryForNullValue(tourTravelNotesImg, tourTravelNotesImg.getId());
+        return tourTravelNotesImgMapper.update(tourTravelNotesImg, uw) == 1;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean remove(Long id) {
+        return tourTravelNotesImgMapper.deleteById(id) == 1;
+    }
+
+    @Override
+    public List<TourTravelNotesImg> getTourTravelNotesImgList(TourTravelNotesImg filter, String orderBy) {
+        return tourTravelNotesImgMapper.getTourTravelNotesImgList(filter, orderBy);
+    }
+
+    @Override
+    public List<TourTravelNotesImg> getTourTravelNotesImgListWithRelation(TourTravelNotesImg filter, String orderBy) {
+        List<TourTravelNotesImg> resultList = tourTravelNotesImgMapper.getTourTravelNotesImgList(filter, orderBy);
+        // 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
+        // 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
+        int batchSize = resultList instanceof Page ? 0 : 1000;
+        this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
+        return resultList;
+    }
+
+    private TourTravelNotesImg buildDefaultValue(TourTravelNotesImg tourTravelNotesImg) {
+        if (tourTravelNotesImg.getId() == null) {
+            tourTravelNotesImg.setId(idGenerator.nextLongId());
+        }
+        return tourTravelNotesImg;
+    }
+}

+ 98 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourTravelNotesMentionUserServiceImpl.java

@@ -0,0 +1,98 @@
+package com.tourism.webadmin.back.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.tourism.webadmin.back.service.*;
+import com.tourism.webadmin.back.dao.*;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.config.DataSourceType;
+import com.tourism.common.core.annotation.MyDataSource;
+import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.common.core.object.MyRelationParam;
+import com.tourism.common.core.base.service.BaseService;
+import com.tourism.common.sequence.wrapper.IdGeneratorWrapper;
+import com.github.pagehelper.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * 游记提及的用户数据操作服务类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Slf4j
+@Service("tourTravelNotesMentionUserService")
+public class TourTravelNotesMentionUserServiceImpl extends BaseService<TourTravelNotesMentionUser, Long> implements TourTravelNotesMentionUserService {
+
+    @Autowired
+    private IdGeneratorWrapper idGenerator;
+    @Autowired
+    private TourTravelNotesMentionUserMapper tourTravelNotesMentionUserMapper;
+
+    /**
+     * 返回当前Service的主表Mapper对象。
+     *
+     * @return 主表Mapper对象。
+     */
+    @Override
+    protected BaseDaoMapper<TourTravelNotesMentionUser> mapper() {
+        return tourTravelNotesMentionUserMapper;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public TourTravelNotesMentionUser saveNew(TourTravelNotesMentionUser tourTravelNotesMentionUser) {
+        tourTravelNotesMentionUserMapper.insert(this.buildDefaultValue(tourTravelNotesMentionUser));
+        return tourTravelNotesMentionUser;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void saveNewBatch(List<TourTravelNotesMentionUser> tourTravelNotesMentionUserList) {
+        if (CollUtil.isNotEmpty(tourTravelNotesMentionUserList)) {
+            tourTravelNotesMentionUserList.forEach(this::buildDefaultValue);
+            tourTravelNotesMentionUserMapper.insertList(tourTravelNotesMentionUserList);
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean update(TourTravelNotesMentionUser tourTravelNotesMentionUser, TourTravelNotesMentionUser originalTourTravelNotesMentionUser) {
+        // 这里重点提示,在执行主表数据更新之前,如果有哪些字段不支持修改操作,请用原有数据对象字段替换当前数据字段。
+        UpdateWrapper<TourTravelNotesMentionUser> uw = this.createUpdateQueryForNullValue(tourTravelNotesMentionUser, tourTravelNotesMentionUser.getId());
+        return tourTravelNotesMentionUserMapper.update(tourTravelNotesMentionUser, uw) == 1;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean remove(Long id) {
+        return tourTravelNotesMentionUserMapper.deleteById(id) == 1;
+    }
+
+    @Override
+    public List<TourTravelNotesMentionUser> getTourTravelNotesMentionUserList(TourTravelNotesMentionUser filter, String orderBy) {
+        return tourTravelNotesMentionUserMapper.getTourTravelNotesMentionUserList(filter, orderBy);
+    }
+
+    @Override
+    public List<TourTravelNotesMentionUser> getTourTravelNotesMentionUserListWithRelation(TourTravelNotesMentionUser filter, String orderBy) {
+        List<TourTravelNotesMentionUser> resultList = tourTravelNotesMentionUserMapper.getTourTravelNotesMentionUserList(filter, orderBy);
+        // 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
+        // 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
+        int batchSize = resultList instanceof Page ? 0 : 1000;
+        this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
+        return resultList;
+    }
+
+    private TourTravelNotesMentionUser buildDefaultValue(TourTravelNotesMentionUser tourTravelNotesMentionUser) {
+        if (tourTravelNotesMentionUser.getId() == null) {
+            tourTravelNotesMentionUser.setId(idGenerator.nextLongId());
+        }
+        return tourTravelNotesMentionUser;
+    }
+}

+ 98 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourTravelNotesTopicRelationServiceImpl.java

@@ -0,0 +1,98 @@
+package com.tourism.webadmin.back.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.tourism.webadmin.back.service.*;
+import com.tourism.webadmin.back.dao.*;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.config.DataSourceType;
+import com.tourism.common.core.annotation.MyDataSource;
+import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.common.core.object.MyRelationParam;
+import com.tourism.common.core.base.service.BaseService;
+import com.tourism.common.sequence.wrapper.IdGeneratorWrapper;
+import com.github.pagehelper.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * 游记与话题关联数据操作服务类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Slf4j
+@Service("tourTravelNotesTopicRelationService")
+public class TourTravelNotesTopicRelationServiceImpl extends BaseService<TourTravelNotesTopicRelation, Long> implements TourTravelNotesTopicRelationService {
+
+    @Autowired
+    private IdGeneratorWrapper idGenerator;
+    @Autowired
+    private TourTravelNotesTopicRelationMapper tourTravelNotesTopicRelationMapper;
+
+    /**
+     * 返回当前Service的主表Mapper对象。
+     *
+     * @return 主表Mapper对象。
+     */
+    @Override
+    protected BaseDaoMapper<TourTravelNotesTopicRelation> mapper() {
+        return tourTravelNotesTopicRelationMapper;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public TourTravelNotesTopicRelation saveNew(TourTravelNotesTopicRelation tourTravelNotesTopicRelation) {
+        tourTravelNotesTopicRelationMapper.insert(this.buildDefaultValue(tourTravelNotesTopicRelation));
+        return tourTravelNotesTopicRelation;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void saveNewBatch(List<TourTravelNotesTopicRelation> tourTravelNotesTopicRelationList) {
+        if (CollUtil.isNotEmpty(tourTravelNotesTopicRelationList)) {
+            tourTravelNotesTopicRelationList.forEach(this::buildDefaultValue);
+            tourTravelNotesTopicRelationMapper.insertList(tourTravelNotesTopicRelationList);
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean update(TourTravelNotesTopicRelation tourTravelNotesTopicRelation, TourTravelNotesTopicRelation originalTourTravelNotesTopicRelation) {
+        // 这里重点提示,在执行主表数据更新之前,如果有哪些字段不支持修改操作,请用原有数据对象字段替换当前数据字段。
+        UpdateWrapper<TourTravelNotesTopicRelation> uw = this.createUpdateQueryForNullValue(tourTravelNotesTopicRelation, tourTravelNotesTopicRelation.getId());
+        return tourTravelNotesTopicRelationMapper.update(tourTravelNotesTopicRelation, uw) == 1;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean remove(Long id) {
+        return tourTravelNotesTopicRelationMapper.deleteById(id) == 1;
+    }
+
+    @Override
+    public List<TourTravelNotesTopicRelation> getTourTravelNotesTopicRelationList(TourTravelNotesTopicRelation filter, String orderBy) {
+        return tourTravelNotesTopicRelationMapper.getTourTravelNotesTopicRelationList(filter, orderBy);
+    }
+
+    @Override
+    public List<TourTravelNotesTopicRelation> getTourTravelNotesTopicRelationListWithRelation(TourTravelNotesTopicRelation filter, String orderBy) {
+        List<TourTravelNotesTopicRelation> resultList = tourTravelNotesTopicRelationMapper.getTourTravelNotesTopicRelationList(filter, orderBy);
+        // 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
+        // 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
+        int batchSize = resultList instanceof Page ? 0 : 1000;
+        this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
+        return resultList;
+    }
+
+    private TourTravelNotesTopicRelation buildDefaultValue(TourTravelNotesTopicRelation tourTravelNotesTopicRelation) {
+        if (tourTravelNotesTopicRelation.getId() == null) {
+            tourTravelNotesTopicRelation.setId(idGenerator.nextLongId());
+        }
+        return tourTravelNotesTopicRelation;
+    }
+}

+ 109 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourTravelNotesTopicServiceImpl.java

@@ -0,0 +1,109 @@
+package com.tourism.webadmin.back.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.tourism.webadmin.app.website.model.TourShortTopic;
+import com.tourism.webadmin.back.service.*;
+import com.tourism.webadmin.back.dao.*;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.config.DataSourceType;
+import com.tourism.common.core.annotation.MyDataSource;
+import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.common.core.constant.GlobalDeletedFlag;
+import com.tourism.common.core.object.MyRelationParam;
+import com.tourism.common.core.base.service.BaseService;
+import com.tourism.common.core.util.MyModelUtil;
+import com.tourism.common.sequence.wrapper.IdGeneratorWrapper;
+import com.github.pagehelper.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * 游记话题数据操作服务类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Slf4j
+@Service("tourTravelNotesTopicService")
+public class TourTravelNotesTopicServiceImpl extends BaseService<TourTravelNotesTopic, Long> implements TourTravelNotesTopicService {
+
+    @Autowired
+    private IdGeneratorWrapper idGenerator;
+    @Autowired
+    private TourTravelNotesTopicMapper tourTravelNotesTopicMapper;
+
+    /**
+     * 返回当前Service的主表Mapper对象。
+     *
+     * @return 主表Mapper对象。
+     */
+    @Override
+    protected BaseDaoMapper<TourTravelNotesTopic> mapper() {
+        return tourTravelNotesTopicMapper;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public TourTravelNotesTopic saveNew(TourTravelNotesTopic tourTravelNotesTopic) {
+        tourTravelNotesTopicMapper.insert(this.buildDefaultValue(tourTravelNotesTopic));
+        return tourTravelNotesTopic;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void saveNewBatch(List<TourTravelNotesTopic> tourTravelNotesTopicList) {
+        if (CollUtil.isNotEmpty(tourTravelNotesTopicList)) {
+            tourTravelNotesTopicList.forEach(this::buildDefaultValue);
+            tourTravelNotesTopicMapper.insertList(tourTravelNotesTopicList);
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean update(TourTravelNotesTopic tourTravelNotesTopic, TourTravelNotesTopic originalTourTravelNotesTopic) {
+        MyModelUtil.fillCommonsForUpdate(tourTravelNotesTopic, originalTourTravelNotesTopic);
+        // 这里重点提示,在执行主表数据更新之前,如果有哪些字段不支持修改操作,请用原有数据对象字段替换当前数据字段。
+        UpdateWrapper<TourTravelNotesTopic> uw = this.createUpdateQueryForNullValue(tourTravelNotesTopic, tourTravelNotesTopic.getId());
+        return tourTravelNotesTopicMapper.update(tourTravelNotesTopic, uw) == 1;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean remove(Long id) {
+        return tourTravelNotesTopicMapper.deleteById(id) == 1;
+    }
+
+    @Override
+    public List<TourTravelNotesTopic> getTourTravelNotesTopicList(TourTravelNotesTopic filter, String orderBy) {
+        return tourTravelNotesTopicMapper.getTourTravelNotesTopicList(filter, orderBy);
+    }
+
+    @Override
+    public List<TourTravelNotesTopic> getTourTravelNotesTopicListWithRelation(TourTravelNotesTopic filter, String orderBy) {
+        List<TourTravelNotesTopic> resultList = tourTravelNotesTopicMapper.getTourTravelNotesTopicList(filter, orderBy);
+        // 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
+        // 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
+        int batchSize = resultList instanceof Page ? 0 : 1000;
+        this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
+        return resultList;
+    }
+
+    private TourTravelNotesTopic buildDefaultValue(TourTravelNotesTopic tourTravelNotesTopic) {
+        if (tourTravelNotesTopic.getId() == null) {
+            tourTravelNotesTopic.setId(idGenerator.nextLongId());
+        }
+        MyModelUtil.fillCommonsForInsert(tourTravelNotesTopic);
+        tourTravelNotesTopic.setDataState(GlobalDeletedFlag.NORMAL);
+        return tourTravelNotesTopic;
+    }
+
+    @Override
+    public List<TourShortTopic> getTourTravelNotesTopicListByName(String name) {
+        return tourTravelNotesTopicMapper.getTourTravelNotesTopicListByName(name);
+    }
+}

+ 33 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourTravelNotesImgVo.java

@@ -0,0 +1,33 @@
+package com.tourism.webadmin.back.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 游记中的图片VO视图对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "游记中的图片VO视图对象")
+@Data
+public class TourTravelNotesImgVo {
+
+    /**
+     * id。
+     */
+    @Schema(description = "id")
+    private Long id;
+
+    /**
+     * 图片地址。
+     */
+    @Schema(description = "图片地址")
+    private String imgUrl;
+
+    /**
+     * 游记id。
+     */
+    @Schema(description = "游记id")
+    private Long travelNotesId;
+}

+ 39 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourTravelNotesMentionUserVo.java

@@ -0,0 +1,39 @@
+package com.tourism.webadmin.back.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 游记提及的用户VO视图对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "游记提及的用户VO视图对象")
+@Data
+public class TourTravelNotesMentionUserVo {
+
+    /**
+     * 主键id。
+     */
+    @Schema(description = "主键id")
+    private Long id;
+
+    /**
+     * 游记id。
+     */
+    @Schema(description = "游记id")
+    private Long travelNotesId;
+
+    /**
+     * 写游记提到的用户昵称。
+     */
+    @Schema(description = "写游记提到的用户昵称")
+    private String userName;
+
+    /**
+     * 写游记提到的用户id。
+     */
+    @Schema(description = "写游记提到的用户id")
+    private Long userId;
+}

+ 39 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourTravelNotesTopicRelationVo.java

@@ -0,0 +1,39 @@
+package com.tourism.webadmin.back.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 游记与话题关联VO视图对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "游记与话题关联VO视图对象")
+@Data
+public class TourTravelNotesTopicRelationVo {
+
+    /**
+     * 主键id。
+     */
+    @Schema(description = "主键id")
+    private Long id;
+
+    /**
+     * 游记id。
+     */
+    @Schema(description = "游记id")
+    private Long travelNotesId;
+
+    /**
+     * 话题id。
+     */
+    @Schema(description = "话题id")
+    private Long topicId;
+
+    /**
+     * 话题名称。
+     */
+    @Schema(description = "话题名称")
+    private String topicName;
+}

+ 43 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourTravelNotesTopicVo.java

@@ -0,0 +1,43 @@
+package com.tourism.webadmin.back.vo;
+
+import com.tourism.common.core.base.vo.BaseVo;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.util.Map;
+
+/**
+ * 游记话题VO视图对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "游记话题VO视图对象")
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TourTravelNotesTopicVo extends BaseVo {
+
+    /**
+     * 主键id。
+     */
+    @Schema(description = "主键id")
+    private Long id;
+
+    /**
+     * 话题名称。
+     */
+    @Schema(description = "话题名称")
+    private String name;
+
+    /**
+     * 是否启用,0否,1是。
+     */
+    @Schema(description = "是否启用,0否,1是")
+    private Integer enable;
+
+    /**
+     * enable 常量字典关联数据。
+     */
+    @Schema(description = "enable 常量字典关联数据")
+    private Map<String, Object> enableDictMap;
+}

+ 19 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourismProjectTravelNotesWriteVo.java

@@ -1,6 +1,7 @@
 package com.tourism.webadmin.back.vo;
 
 import com.tourism.common.core.base.vo.BaseVo;
+import com.tourism.webadmin.back.model.TourImGroup;
 import com.tourism.webadmin.back.model.TourismTravelNotesContentWrite;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -225,4 +226,22 @@ public class TourismProjectTravelNotesWriteVo extends BaseVo {
      */
     @Schema(description = "游玩人数")
     private String travelNumber;
+
+    /**
+     * 群聊id。
+     */
+    @Schema(description = "群聊id")
+    private String tourImGroupId;
+
+    /**
+     * 群聊。
+     */
+    @Schema(description = "群聊")
+    private TourImGroup tourImGroup;
+
+    /**
+     * 目的地区。
+     */
+    @Schema(description = "目的地区")
+    private String endArea;
 }

+ 3 - 1
common/common-core/src/main/java/com/tourism/common/core/constant/ErrorCodeEnum.java

@@ -102,7 +102,9 @@ public enum ErrorCodeEnum {
     NON_UNCONFIRMED_ORDERS_CANNOT_BE_CANCELLED("此订单当前状态不允许取消!"),
     GROUP_BUYING_HAS_EXPIRED_CANNOT_BE_CANCELLED("超过拼团截止日期的团购订单不允许取消!"),
     ALREADY_FORMED_A_GROUP_CANNOT_BE_CANCELLED("已成团团购订单不允许取消!"),
-    GROUP_BUYING_ERROR("拼团失败!")
+    GROUP_BUYING_ERROR("拼团失败!"),
+    MENTION_USER_ERROR("提及的用户与本人不符合互关的状态!"),
+    MENTION_GROUP_ERROR("本人未参与到关联的群聊中!")
     ;
     // 下面的枚举值为特定枚举值,即开发者可以根据自己的项目需求定义更多的非通用枚举值