Browse Source

Merge remote-tracking branch 'origin/v0.3' into dev

# Conflicts:
#	application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/LoginToWebsiteController.java
limeng 4 months ago
parent
commit
5c5e74cf74
57 changed files with 2472 additions and 589 deletions
  1. 16 6
      application-webadmin/pom.xml
  2. 103 35
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/CleanDataController.java
  3. 5 10
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/JobProjectToWebController.java
  4. 19 12
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/LoginToWebsiteController.java
  5. 1 1
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/TourismProjectToWebController.java
  6. 465 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/WebSiteTourismTravelNotesPublishController.java
  7. 96 34
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/WebsiteTourismProjectTravelNotesController.java
  8. 25 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/TourismCollectDto.java
  9. 38 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/TourismProjectTravelNotesWriteDetailPageDto.java
  10. 83 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/TourismTravelNotesWriteDto.java
  11. 42 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/WebsiteTourUserDto.java
  12. 5 3
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/BasicToWebService.java
  13. 119 99
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/impl/BasicToWebServiceImpl.java
  14. 3 6
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/impl/TourismProjectToWebServiceImpl.java
  15. 23 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/TourWriteBelongTabVo.java
  16. 209 0
      application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/TourismProjectTravelNotesWriteCovertVo.java
  17. 51 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourismProjectTravelNotesWriteController.java
  18. 11 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourUserLikeTravelNotesMapper.java
  19. 2 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourismProjectTravelNotesWriteMapper.java
  20. 3 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourTourismProjectTravelNotesMapper.xml
  21. 46 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourUserLikeTravelNotesMapper.xml
  22. 8 2
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourUserMapper.xml
  23. 94 6
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourismProjectTravelNotesWriteMapper.xml
  24. 18 13
      application-webadmin/src/main/java/com/tourism/webadmin/back/dao/mapper/TourismTravelNotesContentWriteMapper.xml
  25. 10 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourUserDto.java
  26. 89 11
      application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourismProjectTravelNotesWriteDto.java
  27. 18 6
      application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourismTravelNotesContentWriteDto.java
  28. 13 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourUser.java
  29. 8 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourUserLikeTravelNotes.java
  30. 117 21
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourismProjectTravelNotesWrite.java
  31. 18 6
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourismTravelNotesContentWrite.java
  32. 44 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/constant/AudioState.java
  33. 11 6
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/constant/AuditState.java
  34. 44 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/constant/IsOriginal.java
  35. 44 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/model/constant/UnmountState.java
  36. 11 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourUserLikeTravelNotesService.java
  37. 24 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourismProjectTravelNotesWriteService.java
  38. 10 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourUserLikeTravelNotesServiceImpl.java
  39. 80 4
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourismProjectTravelNotesWriteServiceImpl.java
  40. 2 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourismTravelNotesContentWriteServiceImpl.java
  41. 16 10
      application-webadmin/src/main/java/com/tourism/webadmin/back/util/SMSUtils.java
  42. 8 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourUserLikeTravelNotesVo.java
  43. 12 0
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourUserVo.java
  44. 117 18
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourismProjectTravelNotesWriteVo.java
  45. 18 6
      application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourismTravelNotesContentWriteVo.java
  46. 38 0
      application-webadmin/src/main/java/com/tourism/webadmin/config/SmsSwitch.java
  47. 0 233
      application-webadmin/src/main/resources/application-dev.yml
  48. 23 18
      application-webadmin/src/main/resources/application-prod.yml
  49. 41 18
      application-webadmin/src/main/resources/application-test.yml
  50. 1 1
      application-webadmin/src/main/resources/application.yml
  51. 6 3
      common/common-additional/src/main/java/com/tourism/common/additional/utils/UrlConvertUtils.java
  52. 3 1
      common/common-core/src/main/java/com/tourism/common/core/constant/ErrorCodeEnum.java
  53. 26 0
      common/common-huaweicloud/common-huaweicloud-moderation/pom.xml
  54. 16 0
      common/common-huaweicloud/common-huaweicloud-moderation/src/main/java/com/tourism/common/huaweicloud/moderation/config/HuaweiCloudConfig.java
  55. 105 0
      common/common-huaweicloud/common-huaweicloud-moderation/src/main/java/com/tourism/common/huaweicloud/moderation/service/HuaweiCloudModerationService.java
  56. 1 0
      common/common-huaweicloud/pom.xml
  57. 13 0
      common/common-satoken/src/main/java/com/tourism/common/satoken/util/SaTokenUtil.java

+ 16 - 6
application-webadmin/pom.xml

@@ -62,6 +62,11 @@
         </dependency>
         <dependency>
             <groupId>com.tourism</groupId>
+            <artifactId>common-huaweicloud-moderation</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.tourism</groupId>
             <artifactId>common-sequence</artifactId>
             <version>1.0.0</version>
         </dependency>
@@ -85,18 +90,17 @@
             <artifactId>common-additional</artifactId>
             <version>1.0.0</version>
         </dependency>
-
         <dependency>
             <groupId>javax.annotation</groupId>
             <artifactId>javax.annotation-api</artifactId>
             <version>1.3</version>
         </dependency>
 
-        <dependency>
-            <groupId>org.dromara.sms4j</groupId>
-            <artifactId>sms4j-spring-boot-starter</artifactId>
-            <version>3.3.3</version>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.dromara.sms4j</groupId>-->
+<!--            <artifactId>sms4j-spring-boot-starter</artifactId>-->
+<!--            <version>3.3.3</version>-->
+<!--        </dependency>-->
 
         <dependency>
             <groupId>com.github.binarywang</groupId>
@@ -122,6 +126,12 @@
             <version>1.15</version> <!-- 请根据实际情况调整版本号 -->
         </dependency>
 
+        <dependency>
+            <groupId>org.jsoup</groupId>
+            <artifactId>jsoup</artifactId>
+            <version>1.14.3</version>
+        </dependency>
+
         <!--        <dependency>-->
 <!--            <groupId>com.anji-plus</groupId>-->
 <!--            <artifactId>spring-boot-starter-captcha</artifactId>-->

+ 103 - 35
application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/CleanDataController.java

@@ -1,37 +1,35 @@
-//package com.tourism.webadmin.app.website.controller;
-//
-//import cn.dev33.satoken.annotation.SaIgnore;
-//import com.tourism.common.core.util.MyDateUtil;
-//import com.tourism.webadmin.back.model.TourismDatePrice;
-//import com.tourism.webadmin.back.model.TourismProject;
-//import com.tourism.webadmin.back.service.TourismDatePriceService;
-//import com.tourism.webadmin.back.service.TourismProjectService;
-//import io.swagger.v3.oas.annotations.tags.Tag;
-//import lombok.extern.slf4j.Slf4j;
-//import org.apache.commons.lang3.time.DateUtils;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.web.bind.annotation.GetMapping;
-//import org.springframework.web.bind.annotation.PostMapping;
-//import org.springframework.web.bind.annotation.RequestMapping;
-//import org.springframework.web.bind.annotation.RestController;
-//import com.tourism.webadmin.app.website.service.CleanDataService;
-//
-//import java.util.ArrayList;
-//import java.util.Date;
-//import java.util.List;
-//
-///**
-// * 数据清洗接口。
-// *
-// * @author 吃饭睡觉
-// * @date 2024-09-06
-// */
-//@Tag(name = "数据清洗接口")
-//@Slf4j
-//@RestController
-//@RequestMapping("/cleanData")
-//public class CleanDataController {
-//
+package com.tourism.webadmin.app.website.controller;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import com.tourism.common.core.util.MyDateUtil;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.back.service.*;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.tourism.webadmin.app.website.service.CleanDataService;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 数据清洗接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Tag(name = "数据清洗接口")
+@Slf4j
+@RestController
+@RequestMapping("/cleanData")
+public class CleanDataController {
+
 //    @Autowired
 //    private CleanDataService cleanDataService;
 //    @Autowired
@@ -76,4 +74,74 @@
 //        });
 //
 //    }
-//}
+
+//
+//    @Autowired
+//    private TourTourismProjectTravelNotesService tourTourismProjectTravelNotesService;
+//
+//    @Autowired
+//    private TourTourismTravelNotesContentService tourTourismTravelNotesContentService;
+//
+//    @Autowired
+//    private TourismProjectTravelNotesWriteService tourismProjectTravelNotesWriteService;
+//
+//    @Autowired
+//    private TourismProjectTravelNotesWriteService writeService;
+//
+//    @Autowired
+//    private TourismTravelNotesContentWriteService contentWriteService;
+//
+//    @SaIgnore
+//    @GetMapping("/test")
+//    public void moveData(){
+//        // 查询原游记信息
+//        List<TourTourismProjectTravelNotes> originNoteList = tourTourismProjectTravelNotesService.getTourTourismProjectTravelNotesList(new TourTourismProjectTravelNotes(), "");
+//        // 游记主表数据写入write表
+//        List<TourismProjectTravelNotesWrite> writeList = new ArrayList<>();
+//        List<TourismTravelNotesContentWrite> contentList = new ArrayList<>();
+//        originNoteList.forEach(e->{
+//            TourismProjectTravelNotesWrite write = new TourismProjectTravelNotesWrite();
+//            write.setId(Long.valueOf(e.getId()));
+//            write.setProjectTitle(e.getProjectTitle());
+//            write.setRemarks(e.getRemarks());
+//            //热点
+//            write.setIsHotspot(e.getIsHotspot());
+//            //标签
+//            write.setNoteLabel(e.getProjectLabel());
+//            //目的地
+//            write.setEndPlace(e.getBelongTab());
+//            write.setCountTimes(e.getCountTimes());
+//            write.setTourismUrl(e.getTourismUrl());
+//            write.setCreateTime(e.getCreateTime());
+//            write.setCreateUserId(e.getCreateUserId());
+//            write.setUpdateTime(e.getUpdateTime());
+//            write.setUpdateUserId(e.getUpdateUserId());
+//            write.setDataState(e.getDataState());
+//            write.setTravelNotesBanner(e.getTravelNotesBanner());
+//            write.setLikeCount(e.getLikeCount());
+//            write.setPageViewCount(e.getPageViewCount());
+//            write.setRole(e.getRole());
+//            write.setDepartureTime(e.getDepartureTime());
+//            write.setAverageCost(e.getAverageCost());
+//            write.setRecommendationRate(e.getRecommendationRate());
+//            write.setHotValue(e.getHotValue());
+//            write.setIsOriginal(e.getIsOriginal());
+//            write.setState(3);
+//            write.setUnmountState(1);
+//            writeList.add(write);
+//        });
+//
+//        List<TourTourismTravelNotesContent> originContentList = tourTourismTravelNotesContentService.getTourTourismTravelNotesContentList(new TourTourismTravelNotesContent(), "");
+//        // 游记富文本数据写入write_content表
+//        originContentList.forEach(e->{
+//            List<TourismTravelNotesContentWrite> content = tourismProjectTravelNotesWriteService.parseHTML(e);
+//            contentList.addAll(content);
+//        });
+//
+//        log.info("清洗完了~~~");
+//
+//        writeService.saveNewBatch(writeList);
+//        contentWriteService.saveNewBatch(contentList);
+//        // 结束
+//    }
+}

+ 5 - 10
application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/JobProjectToWebController.java

