Эх сурвалжийг харах

Merge remote-tracking branch 'origin/v0.1' into v0.1

chenchen 5 сар өмнө
parent
commit
d53fa784d5

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

@@ -1,53 +1,28 @@
 package com.tourism.webadmin.app.website.controller;
 
-import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.annotation.SaIgnore;
-import cn.hutool.core.date.DateUnit;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.pagehelper.page.PageMethod;
-import com.tourism.common.additional.utils.MapConvertUtils;
-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.IpUtil;
-import com.tourism.common.core.util.MyDateUtil;
-import com.tourism.common.core.util.MyModelUtil;
-import com.tourism.common.core.util.MyPageUtil;
+import com.tourism.common.core.util.MyCommonUtil;
+import com.tourism.common.core.validator.UpdateGroup;
 import com.tourism.webadmin.app.website.dto.TourismBookProjectDto;
 import com.tourism.webadmin.app.website.dto.TourismProjectToWebDto;
-import com.tourism.webadmin.app.website.vo.DateRange;
-import com.tourism.webadmin.app.website.vo.TourismProjectDatePriceVo;
+import com.tourism.webadmin.app.website.service.TourismProjectToWebService;
 import com.tourism.webadmin.app.website.vo.WebSiteProjectDatePriceVo;
-import com.tourism.webadmin.back.dto.TourBookInfoDto;
 import com.tourism.webadmin.back.model.*;
-import com.tourism.webadmin.back.service.TourBookInfoService;
-import com.tourism.webadmin.back.service.TourUserService;
-import com.tourism.webadmin.back.service.TourismDatePriceService;
 import com.tourism.webadmin.back.service.TourismProjectService;
 import com.tourism.webadmin.back.vo.TourismProjectVo;
-import com.tourism.common.additional.config.ApplicationConfig;
-import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.validation.Valid;
 import jakarta.validation.constraints.NotNull;
+import jakarta.validation.groups.Default;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.time.DateUtils;
-import org.joda.time.DateTime;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import java.math.BigDecimal;
-import java.time.LocalDate;
-import java.time.ZoneId;
-import java.util.*;
-import java.util.stream.Collectors;
-
-import static java.util.stream.Collectors.toList;
-
 /**
  * 旅游项目管理操作控制器类。
  *
@@ -63,14 +38,9 @@ public class TourismProjectToWebController {
 
     @Autowired
     private TourismProjectService tourismProjectService;
+
     @Autowired
-    private ApplicationConfig applicationConfig;
-    @Autowired
-    private TourismDatePriceService tourismDatePriceService;
-    @Autowired
-    private TourUserService tourUserService;
-    @Autowired
-    private TourBookInfoService tourBookInfoService;
+    private TourismProjectToWebService tourismProjectToWebService;
 
     /**
      * 列出符合过滤条件的旅游项目管理列表。
@@ -82,42 +52,7 @@ public class TourismProjectToWebController {
     @GetMapping("/list")
     public ResponseResult<MyPageData<TourismProjectVo>> list(
             @Valid @ModelAttribute TourismProjectToWebDto tourismProjectDtoFilter) {
-//        if(tourismProjectDtoFilter.getBelongTab() == null){
-//            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST,"所属分类(belongTab)不能为空!");
-//        }
-        //如果belongTab小于1000并且大于10.则表明查询的是一级菜单
-        if(tourismProjectDtoFilter.getBelongTab() !=null && tourismProjectDtoFilter.getBelongTab()>=10 && tourismProjectDtoFilter.getBelongTab()<1000){
-            DirectoryInfo filter = new DirectoryInfo();
-            filter.setParentId(tourismProjectDtoFilter.getBelongTab());
-            filter.setEnable(1);
-            List<DirectoryInfo> directoryInfoList = tourismProjectService.getDirectoryInfoList(filter, null);
-            tourismProjectDtoFilter.setBelongTab(null);
-            tourismProjectDtoFilter.setDirectoryInfoIds(directoryInfoList.stream().map(DirectoryInfo::getId).collect(toList()));
-        }
-        TourismProject tourismProjectFilter = MyModelUtil.copyTo(tourismProjectDtoFilter, TourismProject.class);
-        //首页展示的为启用的内容
-        tourismProjectFilter.setEnable(1);
-        String orderBy = MyOrderParam.buildOrderBy(tourismProjectDtoFilter.getOrderParamList(), TourismProject.class);
-        if (tourismProjectDtoFilter.getPageNum() != null && tourismProjectDtoFilter.getPageSize() != null ) {
-            PageMethod.startPage(tourismProjectDtoFilter.getPageNum(), tourismProjectDtoFilter.getPageSize(), true);
-        }
-        List<TourismProject> tourismProjectList =
-                tourismProjectService.getTourismProjectList(tourismProjectFilter, orderBy);
-//        List<TourismProject> tourismProjectList =
-//                tourismProjectService.getTourismProjectListWithRelation(tourismProjectFilter, orderBy);
-        MyPageData<TourismProjectVo> tourismProjectVoMyPageData = MyPageUtil.makeResponseData(tourismProjectList, TourismProjectVo.class);
-
-        List<TourismProjectVo> dataList = tourismProjectVoMyPageData.getDataList();
-        //先把imgUrl由jaon转换为List<FileUrlObject>
-        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());
-            item.setTourismUrlsAfterConvert(arrayList);
-            List<String> arrayList1 = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTravelNotesBanner());
-            item.setTravelNotesBannerAfterConvert(arrayList1);
-        });
+        MyPageData<TourismProjectVo> tourismProjectVoMyPageData = tourismProjectToWebService.list(tourismProjectDtoFilter);
         return ResponseResult.success(tourismProjectVoMyPageData);
     }
 
@@ -128,38 +63,13 @@ public class TourismProjectToWebController {
      * @return 应答结果对象,包含对象详情。
      */
     @SaIgnore