@@ -86,12 +86,9 @@ public class JobProjectToWebController {
         MyPageData<JobProjectVo> jobProjectVoMyPageData = MyPageUtil.makeResponseData(jobProjectList, JobProjectVo.class);
         List<JobProjectVo> dataList = jobProjectVoMyPageData.getDataList();
         //先把imgUrl由jaon转换为List<FileUrlObject>
-        dataList.stream().forEach(item ->
-        {
-            if (StringUtils.isNotEmpty(item.getJobUrl())) {
-                List<String> jobUrl = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getJobUrl());
-                item.setJobUrlsAfterConvert(jobUrl);
-            }
+        dataList.stream().forEach(item ->{
+            List<String> jobUrl = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getJobUrl());
+            item.setJobUrlsAfterConvert(jobUrl);
         });
 
         return ResponseResult.success(jobProjectVoMyPageData);
@@ -117,10 +114,8 @@ public class JobProjectToWebController {
             // 使用 Jackson 的 ObjectMapper 进行转换
             ObjectMapper objectMapper = new ObjectMapper();
             TourismFile tourismFile = objectMapper.convertValue(jobProjectVo.getJobFile(), TourismFile.class);
-            if (StringUtils.isNotEmpty(tourismFile.getFileUrl())) {
-                tourismFile.setFileUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismFile.getFileUrl()));
-                jobProjectVo.setJobFile(MapConvertUtils.convertObjectToMap(tourismFile));
-            }
+            tourismFile.setFileUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismFile.getFileUrl()));
+            jobProjectVo.setJobFile(MapConvertUtils.convertObjectToMap(tourismFile));
         }
         if(jobProjectVo != null) {
             jobProjectVo.setContactCodeConvert("https://v.xiaoyaotravel.com/image/ContactQRCode/labor_service.png");

+ 19 - 12
application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/LoginToWebsiteController.java

@@ -44,6 +44,7 @@ import com.tourism.webadmin.back.service.TourUserService;
 import com.tourism.webadmin.back.service.impl.TourBookInfoServiceImpl;
 import com.tourism.webadmin.back.util.SMSUtils;
 import com.tourism.common.additional.config.ApplicationConfig;
+import com.tourism.webadmin.config.SmsSwitch;
 import com.tourism.webadmin.upms.model.SysUser;
 import io.jsonwebtoken.lang.Collections;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -106,14 +107,18 @@ public class LoginToWebsiteController {
     private UpDownloaderFactory upDownloaderFactory;
     @Autowired
     private WxMaService wxMaService;
-
     @Autowired
     private TourCountryCodeService tourCountryCodeService;
+    @Autowired
+    private TourBookInfoServiceImpl tourBookInfoService;
+    @Autowired
+    private SmsSwitch smsSwitch;
+
+    @Autowired
+    private SMSUtils smsUtils;
 
     private static final String SHOW_NAME_FIELD = "showName";
     private static final String HEAD_IMAGE_URL_FIELD = "headImageUrl";
-    @Autowired
-    private TourBookInfoServiceImpl tourBookInfoService;
 
 
     /**
@@ -259,7 +264,7 @@ public class LoginToWebsiteController {
 //        String code = String.valueOf(rondom);
         // 校验成功后,发短信到手机
 //        SmsResponse huawei = SmsFactory.getSmsBlend("huawei").sendMessage(checkImageDto.getPhoneNumber(), random);
-        SMSUtils.sendMsg(checkImageDto.getCountryCode(), checkImageDto.getPhoneNumber(), random);
+        smsUtils.sendMsg(checkImageDto.getCountryCode(), checkImageDto.getPhoneNumber(), random);
         String smsCodeKey = CacheConstants.getSmsCodeKey(checkImageDto.getPhoneNumber());
         //5分钟有效时长
         redissonClient.getBucket(smsCodeKey).set(random, CacheConstants.getSmsEffectiveSeconds(), TimeUnit.SECONDS);
@@ -279,15 +284,17 @@ public class LoginToWebsiteController {
             @MyRequestBody String smsCode,
             @MyRequestBody String countryCode) throws UnsupportedEncodingException
     {
-        // 校验短信验证码
-        String smsCodeKey = CacheConstants.getSmsCodeKey(loginMoblie);
-        RBucket<String> bucket = redissonClient.getBucket(smsCodeKey);
-        String redisCode = bucket.get();
-        if(StringUtils.isBlank(redisCode) || !redisCode.equals(smsCode)){
-            return ResponseResult.error(ErrorCodeEnum.SMS_CODE_ERR);
+        if(smsSwitch.isEnable()) {
+            // 校验短信验证码
+            String smsCodeKey = CacheConstants.getSmsCodeKey(loginMoblie);
+            RBucket<String> bucket = redissonClient.getBucket(smsCodeKey);
+            String redisCode = bucket.get();
+            if(StringUtils.isBlank(redisCode) || !redisCode.equals(smsCode)){
+                return ResponseResult.error(ErrorCodeEnum.SMS_CODE_ERR);
+            }
+            // 短信验证码校验成功,清除验证码
+            bucket.delete();
         }
-        // 短信验证码校验成功,清除验证码
-        bucket.delete();
         // 查询用户信息
         TourUser tourUser = tourUserService.getOne(Wrappers.<TourUser>lambdaQuery().eq(TourUser::getMobile, loginMoblie));
         // 如果用户信息不存在,则新建

+ 1 - 1
application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/TourismProjectToWebController.java

@@ -73,7 +73,7 @@ public class TourismProjectToWebController {
         return ResponseResult.success(tourismProjectVo);
     }
     /**
-     * 查看指定旅游项目管理对象详情
+     * 查看指定旅游项目管理对象的日历价格
      *
      * @param projectId 项目id。
      * @return 应答结果对象,包含对象详情。

+ 465 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/WebSiteTourismTravelNotesPublishController.java

@@ -0,0 +1,465 @@
+package com.tourism.webadmin.app.website.controller;
+
+import com.github.pagehelper.page.PageMethod;
+import com.tourism.common.additional.config.ApplicationConfig;
+import com.tourism.common.additional.utils.StringUtils;
+import com.tourism.common.additional.utils.UrlConvertUtils;
+import com.tourism.common.core.annotation.MyRequestBody;
+import com.tourism.common.core.constant.ErrorCodeEnum;
+import com.tourism.common.core.object.*;
+import com.tourism.common.core.util.MyCommonUtil;
+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.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.WebsiteTourUserDto;
+import com.tourism.webadmin.app.website.vo.TourWriteBelongTabVo;
+import com.tourism.webadmin.app.website.vo.TourismProjectTravelNotesWriteCovertVo;
+import com.tourism.webadmin.back.dto.TourismProjectTravelNotesWriteDto;
+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.TourismProjectTravelNotesWriteVo;
+import com.tourism.webadmin.back.vo.TourismTravelNotesContentWriteVo;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import ognl.Token;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.poi.ss.formula.functions.T;
+import org.springframework.beans.factory.annotation.Autowired;
+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.stream.Collectors;
+
+@Tag(name = "门户网站发布游记接口")
+@Slf4j
+@RestController
+@RequestMapping("/website/tourism/publishTravelNotes")
+public class WebSiteTourismTravelNotesPublishController {
+
+    @Autowired
+    private IdGeneratorWrapper idGenerator;
+    @Autowired
+    private TourismProjectTravelNotesWriteService tourismProjectTravelNotesWriteService;
+    @Autowired
+    private TourismTravelNotesContentWriteService tourismTravelNotesContentWriteService;
+    @Autowired
+    private TourTourismProjectTravelNotesService tourTourismProjectTravelNotesService;
+    @Autowired
+    private TourUserService tourUserService;
+    @Autowired
+    private DirectoryInfoService directoryInfoService;
+    @Autowired
+    private HuaweiCloudModerationService huaweiCloudModerationService;
+    @Autowired
+    private ApplicationConfig applicationConfig;
+
+    /**
+     * 获取草稿id
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.LIST)
+    @GetMapping("/getDraftId")
+    public ResponseResult<String> getDraftId() {
+        return ResponseResult.success(String.valueOf(idGenerator.nextLongId()));
+    }
+
+    /**
+     * 存为草稿
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/saveDraft")
+    public ResponseResult<Void> saveDraft(@RequestBody TourismProjectTravelNotesWriteDto tourismProjectTravelNotesWriteDto) {
+
+
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite =
+                tourismProjectTravelNotesWriteService.getById(tourismProjectTravelNotesWriteDto.getId());
+
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWriteSave =
+                MyModelUtil.copyTo(tourismProjectTravelNotesWriteDto,TourismProjectTravelNotesWrite.class);
+
+        //将从表中的数据进行过滤,筛选出cover为1的图片为封面图,第一段落为项目简述
+        List<TourismTravelNotesContentWriteDto> travelNotesContent = tourismProjectTravelNotesWriteDto.getTravelNotesContent();
+        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());
+        }
+
+        //判断是新增还是更新
+        if(tourismProjectTravelNotesWrite == null){
+            //草稿为下架状态
+            tourismProjectTravelNotesWriteSave.setUnmountState(UnmountState.DELIST);
+            tourismProjectTravelNotesWriteService.saveNew(tourismProjectTravelNotesWriteSave);
+        }else {
+            //草稿为下架状态
+            tourismProjectTravelNotesWriteSave.setUnmountState(UnmountState.DELIST);
+            tourismProjectTravelNotesWriteService.updateById(tourismProjectTravelNotesWriteSave);
+        }
+
+        //判断内容是否为空
+        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);
+        }
+        return ResponseResult.success();
+    }
+
+
+    /**
+     * 获取数据列表
+     * param type--->类型(0,草稿;1,待审核;2,审核未通过;3,审核通过
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.LIST)
+    @GetMapping("/getDraftList")
+    public ResponseResult<MyPageData<TourismProjectTravelNotesWriteCovertVo>> getDraftList(@Validated TourismProjectTravelNotesWriteDetailPageDto pageDto) {
+        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);
+
+        MyPageData<TourismProjectTravelNotesWriteCovertVo> tourismProjectTravelNotesWriteVoMyPageData = MyPageUtil.makeResponseData(tourismProjectTravelNotesWriteList, TourismProjectTravelNotesWriteCovertVo.class);
+        List<TourismProjectTravelNotesWriteCovertVo> dataList = tourismProjectTravelNotesWriteVoMyPageData.getDataList();
+        if(CollectionUtils.isNotEmpty(dataList)){
+            dataList.stream().forEach(item->{
+                item.setTourismUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTourismUrl()));
+            });
+        }
+        return ResponseResult.success(tourismProjectTravelNotesWriteVoMyPageData);
+    }
+
+    /**
+     * 根据草稿id,获取草稿详情
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.LIST)
+    @GetMapping("/getDraftDetail")
+    public ResponseResult<TourismProjectTravelNotesWriteVo> getDraftDetail(@RequestParam Long writeId) {
+
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite = tourismProjectTravelNotesWriteService.getByIdWithRelation(writeId,MyRelationParam.full());
+        if(tourismProjectTravelNotesWrite == null){
+            return ResponseResult.success(null);
+        }
+        TourismProjectTravelNotesWriteVo tourismProjectTravelNotesWriteVo = MyModelUtil.copyTo(tourismProjectTravelNotesWrite, TourismProjectTravelNotesWriteVo.class);
+
+        return ResponseResult.success(tourismProjectTravelNotesWriteVo);
+    }
+
+    /**
+     * 根据草稿id,删除草稿
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/removeByDraftId")
+    public ResponseResult<Void> removeByDraftId(@MyRequestBody String writeId) {
+        if (MyCommonUtil.existBlankArgument(writeId)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        //验证是否为本人创建的数据
+        Long userId = TokenData.takeFromRequest().getUserId();
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite = tourismProjectTravelNotesWriteService.getById(Long.valueOf(writeId));
+        if(tourismProjectTravelNotesWrite == null){
+            return ResponseResult.success();
+        }else {
+            if(!tourismProjectTravelNotesWrite.getState().equals(AuditState.DRAFT)
+                    && !tourismProjectTravelNotesWrite.getState().equals(AuditState.FAILAUDIT)){
+                return ResponseResult.error(ErrorCodeEnum.UPLOAD_FILE_FAILED,"该数据状态不允许删除!");
+            }
+            //不是本人创建的数据
+            if(!tourismProjectTravelNotesWrite.getCreateUserId().equals(userId)){
+                return ResponseResult.error(ErrorCodeEnum.DATA_NOT_FOUND);
+            }
+        }
+        tourismProjectTravelNotesWriteService.remove(Long.valueOf(writeId));
+        tourismTravelNotesContentWriteService.removeByAssociationId(Long.valueOf(writeId));
+        return ResponseResult.success();
+    }
+
+    /**
+     * 草稿发布接口
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.PUBLISH)
+    @PostMapping("/publishDraft")
+    @Transactional
+    public ResponseResult<Void> publishDraft(@RequestBody TourismProjectTravelNotesWriteDto tourismProjectTravelNotesWriteDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourismProjectTravelNotesWriteDto,UpdateGroup.class);
+        if (errorMessage != null) {
+            return ResponseResult.success(null);
+        }
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite =
+                MyModelUtil.copyTo(tourismProjectTravelNotesWriteDto, TourismProjectTravelNotesWrite.class);
+
+        //将从表中的数据进行过滤,筛选出cover为1的图片为封面图,第一段落为项目简述
+        List<TourismTravelNotesContentWriteDto> travelNotesContent = tourismProjectTravelNotesWriteDto.getTravelNotesContent();
+        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());
+        }
+
+        // 文案审核
+        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);
+        }
+        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();
+    }
+
+    /**
+     * 审核中---->撤回接口
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/withdraw")
+    public ResponseResult<Void> withdraw(@MyRequestBody String writeId) {
+        if (MyCommonUtil.existBlankArgument(writeId)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite = tourismProjectTravelNotesWriteService.getById(Long.valueOf(writeId));
+        //判断状态是否为审核中
+        if(tourismProjectTravelNotesWrite == null){
+            return ResponseResult.error(ErrorCodeEnum.DATA_ACCESS_FAILED,"该游记内容不存在,请刷新重试!");
+        }
+        if(!tourismProjectTravelNotesWrite.getState().equals(AuditState.UNAUDITSTATE)){
+            return ResponseResult.error(ErrorCodeEnum.DATA_ACCESS_FAILED,"当前状态无法撤回");
+        }else if(!tourismProjectTravelNotesWrite.getCreateUserId().equals(TokenData.takeFromRequest().getUserId())){
+            return ResponseResult.error(ErrorCodeEnum.DATA_ACCESS_FAILED,"当前用户无法撤回");
+        }else {
+            tourismProjectTravelNotesWrite.setState(AuditState.DRAFT);
+            tourismProjectTravelNotesWriteService.updateById(tourismProjectTravelNotesWrite);
+            return ResponseResult.success();
+        }
+    }
+
+    /**
+     * 已审核通过的接口进行下架操作
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/delist")
+    public ResponseResult<Void> delist(@MyRequestBody String writeId) {
+        if (MyCommonUtil.existBlankArgument(writeId)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite = tourismProjectTravelNotesWriteService.getById(Long.valueOf(writeId));
+        //校验该数据是否为用户所创建的数据
+        if(!tourismProjectTravelNotesWrite.getCreateUserId().equals(TokenData.takeFromRequest().getUserId())){
+            return ResponseResult.error(ErrorCodeEnum.DATA_ACCESS_FAILED,"当前用户无法进行下架操作");
+        }
+        //校验数据状态是否允许下架状态
+        if(tourismProjectTravelNotesWrite.getUnmountState().equals(UnmountState.LISTING) && tourismProjectTravelNotesWrite.getState().equals(AuditState.SUCCEEDAUDIT)){
+            tourismProjectTravelNotesWrite.setUnmountState(UnmountState.DELIST);
+            tourismProjectTravelNotesWrite.setState(AuditState.DRAFT);
+            tourismProjectTravelNotesWriteService.updateById(tourismProjectTravelNotesWrite);
+            return ResponseResult.success();
+        }else {
+            return ResponseResult.error(ErrorCodeEnum.DATA_ACCESS_FAILED,"数据状态不允许下架");
+        }
+    }
+
+    /**
+     * 在写日志的页面,返回是否需要完善个人信息(0:需要完善个人信息;1:不需要完善)
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.LIST)
+    @GetMapping("/isPerfect")
+    public ResponseResult<Integer> isPerfect() {
+        Long userId = TokenData.takeFromRequest().getUserId();
+        TourismProjectTravelNotesWrite filter = new TourismProjectTravelNotesWrite();
+        filter.setCreateUserId(userId);
+        List<TourismProjectTravelNotesWrite> tourismProjectTravelNotesWriteList = tourismProjectTravelNotesWriteService.getTourismProjectTravelNotesWriteList(filter, "");
+        int tourismProjectTravelNotesWriteCount = 0;
+        if(CollectionUtils.isNotEmpty(tourismProjectTravelNotesWriteList)){
+            tourismProjectTravelNotesWriteCount = tourismProjectTravelNotesWriteCount+(tourismProjectTravelNotesWriteList.size());
+        }
+        TourTourismProjectTravelNotes tourTourismProjectTravelNotes = new TourTourismProjectTravelNotes();
+        tourTourismProjectTravelNotes.setCreateUserId(userId);
+        List<TourTourismProjectTravelNotes> tourTourismProjectTravelNotesList = tourTourismProjectTravelNotesService.getTourTourismProjectTravelNotesList(tourTourismProjectTravelNotes, "");
+        int tourTourismProjectTravelNotesCount = 0;
+        if(CollectionUtils.isNotEmpty(tourTourismProjectTravelNotesList)){
+            tourTourismProjectTravelNotesCount = tourTourismProjectTravelNotesCount+(tourTourismProjectTravelNotesList.size());
+        }
+        int totalCount = tourTourismProjectTravelNotesCount+tourismProjectTravelNotesWriteCount;
+
+        //如果未超过3条,则不需要进行完善个人信息
+        if(totalCount<3){
+            return ResponseResult.success(1);
+        }else {
+            //查询个人信息表是否有必填信息需要用户完善
+            TourUser tourUserInfo = new TourUser();
+            tourUserInfo.setUserId(userId);
+            TourUser tourUser = tourUserService.getOne(tourUserInfo);
+
+            //假设用户的展示姓名和邮箱为空的话,则进行弹窗完善用户个人的信息
+            if(StringUtils.isEmpty(tourUser.getShowName()) || StringUtils.isEmpty(tourUser.getEmail())){
+                return ResponseResult.success(0);
+            }
+            return ResponseResult.success(1);
+        }
+
+    }
+
+    /**
+     * 保存个人信息
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/savePerfect")
+    public ResponseResult<Void> savePerfect(@RequestBody WebsiteTourUserDto websiteTourUserDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(websiteTourUserDto, UpdateGroup.class);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        Long userId = TokenData.takeFromRequest().getUserId();
+        TourUser tourUser = tourUserService.getById(userId);
+        TourUser tourUserModel = MyModelUtil.copyTo(tourUser, TourUser.class);
+        if(websiteTourUserDto.getShowName() != null){
+            tourUserModel.setShowName(websiteTourUserDto.getShowName());
+        }
+        if(websiteTourUserDto.getEmail() != null){
+            tourUserModel.setEmail(websiteTourUserDto.getEmail());
+        }
+        if(websiteTourUserDto.getAddress() != null){
+            tourUserModel.setAddress(websiteTourUserDto.getAddress());
+        }
+        if(websiteTourUserDto.getJob() != null){
+            tourUserModel.setJob(websiteTourUserDto.getJob());
+        }
+        tourUserService.update(tourUserModel,tourUser);
+        return ResponseResult.success();
+    }
+
+    /**
+     * 用户发布游记选择所属分类---->目的地
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.LIST)
+    @GetMapping("/getWriteBelongTab")
+    public ResponseResult<List<TourWriteBelongTabVo>> getWriteBelongTab() {
+
+        DirectoryInfo directoryInfo  = new DirectoryInfo();
+        directoryInfo.setParentId(0L);
+        directoryInfo.setDirectoryType(1);
+        List<DirectoryInfo> directoryInfoList = directoryInfoService.getDirectoryInfoList(directoryInfo, "");
+
+        List<TourWriteBelongTabVo> tourWriteBelongTabVoList = MyModelUtil.copyCollectionTo(directoryInfoList, TourWriteBelongTabVo.class);
+        List<TourWriteBelongTabVo> newDirectoryInfoList = new ArrayList<>();
+        for(TourWriteBelongTabVo i : tourWriteBelongTabVoList){
+            if(!i.getId().equals("10")){
+                DirectoryInfo directoryInfo2  = new DirectoryInfo();
+                directoryInfo2.setParentId(Long.valueOf(i.getId()));
+                directoryInfo2.setDirectoryType(1);
+                List<DirectoryInfo> bodyDirectoryInfoList = directoryInfoService.getDirectoryInfoList(directoryInfo2, "");
+
+                List<TourWriteBelongTabVo> bodyTourWriteBelongTabVoList = MyModelUtil.copyCollectionTo(bodyDirectoryInfoList, TourWriteBelongTabVo.class);
+                if(CollectionUtils.isNotEmpty(bodyDirectoryInfoList)){
+                    i.setTourWriteBelongTabVoList(bodyTourWriteBelongTabVoList);
+                }
+                newDirectoryInfoList.add(i);
+            }
+        }
+        return ResponseResult.success(newDirectoryInfoList);
+    }
+
+
+
+}

+ 96 - 34
application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/WebsiteTourismProjectTravelNotesController.java

@@ -1,31 +1,38 @@
 package com.tourism.webadmin.app.website.controller;
 
 import cn.dev33.satoken.annotation.SaIgnore;
+import com.github.pagehelper.page.PageMethod;
+import com.tourism.common.additional.config.ApplicationConfig;
 import com.tourism.common.additional.utils.UrlConvertUtils;
+import com.tourism.common.core.constant.ErrorCodeEnum;
 import com.tourism.common.core.object.MyOrderParam;
 import com.tourism.common.core.object.MyPageData;
 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.util.MyPageUtil;
+import com.tourism.common.core.validator.UpdateGroup;
 import com.tourism.common.log.annotation.OperationLog;
 import com.tourism.common.log.model.constant.SysOperationLogType;
-import com.tourism.webadmin.app.website.dto.TourismProjectTravelNotesToWebDto;
+import com.tourism.webadmin.app.website.dto.PageDto;
+import com.tourism.webadmin.app.website.dto.TourismCollectDto;
+import com.tourism.webadmin.app.website.dto.TourismTravelNotesWriteDto;
 import com.tourism.webadmin.app.website.service.BasicToWebService;
 import com.tourism.webadmin.app.website.vo.TourTravelNotesDirectoryCountryVo;
 import com.tourism.webadmin.app.website.vo.TourTravelNotesDirectoryVo;
+import com.tourism.webadmin.app.website.vo.TourismProjectTravelNotesWriteCovertVo;
 import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.back.model.constant.UnmountState;
 import com.tourism.webadmin.back.service.*;
-import com.tourism.webadmin.back.vo.TourTourismProjectTravelNotesVo;
+import com.tourism.webadmin.back.vo.TourismProjectTravelNotesWriteVo;
 import com.tourism.webadmin.back.vo.TourismProjectVo;
-import com.tourism.common.additional.config.ApplicationConfig;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -51,6 +58,10 @@ public class WebsiteTourismProjectTravelNotesController {
     private TourTourismProjectTravelNotesService tourTourismProjectTravelNotesService;
     @Autowired
     private ApplicationConfig applicationConfig;
+    @Autowired
+    private TourUserLikeTravelNotesService tourUserLikeTravelNotesService;
+    @Autowired
+    private TourismProjectTravelNotesWriteService tourismProjectTravelNotesWriteService;
 
 
     /**
@@ -60,8 +71,8 @@ public class WebsiteTourismProjectTravelNotesController {
     @OperationLog(type = SysOperationLogType.LIST)
     @GetMapping("/homeList")
     @SaIgnore
-    public ResponseResult<MyPageData<TourTourismProjectTravelNotesVo>> tourTourismTravelNotesList(TourismProjectTravelNotesToWebDto tourismProjectTravelNotesToWebDto) {
-        MyPageData<TourTourismProjectTravelNotesVo> tourTourismProjectTravelNotesList = basicToWebServicel.getTourTourismProjectTravelNotesList(tourismProjectTravelNotesToWebDto);
+    public ResponseResult<MyPageData<TourismProjectTravelNotesWriteVo>> tourTourismTravelNotesList(TourismTravelNotesWriteDto tourismTravelNotesWriteDto) {
+        MyPageData<TourismProjectTravelNotesWriteVo> tourTourismProjectTravelNotesList = basicToWebServicel.getTourTourismProjectTravelNotesList(tourismTravelNotesWriteDto);
 
         return ResponseResult.success(tourTourismProjectTravelNotesList);
     }
@@ -73,8 +84,9 @@ public class WebsiteTourismProjectTravelNotesController {
     @OperationLog(type = SysOperationLogType.LIST)
     @SaIgnore
     @GetMapping("/travelNotesPageList")
-    public ResponseResult<MyPageData<TourTourismProjectTravelNotesVo>> travelNotesPageList(TourismProjectTravelNotesToWebDto tourismProjectTravelNotesToWebDto) {
-        MyPageData<TourTourismProjectTravelNotesVo> tourTourismProjectTravelNotesList = basicToWebServicel.getTravelNotesPageList(tourismProjectTravelNotesToWebDto);
+    @SaIgnore
+    public ResponseResult<MyPageData<TourismProjectTravelNotesWriteVo>> travelNotesPageList(TourismTravelNotesWriteDto tourismTravelNotesWriteDto) {
+        MyPageData<TourismProjectTravelNotesWriteVo> tourTourismProjectTravelNotesList = basicToWebServicel.getTravelNotesPageList(tourismTravelNotesWriteDto);
 
         return ResponseResult.success(tourTourismProjectTravelNotesList);
     }
@@ -86,44 +98,93 @@ public class WebsiteTourismProjectTravelNotesController {
     @OperationLog(type = SysOperationLogType.LIST)
     @GetMapping("/travelNotesDetail")
     @SaIgnore
-    public ResponseResult<TourTourismProjectTravelNotesVo> travelNotesDetail(@RequestParam String id) {
-
-        TourTourismProjectTravelNotesVo tourTourismProjectTravelNotesVo = basicToWebServicel.travelNotesDetail(id);
-//        tourTourismProjectTravelNotesVo.setContactCode("[{\"name\":\"微信图片_20241021154757.png\",\"downloadUri\":\"/admin/app/tourTourismProjectTravelNotes/download\",\"filename\":\"6b92b75edcc04da1bd6e4af056911730.png\",\"uploadPath\":\"image/TourTourismProjectTravelNotes/contactCode\"}]");
-//        List<String> urlConvertList = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourTourismProjectTravelNotesVo.getContactCode());
-//        if(CollectionUtils.isNotEmpty(urlConvertList)) {
-//            tourTourismProjectTravelNotesVo.setContactCodeConvert(urlConvertList.get(0));
-//        }
-//
-        if(tourTourismProjectTravelNotesVo != null) {
-            tourTourismProjectTravelNotesVo.setContactCodeConvert("https://v.xiaoyaotravel.com/image/ContactQRCode/tourism.png");
+    public ResponseResult<TourismProjectTravelNotesWriteVo> travelNotesDetail(@RequestParam String id) {
+
+        TourismProjectTravelNotesWriteVo vo = basicToWebServicel.travelNotesDetail(id);
+
+        if(vo != null) {
+            vo.setContactCodeConvert("https://v.xiaoyaotravel.com/image/ContactQRCode/tourism.png");
         }
-        return ResponseResult.success(tourTourismProjectTravelNotesVo);
+        return ResponseResult.success(vo);
     }
 
     /**
-     * 用户游记点赞
+     * 用户游记收藏
      * param travelNotesId 游记id
-     * param type 0取消点赞 1点赞
+     * param type 0取消收藏 1收藏
      * @return 应答结果对象,包含查询结果集。
      */
+//    @SaIgnore
     @OperationLog(type = SysOperationLogType.UPDATE)
-    @GetMapping("/userLikeTravelNotesUpdate")
-    public ResponseResult<Void> userLikeTravelNotesUpdate(@RequestParam Long travelNotesId,Integer type) {
+    @PostMapping("/userCollectTravelNotesUpdate")
+    public ResponseResult<Void> userCollectTravelNotesUpdate(@RequestBody TourismCollectDto tourismCollectDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourismCollectDto, UpdateGroup.class);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED);
+        }
+        basicToWebServicel.userLikeTravelNotesUpdate(Long.valueOf(tourismCollectDto.getTravelNotesId()),tourismCollectDto.getType());
+        return ResponseResult.success();
+    }
 
-        basicToWebServicel.userLikeTravelNotesUpdate(travelNotesId,type);
+    /**
+     * 用户游记进行点赞
+     * param travelNotesId 游记id
+     * param type 0取消收藏 1收藏
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @SaIgnore
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/userLikeTravelNotesUpdate")
+    public ResponseResult<Void> userLikeTravelNotesUpdate(@RequestBody TourismTravelNotesWriteDto dto) {
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite = new TourismProjectTravelNotesWrite();
+        tourismProjectTravelNotesWrite.setId(Long.valueOf(dto.getTravelNotesId()));
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite1 = tourismProjectTravelNotesWriteService.getOne(tourismProjectTravelNotesWrite);
+
+        tourismProjectTravelNotesWrite1.setLikeCount(tourismProjectTravelNotesWrite1.getLikeCount() + 1);
+        tourismProjectTravelNotesWriteService.updateById(tourismProjectTravelNotesWrite1);
         return ResponseResult.success();
     }
 
     /**
-     * 用户是否对该游记进行点赞
+     * 用户是否对该游记进行收藏
      * param travelNotesId 游记id
      * @return 应答结果对象,包含查询结果集。
      */
     @OperationLog(type = SysOperationLogType.LIST)
-    @GetMapping("/isLikeTravelNotes")
-    public ResponseResult<Boolean> isLikeTravelNotes(@RequestParam Long travelNotesId) {
-        return ResponseResult.success(basicToWebServicel.isLikeTravelNotes(travelNotesId));
+    @GetMapping("/isCollectTravelNotes")
+    public ResponseResult<Boolean> isCollectTravelNotes(@RequestParam String travelNotesId) {
+        return ResponseResult.success(basicToWebServicel.isLikeTravelNotes(Long.valueOf(travelNotesId)));
+    }
+
+    /**
+     * 用户的收藏列表
+     *
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @OperationLog(type = SysOperationLogType.LIST)
+    @GetMapping("/userCollectTravelNotesList")
+    public ResponseResult<MyPageData<TourismProjectTravelNotesWriteVo>> userCollectTravelNotesList(PageDto pageDto) {
+
+        MyOrderParam myOrderParam = new MyOrderParam();
+        myOrderParam.add(new MyOrderParam.OrderInfo("updateTime",false,null));
+        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourUserLikeTravelNotes.class);
+        Long userId = TokenData.takeFromRequest().getUserId();
+        TourUserLikeTravelNotes filter = new TourUserLikeTravelNotes();
+        filter.setUserId(userId);
+        if(pageDto.getPageSize() != null && pageDto.getPageNum() != null){
+            PageMethod.startPage(pageDto.getPageNum(), pageDto.getPageSize(), true);
+        }
+        List<TourismProjectTravelNotesWrite> tourUserLikeTravelNotesList = tourUserLikeTravelNotesService.getTourUserLikeTravelNotesWithRelationWriteList(filter, UnmountState.LISTING, orderBy);
+
+        MyPageData<TourismProjectTravelNotesWriteVo> tourismProjectTravelNotesWriteVoMyPageData = MyPageUtil.makeResponseData(tourUserLikeTravelNotesList, TourismProjectTravelNotesWriteVo.class);
+        List<TourismProjectTravelNotesWriteVo> dataList = tourismProjectTravelNotesWriteVoMyPageData.getDataList();
+        if(CollectionUtils.isNotEmpty(dataList)){
+            dataList.stream().forEach(item->{
+                item.setTourismUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTourismUrl()));
+            });
+        }
+
+        return ResponseResult.success(tourismProjectTravelNotesWriteVoMyPageData);
     }
 
 
@@ -132,6 +193,7 @@ public class WebsiteTourismProjectTravelNotesController {
      * param travelNotesId 游记id
      * @return 应答结果对象,包含查询结果集。
      */
+    @SaIgnore
     @OperationLog(type = SysOperationLogType.ADD)
     @GetMapping("/travelNotesViewCountAdd")
     @SaIgnore
@@ -237,8 +299,8 @@ public class WebsiteTourismProjectTravelNotesController {
     @SaIgnore
     public ResponseResult<Integer> getLikeCount(@RequestParam(required = true) Long travelNotesId) {
 
-        TourTourismProjectTravelNotes tourTourismProjectTravelNotes = tourTourismProjectTravelNotesService.getById(travelNotesId);
-        Integer likeCount = tourTourismProjectTravelNotes.getLikeCount();
+        TourismProjectTravelNotesWrite writeDto = tourismProjectTravelNotesWriteService.getById(travelNotesId);
+        Integer likeCount = writeDto.getLikeCount() == null ? 0 : writeDto.getLikeCount();
         return ResponseResult.success(likeCount);
     }
 }

+ 25 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/TourismCollectDto.java

@@ -0,0 +1,25 @@
+package com.tourism.webadmin.app.website.dto;
+
+import com.tourism.common.core.validator.UpdateGroup;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class TourismCollectDto {
+
+    /**
+     * 游记id
+     */
+    @Schema(description = "游记id。")
+    @NotBlank(message = "游记id不能为空",groups = {UpdateGroup.class})
+    private String travelNotesId;
+
+    /**
+     * 类型(0取消收藏 1收藏)。
+     */
+    @Schema(description = "类型。")
+    @NotNull(message = "类型不能为空",groups = {UpdateGroup.class})
+    private Integer type;
+}

+ 38 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/TourismProjectTravelNotesWriteDetailPageDto.java

@@ -0,0 +1,38 @@
+package com.tourism.webadmin.app.website.dto;
+
+import com.tourism.common.core.validator.UpdateGroup;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import static io.lettuce.core.pubsub.PubSubOutput.Type.message;
+
+@Data
+public class TourismProjectTravelNotesWriteDetailPageDto {
+
+    @Schema(description = "游记ID")
+    @NotNull(message = "草稿id不允许为空!",groups = {UpdateGroup.class})
+    private Long travelNotesId;
+
+    @Schema(description = "类型(0,草稿;1,待审核;2,审核未通过;3,审核通过")
+    @NotNull(message = "类型不允许为空!",groups = {UpdateGroup.class})
+    private Integer type;
+
+    /**
+     * 分页号码,从1开始计数。
+     */
+    @Schema(description = "分页号码。")
+    private Integer pageNum;
+
+    /**
+     * 每页大小。
+     */
+    @Schema(description = "每页大小。")
+    private Integer pageSize;
+
+    /**
+     * 是否统计totalCount。
+     */
+    @Schema(description = "是否统计totalCount。")
+    private Boolean count;
+}

+ 83 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/TourismTravelNotesWriteDto.java

@@ -0,0 +1,83 @@
+package com.tourism.webadmin.app.website.dto;
+
+import com.tourism.common.core.object.MyOrderParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 门户预定管理Dto对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "TourismTravelNotesWriteDto对象")
+@Data
+public class TourismTravelNotesWriteDto {
+
+    /**
+     * 游记ID
+     */
+    private String travelNotesId;
+    /**
+     * 所属分类。
+     */
+    @Schema(description = "所属分类。")
+    private Long belongTab;
+
+    /**
+     * 地区id。
+     */
+    @Schema(description = "地区id。")
+    private String areaId;
+
+    /**
+     * 国家id。
+     */
+    @Schema(description = "国家id。")
+    private String countryId;
+
+    /**
+     * 是否为热点项目。
+     */
+    @Schema(description = "是否热点,0非热点,1热点。")
+    private Integer isHotspot;
+
+    /**
+     * 分页号码,从1开始计数。
+     */
+    @Schema(description = "分页号码。")
+    private Integer pageNum;
+
+    /**
+     * 每页大小。
+     */
+    @Schema(description = "每页大小。")
+    private Integer pageSize;
+
+    /**
+     * 是否统计totalCount。
+     */
+    @Schema(description = "是否统计totalCount。")
+    private Boolean count;
+
+    /**
+     * 排序。
+     */
+    @Schema(description = "排序。")
+    private MyOrderParam orderParamList;
+
+    /**
+     * 菜单id。
+     */
+    private List<Long> directoryInfoIds;
+
+    /**
+     * banner_name LIKE搜索字符串。
+     * NOTE: 可支持LIKE操作符的列表数据过滤。
+     */
+    @Schema(description = "LIKE模糊搜索字符串")
+    private String searchString;
+
+}

+ 42 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/WebsiteTourUserDto.java

@@ -0,0 +1,42 @@
+package com.tourism.webadmin.app.website.dto;
+
+import com.tourism.common.core.validator.UpdateGroup;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 门户网站用户管理Dto对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "WebsiteTourUserDto对象")
+@Data
+public class WebsiteTourUserDto {
+
+    /**
+     *  住址
+     */
+    private String address;
+
+    /**
+     *  职业
+     */
+    private String job;
+
+    /**
+     *  邮箱
+     */
+    @NotBlank(message = "邮箱不能为空!", groups = {UpdateGroup.class})
+    private String email;
+
+    /**
+     *  昵称
+     */
+    @NotBlank(message = "昵称不能为空!", groups = {UpdateGroup.class})
+    private String showName;
+
+
+}

+ 5 - 3
application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/BasicToWebService.java

@@ -3,10 +3,12 @@ package com.tourism.webadmin.app.website.service;
 import com.tourism.common.core.object.MyPageData;
 import com.tourism.common.core.object.ResponseResult;
 import com.tourism.webadmin.app.website.dto.TourismProjectTravelNotesToWebDto;
+import com.tourism.webadmin.app.website.dto.TourismTravelNotesWriteDto;
 import com.tourism.webadmin.back.model.TourTourismProjectTravelNotes;
 import com.tourism.webadmin.back.vo.BannerInfoVo;
 import com.tourism.webadmin.back.vo.DirectoryInfoVo;
 import com.tourism.webadmin.back.vo.TourTourismProjectTravelNotesVo;