-//    @SaCheckPermission("tourismProject.view")
     @GetMapping("/detail")
-    public ResponseResult<TourismProjectVo> detail(@NotNull(message = "所属目录(id)不能为空") String id) {
+    public ResponseResult<TourismProjectVo> detail(@NotNull(message = "所属目录(id)不能为空") Long id) {
         TourismProject tourismProject = tourismProjectService.getByIdWithRelation(id, MyRelationParam.full());
         if (tourismProject == null) {
             return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
         }
-        TourismProjectVo tourismProjectVo = MyModelUtil.copyTo(tourismProject, TourismProjectVo.class);
-        List<String> arrayList = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismProjectVo.getTourismUrl());
-        tourismProjectVo.setTourismUrlsAfterConvert(arrayList);
-        List<String> arrayList1 = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismProjectVo.getHomeHotPicture());
-        tourismProjectVo.setHomeHotPicturesAfterConvert(arrayList1);
-        List<String> arrayList2 = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismProjectVo.getTravelNotesBanner());
-        tourismProjectVo.setTravelNotesBannerAfterConvert(arrayList2);
-        if(tourismProjectVo.getTourismFile() != null){
-            // 使用 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));
-            }
-        }
-        //二维码路径赋值
-//        tourismProjectVo.setContactCode("[{\"name\":\"微信图片_20241021154757.png\",\"downloadUri\":\"/admin/app/tourTourismProjectTravelNotes/download\",\"filename\":\"6b92b75edcc04da1bd6e4af056911730.png\",\"uploadPath\":\"image/TourTourismProjectTravelNotes/contactCode\"}]");
-//        List<String> urlConvertList = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismProjectVo.getContactCode());
-//        if(CollectionUtils.isNotEmpty(urlConvertList)) {
-//            tourismProjectVo.setContactCodeConvert(urlConvertList.get(0));
-//        }
-        if(tourismProjectVo != null) {
-            tourismProjectVo.setContactCodeConvert("https://v.xiaoyaotravel.com/image/ContactQRCode/tourism.png");
-        }
+        TourismProjectVo tourismProjectVo = tourismProjectToWebService.detail(tourismProject);
         return ResponseResult.success(tourismProjectVo);
     }
     /**
@@ -170,92 +80,28 @@ public class TourismProjectToWebController {
      */
     @SaIgnore
     @GetMapping("/viewDatePrice")