+import com.tourism.webadmin.back.vo.TourismProjectTravelNotesWriteVo;
 import org.springframework.web.bind.annotation.RequestParam;
 
 /**
@@ -20,11 +22,11 @@ public interface BasicToWebService
 
     MyPageData<DirectoryInfoVo> getDirectoryInfoList(Long parentId, Integer isHotspot, Integer isAll);
 
-    MyPageData<TourTourismProjectTravelNotesVo> getTourTourismProjectTravelNotesList(TourismProjectTravelNotesToWebDto tourismProjectTravelNotesToWebDto);
+    MyPageData<TourismProjectTravelNotesWriteVo> getTourTourismProjectTravelNotesList(TourismTravelNotesWriteDto tourismTravelNotesWriteDto);
 
-    MyPageData<TourTourismProjectTravelNotesVo> getTravelNotesPageList(TourismProjectTravelNotesToWebDto tourismProjectTravelNotesToWebDto);
+    MyPageData<TourismProjectTravelNotesWriteVo> getTravelNotesPageList(TourismTravelNotesWriteDto tourismTravelNotesWriteDto);
 
-    TourTourismProjectTravelNotesVo travelNotesDetail(String id);
+    TourismProjectTravelNotesWriteVo travelNotesDetail(String id);
 
     void userLikeTravelNotesUpdate(Long travelNotesId,Integer type);
 

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

@@ -10,19 +10,15 @@ import com.tourism.common.core.object.TokenData;
 import com.tourism.common.core.util.MyModelUtil;
 import com.tourism.common.core.util.MyPageUtil;
 import com.tourism.webadmin.app.website.dto.TourismProjectTravelNotesToWebDto;
+import com.tourism.webadmin.app.website.dto.TourismTravelNotesWriteDto;
 import com.tourism.webadmin.app.website.service.BasicToWebService;
-import com.tourism.webadmin.back.model.BannerInfo;
-import com.tourism.webadmin.back.model.DirectoryInfo;
-import com.tourism.webadmin.back.model.TourTourismProjectTravelNotes;
-import com.tourism.webadmin.back.model.TourUserLikeTravelNotes;
-import com.tourism.webadmin.back.service.BannerInfoService;
-import com.tourism.webadmin.back.service.DirectoryInfoService;
-import com.tourism.webadmin.back.service.TourTourismProjectTravelNotesService;
-import com.tourism.webadmin.back.service.TourUserLikeTravelNotesService;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.back.service.*;
 import com.tourism.webadmin.back.vo.BannerInfoVo;
 import com.tourism.webadmin.back.vo.DirectoryInfoVo;
 import com.tourism.webadmin.back.vo.TourTourismProjectTravelNotesVo;
 import com.tourism.common.additional.config.ApplicationConfig;
+import com.tourism.webadmin.back.vo.TourismProjectTravelNotesWriteVo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -52,6 +48,8 @@ public class BasicToWebServiceImpl implements BasicToWebService
     private TourTourismProjectTravelNotesService tourTourismProjectTravelNotesService;
     @Autowired
     private TourUserLikeTravelNotesService tourUserLikeTravelNotesService;
+    @Autowired
+    private TourismProjectTravelNotesWriteService tourismProjectTravelNotesWriteService;
 
     @Override
     public MyPageData<BannerInfoVo> getBannerInfoList(Long belongTab) {
@@ -72,9 +70,7 @@ public class BasicToWebServiceImpl implements BasicToWebService
         List<BannerInfoVo> dataList = bannerInfoVoMyPageData.getDataList();
             //先把imgUrl由jaon转换为List<FileUrlObject>
         dataList.stream().forEach(item ->{
-            if (StringUtils.isNotEmpty(item.getImgUrl())) {
-                item.setImgUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getImgUrl()));
-            }
+            item.setImgUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getImgUrl()));
         });
 
         return bannerInfoVoMyPageData;
@@ -119,145 +115,169 @@ public class BasicToWebServiceImpl implements BasicToWebService
         List<DirectoryInfoVo> dataList = directoryInfoVoMyPageData.getDataList();
         //先把imgUrl由jaon转换为List<FileUrlObject>
         dataList.stream().forEach(item ->{
-            if (StringUtils.isNotEmpty(item.getHotPictureUrl())) {
-                item.setHotPictureUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getHotPictureUrl()));
-            }
+            item.setHotPictureUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getHotPictureUrl()));
         });
         return directoryInfoVoMyPageData;
     }
 
     @Override
-    public MyPageData<TourTourismProjectTravelNotesVo> getTourTourismProjectTravelNotesList(TourismProjectTravelNotesToWebDto tourismProjectTravelNotesToWebDto){
-
-        TourTourismProjectTravelNotes tourTourismProjectTravelNotesFilter = new TourTourismProjectTravelNotes();
-        tourTourismProjectTravelNotesFilter.setEnable(1);
-        tourTourismProjectTravelNotesFilter.setIsHotspot(1);
-        if(tourismProjectTravelNotesToWebDto.getPageNum() != null && tourismProjectTravelNotesToWebDto.getPageSize() != null) {
-            PageMethod.startPage(tourismProjectTravelNotesToWebDto.getPageNum(), tourismProjectTravelNotesToWebDto.getPageSize(), true);
+    public MyPageData<TourismProjectTravelNotesWriteVo> getTourTourismProjectTravelNotesList(TourismTravelNotesWriteDto tourismTravelNotesWriteDto){
+
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWriteFilter = new TourismProjectTravelNotesWrite();
+        tourismProjectTravelNotesWriteFilter.setUnmountState(1);
+        tourismProjectTravelNotesWriteFilter.setIsHotspot(1);
+//        TourTourismProjectTravelNotes tourTourismProjectTravelNotesFilter = new TourTourismProjectTravelNotes();
+//        tourTourismProjectTravelNotesFilter.setEnable(1);
+//        tourTourismProjectTravelNotesFilter.setIsHotspot(1);
+        if(tourismTravelNotesWriteDto.getPageNum() != null && tourismTravelNotesWriteDto.getPageSize() != null) {
+            PageMethod.startPage(tourismTravelNotesWriteDto.getPageNum(), tourismTravelNotesWriteDto.getPageSize(), true);
         }
         MyOrderParam myOrderParam = new MyOrderParam();
-        myOrderParam.add(new MyOrderParam.OrderInfo("showOrder",true,null));
         myOrderParam.add(new MyOrderParam.OrderInfo("updateTime",false,null));
-        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourTourismProjectTravelNotes.class);
-        List<TourTourismProjectTravelNotes> tourTourismProjectTravelNotesList = tourTourismProjectTravelNotesService.getTourTourismProjectTravelNotesList(tourTourismProjectTravelNotesFilter, orderBy);
-        MyPageData<TourTourismProjectTravelNotesVo> tourTourismProjectTravelNotesVoMyPageData = MyPageUtil.makeResponseData(tourTourismProjectTravelNotesList, TourTourismProjectTravelNotesVo.class);
-        List<TourTourismProjectTravelNotesVo> dataList = tourTourismProjectTravelNotesVoMyPageData.getDataList();
+        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourismProjectTravelNotesWrite.class);
+        List<TourismProjectTravelNotesWrite> writeList = tourismProjectTravelNotesWriteService.getTourismProjectTravelNotesWriteListWithRelation(tourismProjectTravelNotesWriteFilter, orderBy);
+//        List<TourTourismProjectTravelNotes> tourTourismProjectTravelNotesList = tourTourismProjectTravelNotesService.getTourTourismProjectTravelNotesList(tourismProjectTravelNotesWriteFilter, orderBy);
+        MyPageData<TourismProjectTravelNotesWriteVo> pageData = MyPageUtil.makeResponseData(writeList, TourismProjectTravelNotesWriteVo.class);
+        List<TourismProjectTravelNotesWriteVo> dataList = pageData.getDataList();
         dataList.stream().forEach(item->{
-            if (StringUtils.isNotEmpty(item.getHomeHotPicture())) {
-                item.setHomeHotPicturesAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getHomeHotPicture()));
-            }
+            item.setHomeHotPicturesAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTourismUrl()));
         });
 
-        return tourTourismProjectTravelNotesVoMyPageData;
+        return pageData;
     }
 
     @Override
-    public MyPageData<TourTourismProjectTravelNotesVo> getTravelNotesPageList(TourismProjectTravelNotesToWebDto tourismProjectTravelNotesToWebDto){
+    public MyPageData<TourismProjectTravelNotesWriteVo> getTravelNotesPageList(TourismTravelNotesWriteDto dto){
         //当belongTab为1的时候,则表明查询全部的游记
         MyOrderParam myOrderParam = new MyOrderParam();
         myOrderParam.add(new MyOrderParam.OrderInfo("isHotspot",false,null));
-        myOrderParam.add(new MyOrderParam.OrderInfo("showOrder",true,null));
         myOrderParam.add(new MyOrderParam.OrderInfo("updateTime",false,null));
-        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourTourismProjectTravelNotes.class);
+        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourismProjectTravelNotesWrite.class);
 
-        TourTourismProjectTravelNotes tourTourismProjectTravelNotes = new TourTourismProjectTravelNotes();
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWriteFilter = new TourismProjectTravelNotesWrite();
+//        TourTourismProjectTravelNotes tourTourismProjectTravelNotes = new TourTourismProjectTravelNotes();
 
-        if(StringUtils.isEmpty(tourismProjectTravelNotesToWebDto.getAreaId()) && StringUtils.isEmpty(tourismProjectTravelNotesToWebDto.getCountryId())){
+        if(StringUtils.isEmpty(dto.getAreaId()) && StringUtils.isEmpty(dto.getCountryId())){
             //判断是否为全部的地区
-            tourTourismProjectTravelNotes.setEnable(1);
-            tourTourismProjectTravelNotes.setBelongTab(null);
-        }else if(StringUtils.isNotEmpty(tourismProjectTravelNotesToWebDto.getAreaId()) && StringUtils.isEmpty(tourismProjectTravelNotesToWebDto.getCountryId())){
+            tourismProjectTravelNotesWriteFilter.setUnmountState(1);
+            tourismProjectTravelNotesWriteFilter.setEndPlace(null);
+        }else if(StringUtils.isNotEmpty(dto.getAreaId()) && StringUtils.isEmpty(dto.getCountryId())){
             //判断是否为该地区的所有国家
             DirectoryInfo directoryInfo = new DirectoryInfo();
-            directoryInfo.setParentId(Long.parseLong(tourismProjectTravelNotesToWebDto.getAreaId()));
+            directoryInfo.setParentId(Long.parseLong(dto.getAreaId()));
             directoryInfo.setEnable(1);
             List<DirectoryInfo> directoryInfoList =
                     directoryInfoService.getDirectoryInfoList(directoryInfo, "");
             List<Long> directoryIdList =
                     directoryInfoList.stream().map(DirectoryInfo::getId).collect(Collectors.toList());
-            tourTourismProjectTravelNotes.setBelongTab(null);
-            tourTourismProjectTravelNotes.setDirectoryInfoIds(directoryIdList);
+            tourismProjectTravelNotesWriteFilter.setEndPlace(null);
+            tourismProjectTravelNotesWriteFilter.setDirectoryInfoIds(directoryIdList);
         }else {
             //如果查询的是某个国家的游记的话
-            if(StringUtils.isNotEmpty(tourismProjectTravelNotesToWebDto.getCountryId())) {
-                tourTourismProjectTravelNotes.setBelongTab(Long.parseLong(tourismProjectTravelNotesToWebDto.getCountryId()));
+            if(StringUtils.isNotEmpty(dto.getCountryId())) {
+                tourismProjectTravelNotesWriteFilter.setEndPlace(Long.parseLong(dto.getCountryId()));
             }
         }
 
-        if(tourismProjectTravelNotesToWebDto.getPageNum() != null && tourismProjectTravelNotesToWebDto.getPageSize() != null) {
-            PageMethod.startPage(tourismProjectTravelNotesToWebDto.getPageNum(), tourismProjectTravelNotesToWebDto.getPageSize(), true);
+        if(dto.getPageNum() != null && dto.getPageSize() != null) {
+            PageMethod.startPage(dto.getPageNum(), dto.getPageSize(), true);
         }
 
-        List<TourTourismProjectTravelNotes> tourTourismProjectTravelNotesList =
-                tourTourismProjectTravelNotesService.getTourTourismProjectTravelNotesList(tourTourismProjectTravelNotes, orderBy);
+//        List<TourTourismProjectTravelNotes> tourTourismProjectTravelNotesList =
+//                tourTourismProjectTravelNotesService.getTourTourismProjectTravelNotesList(tourismProjectTravelNotesWriteFilter, orderBy);
+        List<TourismProjectTravelNotesWrite> writeList =
+                tourismProjectTravelNotesWriteService.getTourismProjectTravelNotesWriteList(tourismProjectTravelNotesWriteFilter, orderBy);
 
-        MyPageData<TourTourismProjectTravelNotesVo> tourTourismProjectTravelNotesVoMyPageData =
-                MyPageUtil.makeResponseData(tourTourismProjectTravelNotesList, TourTourismProjectTravelNotesVo.class);
+        MyPageData<TourismProjectTravelNotesWriteVo> pageData =
+                MyPageUtil.makeResponseData(writeList, TourismProjectTravelNotesWriteVo.class);
 
-        List<TourTourismProjectTravelNotesVo> dataList = tourTourismProjectTravelNotesVoMyPageData.getDataList();
+        List<TourismProjectTravelNotesWriteVo> dataList = pageData.getDataList();
 
         dataList.stream().forEach(item->{
-            if(StringUtils.isNotEmpty(item.getTourismUrl())){
-                item.setTourismUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTourismUrl()));
-            }
+            item.setTourismUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTourismUrl()));
         });
 
-        return tourTourismProjectTravelNotesVoMyPageData;
+        return pageData;
     }
 
     @Override
-    public TourTourismProjectTravelNotesVo travelNotesDetail(String id){
-        TourTourismProjectTravelNotes tourTourismProjectTravelNotes =
-                tourTourismProjectTravelNotesService.getByIdWithRelation(id, MyRelationParam.full());
-
-        TourTourismProjectTravelNotesVo tourTourismProjectTravelNotesVo =
-                MyModelUtil.copyTo(tourTourismProjectTravelNotes, TourTourismProjectTravelNotesVo.class);
-
-        if(tourTourismProjectTravelNotesVo != null) {
-            if (StringUtils.isNotEmpty(tourTourismProjectTravelNotesVo.getTourismUrl())) {
-                tourTourismProjectTravelNotesVo.setTourismUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourTourismProjectTravelNotesVo.getTourismUrl()));
-            }
+    public TourismProjectTravelNotesWriteVo travelNotesDetail(String id){
+        TourismProjectTravelNotesWrite writeDto = tourismProjectTravelNotesWriteService.getByIdWithRelation(Long.parseLong(id), MyRelationParam.full());
+        if(writeDto.getPageViewCount() != null) {
+            writeDto.setPageViewCount(writeDto.getPageViewCount() + 1);
+        }else {
+            writeDto.setPageViewCount(1);
+        }
+        //每有一人浏览,则增加50热度值
+        if(writeDto.getHotValue() != null) {
+            writeDto.setHotValue(writeDto.getHotValue() + 50);
+        }else {
+            writeDto.setHotValue(50);
+        }
+        tourismProjectTravelNotesWriteService.updateById(writeDto);
 
-            if (StringUtils.isNotEmpty(tourTourismProjectTravelNotesVo.getHomeHotPicture())) {
-                tourTourismProjectTravelNotesVo.setHomeHotPicturesAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourTourismProjectTravelNotesVo.getHomeHotPicture()));
-            }
+        TourismProjectTravelNotesWriteVo writeVo =
+                MyModelUtil.copyTo(writeDto, TourismProjectTravelNotesWriteVo.class);
 
-            if (StringUtils.isNotEmpty(tourTourismProjectTravelNotesVo.getTravelNotesBanner())) {
-                tourTourismProjectTravelNotesVo.setTravelNotesBannerAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourTourismProjectTravelNotesVo.getTravelNotesBanner()));
-            }
+        if(writeVo != null) {
+            writeVo.setTourismUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), writeVo.getTourismUrl()));
+            writeVo.setHomeHotPicturesAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), writeVo.getTourismUrl()));
+            writeVo.setTravelNotesBannerAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), writeVo.getTravelNotesBanner()));
         }
-        return tourTourismProjectTravelNotesVo;
+        return writeVo;
     }
 
     @Override
     @Transactional
     public void userLikeTravelNotesUpdate(Long travelNotesId,Integer type){
 
-        TourUserLikeTravelNotes tourUserLikeTravelNotes =
-                new TourUserLikeTravelNotes();
+//        TourUserLikeTravelNotes tourUserLikeTravelNotes =
+//                new TourUserLikeTravelNotes();
+//        tourUserLikeTravelNotes.setTravelNotesId(travelNotesId);
+//        tourUserLikeTravelNotes.setUserId(TokenData.takeFromRequest().getUserId());
+//        TourTourismProjectTravelNotes tourTourismProjectTravelNotes = tourTourismProjectTravelNotesService.getById(travelNotesId);
+//        if(tourTourismProjectTravelNotes.getLikeCount() != null) {
+//            if(type == 1) {
+//                tourTourismProjectTravelNotes.setLikeCount(tourTourismProjectTravelNotes.getLikeCount() + 1);
+//                if(tourTourismProjectTravelNotes.getHotValue() != null) {
+//                    tourTourismProjectTravelNotes.setHotValue(tourTourismProjectTravelNotes.getHotValue() + 100);
+//                }else {
+//                    tourTourismProjectTravelNotes.setHotValue(100);
+//                }
+//            }else {
+//                tourTourismProjectTravelNotes.setLikeCount(tourTourismProjectTravelNotes.getLikeCount() - 1);
+//            }
+//        }else {
+//            tourTourismProjectTravelNotes.setLikeCount(1);
+//        }
+//        if(type == 0){
+//            tourUserLikeTravelNotesService.removeBy(tourUserLikeTravelNotes);
+//        }else {
+//            tourUserLikeTravelNotesService.saveNew(tourUserLikeTravelNotes);
+//        }
+//        TourTourismProjectTravelNotes tourTourismProjectTravelNotes = tourTourismProjectTravelNotesService.getById(travelNotesId);
+//        if(tourTourismProjectTravelNotes != null) {
+//            if (tourTourismProjectTravelNotes.getLikeCount() == null) {
+//                tourTourismProjectTravelNotes.setLikeCount(1);
+//            } else {
+//                tourTourismProjectTravelNotes.setLikeCount(tourTourismProjectTravelNotes.getLikeCount() + 1);
+//            }
+//            tourTourismProjectTravelNotesService.updateById(tourTourismProjectTravelNotes);
+//        }
+        //type为0,则进行删除;type为1,则进行新增
+        TourUserLikeTravelNotes tourUserLikeTravelNotes = new TourUserLikeTravelNotes();
         tourUserLikeTravelNotes.setTravelNotesId(travelNotesId);
         tourUserLikeTravelNotes.setUserId(TokenData.takeFromRequest().getUserId());
-        TourTourismProjectTravelNotes tourTourismProjectTravelNotes = tourTourismProjectTravelNotesService.getById(travelNotesId);
-        if(tourTourismProjectTravelNotes.getLikeCount() != null) {
-            if(type == 1) {
-                tourTourismProjectTravelNotes.setLikeCount(tourTourismProjectTravelNotes.getLikeCount() + 1);
-                if(tourTourismProjectTravelNotes.getHotValue() != null) {
-                    tourTourismProjectTravelNotes.setHotValue(tourTourismProjectTravelNotes.getHotValue() + 100);
-                }else {
-                    tourTourismProjectTravelNotes.setHotValue(100);
-                }
-            }else {
-                tourTourismProjectTravelNotes.setLikeCount(tourTourismProjectTravelNotes.getLikeCount() - 1);
-            }
-        }else {
-            tourTourismProjectTravelNotes.setLikeCount(1);
-        }
         if(type == 0){
             tourUserLikeTravelNotesService.removeBy(tourUserLikeTravelNotes);
         }else {
-            tourUserLikeTravelNotesService.saveNew(tourUserLikeTravelNotes);
+            boolean b = tourUserLikeTravelNotesService.existByFilter(tourUserLikeTravelNotes);
+            if(!b){
+                tourUserLikeTravelNotesService.saveNew(tourUserLikeTravelNotes);
+            }
+
         }
-        tourTourismProjectTravelNotesService.updateById(tourTourismProjectTravelNotes);
+
     }
 
     @Override
@@ -272,19 +292,19 @@ public class BasicToWebServiceImpl implements BasicToWebService
     @Override
     public void travelNotesViewCountAdd(Long travelNotesId){
 
-        TourTourismProjectTravelNotes tourTourismProjectTravelNotes = tourTourismProjectTravelNotesService.getById(travelNotesId);
-        if(tourTourismProjectTravelNotes.getPageViewCount() != null) {
-            tourTourismProjectTravelNotes.setPageViewCount(tourTourismProjectTravelNotes.getPageViewCount() + 1);
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite = tourismProjectTravelNotesWriteService.getById(travelNotesId);
+        if(tourismProjectTravelNotesWrite.getPageViewCount() != null) {
+            tourismProjectTravelNotesWrite.setPageViewCount(tourismProjectTravelNotesWrite.getPageViewCount() + 1);
         }else {
-            tourTourismProjectTravelNotes.setPageViewCount(1);
+            tourismProjectTravelNotesWrite.setPageViewCount(1);
         }
         //每有一人浏览,则增加50热度值
-        if(tourTourismProjectTravelNotes.getHotValue() != null) {
-            tourTourismProjectTravelNotes.setHotValue(tourTourismProjectTravelNotes.getHotValue() + 50);
+        if(tourismProjectTravelNotesWrite.getHotValue() != null) {
+            tourismProjectTravelNotesWrite.setHotValue(tourismProjectTravelNotesWrite.getHotValue() + 50);
         }else {
-            tourTourismProjectTravelNotes.setHotValue(50);
+            tourismProjectTravelNotesWrite.setHotValue(50);
         }
-        tourTourismProjectTravelNotesService.updateById(tourTourismProjectTravelNotes);
+        tourismProjectTravelNotesWriteService.updateById(tourismProjectTravelNotesWrite);
     }
 
     @Override

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

@@ -105,8 +105,7 @@ public class TourismProjectToWebServiceImpl implements TourismProjectToWebServic
 
         List<TourismProjectVo> dataList = tourismProjectVoMyPageData.getDataList();
         //先把imgUrl由jaon转换为List<FileUrlObject>
-        dataList.stream().forEach(item ->
-        {
+        dataList.stream().forEach(item ->{
             List<String> urlList = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getHomeHotPicture());
             item.setHomeHotPicturesAfterConvert(urlList);
             List<String> arrayList = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTourismUrl());
@@ -130,10 +129,8 @@ public class TourismProjectToWebServiceImpl implements TourismProjectToWebServic
             // 使用 Jackson 的 ObjectMapper 进行转换
             ObjectMapper objectMapper = new ObjectMapper();
             TourismFile tourismFile = objectMapper.convertValue(tourismProjectVo.getTourismFile(), TourismFile.class);
-            if(StringUtils.isNotEmpty(tourismFile.getFileUrl())){
-                tourismFile.setFileUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismFile.getFileUrl()));
-                tourismProjectVo.setTourismFile(MapConvertUtils.convertObjectToMap(tourismFile));
-            }
+            tourismFile.setFileUrlsAfterConvert(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismFile.getFileUrl()));
+            tourismProjectVo.setTourismFile(MapConvertUtils.convertObjectToMap(tourismFile));
         }
         //二维码路径赋值
 //        tourismProjectVo.setContactCode("[{\"name\":\"微信图片_20241021154757.png\",\"downloadUri\":\"/admin/app/tourTourismProjectTravelNotes/download\",\"filename\":\"6b92b75edcc04da1bd6e4af056911730.png\",\"uploadPath\":\"image/TourTourismProjectTravelNotes/contactCode\"}]");

+ 23 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/TourWriteBelongTabVo.java

@@ -0,0 +1,23 @@
+package com.tourism.webadmin.app.website.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 门户网站中发布游记的选择所属分类(目的地)。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-10-12
+ */
+@Schema(description = "TourWriteBelongTabVo视图对象")
+@Data
+public class TourWriteBelongTabVo {
+
+    private String id;
+
+    private String menuName;
+
+    private List<TourWriteBelongTabVo> tourWriteBelongTabVoList;
+}

+ 209 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/TourismProjectTravelNotesWriteCovertVo.java

@@ -0,0 +1,209 @@
+package com.tourism.webadmin.app.website.vo;
+
+import com.tourism.common.core.base.vo.BaseVo;
+import com.tourism.webadmin.back.vo.TourismTravelNotesContentWriteVo;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 发布游记VO视图对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "发布游记VO视图对象")
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TourismProjectTravelNotesWriteCovertVo extends BaseVo {
+
+    /**
+     * 主键id。
+     */
+    @Schema(description = "主键id")
+    private String id;
+
+    /**
+     * 项目标题。
+     */
+    @Schema(description = "项目标题")
+    private String projectTitle;
+
+    /**
+     * 出发时间。
+     */
+    @Schema(description = "出发时间")
+    private LocalDate departureTime;
+
+    /**
+     * 总天数。
+     */
+    @Schema(description = "总天数")
+    private String countTimes;
+
+    /**
+     * 人物关系。
+     */
+    @Schema(description = "人物关系")
+    private String role;
+
+    /**
+     * 推荐指数。
+     */
+    @Schema(description = "推荐指数")
+    private Integer recommendationRate;
+
+    /**
+     * 人均费用。
+     */
+    @Schema(description = "人均费用")
+    private String averageCost;
+
+    /**
+     * 审核状态(0,未审核;1,审核通过;2、审核不通过)。
+     */
+    @Schema(description = "审核状态(0,未审核;1,审核通过;2、审核不通过)")
+    private Integer state;
+
+    /**
+     * 审核不通过的原因。
+     */
+    @Schema(description = "审核不通过的原因")
+    private String reason;
+
+    /**
+     * 发布游记的banner图。
+     */
+    @Schema(description = "发布游记的banner图")
+    private String travelNotesBanner;
+
+    /**
+     * 游记内容中的图片。
+     */
+    @Schema(description = "游记内容中的图片")
+    private List<String> tourismTavelNotesUrl;
+
+    /**
+     * 上下架状态(0,下架;1,上架)。
+     */
+    @Schema(description = "上下架状态(0,下架;1,上架)")
+    private Integer unmountState;
+
+    /**
+     * 项目展示图片。
+     */
+    @Schema(description = "项目展示图片")
+    private String tourismUrl;
+
+    /**
+     * 项目简述。
+     */
+    @Schema(description = "项目简述")
+    private String remarks;
+
+    /**
+     * 是否热点,0非热点,1热点。
+     */
+    @Schema(description = "是否热点,0非热点,1热点")
+    private Integer isHotspot;
+
+    /**
+     * 标签。
+     */
+    @Schema(description = "标签")
+    private String noteLabel;
+
+    /**
+     * 点赞数。
+     */
+    @Schema(description = "点赞数")
+    private Integer likeCount;
+
+    /**
+     * 浏览量。
+     */
+    @Schema(description = "浏览量")
+    private Integer pageViewCount;
+
+    /**
+     * 热度值。
+     */
+    @Schema(description = "热度值")
+    private Integer hotValue;
+
+    /**
+     * 是否原创(0:非原创;1:原创)。
+     */
+    @Schema(description = "是否原创(0:非原创;1:原创)")
+    private Integer isOriginal;
+
+    /**
+     * 目的地。
+     */
+    @Schema(description = "目的地")
+    private String endPlace;
+
+    /**
+     * 自动审核结果1:通过,2未通过。
+     */
+    @Schema(description = "自动审核结果1:通过,2未通过")
+    private Integer autoAuditStatus;
+
+    /**
+     * 自动审核未通过原因。
+     */
+    @Schema(description = "自动审核未通过原因")
+    private String autoRejectReason;
+
+    /**
+     * endPlace 字典关联数据。
+     */
+    @Schema(description = "endPlace 字典关联数据")
+    private Map<String, Object> endPlaceDictMap;
+
+    /**
+     * state 常量字典关联数据。
+     */
+    @Schema(description = "state 常量字典关联数据")
+    private Map<String, Object> stateDictMap;
+
+    /**
+     * tourismProjectTravelNotesContentDraft 游记内容。
+     */
+    @Schema(description = "tourismProjectTravelNotesContentDraft 游记内容")
+    private List<TourismTravelNotesContentWriteVo> travelNotesContent;
+
+    /**
+     * isHotspot 常量字典关联数据。
+     */
+    @Schema(description = "isHotspot 常量字典关联数据")
+    private Map<String, Object> isHotspotDictMap;
+
+    /**
+     * isOriginal 常量字典关联数据。
+     */
+    @Schema(description = "isOriginal 常量字典关联数据")
+    private Map<String, Object> isOriginalDictMap;
+
+    @Schema(description = "热门图url转换")
+    private List<String> homeHotPicturesAfterConvert;
+
+    @Schema(description = "游记列表图url转换")
+    private List<String> tourismUrlsAfterConvert;
+
+    @Schema(description = "联系人图片")
+    private String contactCodeConvert;
+
+    @Schema(description = "联系人图片")
+    private List<String> travelNotesBannerAfterConvert;
+
+    /**
+     * autoAuditStatus 常量字典关联数据。
+     */
+    @Schema(description = "autoAuditStatus 常量字典关联数据")
+    private Map<String, Object> autoAuditStatusDictMap;
+}

+ 51 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/controller/TourismProjectTravelNotesWriteController.java

@@ -3,6 +3,7 @@ package com.tourism.webadmin.back.controller;
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.annotation.SaIgnore;
 import cn.hutool.core.util.ReflectUtil;
+import com.tourism.common.additional.utils.StringUtils;
 import com.tourism.common.core.upload.BaseUpDownloader;
 import com.tourism.common.core.upload.UpDownloaderFactory;
 import com.tourism.common.core.upload.UploadResponseInfo;
@@ -10,6 +11,7 @@ import com.tourism.common.core.upload.UploadStoreInfo;
 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.model.constant.AuditState;
 import com.tourism.webadmin.back.vo.*;
 import com.tourism.webadmin.back.dto.*;
 import com.tourism.webadmin.back.model.*;
@@ -111,6 +113,55 @@ public class TourismProjectTravelNotesWriteController {
         return ResponseResult.success();
     }
 
+
+    @SaCheckPermission("tourismProjectTravelNotesWrite.update")
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/audit")
+    public ResponseResult<Void> audit(@MyRequestBody TourismProjectTravelNotesWriteDto tourismProjectTravelNotesWriteDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourismProjectTravelNotesWriteDto, true);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        if(tourismProjectTravelNotesWriteDto.getState().equals(AuditState.DRAFT)){
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "审核状态不能为草稿");
+        }
+        if(tourismProjectTravelNotesWriteDto.getState().equals(AuditState.UNAUDITSTATE)){
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "审核状态不能为未审核");
+        }
+        else if(tourismProjectTravelNotesWriteDto.getState().equals(AuditState.FAILAUDIT) && StringUtils.isBlank(tourismProjectTravelNotesWriteDto.getReason())){
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "审核未通过,审核原因不能为空");
+        }else if(tourismProjectTravelNotesWriteDto.getState().equals(AuditState.SUCCEEDAUDIT)){
+            if (tourismProjectTravelNotesWriteDto.getIsHotspot() == null){
+                return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "审核通过,热度值不能为空");
+            }else if(StringUtils.isBlank(tourismProjectTravelNotesWriteDto.getNoteLabel())){
+                return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "审核通过,标签不能为空");
+            }else if(tourismProjectTravelNotesWriteDto.getLikeCount() == null){
+                return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "审核通过,点赞数不能为空");
+            }else if(tourismProjectTravelNotesWriteDto.getPageViewCount() == null){
+                return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "审核通过,浏览数不能为空");
+            }else if(tourismProjectTravelNotesWriteDto.getHotValue() == null){
+                return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "审核通过,热度值不能为空");
+            }else if(tourismProjectTravelNotesWriteDto.getIsOriginal() == null){
+                return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "审核通过,是否原创不能为空");
+            }
+
+        }
+        TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite = MyModelUtil.copyTo(tourismProjectTravelNotesWriteDto, TourismProjectTravelNotesWrite.class);
+        TourismProjectTravelNotesWrite originalTourismProjectTravelNotesWrite = tourismProjectTravelNotesWriteService.getById(tourismProjectTravelNotesWrite.getId());
+        if (originalTourismProjectTravelNotesWrite == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+
+        tourismProjectTravelNotesWriteService.audit(tourismProjectTravelNotesWrite);
+//        if (!tourismProjectTravelNotesWriteService.update(tourismProjectTravelNotesWrite, originalTourismProjectTravelNotesWrite)) {
+//            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+//        }
+        return ResponseResult.success();
+    }
+
+
     /**
      * 删除发布游记数据。
      *

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

@@ -2,6 +2,7 @@ package com.tourism.webadmin.back.dao;
 
 import com.tourism.common.core.base.dao.BaseDaoMapper;
 import com.tourism.webadmin.back.model.TourUserLikeTravelNotes;
+import com.tourism.webadmin.back.model.TourismProjectTravelNotesWrite;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.*;
@@ -30,4 +31,14 @@ public interface TourUserLikeTravelNotesMapper extends BaseDaoMapper<TourUserLik
      */
     List<TourUserLikeTravelNotes> getTourUserLikeTravelNotesList(
             @Param("tourUserLikeTravelNotesFilter") TourUserLikeTravelNotes tourUserLikeTravelNotesFilter, @Param("orderBy") String orderBy);
+
+    /**
+     * 获取过滤后的对象列表(关联write表)。
+     *
+     * @param tourUserLikeTravelNotesFilter 主表过滤对象。
+     * @param orderBy 排序字符串,order by从句的参数。
+     * @return 对象列表。
+     */
+    List<TourismProjectTravelNotesWrite> getTourUserLikeTravelNotesWithRelationWriteList(
+            @Param("tourUserLikeTravelNotesFilter") TourUserLikeTravelNotes tourUserLikeTravelNotesFilter,@Param("unmountState") Integer unmountState, @Param("orderBy") String orderBy);
 }

+ 2 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dao/TourismProjectTravelNotesWriteMapper.java

@@ -30,4 +30,6 @@ public interface TourismProjectTravelNotesWriteMapper extends BaseDaoMapper<Tour
      */
     List<TourismProjectTravelNotesWrite> getTourismProjectTravelNotesWriteList(
             @Param("tourismProjectTravelNotesWriteFilter") TourismProjectTravelNotesWrite tourismProjectTravelNotesWriteFilter, @Param("orderBy") String orderBy);
+
+    Integer auditTravelNote(@Param("tourismProjectTravelNotesWriteFilter") TourismProjectTravelNotesWrite entity);
 }

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

@@ -179,6 +179,9 @@
                     #{id}
                 </foreach>
             </if>
+            <if test="tourTourismProjectTravelNotesFilter.createUserId != null">
+                AND tour_tourism_project_travel_notes.create_user_id = #{tourTourismProjectTravelNotesFilter.createUserId}
+            </if>
         </if>
     </sql>
 

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

@@ -12,6 +12,37 @@
         <result column="data_state" jdbcType="TINYINT" property="dataState"/>
     </resultMap>
 
+    <resultMap id="TourismProjectTravelNotesWriteResultMap" type="com.tourism.webadmin.back.model.TourismProjectTravelNotesWrite">
+        <id column="id" jdbcType="BIGINT" property="id"/>
+        <result column="project_title" jdbcType="VARCHAR" property="projectTitle"/>
+        <result column="departure_time" jdbcType="DATE" property="departureTime"/>
+        <result column="count_times" jdbcType="VARCHAR" property="countTimes"/>
+        <result column="role" jdbcType="VARCHAR" property="role"/>
+        <result column="recommendation_rate" jdbcType="TINYINT" property="recommendationRate"/>
+        <result column="average_cost" jdbcType="VARCHAR" property="averageCost"/>
+        <result column="state" jdbcType="TINYINT" property="state"/>
+        <result column="reason" jdbcType="VARCHAR" property="reason"/>
+        <result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
+        <result column="travel_notes_banner" jdbcType="VARCHAR" property="travelNotesBanner"/>
+        <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"/>
+        <result column="tourism_tavel_notes_url" jdbcType="VARCHAR" property="tourismTavelNotesUrl"/>
+        <result column="unmount_state" jdbcType="TINYINT" property="unmountState"/>
+        <result column="tourism_url" jdbcType="VARCHAR" property="tourismUrl"/>
+        <result column="remarks" jdbcType="VARCHAR" property="remarks"/>
+        <result column="is_hotspot" jdbcType="TINYINT" property="isHotspot"/>
+        <result column="note_label" jdbcType="VARCHAR" property="noteLabel"/>
+        <result column="like_count" jdbcType="INTEGER" property="likeCount"/>
+        <result column="page_view_count" jdbcType="INTEGER" property="pageViewCount"/>
+        <result column="hot_value" jdbcType="INTEGER" property="hotValue"/>
+        <result column="is_original" jdbcType="TINYINT" property="isOriginal"/>
+        <result column="end_place" jdbcType="BIGINT" property="endPlace"/>
+        <result column="auto_audit_status" jdbcType="TINYINT" property="autoAuditStatus"/>
+        <result column="auto_reject_reason" jdbcType="VARCHAR" property="autoRejectReason"/>
+    </resultMap>
+
     <insert id="insertList">
         INSERT INTO tour_user_like_travel_notes
             (id,
@@ -63,4 +94,19 @@
             ORDER BY ${orderBy}
         </if>
     </select>
+
+    <select id="getTourUserLikeTravelNotesWithRelationWriteList" resultMap="TourismProjectTravelNotesWriteResultMap" parameterType="com.tourism.webadmin.back.model.TourismProjectTravelNotesWrite">
+        SELECT
+        a.*
+        FROM
+        tour_user_like_travel_notes
+        inner JOIN (select * from tour_tourism_project_travel_notes_writer where tour_tourism_project_travel_notes_writer.unmount_state = ${unmountState}
+        AND tour_tourism_project_travel_notes_writer.data_state = 1) a ON a.id = tour_user_like_travel_notes.travel_notes_id
+        <where>
+            <include refid="filterRef"/>
+        </where>
+        <if test="orderBy != null and orderBy != ''">
+            ORDER BY ${orderBy}
+        </if>
+    </select>
 </mapper>

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

@@ -17,6 +17,8 @@
         <result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
         <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
         <result column="deleted_flag" jdbcType="INTEGER" property="deletedFlag"/>
+        <result column="address" jdbcType="VARCHAR" property="address"/>
+        <result column="job" jdbcType="VARCHAR" property="job"/>
     </resultMap>
 
     <insert id="insertList">
@@ -35,7 +37,9 @@
             create_time,
             update_user_id,
             update_time,
-            deleted_flag)
+            deleted_flag,
+            address,
+            job)
         VALUES
         <foreach collection="list" index="index" item="item" separator="," >
             (#{item.userId},
@@ -52,7 +56,9 @@
             #{item.createTime},
             #{item.updateUserId},
             #{item.updateTime},
-            #{item.deletedFlag})
+            #{item.deletedFlag},
+            #{item.address},
+            #{item.job})
         </foreach>
     </insert>
 

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

@@ -12,13 +12,24 @@
         <result column="state" jdbcType="TINYINT" property="state"/>
         <result column="reason" jdbcType="VARCHAR" property="reason"/>
         <result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
-        <result column="tourism_url" jdbcType="VARCHAR" property="tourismUrl"/>
+        <result column="travel_notes_banner" jdbcType="VARCHAR" property="travelNotesBanner"/>
         <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"/>
         <result column="tourism_tavel_notes_url" jdbcType="VARCHAR" property="tourismTavelNotesUrl"/>
-<!--        <result column="is_complete" jdbcType="TINYINT" property="isComplete"/>-->
+        <result column="unmount_state" jdbcType="TINYINT" property="unmountState"/>
+        <result column="tourism_url" jdbcType="VARCHAR" property="tourismUrl"/>
+        <result column="remarks" jdbcType="VARCHAR" property="remarks"/>
+        <result column="is_hotspot" jdbcType="TINYINT" property="isHotspot"/>
+        <result column="note_label" jdbcType="VARCHAR" property="noteLabel"/>
+        <result column="like_count" jdbcType="INTEGER" property="likeCount"/>
+        <result column="page_view_count" jdbcType="INTEGER" property="pageViewCount"/>
+        <result column="hot_value" jdbcType="INTEGER" property="hotValue"/>
+        <result column="is_original" jdbcType="TINYINT" property="isOriginal"/>
+        <result column="end_place" jdbcType="BIGINT" property="endPlace"/>
+        <result column="auto_audit_status" jdbcType="TINYINT" property="autoAuditStatus"/>
+        <result column="auto_reject_reason" jdbcType="VARCHAR" property="autoRejectReason"/>
     </resultMap>
 
     <insert id="insertList">
@@ -33,12 +44,24 @@
             state,
             reason,
             create_user_id,
-            tourism_url,
+            travel_notes_banner,
             create_time,
             update_user_id,
             update_time,
             data_state,
-            tourism_tavel_notes_url)
+            tourism_tavel_notes_url,
+            unmount_state,
+            tourism_url,
+            remarks,
+            is_hotspot,
+            note_label,
+            like_count,
+            page_view_count,
+            hot_value,
+            is_original,
+            end_place,
+            auto_audit_status,
+            auto_reject_reason)
         VALUES
         <foreach collection="list" index="index" item="item" separator="," >
             (#{item.id},
@@ -51,12 +74,24 @@
             #{item.state},
             #{item.reason},
             #{item.createUserId},
-            #{item.tourismUrl},
+            #{item.travelNotesBanner},
             #{item.createTime},
             #{item.updateUserId},
             #{item.updateTime},
             #{item.dataState},
-            #{item.tourismTavelNotesUrl})
+            #{item.tourismTavelNotesUrl},
+            #{item.unmountState},
+            #{item.tourismUrl},
+            #{item.remarks},
+            #{item.isHotspot},
+            #{item.noteLabel},
+            #{item.likeCount},
+            #{item.pageViewCount},
+            #{item.hotValue},
+            #{item.isOriginal},
+            #{item.endPlace},
+            #{item.autoAuditStatus},
+            #{item.autoRejectReason})
         </foreach>
     </insert>
 
@@ -65,6 +100,7 @@
         <!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
         <include refid="com.tourism.webadmin.back.dao.TourismProjectTravelNotesWriteMapper.inputFilterRef"/>
         AND tour_tourism_project_travel_notes_writer.data_state = ${@com.tourism.common.core.constant.GlobalDeletedFlag@NORMAL}
+        and tour_tourism_project_travel_notes_writer.state in (1,2,3)
     </sql>
 
     <!-- 这里仅包含调用接口输入的主表过滤条件 -->
@@ -98,6 +134,9 @@
             <if test="tourismProjectTravelNotesWriteFilter.state != null">
                 AND tour_tourism_project_travel_notes_writer.state = #{tourismProjectTravelNotesWriteFilter.state}
             </if>
+            <if test="tourismProjectTravelNotesWriteFilter.createUserId != null">
+                AND tour_tourism_project_travel_notes_writer.create_user_id = #{tourismProjectTravelNotesWriteFilter.createUserId}
+            </if>
             <if test="tourismProjectTravelNotesWriteFilter.reason != null and tourismProjectTravelNotesWriteFilter.reason != ''">
                 <bind name = "safeTourismProjectTravelNotesWriteReason" value = "'%' + tourismProjectTravelNotesWriteFilter.reason + '%'" />
                 AND tour_tourism_project_travel_notes_writer.reason LIKE #{safeTourismProjectTravelNotesWriteReason}
@@ -108,10 +147,29 @@
             <if test="tourismProjectTravelNotesWriteFilter.createTimeEnd != null and tourismProjectTravelNotesWriteFilter.createTimeEnd != ''">
                 AND tour_tourism_project_travel_notes_writer.create_time &lt;= #{tourismProjectTravelNotesWriteFilter.createTimeEnd}
             </if>
+            <if test="tourismProjectTravelNotesWriteFilter.isHotspot != null">
+                AND tour_tourism_project_travel_notes_writer.is_hotspot = #{tourismProjectTravelNotesWriteFilter.isHotspot}
+            </if>
+            <if test="tourismProjectTravelNotesWriteFilter.isOriginal != null">
+                AND tour_tourism_project_travel_notes_writer.is_original = #{tourismProjectTravelNotesWriteFilter.isOriginal}
+            </if>
+            <if test="tourismProjectTravelNotesWriteFilter.endPlace != null and tourismProjectTravelNotesWriteFilter.endPlace != ''">
+                AND tour_tourism_project_travel_notes_writer.end_place = #{tourismProjectTravelNotesWriteFilter.endPlace}
+            </if>
             <if test="tourismProjectTravelNotesWriteFilter.searchString != null and tourismProjectTravelNotesWriteFilter.searchString != ''">
                 <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.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=")">
+                    #{id}
+                </foreach>
+            </if>
         </if>
     </sql>
 
@@ -124,4 +182,34 @@
             ORDER BY ${orderBy}
         </if>
     </select>
+
+    <sql id="updateRef">
+        <!-- 审核不通过,设置state为2、驳回原因 -->
+        <if test="tourismProjectTravelNotesWriteFilter.state == 2">
+            unmount_state = 0,
+            state = 2,
+            reason = #{tourismProjectTravelNotesWriteFilter.reason}
+        </if>
+        <!-- 审核通过,设置state为3 -->
+        <if test="tourismProjectTravelNotesWriteFilter.state == 3">
+            unmount_state = 1,
+            state = 3,
+            is_hotspot = #{tourismProjectTravelNotesWriteFilter.isHotspot},
+            note_label = #{tourismProjectTravelNotesWriteFilter.noteLabel},
+            like_count = #{tourismProjectTravelNotesWriteFilter.likeCount},
+            page_view_count = #{tourismProjectTravelNotesWriteFilter.pageViewCount},
+            hot_value = #{tourismProjectTravelNotesWriteFilter.hotValue},
+            is_original = #{tourismProjectTravelNotesWriteFilter.isOriginal}
+        </if>
+    </sql>
+
+    <update id="auditTravelNote" parameterType="com.tourism.webadmin.back.model.TourismProjectTravelNotesWrite">
+        update tour_tourism_project_travel_notes_writer
+        <set>
+            <include refid="updateRef"></include>
+        </set>
+        <where>
+            id = #{tourismProjectTravelNotesWriteFilter.id}
+        </where>
+    </update>
 </mapper>

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

@@ -3,35 +3,38 @@
 <mapper namespace="com.tourism.webadmin.back.dao.TourismTravelNotesContentWriteMapper">
     <resultMap id="BaseResultMap" type="com.tourism.webadmin.back.model.TourismTravelNotesContentWrite">
         <id column="id" jdbcType="BIGINT" property="id"/>
-        <result column="content" jdbcType="LONGVARCHAR" property="content"/>
         <result column="association_id" jdbcType="BIGINT" property="associationId"/>
         <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"/>
+        <result column="type" jdbcType="VARCHAR" property="type"/>
+        <result column="content" jdbcType="VARCHAR" property="content"/>
+        <result column="cover" jdbcType="TINYINT" property="cover"/>
     </resultMap>
 
     <insert id="insertList">
         INSERT INTO tour_tourism_travel_notes_content_writer
-            (id,
-            content,
-            association_id,
-            create_user_id,
-            create_time,
-            update_user_id,
-            update_time,
-            data_state)
+        (id,
+        association_id,
+        create_user_id,
+        create_time,
+        update_user_id,
+        update_time,
+        type,
+        content,
+        cover)
         VALUES
         <foreach collection="list" index="index" item="item" separator="," >
             (#{item.id},
-            #{item.content},
             #{item.associationId},
             #{item.createUserId},
             #{item.createTime},
             #{item.updateUserId},
             #{item.updateTime},
-            #{item.dataState})
+            #{item.type},
+            #{item.content},
+            #{item.cover})
         </foreach>
     </insert>
 
@@ -39,12 +42,14 @@
     <sql id="filterRef">
         <!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
         <include refid="com.tourism.webadmin.back.dao.TourismTravelNotesContentWriteMapper.inputFilterRef"/>
-        AND tour_tourism_travel_notes_content_writer.data_state = ${@com.tourism.common.core.constant.GlobalDeletedFlag@NORMAL}
     </sql>
 
     <!-- 这里仅包含调用接口输入的主表过滤条件 -->
     <sql id="inputFilterRef">
         <if test="tourismTravelNotesContentWriteFilter != null">
+            <if test="tourismTravelNotesContentWriteFilter.associationId != null">
+                AND tour_tourism_travel_notes_content_writer.association_id = #{tourismTravelNotesContentWriteFilter.associationId}
+            </if>
         </if>
     </sql>
 

+ 10 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourUserDto.java

@@ -104,4 +104,14 @@ public class TourUserDto {
      * 国家区号。
      */
     private String countryCode;
+
+    /**
+     *  住址
+     */
+    private String address;
+
+    /**
+     *  职业
+     */
+    private String job;
 }

+ 89 - 11
application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourismProjectTravelNotesWriteDto.java

@@ -2,7 +2,7 @@ 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.AuditState;
+import com.tourism.webadmin.back.model.constant.*;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -10,6 +10,7 @@ import lombok.Data;
 import jakarta.validation.constraints.*;
 
 import java.util.Date;
+import java.util.List;
 
 /**
  * 发布游记Dto对象。
@@ -86,10 +87,10 @@ public class TourismProjectTravelNotesWriteDto {
     private String reason;
 
     /**
-     * 项目展示图片
+     * 发布游记的banner图
      */
-    @Schema(description = "项目展示图片。")
-    private String tourismUrl;
+    @Schema(description = "发布游记的banner图。")
+    private String travelNotesBanner;
 
     /**
      * 游记内容中的图片。
@@ -97,13 +98,83 @@ public class TourismProjectTravelNotesWriteDto {
     @Schema(description = "游记内容中的图片。")
     private String tourismTavelNotesUrl;
 
-//    /**
-//     * 是否完成(0,草稿;1,成稿)。
-//     * NOTE: 可支持等于操作符的列表数据过滤。
-//     */
-//    @Schema(description = "是否完成(0,草稿;1,成稿)。可支持等于操作符的列表数据过滤。")
-//    @ConstDictRef(constDictClass = IsComplete.class, message = "数据验证失败,是否完成(0,草稿;1,成稿)为无效值!")
-//    private Integer isComplete;
+    /**
+     * 上下架状态(0,下架;1,上架)。
+     */
+    @Schema(description = "上下架状态(0,下架;1,上架)。")
+    @ConstDictRef(constDictClass = UnmountState.class, message = "数据验证失败,上下架状态(0,下架;1,上架)为无效值!")
+    private Integer unmountState;
+
+    /**
+     * 项目展示图片。
+     */
+    @Schema(description = "项目展示图片。")
+    private String tourismUrl;
+
+    /**
+     * 项目简述。
+     */
+    @Schema(description = "项目简述。")
+    private String remarks;
+
+    /**
+     * 是否热点,0非热点,1热点。
+     */
+    @Schema(description = "是否热点,0非热点,1热点。")
+    @ConstDictRef(constDictClass = Hotspot.class, message = "数据验证失败,是否热点,0非热点,1热点为无效值!")
+    private Integer isHotspot;
+
+    /**
+     * 标签。
+     */
+    @Schema(description = "标签。")
+    private String noteLabel;
+
+    /**
+     * 点赞数。
+     */
+    @Schema(description = "点赞数。")
+    private Integer likeCount;
+
+    /**
+     * 浏览量。
+     */
+    @Schema(description = "浏览量。")
+    private Integer pageViewCount;
+
+    /**
+     * 热度值。
+     */
+    @Schema(description = "热度值。")
+    private Integer hotValue;
+
+    /**
+     * 是否原创(0:非原创;1:原创)。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "是否原创(0:非原创;1:原创)。可支持等于操作符的列表数据过滤。")
+    @ConstDictRef(constDictClass = IsOriginal.class, message = "数据验证失败,是否原创(0:非原创;1:原创)为无效值!")
+    private Integer isOriginal;
+
+    /**
+     * 目的地。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "目的地。可支持等于操作符的列表数据过滤。")
+    private Long endPlace;
+
+    /**
+     * 自动审核结果1:通过,2未通过。
+     */
+    @Schema(description = "自动审核结果1:通过,2未通过。")
+    @ConstDictRef(constDictClass = AudioState.class, message = "数据验证失败,自动审核结果1:通过,2未通过为无效值!")
+    private Integer autoAuditStatus;
+
+    /**
+     * 自动审核未通过原因。
+     */
+    @Schema(description = "自动审核未通过原因。")
+    private String autoRejectReason;
 
     /**
      * departureTime 范围过滤起始值(>=)。
@@ -139,4 +210,11 @@ public class TourismProjectTravelNotesWriteDto {
      */
     @Schema(description = "LIKE模糊搜索字符串")
     private String searchString;
+
+    /**
+     * 游记内容。
+     */
+    @Schema(description = "游记内容。")
+//    @NotNull(message = "游记内容不能为空!", groups = {UpdateGroup.class})
+    private List<TourismTravelNotesContentWriteDto> travelNotesContent;
 }

+ 18 - 6
application-webadmin/src/main/java/com/tourism/webadmin/back/dto/TourismTravelNotesContentWriteDto.java

@@ -25,15 +25,27 @@ public class TourismTravelNotesContentWriteDto {
     private Long id;
 
     /**
-     * 富文本内容。
-     */
-    @Schema(description = "富文本内容。")
-    private String content;
-
-    /**
      * 关联表id。
      */
     @Schema(description = "关联表id。", requiredMode = Schema.RequiredMode.REQUIRED)
     @NotNull(message = "数据验证失败,关联表id不能为空!", groups = {UpdateGroup.class})
     private Long associationId;
+
+    /**
+     * 类型。
+     */
+    @Schema(description = "类型。")
+    private String type;
+
+    /**
+     * 内容。
+     */
+    @Schema(description = "内容。")
+    private String content;
+
+    /**
+     * 是否为封面图。
+     */
+    @Schema(description = "是否为封面图。")
+    private Integer cover;
 }

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

@@ -6,6 +6,7 @@ import com.tourism.common.core.util.MyCommonUtil;
 import com.tourism.common.core.upload.UploadStoreTypeEnum;
 import com.tourism.common.core.annotation.*;
 import com.tourism.common.core.base.model.BaseModel;
+import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
@@ -118,4 +119,16 @@ public class TourUser extends BaseModel {
             dictCode = "UserSex")
     @TableField(exist = false)
     private Map<String, Object> sexDictMap;
+
+    /**
+     *  住址
+     */
+    @TableField(value = "address")
+    private String address;
+
+    /**
+     *  职业
+     */
+    @TableField(value = "job")
+    private String job;
 }