-    public ResponseResult<WebSiteProjectDatePriceVo> view(@RequestParam String projectId) {
-
-        TourismDatePrice tourismDatePrice = new TourismDatePrice();
-        tourismDatePrice.setProjectId(projectId);
-        tourismDatePrice.setNowDate(new Date());
-
-        //查询进行排序
-        MyOrderParam myOrderParam = new MyOrderParam();
-        MyOrderParam.OrderInfo orderInfo = new MyOrderParam.OrderInfo();
-        orderInfo.setFieldName("departureDate");
-        orderInfo.setAsc(true);
-        myOrderParam.add(orderInfo);
-        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourismDatePrice.class);
-        List<TourismDatePrice> tourismDatePriceList =
-                tourismDatePriceService.getTourismDatePriceList(tourismDatePrice, orderBy);
-//        List<TourismDatePrice> tourismDatePriceSortList = tourismDatePriceList.stream()
-//                .sorted(Comparator.comparing(TourismDatePrice::getDepartureDate))
-//                .collect(Collectors.toList());
-        List<TourismProjectDatePriceVo> tourismProjectDatePriceVos = MyModelUtil.copyCollectionTo(tourismDatePriceList, TourismProjectDatePriceVo.class);
-
-        DateRange dateRange = new DateRange();
-        dateRange.setStartDate(new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
-        if(!CollectionUtils.isEmpty(tourismDatePriceList)) {
-            Optional<Date> max = tourismDatePriceList.stream()
-                    .map(TourismDatePrice::getDepartureDate)
-                    .max(Comparator.naturalOrder());
-            dateRange.setEndDate(max.get().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
-        }else {
-            dateRange.setEndDate(DateUtils.addDays(new Date(), 30).toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
-        }
-//        //查询项目的默认价格
-//        TourismProject tourismProject = tourismProjectService.getById(projectId);
-//        if(tourismProject != null){
-//            tourismProjectDatePriceVos.stream().forEach(item->{
-//                item.setProjectPrice(tourismProject.getPrice().toString().concat(tourismProject.getPriceUnit()));
-//            });
-//        }
-        WebSiteProjectDatePriceVo webSiteProjectDatePriceVo = new WebSiteProjectDatePriceVo();
-        // 使用 Stream API 将列表转换为 Map
-        Map<LocalDate, TourismProjectDatePriceVo> map = tourismProjectDatePriceVos.stream()
-                .collect(Collectors.toMap(
-                        TourismProjectDatePriceVo::getDepartureDate, // key
-                        vo -> vo // value
-                ));
-        webSiteProjectDatePriceVo.setTourismProjectDatePriceVos(map);
-        webSiteProjectDatePriceVo.setDateRange(dateRange);
+    public ResponseResult<WebSiteProjectDatePriceVo> view(@RequestParam Long projectId) {
+        WebSiteProjectDatePriceVo webSiteProjectDatePriceVo = tourismProjectToWebService.view(projectId);
         return ResponseResult.success(webSiteProjectDatePriceVo);
     }
 
     /**
     * 项目详情页面的预定接口
     *
-    * @param tourismBookProjectDto 预定项目的Dto
+    * @param tourBookInfoDto 预定项目的Dto
     * @return 应答结果对象,包含对象详情。
     */
     @PostMapping("/bookProject")
-    public ResponseResult<Void> view(HttpServletRequest request,@RequestBody TourismBookProjectDto tourismBookProjectDto) {
-        //获取用户的手机号
-        Long userId = TokenData.takeFromRequest().getUserId();
-        TourUser tourUser = tourUserService.getById(userId);
-        String mobile = tourUser.getMobile();
-
-        //根据当前日期,查询当天的项目日历价格
-        TourismDatePrice tourismDatePrice = new TourismDatePrice();
-//        tourismDatePrice.setDepartureDate(MyDateUtil.truncateToDay(new Date()));
-        tourismDatePrice.setProjectId(tourismBookProjectDto.getProjectId());
-        tourismDatePrice.setDepartureDate(tourismBookProjectDto.getStartDate());
-        TourismDatePrice tourismDatePriceOne = tourismDatePriceService.getOne(tourismDatePrice);
-
-        //构建预定的数据进行保存
-        TourBookInfo tourBookInfo = new TourBookInfo();
-        tourBookInfo.setType(tourismBookProjectDto.getType());
-        tourBookInfo.setProjectId(tourismBookProjectDto.getProjectId());
-        tourBookInfo.setAdultNumber(tourismBookProjectDto.getAdultNumber());
-        tourBookInfo.setChildrenNumber(tourismBookProjectDto.getChildrenNumber());
-        tourBookInfo.setAdultPrice(tourismDatePriceOne.getAdultPrice());
-        tourBookInfo.setChildrenPrice(tourismDatePriceOne.getChildrenPrice());
-        tourBookInfo.setBookMobile(mobile);
-        tourBookInfo.setBookName(mobile);
-        tourBookInfo.setBookTime(tourismBookProjectDto.getStartDate());
-        tourBookInfo.setTotalPrice( tourismDatePriceOne.getAdultPrice().multiply(BigDecimal.valueOf(tourismBookProjectDto.getAdultNumber()))
-                .add(tourismDatePriceOne.getChildrenPrice().multiply(BigDecimal.valueOf(tourismBookProjectDto.getChildrenNumber()))));
-//        tourBookInfo.setBookIp(IpUtil.getRemoteIpAddress(request));
-
-        tourBookInfoService.saveNew(tourBookInfo);
-        return ResponseResult.success();
+    public ResponseResult<Integer> bookProject(HttpServletRequest request,@MyRequestBody TourismBookProjectDto tourBookInfoDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourBookInfoDto, Default.class, UpdateGroup.class);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        Boolean state = tourismProjectToWebService.bookProject(request, tourBookInfoDto);
+        if(!state){
+            return ResponseResult.success(2);
+        }
+        return ResponseResult.success(1);
     }
 
 }

+ 20 - 2
application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/TourismBookProjectDto.java

@@ -1,11 +1,29 @@
 package com.tourism.webadmin.app.website.dto;
 
+import com.tourism.common.core.validator.UpdateGroup;
+import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
 import java.util.Date;
 
 @Data
 public class TourismBookProjectDto {
-    private Integer type;private String projectId;
-    private Integer adultNumber;private Integer childrenNumber;private Date startDate;
+
+    @NotNull(message = "type不能为空!", groups = {UpdateGroup.class})
+    private Integer type;
+
+    @NotNull(message = "项目不能为空!", groups = {UpdateGroup.class})
+    private Long projectId;
+
+    @NotNull(message = "成人数量不能为空!", groups = {UpdateGroup.class})
+    private Integer adultNumber;
+
+    private Integer childrenNumber;
+
+    @NotNull(message = "预定日期不能为空!", groups = {UpdateGroup.class})
+    private Date startDate;
+
+    public String getString() {
+        return type + "_" + projectId + "_" + adultNumber + "_" + childrenNumber + "_" + startDate;
+    }
 }

+ 23 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/TourismProjectToWebService.java

@@ -0,0 +1,23 @@
+package com.tourism.webadmin.app.website.service;
+
+import com.tourism.common.core.object.MyPageData;
+import com.tourism.webadmin.app.website.dto.TourismBookProjectDto;
+import com.tourism.webadmin.app.website.dto.TourismProjectToWebDto;
+import com.tourism.webadmin.app.website.vo.WebSiteProjectDatePriceVo;
+import com.tourism.webadmin.back.model.TourismProject;
+import com.tourism.webadmin.back.vo.TourismProjectVo;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.constraints.NotNull;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+public interface TourismProjectToWebService {
+
+    MyPageData<TourismProjectVo> list(TourismProjectToWebDto tourismProjectDtoFilter);
+
+    TourismProjectVo detail(TourismProject tourismProject);
+
+    WebSiteProjectDatePriceVo view(@RequestParam Long projectId);
+
+    Boolean bookProject(HttpServletRequest request, @RequestBody TourismBookProjectDto tourismBookProjectDto);
+}

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

@@ -0,0 +1,243 @@
+package com.tourism.webadmin.app.website.service.impl;
+
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.pagehelper.page.PageMethod;
+import com.tourism.common.additional.config.ApplicationConfig;
+import com.tourism.common.additional.utils.MapConvertUtils;
+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.upload.BaseUpDownloader;
+import com.tourism.common.core.upload.UpDownloaderFactory;
+import com.tourism.common.core.upload.UploadResponseInfo;
+import com.tourism.common.core.upload.UploadStoreTypeEnum;
+import com.tourism.common.core.util.IpUtil;
+import com.tourism.common.core.util.MyModelUtil;
+import com.tourism.common.core.util.MyPageUtil;
+import com.tourism.webadmin.app.website.dto.TourismBookProjectDto;
+import com.tourism.webadmin.app.website.dto.TourismProjectToWebDto;
+import com.tourism.webadmin.app.website.service.CleanDataService;
+import com.tourism.webadmin.app.website.service.TourismProjectToWebService;
+import com.tourism.webadmin.app.website.vo.DateRange;
+import com.tourism.webadmin.app.website.vo.TourismProjectDatePriceVo;
+import com.tourism.webadmin.app.website.vo.WebSiteProjectDatePriceVo;
+import com.tourism.webadmin.back.dao.JobContentMapper;
+import com.tourism.webadmin.back.dao.TourTourismTravelNotesContentMapper;
+import com.tourism.webadmin.back.dao.TourismContentMapper;
+import com.tourism.webadmin.back.dto.MultipartFileDto;
+import com.tourism.webadmin.back.model.*;
+import com.tourism.webadmin.back.service.*;
+import com.tourism.webadmin.back.vo.TourismProjectVo;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.time.DateUtils;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toList;
+
+/**
+ * 门户网站首页Service
+ *
+ * @author tourism
+ */
+@Slf4j
+@Service("TourismProjectToWebService")
+public class TourismProjectToWebServiceImpl implements TourismProjectToWebService {
+
+    @Autowired
+    private TourismProjectService tourismProjectService;
+    @Autowired
+    private ApplicationConfig applicationConfig;
+    @Autowired
+    private TourismDatePriceService tourismDatePriceService;
+    @Autowired
+    private TourUserService tourUserService;
+    @Autowired
+    private TourBookInfoService tourBookInfoService;
+    @Autowired
+    private RedissonClient redissonClient;
+
+
+    @Override
+    public MyPageData<TourismProjectVo> list(TourismProjectToWebDto tourismProjectDtoFilter) {
+//        if(tourismProjectDtoFilter.getBelongTab() == null){
+//            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST,"所属分类(belongTab)不能为空!");
+//        }
+        //如果belongTab小于1000并且大于10.则表明查询的是一级菜单
+        if(tourismProjectDtoFilter.getBelongTab() !=null && tourismProjectDtoFilter.getBelongTab()>=10 && tourismProjectDtoFilter.getBelongTab()<1000){
+            DirectoryInfo filter = new DirectoryInfo();
+            filter.setParentId(tourismProjectDtoFilter.getBelongTab());
+            filter.setEnable(1);
+            List<DirectoryInfo> directoryInfoList = tourismProjectService.getDirectoryInfoList(filter, null);
+            tourismProjectDtoFilter.setBelongTab(null);
+            tourismProjectDtoFilter.setDirectoryInfoIds(directoryInfoList.stream().map(DirectoryInfo::getId).collect(toList()));
+        }
+        TourismProject tourismProjectFilter = MyModelUtil.copyTo(tourismProjectDtoFilter, TourismProject.class);
+        //首页展示的为启用的内容
+        tourismProjectFilter.setEnable(1);
+        String orderBy = MyOrderParam.buildOrderBy(tourismProjectDtoFilter.getOrderParamList(), TourismProject.class);
+        if (tourismProjectDtoFilter.getPageNum() != null && tourismProjectDtoFilter.getPageSize() != null ) {
+            PageMethod.startPage(tourismProjectDtoFilter.getPageNum(), tourismProjectDtoFilter.getPageSize(), true);
+        }
+        List<TourismProject> tourismProjectList =
+                tourismProjectService.getTourismProjectList(tourismProjectFilter, orderBy);
+//        List<TourismProject> tourismProjectList =
+//                tourismProjectService.getTourismProjectListWithRelation(tourismProjectFilter, orderBy);
+        MyPageData<TourismProjectVo> tourismProjectVoMyPageData = MyPageUtil.makeResponseData(tourismProjectList, TourismProjectVo.class);
+
+        List<TourismProjectVo> dataList = tourismProjectVoMyPageData.getDataList();
+        //先把imgUrl由jaon转换为List<FileUrlObject>
+        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());
+            item.setTourismUrlsAfterConvert(arrayList);
+            List<String> arrayList1 = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTravelNotesBanner());
+            item.setTravelNotesBannerAfterConvert(arrayList1);
+        });
+        return tourismProjectVoMyPageData;
+    }
+
+    @Override
+    public TourismProjectVo detail(TourismProject tourismProject) {
+        TourismProjectVo tourismProjectVo = MyModelUtil.copyTo(tourismProject, TourismProjectVo.class);
+        List<String> arrayList = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismProjectVo.getTourismUrl());
+        tourismProjectVo.setTourismUrlsAfterConvert(arrayList);
+        List<String> arrayList1 = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismProjectVo.getHomeHotPicture());
+        tourismProjectVo.setHomeHotPicturesAfterConvert(arrayList1);
+        List<String> arrayList2 = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismProjectVo.getTravelNotesBanner());
+        tourismProjectVo.setTravelNotesBannerAfterConvert(arrayList2);
+        if(tourismProjectVo.getTourismFile() != null){
+            // 使用 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));
+            }
+        }
+        //二维码路径赋值
+//        tourismProjectVo.setContactCode("[{\"name\":\"微信图片_20241021154757.png\",\"downloadUri\":\"/admin/app/tourTourismProjectTravelNotes/download\",\"filename\":\"6b92b75edcc04da1bd6e4af056911730.png\",\"uploadPath\":\"image/TourTourismProjectTravelNotes/contactCode\"}]");
+//        List<String> urlConvertList = UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), tourismProjectVo.getContactCode());
+//        if(CollectionUtils.isNotEmpty(urlConvertList)) {
+//            tourismProjectVo.setContactCodeConvert(urlConvertList.get(0));
+//        }
+        if(tourismProjectVo != null) {
+            tourismProjectVo.setContactCodeConvert("https://v.xiaoyaotravel.com/image/ContactQRCode/tourism.png");
+        }
+        return tourismProjectVo;
+    }
+
+    @Override
+    public WebSiteProjectDatePriceVo view(Long projectId) {
+
+        TourismDatePrice tourismDatePrice = new TourismDatePrice();
+        tourismDatePrice.setProjectId(projectId);
+        tourismDatePrice.setNowDate(new Date());
+
+        //查询进行排序
+        MyOrderParam myOrderParam = new MyOrderParam();
+        MyOrderParam.OrderInfo orderInfo = new MyOrderParam.OrderInfo();
+        orderInfo.setFieldName("departureDate");
+        orderInfo.setAsc(true);
+        myOrderParam.add(orderInfo);
+        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourismDatePrice.class);
+        List<TourismDatePrice> tourismDatePriceList =
+                tourismDatePriceService.getTourismDatePriceList(tourismDatePrice, orderBy);
+//        List<TourismDatePrice> tourismDatePriceSortList = tourismDatePriceList.stream()
+//                .sorted(Comparator.comparing(TourismDatePrice::getDepartureDate))
+//                .collect(Collectors.toList());
+        List<TourismProjectDatePriceVo> tourismProjectDatePriceVos = MyModelUtil.copyCollectionTo(tourismDatePriceList, TourismProjectDatePriceVo.class);
+
+        DateRange dateRange = new DateRange();
+        dateRange.setStartDate(new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
+        if(!CollectionUtils.isEmpty(tourismDatePriceList)) {
+            Optional<Date> max = tourismDatePriceList.stream()
+                    .map(TourismDatePrice::getDepartureDate)
+                    .max(Comparator.naturalOrder());
+            dateRange.setEndDate(max.get().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
+        }else {
+            dateRange.setEndDate(DateUtils.addDays(new Date(), 30).toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
+        }
+//        //查询项目的默认价格
+//        TourismProject tourismProject = tourismProjectService.getById(projectId);
+//        if(tourismProject != null){
+//            tourismProjectDatePriceVos.stream().forEach(item->{
+//                item.setProjectPrice(tourismProject.getPrice().toString().concat(tourismProject.getPriceUnit()));
+//            });
+//        }
+        WebSiteProjectDatePriceVo webSiteProjectDatePriceVo = new WebSiteProjectDatePriceVo();
+        // 使用 Stream API 将列表转换为 Map
+        Map<LocalDate, TourismProjectDatePriceVo> map = tourismProjectDatePriceVos.stream()
+                .collect(Collectors.toMap(
+                        TourismProjectDatePriceVo::getDepartureDate, // key
+                        vo -> vo // value
+                ));
+        webSiteProjectDatePriceVo.setTourismProjectDatePriceVos(map);
+        webSiteProjectDatePriceVo.setDateRange(dateRange);
+        return webSiteProjectDatePriceVo;
+    }
+
+    @Override
+    public Boolean bookProject(HttpServletRequest request, TourismBookProjectDto tourBookInfoDto) {
+
+        //获取用户的手机号
+        Long userId = TokenData.takeFromRequest().getUserId();
+        TourUser tourUser = tourUserService.getById(userId);
+        String mobile = tourUser.getMobile();
+
+        RBucket<Object> bucket = redissonClient.getBucket(tourBookInfoDto.getString().concat(mobile));
+        if(bucket.get() != null){
+            return false;
+        }
+
+        if(tourBookInfoDto == null){
+            throw new RuntimeException("预定参数为空!");
+        }
+
+        //根据当前日期,查询当天的项目日历价格
+        TourismDatePrice tourismDatePrice = new TourismDatePrice();
+        tourismDatePrice.setProjectId(tourBookInfoDto.getProjectId());
+        tourismDatePrice.setDepartureDate(tourBookInfoDto.getStartDate());
+        TourismDatePrice tourismDatePriceOne = tourismDatePriceService.getOne(tourismDatePrice);
+
+
+        //构建预定的数据进行保存
+        TourBookInfo tourBookInfo = new TourBookInfo();
+        tourBookInfo.setType(tourBookInfoDto.getType());
+        tourBookInfo.setProjectId(tourBookInfoDto.getProjectId());
+        tourBookInfo.setAdultNumber(tourBookInfoDto.getAdultNumber());
+        tourBookInfo.setChildrenNumber(tourBookInfoDto.getChildrenNumber());
+        tourBookInfo.setAdultPrice(tourismDatePriceOne.getAdultPrice());
+        tourBookInfo.setChildrenPrice(tourismDatePriceOne.getChildrenPrice());
+        tourBookInfo.setBookMobile(mobile);
+        tourBookInfo.setBookName(mobile);
+        tourBookInfo.setIsHandle("0");
+        tourBookInfo.setBookTime(tourBookInfoDto.getStartDate());
+        tourBookInfo.setTotalPrice( tourismDatePriceOne.getAdultPrice().multiply(BigDecimal.valueOf(tourBookInfoDto.getAdultNumber()))
+                .add(tourismDatePriceOne.getChildrenPrice().multiply(BigDecimal.valueOf(tourBookInfoDto.getChildrenNumber()))));
+        tourBookInfo.setBookIp(IpUtil.getRemoteIpAddress(request));
+        tourBookInfoService.saveNew(tourBookInfo);
+        bucket.set("预约成功!");
+        return true;
+    }
+}

+ 70 - 7
application-webadmin/src/main/java/com/tourism/webadmin/back/controller/ExtraController.java

@@ -1,25 +1,26 @@
 package com.tourism.webadmin.back.controller;
 
-import ch.qos.logback.core.joran.sanity.Pair;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.tourism.common.core.annotation.MyRequestBody;
 import com.tourism.common.core.constant.ErrorCodeEnum;
 import com.tourism.common.core.object.MyOrderParam;
-import com.tourism.common.core.object.MyRelationParam;
 import com.tourism.common.core.object.ResponseResult;
 import com.tourism.common.core.util.MyDateUtil;
 import com.tourism.common.core.util.MyModelUtil;
 import com.tourism.webadmin.app.website.dto.DatePriceSaveDto;
 import com.tourism.webadmin.app.website.vo.DateRangePriceVo;
 import com.tourism.webadmin.app.website.vo.DateRangesPriceVo;
+import com.tourism.webadmin.back.dto.TourTourismProjectTravelNotesDto;
+import com.tourism.webadmin.back.dto.TourismProjectDto;
+import com.tourism.webadmin.back.model.TourTourismProjectTravelNotes;
 import com.tourism.webadmin.back.model.TourismDatePrice;
 import com.tourism.webadmin.back.model.TourismProject;
+import com.tourism.webadmin.back.service.TourTourismProjectTravelNotesService;
 import com.tourism.webadmin.back.service.TourismDatePriceService;
 import com.tourism.webadmin.back.service.TourismProjectService;
-import com.tourism.webadmin.back.vo.TourismProjectVo;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.time.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
@@ -28,7 +29,6 @@ import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.ZoneId;
 import java.util.ArrayList;
-import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -49,6 +49,8 @@ public class ExtraController {
     private TourismDatePriceService tourismDatePriceService;
     @Autowired
     private TourismProjectService tourismProjectService;
+    @Autowired
+    private TourTourismProjectTravelNotesService tourTourismProjectTravelNotesService;
     /**
      * 查看指定旅游项目的日历价格。
      *
@@ -133,9 +135,18 @@ public class ExtraController {
     @SaCheckPermission("tourismProject.view")
     @PostMapping("/saveDatePrice")
     public ResponseResult<Void> saveDatePrice(@RequestBody DatePriceSaveDto datePriceSaveDto) {
-        //dateRangesPriceVoList为空的话,直接返回成功
+        //dateRangesPriceVoList为空的话,则删除全部的日历价格
         if(CollectionUtils.isEmpty(datePriceSaveDto.getDateRangesPriceVoList())){
-            return ResponseResult.success();
+            TourismProject tourismProject = tourismProjectService.getById(datePriceSaveDto.getProjectId());
+            if(tourismProject == null){
+                return ResponseResult.error(ErrorCodeEnum.DATA_SAVE_FAILED,"旅游项目不存在");
+                }else {
+                TourismDatePrice filter = new TourismDatePrice();
+                filter.setProjectId(datePriceSaveDto.getProjectId());
+                filter.setNowDate(MyDateUtil.truncateToDay(new Date()));
+                List<TourismDatePrice> tourismDatePriceList = tourismDatePriceService.getTourismDatePriceList(filter, "");
+                tourismDatePriceList.stream().map(TourismDatePrice::getId).forEach(tourismDatePriceService::remove);
+            }
         }
         //取旅游项目的价格,来对列表数据进行对比,如果列表数据低于旅游项目的价格,则进行提示
         TourismProject tourismProject = tourismProjectService.getById(datePriceSaveDto.getProjectId());
@@ -226,5 +237,57 @@ public class ExtraController {
         });
         return ResponseResult.success();
     }
+    /**
+     * 更新项目的状态(1.启用;0.禁用。)
+     *
+     * @param tourismProjectDto 旅游项目管理Dto对象。
+     * @return void。
+     */
+    @Transactional
+    @SaCheckPermission("tourismProject.update")
+    @PostMapping("/updateProjectState")
+    public ResponseResult<Void> updateProjectState(@MyRequestBody TourismProjectDto tourismProjectDto) {
+        TourismProject tourismProject = tourismProjectService.getById(tourismProjectDto.getId());
+        if (tourismProject == null) {
+            return ResponseResult.error(ErrorCodeEnum.PROJECT_NOT_EXIST);
+        }
+        if(tourismProjectDto.getEnable() == 1) {
+            //查看该项目是否设置日历;设置日历,则允许修改项目状态;若未设置日历,则不允许修改项目状态
+            TourismDatePrice tourismDatePrice = new TourismDatePrice();
+            tourismDatePrice.setProjectId(tourismProject.getId());
+            tourismDatePrice.setNowDate(new Date());
+            List<TourismDatePrice> listByFilter = tourismDatePriceService.getTourismDatePriceList(tourismDatePrice,"");
+            if (listByFilter.isEmpty()) {
+                return ResponseResult.error(ErrorCodeEnum.DATE_PRICE_NOTEXIST);
+            }
+        }
+        TourismProject originalTourismProject = MyModelUtil.copyTo(tourismProject, TourismProject.class);
+        tourismProject.setEnable(tourismProjectDto.getEnable());
+        tourismProjectService.update(tourismProject,originalTourismProject);
+        return ResponseResult.success();
+    }
+
+    /**
+     * 更新游记是否原创的字段(1.原创;0.非原创。)
+     *
+     * @param tourTourismProjectTravelNotesDto 旅游项目游记管理Dto对象。
+     * @return void。
+     */
+    @Transactional
+    @SaCheckPermission("tourTourismProjectTravelNotes.update")
+    @PostMapping("/updateIsOriginalChange")
+    public ResponseResult<Void> updateIsOriginalChange(@MyRequestBody TourTourismProjectTravelNotesDto tourTourismProjectTravelNotesDto) {
+
+        TourTourismProjectTravelNotes tourTourismProjectTravelNote =
+                tourTourismProjectTravelNotesService.getById(tourTourismProjectTravelNotesDto.getId());
+        if(tourTourismProjectTravelNote == null){
+            return ResponseResult.error(ErrorCodeEnum.PROJECT_NOT_EXIST);
+        }
+        TourTourismProjectTravelNotes tourTourismProjectTravelNotes =
+                MyModelUtil.copyTo(tourTourismProjectTravelNote, TourTourismProjectTravelNotes.class);
+        tourTourismProjectTravelNotes.setIsOriginal(tourTourismProjectTravelNotesDto.getIsOriginal());
+        tourTourismProjectTravelNotesService.update(tourTourismProjectTravelNotes,tourTourismProjectTravelNote);
+        return ResponseResult.success();
+    }
 
 }

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

@@ -36,6 +36,7 @@
         <result column="average_cost" jdbcType="VARCHAR" property="averageCost"/>
         <result column="recommendation_rate" jdbcType="TINYINT" property="recommendationRate"/>
         <result column="hot_value" jdbcType="INTEGER" property="hotValue"/>
+        <result column="is_original" jdbcType="INTEGER" property="isOriginal"/>
     </resultMap>
 
     <insert id="insertList">
@@ -73,7 +74,8 @@
             departure_time,
             average_cost,
             recommendation_rate,
-            hot_value)
+            hot_value,
+            is_original)
         VALUES
         <foreach collection="list" index="index" item="item" separator="," >
             (#{item.id},
@@ -109,7 +111,8 @@
             #{item.departureTime},
             #{item.averageCost},
             #{item.recommendationRate},
-            #{item.hotValue})
+            #{item.hotValue},
+            #{item.isOriginal})
         </foreach>
     </insert>
 

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

@@ -212,6 +212,12 @@ public class TourTourismProjectTravelNotesDto {
     private Integer hotValue;
 
     /**
+     * 是否原创。
+     */
+    @Schema(description = "是否原创。")
+    private Integer isOriginal;
+
+    /**
      * remarks / project_label / start_place / end_place / short_title / short_description / contact_description LIKE搜索字符串。
      * NOTE: 可支持LIKE操作符的列表数据过滤。
      */

+ 5 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourBookInfo.java

@@ -136,4 +136,9 @@ public class TourBookInfo extends BaseModel {
             dictCode = "IsHandle")
     @TableField(exist = false)
     private Map<String, Object> isHandleDictMap;
+
+
+    public String getString() {
+        return type + "_" + projectId + "_" + adultNumber + "_" + childrenNumber + "_" + startTime;
+    }
 }

+ 6 - 1
application-webadmin/src/main/java/com/tourism/webadmin/back/model/TourTourismProjectTravelNotes.java

@@ -1,7 +1,6 @@
 package com.tourism.webadmin.back.model;
 
 import com.baomidou.mybatisplus.annotation.*;
-import com.fasterxml.jackson.annotation.JsonFormat;
 import com.tourism.webadmin.back.model.constant.Hotspot;
 import com.tourism.webadmin.back.model.constant.Enable;
 import com.tourism.common.core.util.MyCommonUtil;
@@ -212,6 +211,12 @@ public class TourTourismProjectTravelNotes extends BaseModel {
     private Integer hotValue;
 
     /**
+     * 是否原创。
+     */
+    @TableField(value = "is_original")
+    private Integer isOriginal;
+
+    /**
      * remarks / project_label / start_place / end_place / short_title / short_description / contact_description LIKE搜索字符串。
      */
     @TableField(exist = false)

+ 7 - 0
application-webadmin/src/main/java/com/tourism/webadmin/back/vo/TourTourismProjectTravelNotesVo.java

@@ -1,5 +1,6 @@
 package com.tourism.webadmin.back.vo;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.tourism.common.core.base.vo.BaseVo;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -206,6 +207,12 @@ public class TourTourismProjectTravelNotesVo extends BaseVo {
     private String contactCode;
 
     /**
+     * 是否原创。
+     */
+    @Schema(description = "是否原创")
+    private Integer isOriginal;
+
+    /**
      * id 的一对一关联数据对象,数据对应类型为TourTourismTravelNotesFileVo。
      */
     @Schema(description = "id 的一对一关联数据对象,数据对应类型为TourTourismTravelNotesFileVo")

+ 5 - 5
application-webadmin/src/main/resources/application-test.yml

@@ -10,27 +10,27 @@ spring:
       main:
         url: jdbc:mysql://101.126.146.250:3306/tourism?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
         username: root
-        password: xyy1q2w!
+        password: XYY1q2w!
       # 默认生成的操作日志数据源配置。
       operation-log:
         url: jdbc:mysql://101.126.146.250:3306/tourism?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
         username: root
-        password: xyy1q2w!
+        password: XYY1q2w!
       # 默认生成的全局编码字典数据源配置。
       global-dict:
         url: jdbc:mysql://101.126.146.250:3306/tourism?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
         username: root
-        password: xyy1q2w!
+        password: XYY1q2w!
       # 默认生成的工作流及在线表单数据源配置。
       common-flow-online:
         url: jdbc:mysql://101.126.146.250:3306/tourism?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
         username: root
-        password: xyy1q2w!
+        password: XYY1q2w!
       # 默认生成的统计打印模块的数据源配置。
       common-report:
         url: jdbc:mysql://101.126.146.250:3306/tourism?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
         username: root
-        password: xyy1q2w!
+        password: XYY1q2w!
       driverClassName: com.mysql.cj.jdbc.Driver
       name: application-webadmin
       initialSize: 10

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

@@ -71,7 +71,9 @@ public enum ErrorCodeEnum {
     MOBILE_EXIST("该手机号已被注册!"),
     PROJECT_ALREADY_BOOKING("该项目已被您预定,请选择其他项目!"),
     DATE_OVERLAP("日期重叠,请重新选择!"),
-    PRICE_ERROR("价格错误,请重新填写!");
+    PRICE_ERROR("价格错误,请重新填写!"),
+    PROJECT_NOT_EXIST("该项目不存在,请重新选择!"),
+    DATE_PRICE_NOTEXIST("请先编辑日历价格!");
     // 下面的枚举值为特定枚举值,即开发者可以根据自己的项目需求定义更多的非通用枚举值
 
     /**