+ 8 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourUserLikeTravelNotes.java

@@ -1,6 +1,7 @@
 package com.tourism.webadmin.back.model;
 
 import com.baomidou.mybatisplus.annotation.*;
+import com.tourism.common.core.annotation.RelationOneToOne;
 import com.tourism.common.core.base.model.BaseModel;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -40,4 +41,11 @@ public class TourUserLikeTravelNotes extends BaseModel {
     @TableLogic
     @TableField(value = "data_state")
     private Integer dataState;
+
+    @RelationOneToOne(
+            masterIdField = "travelNotesId",
+            slaveModelClass = TourismProjectTravelNotesWrite.class,
+            slaveIdField = "id")
+    @TableField(exist = false)
+    private TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite;
 }

+ 117 - 21
application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourismProjectTravelNotesWrite.java

@@ -1,15 +1,15 @@
 package com.tourism.webadmin.back.model;
 
 import com.baomidou.mybatisplus.annotation.*;
-import com.tourism.webadmin.back.model.constant.AuditState;
+import com.tourism.webadmin.back.model.constant.*;
 import com.tourism.common.core.util.MyCommonUtil;
 import com.tourism.common.core.upload.UploadStoreTypeEnum;
 import com.tourism.common.core.annotation.*;
 import com.tourism.common.core.base.model.BaseModel;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
+import lombok.*;
 
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -78,11 +78,11 @@ public class TourismProjectTravelNotesWrite extends BaseModel {
     private String reason;
 
     /**
-     * 项目展示图片
+     * 发布游记的banner图
      */
     @UploadFlagColumn(storeType = UploadStoreTypeEnum.HUAWEI_OBS_SYSTEM)
-    @TableField(value = "tourism_url")
-    private String tourismUrl;
+    @TableField(value = "travel_notes_banner")
+    private String travelNotesBanner;
 
     /**
      * 逻辑删除标记字段(1: 正常 -1: 已删除)。
@@ -98,11 +98,78 @@ public class TourismProjectTravelNotesWrite extends BaseModel {
     @TableField(value = "tourism_tavel_notes_url")
     private String tourismTavelNotesUrl;
 
-//    /**
-//     * 是否完成(0,草稿;1,成稿)。
-//     */
-//    @TableField(value = "is_complete")
-//    private Integer isComplete;
+    /**
+     * 上下架状态(0,下架;1,上架)。
+     */
+    @TableField(value = "unmount_state")
+    private Integer unmountState;
+
+    /**
+     * 项目展示图片。
+     */
+    @UploadFlagColumn(storeType = UploadStoreTypeEnum.HUAWEI_OBS_SYSTEM)
+    @TableField(value = "tourism_url")
+    private String tourismUrl;
+
+    /**
+     * 项目简述。
+     */
+    @TableField(value = "remarks")
+    private String remarks;
+
+    /**
+     * 是否热点,0非热点,1热点。
+     */
+    @TableField(value = "is_hotspot")
+    private Integer isHotspot;
+
+    /**
+     * 标签。
+     */
+    @TableField(value = "note_label")
+    private String noteLabel;
+
+    /**
+     * 点赞数。
+     */
+    @TableField(value = "like_count")
+    private Integer likeCount;
+
+    /**
+     * 浏览量。
+     */
+    @TableField(value = "page_view_count")
+    private Integer pageViewCount;
+
+    /**
+     * 热度值。
+     */
+    @TableField(value = "hot_value")
+    private Integer hotValue;
+
+    /**
+     * 是否原创(0:非原创;1:原创)。
+     */
+    @TableField(value = "is_original")
+    private Integer isOriginal;
+
+    /**
+     * 目的地。
+     */
+    @TableField(value = "end_place")
+    private Long endPlace;
+
+    /**
+     * 自动审核结果1:通过,2未通过。
+     */
+    @TableField(value = "auto_audit_status")
+    private Integer autoAuditStatus;
+
+    /**
+     * 自动审核未通过原因。
+     */
+    @TableField(value = "auto_reject_reason")
+    private String autoRejectReason;
 
     /**
      * departureTime 范围过滤起始值(>=)。
@@ -138,12 +205,13 @@ public class TourismProjectTravelNotesWrite extends BaseModel {
         this.searchString = MyCommonUtil.replaceSqlWildcard(searchString);
     }
 
-    @RelationOneToOne(
-            masterIdField = "id",
-            slaveModelClass = TourismTravelNotesContentWrite.class,
-            slaveIdField = "associationId")
+    @RelationDict(
+            masterIdField = "endPlace",
+            slaveModelClass = DirectoryInfo.class,
+            slaveIdField = "id",
+            slaveNameField = "menuName")
     @TableField(exist = false)
-    private TourismTravelNotesContentWrite tourismTravelNotesContentWrite;
+    private Map<String, Object> endPlaceDictMap;
 
     @RelationConstDict(
             masterIdField = "state",
@@ -151,9 +219,37 @@ public class TourismProjectTravelNotesWrite extends BaseModel {
     @TableField(exist = false)
     private Map<String, Object> stateDictMap;
 
-//    @RelationConstDict(
-//            masterIdField = "isComplete",
-//            constantDictClass = IsComplete.class)
-//    @TableField(exist = false)
-//    private Map<String, Object> isCompleteDictMap;
+    @RelationOneToMany(
+            masterIdField = "id",
+            slaveModelClass = TourismTravelNotesContentWrite.class,
+            slaveIdField = "associationId")
+    @TableField(exist = false)
+    private List<TourismTravelNotesContentWrite> travelNotesContent;
+
+    @RelationConstDict(
+            masterIdField = "unmountState",
+            constantDictClass = UnmountState.class)
+    @TableField(exist = false)
+    private Map<String, Object> unmountStateDictMap;
+
+    @RelationConstDict(
+            masterIdField = "isHotspot",
+            constantDictClass = Hotspot.class)
+    @TableField(exist = false)
+    private Map<String, Object> isHotspotDictMap;
+
+    @RelationConstDict(
+            masterIdField = "isOriginal",
+            constantDictClass = IsOriginal.class)
+    @TableField(exist = false)
+    private Map<String, Object> isOriginalDictMap;
+
+    @TableField(exist = false)
+    private List<Long> directoryInfoIds;
+
+    @RelationConstDict(
+            masterIdField = "autoAuditStatus",
+            constantDictClass = AudioState.class)
+    @TableField(exist = false)
+    private Map<String, Object> autoAuditStatusDictMap;
 }

+ 18 - 6
application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourismTravelNotesContentWrite.java

@@ -23,12 +23,6 @@ public class TourismTravelNotesContentWrite extends BaseModel {
     private Long id;
 
     /**
-     * 富文本内容。
-     */
-    @TableField(value = "content")
-    private String content;
-
-    /**
      * 关联表id。
      */
     @TableField(value = "association_id")
@@ -40,4 +34,22 @@ public class TourismTravelNotesContentWrite extends BaseModel {
     @TableLogic
     @TableField(value = "data_state")
     private Integer dataState;
+
+    /**
+     * 类型。
+     */
+    @TableField(value = "type")
+    private String type;
+
+    /**
+     * 内容。
+     */
+    @TableField(value = "content")
+    private String content;
+
+    /**
+     * 是否为封面图。
+     */
+    @TableField(value = "cover")
+    private Integer cover;
 }

+ 44 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/constant/AudioState.java

@@ -0,0 +1,44 @@
+package com.tourism.webadmin.back.model.constant;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 自动审核状态常量字典对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public final class AudioState {
+
+    /**
+     * 自动审核通过。
+     */
+    public static final int AGREE = 1;
+    /**
+     * 自动审核未通过。
+     */
+    public static final int REJECT = 2;
+
+    private static final Map<Object, String> DICT_MAP = new HashMap<>(2);
+    static {
+        DICT_MAP.put(AGREE, "自动审核通过");
+        DICT_MAP.put(REJECT, "自动审核未通过");
+    }
+
+    /**
+     * 判断参数是否为当前常量字典的合法值。
+     *
+     * @param value 待验证的参数值。
+     * @return 合法返回true,否则false。
+     */
+    public static boolean isValid(Integer value) {
+        return value != null && DICT_MAP.containsKey(value);
+    }
+
+    /**
+     * 私有构造函数,明确标识该常量类的作用。
+     */
+    private AudioState() {
+    }
+}

+ 11 - 6
application-webadmin/src/main/java/com/tourism/webadmin/back/model/constant/AuditState.java

@@ -12,23 +12,28 @@ import java.util.Map;
 public final class AuditState {
 
     /**
-     * 审核。
+     * 审核。
      */
-    public static final int UNAUDITSTATE = 0;
+    public static final int UNAUDITSTATE = 1;
     /**
      * 审核未通过。
      */
-    public static final int FAILAUDIT = 1;
+    public static final int FAILAUDIT = 2;
     /**
      * 审核通过。
      */
-    public static final int SUCCEEDAUDIT = 2;
+    public static final int SUCCEEDAUDIT = 3;
+    /**
+     * 草稿。
+     */
+    public static final int DRAFT = 0;
 
-    private static final Map<Object, String> DICT_MAP = new HashMap<>(3);
+    private static final Map<Object, String> DICT_MAP = new HashMap<>(4);
     static {
-        DICT_MAP.put(UNAUDITSTATE, "未审核");
+        DICT_MAP.put(UNAUDITSTATE, "审核");
         DICT_MAP.put(FAILAUDIT, "审核未通过");
         DICT_MAP.put(SUCCEEDAUDIT, "审核通过");
+        DICT_MAP.put(DRAFT, "草稿");
     }
 
     /**

+ 44 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/constant/IsOriginal.java

@@ -0,0 +1,44 @@
+package com.tourism.webadmin.back.model.constant;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 是否原创常量字典对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public final class IsOriginal {
+
+    /**
+     * 非原创。
+     */
+    public static final int NOT_ORIGINAL = 0;
+    /**
+     * 原创。
+     */
+    public static final int ORIGINAL = 1;
+
+    private static final Map<Object, String> DICT_MAP = new HashMap<>(2);
+    static {
+        DICT_MAP.put(NOT_ORIGINAL, "非原创");
+        DICT_MAP.put(ORIGINAL, "原创");
+    }
+
+    /**
+     * 判断参数是否为当前常量字典的合法值。
+     *
+     * @param value 待验证的参数值。
+     * @return 合法返回true,否则false。
+     */
+    public static boolean isValid(Integer value) {
+        return value != null && DICT_MAP.containsKey(value);
+    }
+
+    /**
+     * 私有构造函数,明确标识该常量类的作用。
+     */
+    private IsOriginal() {
+    }
+}

+ 44 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/constant/UnmountState.java

@@ -0,0 +1,44 @@
+package com.tourism.webadmin.back.model.constant;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 上下架状态常量字典对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public final class UnmountState {
+
+    /**
+     * 下架。
+     */
+    public static final int DELIST = 0;
+    /**
+     * 上架。
+     */
+    public static final int LISTING = 1;
+
+    private static final Map<Object, String> DICT_MAP = new HashMap<>(2);
+    static {
+        DICT_MAP.put(DELIST, "下架");
+        DICT_MAP.put(LISTING, "上架");
+    }
+
+    /**
+     * 判断参数是否为当前常量字典的合法值。
+     *
+     * @param value 待验证的参数值。
+     * @return 合法返回true,否则false。
+     */
+    public static boolean isValid(Integer value) {
+        return value != null && DICT_MAP.containsKey(value);
+    }
+
+    /**
+     * 私有构造函数,明确标识该常量类的作用。
+     */
+    private UnmountState() {
+    }
+}

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

@@ -65,4 +65,15 @@ public interface TourUserLikeTravelNotesService extends IBaseService<TourUserLik
      * @return 查询结果集。
      */
     List<TourUserLikeTravelNotes> getTourUserLikeTravelNotesListWithRelation(TourUserLikeTravelNotes filter, String orderBy);
+
+    /**
+     * 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
+     * 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
+     * 如果仅仅需要获取主表数据,请移步(getTourUserLikeTravelNotesList),以便获取更好的查询性能。
+     *
+     * @param filter 主表过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<TourismProjectTravelNotesWrite> getTourUserLikeTravelNotesWithRelationWriteList(TourUserLikeTravelNotes filter,Integer unmountState, String orderBy);
 }

+ 24 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/TourismProjectTravelNotesWriteService.java

@@ -1,5 +1,6 @@
 package com.tourism.webadmin.back.service;
 
+import com.alibaba.fastjson.JSONObject;
 import com.tourism.webadmin.back.model.*;
 import com.tourism.common.core.base.service.IBaseService;
 
@@ -29,6 +30,15 @@ public interface TourismProjectTravelNotesWriteService extends IBaseService<Tour
     void saveNewBatch(List<TourismProjectTravelNotesWrite> tourismProjectTravelNotesWriteList);
 
     /**
+     * 保存新增主表对象及关联对象。
+     *
+     * @param tourismProjectTravelNotesWrite 新增主表对象。
+     * @param relationData 全部关联从表数据。
+     * @return 返回新增主表对象。
+     */
+    TourismProjectTravelNotesWrite saveNewWithRelation(TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite, JSONObject relationData);
+
+    /**
      * 更新数据对象。
      *
      * @param tourismProjectTravelNotesWrite         更新的对象。
@@ -38,6 +48,16 @@ public interface TourismProjectTravelNotesWriteService extends IBaseService<Tour
     boolean update(TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite, TourismProjectTravelNotesWrite originalTourismProjectTravelNotesWrite);
 
     /**
+     * 更新主表对象及关联对象。
+     *
+     * @param tourismProjectTravelNotesWrite 主表对象新数据。
+     * @param originalTourismProjectTravelNotesWrite 主表对象源数据。
+     * @param relationData 全部关联从表数据。
+     * @return 修改成功返回true,否则false。
+     */
+    boolean updateWithRelation(TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite, TourismProjectTravelNotesWrite originalTourismProjectTravelNotesWrite, JSONObject relationData);
+
+    /**
      * 删除指定数据。
      *
      * @param id 主键Id。
@@ -65,4 +85,8 @@ public interface TourismProjectTravelNotesWriteService extends IBaseService<Tour
      * @return 查询结果集。
      */
     List<TourismProjectTravelNotesWrite> getTourismProjectTravelNotesWriteListWithRelation(TourismProjectTravelNotesWrite filter, String orderBy);
+
+    List<TourismTravelNotesContentWrite> parseHTML(TourTourismTravelNotesContent entity);
+
+    Integer audit(TourismProjectTravelNotesWrite enrity);
 }

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

@@ -93,6 +93,16 @@ public class TourUserLikeTravelNotesServiceImpl extends BaseService<TourUserLike
         return resultList;
     }
 
+    @Override
+    public List<TourismProjectTravelNotesWrite> getTourUserLikeTravelNotesWithRelationWriteList(TourUserLikeTravelNotes filter,Integer unmountState, String orderBy) {
+        List<TourismProjectTravelNotesWrite> resultList = tourUserLikeTravelNotesMapper.getTourUserLikeTravelNotesWithRelationWriteList(filter, unmountState, orderBy);
+        // 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
+        // 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
+//        int batchSize = resultList instanceof Page ? 0 : 1000;
+//        this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
+        return resultList;
+    }
+
     private TourUserLikeTravelNotes buildDefaultValue(TourUserLikeTravelNotes tourUserLikeTravelNotes) {
         if (tourUserLikeTravelNotes.getId() == null) {
             tourUserLikeTravelNotes.setId(idGenerator.nextLongId());

+ 80 - 4
application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourismProjectTravelNotesWriteServiceImpl.java

@@ -1,13 +1,12 @@
 package com.tourism.webadmin.back.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.tourism.webadmin.back.model.constant.AuditState;
 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;
@@ -16,6 +15,10 @@ 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.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -67,6 +70,14 @@ public class TourismProjectTravelNotesWriteServiceImpl extends BaseService<Touri
 
     @Transactional(rollbackFor = Exception.class)
     @Override
+    public TourismProjectTravelNotesWrite saveNewWithRelation(TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite, JSONObject relationData) {
+        this.saveNew(tourismProjectTravelNotesWrite);
+        this.saveOrUpdateOneToOneRelationData(tourismProjectTravelNotesWrite, relationData);
+        return tourismProjectTravelNotesWrite;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
     public boolean update(TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite, TourismProjectTravelNotesWrite originalTourismProjectTravelNotesWrite) {
         MyModelUtil.fillCommonsForUpdate(tourismProjectTravelNotesWrite, originalTourismProjectTravelNotesWrite);
         // 这里重点提示,在执行主表数据更新之前,如果有哪些字段不支持修改操作,请用原有数据对象字段替换当前数据字段。
@@ -76,6 +87,28 @@ public class TourismProjectTravelNotesWriteServiceImpl extends BaseService<Touri
 
     @Transactional(rollbackFor = Exception.class)
     @Override
+    public boolean updateWithRelation(
+            TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite, TourismProjectTravelNotesWrite originalTourismProjectTravelNotesWrite, JSONObject relationData) {
+        // tourismProjectTravelNotesWrite 为空的时候,无需修改主表数据。
+        if (tourismProjectTravelNotesWrite != null && !this.update(tourismProjectTravelNotesWrite, originalTourismProjectTravelNotesWrite)) {
+            return false;
+        }
+        this.saveOrUpdateOneToOneRelationData(originalTourismProjectTravelNotesWrite, relationData);
+        return true;
+    }
+
+    private void saveOrUpdateOneToOneRelationData(TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite, JSONObject relationData) {
+        // 对于一对一新增或更新,如果主键值为空就新增,否则就更新,同时更新updateTime和updateUserId。
+        TourismTravelNotesContentWrite tourismTravelNotesContentWrite = relationData.getObject("tourismTravelNotesContentWrite", TourismTravelNotesContentWrite.class);
+        if (tourismTravelNotesContentWrite != null) {
+            tourismTravelNotesContentWrite.setAssociationId(tourismProjectTravelNotesWrite.getId());
+            tourismTravelNotesContentWriteService.saveNewOrUpdate(tourismTravelNotesContentWrite,
+                    tourismTravelNotesContentWriteService::saveNew, tourismTravelNotesContentWriteService::update);
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
     public boolean remove(Long id) {
         if (tourismProjectTravelNotesWriteMapper.deleteById(id) == 0) {
             return false;
@@ -99,6 +132,49 @@ public class TourismProjectTravelNotesWriteServiceImpl extends BaseService<Touri
         return resultList;
     }
 
+    @Override
+    public List<TourismTravelNotesContentWrite> parseHTML(TourTourismTravelNotesContent entity) {
+        List<TourismTravelNotesContentWrite> notes = new ArrayList<>();
+        Document doc = Jsoup.parse(entity.getContent());
+
+        // 获取所有的<p>标签
+        Elements paragraphs = doc.select("p");
+
+        for (Element p : paragraphs) {
+            TourismTravelNotesContentWrite content = new TourismTravelNotesContentWrite();
+
+            content.setAssociationId(Long.parseLong(entity.getAssociationId()));
+            content.setCreateUserId(entity.getCreateUserId());
+            content.setCreateTime(entity.getCreateTime());
+            content.setUpdateTime(entity.getUpdateTime());
+            content.setUpdateUserId(entity.getUpdateUserId());
+            content.setDataState(entity.getDataState());
+
+            // 提取文本内容
+            String textContent = p.text();
+            if (!textContent.trim().isEmpty()) {
+                content.setType("sectionContent");
+                content.setContent(textContent);
+            }
+
+            // 提取图片URL
+            Element img = p.selectFirst("img");
+            if (img != null) {
+                content.setType("image");
+                String imageUrl = img.attr("src");
+                content.setContent(imageUrl);
+            }
+            notes.add(content);
+        }
+
+        return notes;
+    }
+
+    @Override
+    public Integer audit(TourismProjectTravelNotesWrite enrity) {
+        return tourismProjectTravelNotesWriteMapper.auditTravelNote(enrity);
+    }
+
     private TourismProjectTravelNotesWrite buildDefaultValue(TourismProjectTravelNotesWrite tourismProjectTravelNotesWrite) {
         if (tourismProjectTravelNotesWrite.getId() == null) {
             tourismProjectTravelNotesWrite.setId(idGenerator.nextLongId());
@@ -106,9 +182,9 @@ public class TourismProjectTravelNotesWriteServiceImpl extends BaseService<Touri
         MyModelUtil.fillCommonsForInsert(tourismProjectTravelNotesWrite);
         tourismProjectTravelNotesWrite.setDataState(GlobalDeletedFlag.NORMAL);
         MyModelUtil.setDefaultValue(tourismProjectTravelNotesWrite, "reason", "");
-        MyModelUtil.setDefaultValue(tourismProjectTravelNotesWrite, "tourismUrl", "");
+        MyModelUtil.setDefaultValue(tourismProjectTravelNotesWrite, "travelNotesBanner", "");
         MyModelUtil.setDefaultValue(tourismProjectTravelNotesWrite, "tourismTavelNotesUrl", "");
-        MyModelUtil.setDefaultValue(tourismProjectTravelNotesWrite, "state", AuditState.UNAUDITSTATE);
+        MyModelUtil.setDefaultValue(tourismProjectTravelNotesWrite, "state", AuditState.DRAFT);
         return tourismProjectTravelNotesWrite;
     }
 }

+ 2 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/service/impl/TourismTravelNotesContentWriteServiceImpl.java

@@ -1,8 +1,10 @@
 package com.tourism.webadmin.back.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.*;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.tourism.common.sequence.wrapper.IdGeneratorWrapper;
 import com.tourism.webadmin.back.service.*;
 import com.tourism.webadmin.back.dao.*;
 import com.tourism.webadmin.back.model.*;

+ 16 - 10
application-webadmin/src/main/java/com/tourism/webadmin/back/util/SMSUtils.java

@@ -1,34 +1,40 @@
 package com.tourism.webadmin.back.util;
 
 import com.alibaba.fastjson.JSON;
+import com.tourism.webadmin.config.SmsSwitch;
 import com.volcengine.model.request.SmsSendRequest;
 import com.volcengine.model.response.SmsSendResponse;
 import com.volcengine.service.sms.SmsService;
 import com.volcengine.service.sms.SmsServiceInfoConfig;
 import com.volcengine.service.sms.impl.SmsServiceImpl;
 import org.apache.commons.lang3.StringUtils;
+import org.checkerframework.checker.units.qual.A;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 import java.util.HashMap;
 import java.util.Map;
 
+@Service
 public class SMSUtils {
-    private static final String AK = "AKLTYzA3ZDNiY2M5MWNlNGM1NThhM2ZlN2JhNTIyYWMxZDA";
 
-    private static final String SK = "WXpVME1USTBNbVprTnpKaU5HTTNORGhsT1dJNU1tUXlaVFl4TjJVeE1Uaw==";
+    @Autowired
+    private SmsSwitch smsSwitch;
 
-    private static SmsService smsService = SmsServiceImpl.getInstance(new SmsServiceInfoConfig(AK, SK));
+    private static SmsService smsService;
+
+    public void sendMsg(String countryCode, String phoneNumber, String code){
+        smsService = SmsServiceImpl.getInstance(new SmsServiceInfoConfig(smsSwitch.getAK(), smsSwitch.getSK()));
 
-    public static void sendMsg(String countryCode, String phoneNumber, String code){
         SmsSendRequest req = new SmsSendRequest();
         req.setPhoneNumbers(countryCode.replaceAll("\\+", "") + phoneNumber);
+        req.setSmsAccount(smsSwitch.getSmsAccount());
         if(countryCode.equals("86") || StringUtils.isBlank(countryCode)){
-            req.setSmsAccount("7fe76339");
-            req.setTemplateId("ST_7fe71e56");
-            req.setSign("山东老韩国际人才合作");
+            req.setTemplateId(smsSwitch.getChinaTemplateId());
+            req.setSign(smsSwitch.getChinaSign());
         }else {
-            req.setSmsAccount("7fe76339");
-            req.setTemplateId("ST_7fe70c7c");
-            req.setSign("XYTravel");
+            req.setTemplateId(smsSwitch.getOtherTemplateId());
+            req.setSign(smsSwitch.getOtherSign());
         }
 
         Map<String,String> param = new HashMap<>();

+ 8 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourUserLikeTravelNotesVo.java

@@ -5,6 +5,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import java.util.Map;
+
 /**
  * 用户游记点赞表VO视图对象。
  *
@@ -33,4 +35,10 @@ public class TourUserLikeTravelNotesVo extends BaseVo {
      */
     @Schema(description = "游记id")
     private Long travelNotesId;
+
+    /**
+     * tourismProjectTravelNotesWrite 的一对一关联数据对象,数据对应类型为TourismProjectTravelNotesWriteVo。
+     */
+    @Schema(description = "tourismProjectTravelNotesWrite 的一对一关联数据对象,数据对应类型为TourismProjectTravelNotesWrite")
+    private Map<String, Object> tourismProjectTravelNotesWrite;
 }

+ 12 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourUserVo.java

@@ -96,4 +96,16 @@ public class TourUserVo extends BaseVo {
      */
     @Schema(description = "国家代码")
     private String countryCode;
+
+    /**
+     *  住址
+     */
+    @Schema(description = "住址")
+    private String address;
+
+    /**
+     *  职业
+     */
+    @Schema(description = "职业")
+    private String job;
 }

+ 117 - 18
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourismProjectTravelNotesWriteVo.java

@@ -1,11 +1,14 @@
 package com.tourism.webadmin.back.vo;
 
 import com.tourism.common.core.base.vo.BaseVo;
+import com.tourism.webadmin.back.model.TourismTravelNotesContentWrite;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import java.time.LocalDate;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -23,7 +26,7 @@ public class TourismProjectTravelNotesWriteVo extends BaseVo {
      * 主键id。
      */
     @Schema(description = "主键id")
-    private Long id;
+    private String id;
 
     /**
      * 项目标题。
@@ -35,7 +38,7 @@ public class TourismProjectTravelNotesWriteVo extends BaseVo {
      * 出发时间。
      */
     @Schema(description = "出发时间")
-    private Date departureTime;
+    private LocalDate departureTime;
 
     /**
      * 总天数。
@@ -74,10 +77,10 @@ public class TourismProjectTravelNotesWriteVo extends BaseVo {
     private String reason;
 
     /**
-     * 项目展示图片
+     * 发布游记的banner图
      */
-    @Schema(description = "项目展示图片")
-    private String tourismUrl;
+    @Schema(description = "发布游记的banner图")
+    private String travelNotesBanner;
 
     /**
      * 游记内容中的图片。
@@ -85,17 +88,83 @@ public class TourismProjectTravelNotesWriteVo extends BaseVo {
     @Schema(description = "游记内容中的图片")
     private String tourismTavelNotesUrl;
 
-//    /**
-//     * 是否完成(0,草稿;1,成稿)。
-//     */
-//    @Schema(description = "是否完成(0,草稿;1,成稿)")
-//    private Integer isComplete;
+    /**
+     * 上下架状态(0,下架;1,上架)。
+     */
+    @Schema(description = "上下架状态(0,下架;1,上架)")
+    private Integer unmountState;
+
+    /**
+     * 项目展示图片。
+     */
+    @Schema(description = "项目展示图片")
+    private String tourismUrl;
+
+    /**
+     * 项目简述。
+     */
+    @Schema(description = "项目简述")
+    private String remarks;
+
+    /**
+     * 是否热点,0非热点,1热点。
+     */
+    @Schema(description = "是否热点,0非热点,1热点")
+    private Integer isHotspot;
+
+    /**
+     * 标签。
+     */
+    @Schema(description = "标签")
+    private String noteLabel;
+
+    /**
+     * 点赞数。
+     */
+    @Schema(description = "点赞数")
+    private Integer likeCount;
+
+    /**
+     * 浏览量。
+     */
+    @Schema(description = "浏览量")
+    private Integer pageViewCount;
+
+    /**
+     * 热度值。
+     */
+    @Schema(description = "热度值")
+    private Integer hotValue;
+
+    /**
+     * 是否原创(0:非原创;1:原创)。
+     */
+    @Schema(description = "是否原创(0:非原创;1:原创)")
+    private Integer isOriginal;
+
+    /**
+     * 目的地。
+     */
+    @Schema(description = "目的地")
+    private String endPlace;
+
+    /**
+     * 自动审核结果1:通过,2未通过。
+     */
+    @Schema(description = "自动审核结果1:通过,2未通过")
+    private Integer autoAuditStatus;
 
     /**
-     * id 的一对一关联数据对象,数据对应类型为TourismTravelNotesContentWriteVo。
+     * 自动审核未通过原因
      */
-    @Schema(description = "id 的一对一关联数据对象,数据对应类型为TourismTravelNotesContentWriteVo")
-    private Map<String, Object> tourismTravelNotesContentWrite;
+    @Schema(description = "自动审核未通过原因")
+    private String autoRejectReason;
+
+    /**
+     * endPlace 字典关联数据。
+     */
+    @Schema(description = "endPlace 字典关联数据")
+    private Map<String, Object> endPlaceDictMap;
 
     /**
      * state 常量字典关联数据。
@@ -103,9 +172,39 @@ public class TourismProjectTravelNotesWriteVo extends BaseVo {
     @Schema(description = "state 常量字典关联数据")
     private Map<String, Object> stateDictMap;
 
-//    /**
-//     * isComplete 常量字典关联数据。
-//     */
-//    @Schema(description = "isComplete 常量字典关联数据")
-//    private Map<String, Object> isCompleteDictMap;
+    /**
+     * tourismProjectTravelNotesContentDraft 游记内容。
+     */
+    @Schema(description = "tourismProjectTravelNotesContentDraft 游记内容")
+    private List<TourismTravelNotesContentWriteVo> travelNotesContent;
+
+    /**
+     * isHotspot 常量字典关联数据。
+     */
+    @Schema(description = "isHotspot 常量字典关联数据")
+    private Map<String, Object> isHotspotDictMap;
+
+    /**
+     * isOriginal 常量字典关联数据。
+     */
+    @Schema(description = "isOriginal 常量字典关联数据")
+    private Map<String, Object> isOriginalDictMap;
+
+    @Schema(description = "热门图url转换")
+    private List<String> homeHotPicturesAfterConvert;
+
+    @Schema(description = "游记列表图url转换")
+    private List<String> tourismUrlsAfterConvert;
+
+    @Schema(description = "联系人图片")
+    private String contactCodeConvert;
+
+    @Schema(description = "联系人图片")
+    private List<String> travelNotesBannerAfterConvert;
+
+    /**
+     * autoAuditStatus 常量字典关联数据。
+     */
+    @Schema(description = "autoAuditStatus 常量字典关联数据")
+    private Map<String, Object> autoAuditStatusDictMap;
 }

+ 18 - 6
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourismTravelNotesContentWriteVo.java

@@ -20,17 +20,29 @@ public class TourismTravelNotesContentWriteVo extends BaseVo {
      * 主键id。
      */
     @Schema(description = "主键id")
-    private Long id;
+    private String id;
 
     /**
-     * 富文本内容。
+     * 关联表id。
+     */
+    @Schema(description = "关联表id")
+    private Long associationId;
+
+    /**
+     * 类型。
      */
-    @Schema(description = "富文本内容")
+    @Schema(description = "类型")
+    private String type;
+
+    /**
+     * 内容。
+     */
+    @Schema(description = "内容")
     private String content;
 
     /**
-     * 关联表id。
+     * 是否为封面图
      */
-    @Schema(description = "关联表id")
-    private Long associationId;
+    @Schema(description = "是否为封面图")
+    private Integer cover;
 }

+ 38 - 0
application-webadmin/src/main/java/com/tourism/webadmin/config/SmsSwitch.java

@@ -0,0 +1,38 @@
+package com.tourism.webadmin.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "sms.blends.huoshan")
+public class SmsSwitch {
+    private String aK;
+
+    private String sK;
+    /**
+     * 短信开关
+     */
+    private boolean enable;
+    /**
+     * 短信账号
+     */
+    private String smsAccount;
+    /**
+     * 国内签名
+     */
+    private String chinaSign;
+    /**
+     * 国外签名
+     */
+    private String otherSign;
+    /**
+     * 国内模板ID
+     */
+    private String chinaTemplateId;
+    /**
+     * 国外模板ID
+     */
+    private String otherTemplateId;
+}

+ 0 - 233
application-webadmin/src/main/resources/application-dev.yml

@@ -1,233 +0,0 @@
-spring:
-  data:
-    redis:
-      host: localhost
-      port: 6379
-  datasource:
-    type: com.alibaba.druid.pool.DruidDataSource
-    druid:
-      # 数据库链接 [主数据源]
-      main:
-        url: jdbc:mysql://62.234.11.186:3306/tourism?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
-        username: root
-        password: Lm8458!23
-      # 默认生成的操作日志数据源配置。
-      operation-log:
-        url: jdbc:mysql://62.234.11.186:3306/tourism?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
-        username: root
-        password: Lm8458!23
-      # 默认生成的全局编码字典数据源配置。
-      global-dict:
-        url: jdbc:mysql://62.234.11.186:3306/tourism?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
-        username: root
-        password: Lm8458!23
-      # 默认生成的工作流及在线表单数据源配置。
-      common-flow-online:
-        url: jdbc:mysql://62.234.11.186:3306/tourism?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
-        username: root
-        password: Lm8458!23
-      # 默认生成的统计打印模块的数据源配置。
-      common-report:
-        url: jdbc:mysql://62.234.11.186:3306/tourism?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
-        username: root
-        password: Lm8458!23
-      driverClassName: com.mysql.cj.jdbc.Driver
-      name: application-webadmin
-      initialSize: 10
-      minIdle: 10
-      maxActive: 50
-      maxWait: 60000
-      timeBetweenEvictionRunsMillis: 60000
-      minEvictableIdleTimeMillis: 300000
-      poolPreparedStatements: true
-      maxPoolPreparedStatementPerConnectionSize: 20
-      maxOpenPreparedStatements: 20
-      validationQuery: SELECT 'x'
-      testWhileIdle: true
-      testOnBorrow: false
-      testOnReturn: false
-      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
-      filters: stat,wall
-      useGlobalDataSourceStat: true
-      web-stat-filter:
-        enabled: true
-        url-pattern: /*
-        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*,/actuator/*"
-      stat-view-servlet:
-        enabled: true
-        urlPattern: /druid/*
-        resetEnable: true
-
-application:
-  # 初始化密码。
-  defaultUserPassword: 123456
-  # 缺省的文件上传根目录。
-  uploadFileBaseDir: ./zz-resource/upload-files/app
-  # 跨域的IP(http://192.168.10.10:8086)白名单列表,多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
-  credentialIpList: "*"
-  # Session的用户和数据权限在Redis中的过期时间(秒)。一定要和sa-token.timeout
-  sessionExpiredSeconds: 86400
-  # 是否排他登录。
-  excludeLogin: false
-  hostIpPort: http://v.xiaoyaotravel.com
-
-# 这里仅仅是一个第三方配置的示例,如果没有接入斯三方系统,
-# 这里的配置项也不会影响到系统的行为,如果觉得多余,也可以手动删除。
-third-party:
-  # 第三方系统接入的用户鉴权配置。
-  auth:
-  - appCode: orange-forms-default
-    # 访问第三方系统接口的URL前缀,橙单会根据功能添加接口路径的其余部分,
-    # 比如获取用户Token的接口 http://localhost:8083/orangePluginTest/getTokenData
-    baseUrl: http://localhost:8083/orangePlugin
-    # 第三方应用鉴权的HTTP请求令牌头的KEY。
-    tokenHeaderKey: Authorization
-    # 第三方返回的用户Token数据的缓存过期时长,单位秒。
-    # 如果为0,则不缓存,每次涉及第三方的请求,都会发出http请求,交由第三方验证,这样对系统性能会有影响。
-    tokenExpiredSeconds: 60
-    # 第三方返回的权限数据的缓存过期时长,单位秒。
-    permExpiredSeconds: 86400
-
-# 这里仅仅是一个第三方配置的示例,如果没有接入斯三方系统,
-# 这里的配置项也不会影响到系统的行为,如果觉得多余,也可以手动删除。
-common-ext:
-  urlPrefix: /admin/commonext
-  # 这里可以配置多个第三方应用,这里的应用数量,通常会和上面third-party.auth的配置数量一致。
-  apps:
-    # 应用唯一编码,尽量不要使用中文。
-  - appCode: orange-forms-default
-    # 业务组件的数据源配置。
-    bizWidgetDatasources:
-    # 组件的类型,多个类型之间可以逗号分隔。
-    - types: upms_user,upms_dept
-      # 组件获取列表数据的接口地址。
-      listUrl: http://localhost:8083/orangePlugin/listBizWidgetData
-      # 组件获取详情数据的接口地址。
-      viewUrl: http://localhost:8083/orangePlugin/viewBizWidgetData
-
-common-sequence:
-  # Snowflake 分布式Id生成算法所需的WorkNode参数值。
-  snowflakeWorkNode: 1
-
-# 存储session数据的Redis,所有服务均需要,因此放到公共配置中。
-# 根据实际情况,该Redis也可以用于存储其他数据。
-common-redis:
-  # redisson的配置。每个服务可以自己的配置文件中覆盖此选项。
-  redisson:
-    # 如果该值为false,系统将不会创建RedissionClient的bean。
-    enabled: true
-    # mode的可用值为,single/cluster/sentinel/master-slave
-    mode: single
-    # single: 单机模式
-    #   address: redis://localhost:6379
-    # cluster: 集群模式
-    #   每个节点逗号分隔,同时每个节点前必须以redis://开头。
-    #   address: redis://localhost:6379,redis://localhost:6378,...
-    # sentinel:
-    #   每个节点逗号分隔,同时每个节点前必须以redis://开头。
-    #   address: redis://localhost:6379,redis://localhost:6378,...
-    # master-slave:
-    #   每个节点逗号分隔,第一个为主节点,其余为从节点。同时每个节点前必须以redis://开头。
-    #   address: redis://localhost:6379,redis://localhost:6378,...
-    address: redis://localhost:6379
-    # 链接超时,单位毫秒。
-    timeout: 6000
-    # 单位毫秒。分布式锁的超时检测时长。
-    # 如果一次锁内操作超该毫秒数,或在释放锁之前异常退出,Redis会在该时长之后主动删除该锁使用的key。
-    lockWatchdogTimeout: 60000
-    # redis 密码,空可以不填。
-    password:
-    pool:
-      # 连接池数量。
-      poolSize: 20
-      # 连接池中最小空闲数量。
-      minIdle: 5
-
-common-report:
-  # 注意不要以反斜杠(/)结尾。
-  urlPrefix: /admin/report
-  # 统计打印表单业务数据上传资源路径
-  uploadFileBaseDir: ./zz-resource/upload-files/report
-  # 如果为false,报表模块的所有Controller中的接口将不能使用。
-  operationEnabled: true
-  # 该配置项仅当打印模板中,打印图片字段时,才会需要。
-  # 这里的url配置只是一个示例,并不能保证开箱即用,代码示例和说明可参考common-report模块
-  # example包内的ReportExampleController中的代码和详细说明。
-  imageDownloadUrl: "http://localhost:8082/admin/report/example/downloadDirectly"
-  # 该配置用于报表部分的数据权限过滤功能。
-  # 当前数据权限需要获取指定部门Ids的所有下级子部门Ids的时候,会调用该接口。
-  dataPermAllChildrenDeptIdUrl: "http://localhost:8082/admin/upms/sysDept/listAllChildDeptIdByParentIds"
-  # 业务表和统计打印内置表是否跨库。
-  enabledMultiDatabaseWrite: true
-  # 当前服务是否为可视化后台服务。
-  isVisualization: false
-  # 下面的url列表,请保持反斜杠(/)结尾。
-  viewUrlList:
-  - ${common-report.urlPrefix}/reportOperation/listData/
-
-huaweicloud:
-  obs:
-    enabled: true
-    expireSeconds: 1000
-    # 下面几项均需在申请华为云OBS后,根据自己的实际情况进行配置。
-    endpoint: obs.cn-north-4.myhuaweicloud.com
-    accessKey: C9WI47G4DXXN2EMIL1OO
-    secretKey: tfrZ9aw8wjfotUlG6IUCMjtAgzIzErL5qpPPt9AO
-    bucketName: v-xiaoyaotravel
-
-sa-token:
-  # token 名称(同时也是 cookie 名称)
-  token-name: Authorization
-  # token 有效期(单位:秒) 默认30天,-1 代表永久有效
-  timeout: ${application.sessionExpiredSeconds}
-  # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
-  active-timeout: -1
-  # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
-  is-concurrent: true
-  # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
-  is-share: false
-  # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
-  token-style: uuid
-  # 是否输出操作日志
-  is-log: true
-  # 配置 Sa-Token 单独使用的 Redis 连接
-  # 修改这里Sa-Token的Redis配置,同时也要修改当前配置文件顶部spring.data.redis的相关配置。
-  alone-redis:
-    # Redis数据库索引(默认为0)
-    database: 0
-    # Redis服务器地址
-    host: localhost
-    # Redis服务器连接端口
-    port: 6379
-    # Redis服务器连接密码(默认为空)
-    password:
-    # 连接超时时间
-    timeout: 10s
-  is-read-header: true
-  is-read-cookie: false
-sms:
-  config-type: yaml
-  blends:
-    huawei:
-      #华为短信appKey
-      accessKeyId: 7aUa9993Ggq76rRK0Bb35vZb5NCq
-      #华为短信appSecret
-      accessKeySecret: vk2BGZr08FHjkwbBAGjhO4qKwTbM
-      #短信签名
-      signature: 华为云短信测试
-      #通道号
-      sender: 1069368924410007823
-      #模板ID 如果使用自定义模板发送方法可不设定
-      template-id: c4ef7de4affd4f1ca4c71cf7e62a024e
-      #华为回调地址,如不需要可不设置或为空
-      statusCallBack:
-      #华为分配的app请求地址
-      url: https://smsapi.cn-north-4.myhuaweicloud.com:443
-wx:
-  miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
-    appid: wx2d0bc678042f0817
-    secret: e7963a0242de3ea651578874a12e33c7
-    config-storage:
-      type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
-      key-prefix: wa # Redis Key 的前缀
-      http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台

+ 23 - 18
application-webadmin/src/main/resources/application-prod.yml

@@ -66,7 +66,7 @@ application:
   # 跨域的IP(http://192.168.10.10:8086)白名单列表,多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
   credentialIpList: "*"
   # Session的用户和数据权限在Redis中的过期时间(秒)。一定要和sa-token.timeout
-  sessionExpiredSeconds: 86400
+  sessionExpiredSeconds: 2592000
   # 是否排他登录。
   excludeLogin: false
   hostIpPort: https://v.xiaoyaotravel.com
@@ -86,7 +86,7 @@ third-party:
     # 如果为0,则不缓存,每次涉及第三方的请求,都会发出http请求,交由第三方验证,这样对系统性能会有影响。
     tokenExpiredSeconds: 60
     # 第三方返回的权限数据的缓存过期时长,单位秒。
-    permExpiredSeconds: 86400
+    permExpiredSeconds: 2592000
 
 # 这里仅仅是一个第三方配置的示例,如果没有接入斯三方系统,
 # 这里的配置项也不会影响到系统的行为,如果觉得多余,也可以手动删除。
@@ -174,12 +174,17 @@ huaweicloud:
     accessKey: C9WI47G4DXXN2EMIL1OO
     secretKey: tfrZ9aw8wjfotUlG6IUCMjtAgzIzErL5qpPPt9AO
     bucketName: v-xiaoyaotravel
+  moderation:
+    accessKey: C9WI47G4DXXN2EMIL1OO
+    secretKey: tfrZ9aw8wjfotUlG6IUCMjtAgzIzErL5qpPPt9AO
+    region: cn-north-4
+    projectId: 23089a903d5041b4a55170556cf8cae1
 
 sa-token:
   # token 名称(同时也是 cookie 名称)
   token-name: Authorization
   # token 有效期(单位:秒) 默认30天,-1 代表永久有效
-  timeout: ${application.sessionExpiredSeconds}
+  timeout: 2592000
   # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
   active-timeout: -1
   # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
@@ -208,21 +213,21 @@ sa-token:
 sms:
   config-type: yaml
   blends:
-    huawei:
-      #华为短信appKey
-      accessKeyId: 7aUa9993Ggq76rRK0Bb35vZb5NCq
-      #华为短信appSecret
-      accessKeySecret: vk2BGZr08FHjkwbBAGjhO4qKwTbM
-      #短信签名
-      signature: 华为云短信测试
-      #通道号
-      sender: 1069368924410007823
-      #模板ID 如果使用自定义模板发送方法可不设定
-      template-id: c4ef7de4affd4f1ca4c71cf7e62a024e
-      #华为回调地址,如不需要可不设置或为空
-      statusCallBack:
-      #华为分配的app请求地址
-      url: https://smsapi.cn-north-4.myhuaweicloud.com:443
+    huoshan:
+      ak: AKLTYzA3ZDNiY2M5MWNlNGM1NThhM2ZlN2JhNTIyYWMxZDA
+      sk: WXpVME1USTBNbVprTnpKaU5HTTNORGhsT1dJNU1tUXlaVFl4TjJVeE1Uaw
+      #华为短信开关
+      enable: true
+      #短信账号
+      smsAccount: 7fe76339
+      #国内短信签名
+      chinaSign: 山东老韩国际人才合作
+      #国外短信签名
+      otherSign: XYTravel
+      #国内短信模板
+      chinaTemplateId: ST_7fe71e56
+      #国外短信模板
+      otherTemplateId: ST_7fe70c7c
 wx:
   miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
     appid: wx2d0bc678042f0817

+ 41 - 18
application-webadmin/src/main/resources/application-test.yml

@@ -66,7 +66,7 @@ application:
   # 跨域的IP(http://192.168.10.10:8086)白名单列表,多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
   credentialIpList: "*"
   # Session的用户和数据权限在Redis中的过期时间(秒)。一定要和sa-token.timeout
-  sessionExpiredSeconds: 86400
+  sessionExpiredSeconds: 2592000
   # 是否排他登录。
   excludeLogin: false
   hostIpPort: https://t.xiaoyaotravel.com
@@ -86,7 +86,7 @@ third-party:
     # 如果为0,则不缓存,每次涉及第三方的请求,都会发出http请求,交由第三方验证,这样对系统性能会有影响。
     tokenExpiredSeconds: 60
     # 第三方返回的权限数据的缓存过期时长,单位秒。
-    permExpiredSeconds: 86400
+    permExpiredSeconds: 2592000
 
 # 这里仅仅是一个第三方配置的示例,如果没有接入斯三方系统,
 # 这里的配置项也不会影响到系统的行为,如果觉得多余,也可以手动删除。
@@ -174,12 +174,20 @@ huaweicloud:
     accessKey: C9WI47G4DXXN2EMIL1OO
     secretKey: tfrZ9aw8wjfotUlG6IUCMjtAgzIzErL5qpPPt9AO
     bucketName: test-xiaoyaotravel
+  moderation:
+    accessKey: C9WI47G4DXXN2EMIL1OO
+    secretKey: tfrZ9aw8wjfotUlG6IUCMjtAgzIzErL5qpPPt9AO
+    region: cn-north-4
+    projectId: 23089a903d5041b4a55170556cf8cae1
+
+
 
 sa-token:
   # token 名称(同时也是 cookie 名称)
   token-name: Authorization
   # token 有效期(单位:秒) 默认30天,-1 代表永久有效
-  timeout: ${application.sessionExpiredSeconds}
+  # ${application.sessionExpiredSeconds}
+  timeout: 2592000
   # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
   active-timeout: -1
   # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
@@ -208,21 +216,36 @@ sa-token:
 sms:
   config-type: yaml
   blends:
-    huawei:
-      #华为短信appKey
-      accessKeyId: 7aUa9993Ggq76rRK0Bb35vZb5NCq
-      #华为短信appSecret
-      accessKeySecret: vk2BGZr08FHjkwbBAGjhO4qKwTbM
-      #短信签名
-      signature: 华为云短信测试
-      #通道号
-      sender: 1069368924410007823
-      #模板ID 如果使用自定义模板发送方法可不设定
-      template-id: c4ef7de4affd4f1ca4c71cf7e62a024e
-      #华为回调地址,如不需要可不设置或为空
-      statusCallBack:
-      #华为分配的app请求地址
-      url: https://smsapi.cn-north-4.myhuaweicloud.com:443
+    huoshan:
+      ak: AKLTYzA3ZDNiY2M5MWNlNGM1NThhM2ZlN2JhNTIyYWMxZDA
+      sk: WXpVME1USTBNbVprTnpKaU5HTTNORGhsT1dJNU1tUXlaVFl4TjJVeE1Uaw
+      #华为短信开关
+      enable: true
+      #短信账号
+      smsAccount: 7fe76339
+      #国内短信签名
+      chinaSign: 山东老韩国际人才合作
+      #国外短信签名
+      otherSign: XYTravel
+      #国内短信模板
+      chinaTemplateId: ST_7fe71e56
+      #国外短信模板
+      otherTemplateId: ST_7fe70c7c
+#    huawei:
+#      #华为短信appKey
+#      accessKeyId: 7aUa9993Ggq76rRK0Bb35vZb5NCq
+#      #华为短信appSecret
+#      accessKeySecret: vk2BGZr08FHjkwbBAGjhO4qKwTbM
+#      #短信签名
+#      signature: 华为云短信测试
+#      #通道号
+#      sender: 1069368924410007823
+#      #模板ID 如果使用自定义模板发送方法可不设定
+#      template-id: c4ef7de4affd4f1ca4c71cf7e62a024e
+#      #华为回调地址,如不需要可不设置或为空
+#      statusCallBack:
+#      #华为分配的app请求地址
+#      url: https://smsapi.cn-north-4.myhuaweicloud.com:443
 wx:
   miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
     appid: wx2d0bc678042f0817

+ 1 - 1
application-webadmin/src/main/resources/application.yml

@@ -22,7 +22,7 @@ spring:
   application:
     name: application-webadmin
   profiles:
-    active: dev
+    active: test
   servlet:
     multipart:
       max-file-size: 50MB

+ 6 - 3
common/common-additional/src/main/java/com/tourism/common/additional/utils/UrlConvertUtils.java

@@ -1,18 +1,21 @@
 package com.tourism.common.additional.utils;
 
 import com.tourism.common.additional.model.FileUrlObject;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.CollectionUtils;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 
 public class UrlConvertUtils {
 
     public static List<String> urlConvert(String hostIpPort, String url){
+        if(StringUtils.isBlank(url)){
+            return new ArrayList<>();
+        }
         ArrayList<String> arrayList = new ArrayList<>();
-        if (StringUtils.isNotEmpty(url)) {
+        if(url.contains("https")){
+            arrayList.add(url);
+        }else {
             List<FileUrlObject> fileUrlObjectList = JsonUtils.parseFileUrlArray(url, FileUrlObject.class);
             if (!CollectionUtils.isEmpty(fileUrlObjectList)) {
                 //遍历每个元素的数组对象,对元素的url对象进行拼接

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

@@ -73,7 +73,9 @@ public enum ErrorCodeEnum {
     DATE_OVERLAP("日期重叠,请重新选择!"),
     PRICE_ERROR("价格错误,请重新填写!"),
     PROJECT_NOT_EXIST("该项目不存在,请重新选择!"),
-    DATE_PRICE_NOTEXIST("请先编辑日历价格!");
+    DATE_PRICE_NOTEXIST("请先编辑日历价格!"),
+    DATA_NOT_FOUND("数据不存在,请联系管理员!"),
+    NOT_COVER("请选中图片中哪个为封面图!");
     // 下面的枚举值为特定枚举值,即开发者可以根据自己的项目需求定义更多的非通用枚举值
 
     /**

+ 26 - 0
common/common-huaweicloud/common-huaweicloud-moderation/pom.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>common-huaweicloud</artifactId>
+        <groupId>com.tourism</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>common-huaweicloud-moderation</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.huaweicloud.sdk</groupId>
+            <artifactId>huaweicloud-sdk-moderation</artifactId>
+            <version>3.1.121</version>
+        </dependency>
+    </dependencies>
+</project>

+ 16 - 0
common/common-huaweicloud/common-huaweicloud-moderation/src/main/java/com/tourism/common/huaweicloud/moderation/config/HuaweiCloudConfig.java

@@ -0,0 +1,16 @@
+package com.tourism.common.huaweicloud.moderation.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "huaweicloud.moderation")
+public class HuaweiCloudConfig {
+    private String accessKey;
+    private String secretKey;
+    private String region;
+    private String endpoint;
+    private String projectId;
+}

+ 105 - 0
common/common-huaweicloud/common-huaweicloud-moderation/src/main/java/com/tourism/common/huaweicloud/moderation/service/HuaweiCloudModerationService.java

@@ -0,0 +1,105 @@
+package com.tourism.common.huaweicloud.moderation.service;
+
+import com.huaweicloud.sdk.core.auth.BasicCredentials;
+import com.huaweicloud.sdk.core.auth.ICredential;
+import com.huaweicloud.sdk.core.exception.ServiceResponseException;
+import com.huaweicloud.sdk.moderation.v3.ModerationClient;
+import com.huaweicloud.sdk.moderation.v3.model.*;
+import com.huaweicloud.sdk.moderation.v3.region.ModerationRegion;
+import com.tourism.common.huaweicloud.moderation.config.HuaweiCloudConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+
+@Service
+public class HuaweiCloudModerationService {
+
+    @Autowired
+    private HuaweiCloudConfig huaweiCloudConfig;
+
+    /**
+     * 文案审核,只要有一个不通过,都认为不通过
+     * @param texts
+     * @return
+     */
+    public Boolean runTextModeration(List<String> texts) {
+        Boolean result = true;
+        ICredential credential = new BasicCredentials()
+                .withProjectId(huaweiCloudConfig.getProjectId())
+                .withAk(huaweiCloudConfig.getAccessKey())
+                .withSk(huaweiCloudConfig.getSecretKey());
+
+        ModerationClient client = ModerationClient.newBuilder()
+                .withCredential(credential)
+                .withRegion(ModerationRegion.valueOf(huaweiCloudConfig.getRegion()))
+                .build();
+
+        RunTextModerationRequest request = new RunTextModerationRequest();
+        TextDetectionReq body = new TextDetectionReq();
+        TextDetectionDataReq databody = new TextDetectionDataReq();
+        body.withCategories(Arrays.asList("terrorism", "porn", "abuse", "ban"));
+        for (String text : texts) {
+            databody.withText(text);
+            body.withData(databody);
+            body.withEventType("comment");
+            request.withBody(body);
+            try {
+                RunTextModerationResponse response = client.runTextModeration(request);
+                if("pass".equals(response.getResult().getSuggestion())){
+                }else {
+                    result = false;
+                    break;
+                }
+            } catch (ServiceResponseException e) {
+                // 处理异常
+                e.printStackTrace();
+                result = false;
+                break;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 只要有一张图片不通过,就认为不通过
+     * @param urls
+     * @return
+     */
+    public Boolean runImageModeration(List<String> urls) {
+        Boolean result = true;
+        ICredential credential = new BasicCredentials()
+                .withProjectId(huaweiCloudConfig.getProjectId())
+                .withAk(huaweiCloudConfig.getAccessKey())
+                .withSk(huaweiCloudConfig.getSecretKey());
+
+        ModerationClient client = ModerationClient.newBuilder()
+                .withCredential(credential)
+                .withRegion(ModerationRegion.valueOf(huaweiCloudConfig.getRegion()))
+                .build();
+
+        CheckImageModerationRequest request = new CheckImageModerationRequest();
+        ImageDetectionReq body = new ImageDetectionReq();
+        body.withCategories(Arrays.asList("terrorism", "porn", "abuse", "ban"));
+        body.withEventType("head_image");
+        for (String url : urls) {
+            body.withUrl(url);
+            request.withBody(body);
+            try {
+                CheckImageModerationResponse response = client.checkImageModeration(request);
+                if("pass".equals(response.getResult().getSuggestion())){
+                }else {
+                    result = false;
+                    break;
+                }
+            } catch (ServiceResponseException e) {
+                // 处理异常
+                e.printStackTrace();
+                result = false;
+                break;
+            }
+        }
+        return result;
+    }
+}

+ 1 - 0
common/common-huaweicloud/pom.xml

@@ -14,5 +14,6 @@
 
     <modules>
         <module>common-huaweicloud-obs</module>
+        <module>common-huaweicloud-moderation</module>
     </modules>
 </project>

+ 13 - 0
common/common-satoken/src/main/java/com/tourism/common/satoken/util/SaTokenUtil.java

@@ -12,6 +12,8 @@ import cn.hutool.core.util.ReflectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.tourism.common.core.cache.CacheConfig;
 import com.tourism.common.core.constant.ApplicationConstant;
 import com.tourism.common.core.constant.ErrorCodeEnum;
@@ -22,6 +24,7 @@ import com.tourism.common.core.util.AopTargetUtil;
 import com.tourism.common.core.util.MyCommonUtil;
 import com.tourism.common.core.util.RedisKeyUtil;
 import com.tourism.common.satoken.annotation.SaTokenDenyAuth;
+import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.RMap;
 import org.redisson.api.RSet;
 import org.redisson.api.RTopic;
@@ -48,6 +51,7 @@ import java.util.*;
  * @author 吃饭睡觉
  * @date 2024-09-06
  */
+@Slf4j
 @Component
 public class SaTokenUtil {
 
@@ -119,12 +123,21 @@ public class SaTokenUtil {
         }
         Method method = ((HandlerMethod) handler).getMethod();
         String errorMessage;
+        ObjectMapper mapper = new ObjectMapper();
         //如果没有登录则直接交给satoken注解去验证。
         if (!StpUtil.isLogin()) {
             // 如果此 Method 或其所属 Class 标注了 @SaIgnore,则忽略掉鉴权
             if (BooleanUtil.isTrue(SaStrategy.instance.isAnnotationPresent.apply(method, SaIgnore.class))) {
                 return ResponseResult.success();
             }
+            try {
+//            log.info("request::::::::{}", mapper.writeValueAsString(request));
+//            log.info("handler::::::::{}", mapper.writeValueAsString(handler));
+                log.info("StpUtil::::::::getTokenInfo:::{}", mapper.writeValueAsString(StpUtil.getTokenInfo()));
+//            log.info("StpUtil::::::::getTokenSession:::{}", mapper.writeValueAsString(StpUtil.getTokenSession()));
+            } catch (JsonProcessingException e) {
+                throw new RuntimeException(e);
+            }
             errorMessage = "非免登录接口必须包含Token信息!";
             return ResponseResult.error(HttpServletResponse.SC_UNAUTHORIZED, ErrorCodeEnum.UNAUTHORIZED_LOGIN, errorMessage);
         }