Browse Source

增加用户预约信息的接口

chenchen 6 months ago
parent
commit
d6b6941b91

+ 20 - 10
application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/LoginToWebsiteController.java

@@ -30,6 +30,7 @@ import com.tourism.common.log.annotation.OperationLog;
 import com.tourism.common.log.model.constant.SysOperationLogType;
 import com.tourism.common.redis.cache.SessionCacheHelper;
 import com.tourism.common.satoken.util.SaTokenUtil;
+import com.tourism.webadmin.app.website.dto.TourBookInfoDto;
 import com.tourism.webadmin.app.website.dto.TourUserRegisterDto;
 import com.tourism.webadmin.app.website.model.TourUser;
 import com.tourism.webadmin.app.website.model.constant.TourUserStatus;
@@ -40,6 +41,7 @@ import com.tourism.webadmin.upms.model.SysUser;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import com.tourism.common.core.annotation.DisableDataFilter;
 import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.RedissonClient;
@@ -95,11 +97,26 @@ public class LoginToWebsiteController {
     private static final String HEAD_IMAGE_URL_FIELD = "headImageUrl";
 
     /**
+     * 门户网站留存信息
+     */
+    @SaIgnore
+    @Transactional(rollbackFor = Exception.class)
+    @PostMapping("saveBookInfo")
+    public ResponseResult<Void> saveBookInfo(HttpServletRequest request,
+                                             @MyRequestBody TourBookInfoDto tourBookInfoDto){
+        boolean isSave =
+                loginToWebsiteService.saveBookInfo(request, tourBookInfoDto.getBookMobile(), tourBookInfoDto.getBookName());
+        if(!isSave){
+            return ResponseResult.error(ErrorCodeEnum.DATA_SAVE_FAILED);
+        }
+        return ResponseResult.success();
+    }
+    /**
      * 生成验证码(math)
      */
     @SaIgnore
     @GetMapping("/captchaImage")
-    public AjaxResult getCode(HttpServletResponse response) throws IOException
+    public AjaxResult getCode() throws IOException
     {
         AjaxResult ajax = AjaxResult.success();
 
@@ -162,15 +179,8 @@ public class LoginToWebsiteController {
         if (tourUserService.getTourUserByLoginMobile(tourUserRegisterDto.getMobile()) != null){
             return ResponseResult.error(ErrorCodeEnum.MOBILE_EXIST);
         }
-
-        //存储用户信息
-        TourUser tourUser = MyModelUtil.copyTo(tourUserRegisterDto, TourUser.class);
-        //手机号注册,默认用户名为手机号
-        tourUser.setLoginName(tourUserRegisterDto.getMobile());
-        tourUser.setUserStatus(TourUserStatus.STATUS_NORMAL);
-        tourUser.setPassword(passwordEncoder.encode(tourUser.getPassword()));
-        tourUser = tourUserService.saveNew(tourUser);
-        return ResponseResult.success(tourUser.getUserId());
+        loginToWebsiteService.saveRegisterUserInfo(tourUserRegisterDto);
+        return ResponseResult.success();
 
     }
 

+ 269 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/controller/TourBookInfoController.java

@@ -0,0 +1,269 @@
+package com.tourism.webadmin.app.website.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.tourism.common.log.annotation.OperationLog;
+import com.tourism.common.log.model.constant.SysOperationLogType;
+import com.github.pagehelper.page.PageMethod;
+import com.tourism.webadmin.app.website.vo.*;
+import com.tourism.webadmin.app.website.dto.*;
+import com.tourism.webadmin.app.website.model.*;
+import com.tourism.webadmin.app.website.service.*;
+import com.tourism.common.core.object.*;
+import com.tourism.common.core.util.*;
+import com.tourism.common.core.constant.*;
+import com.tourism.common.core.annotation.MyRequestBody;
+import com.tourism.webadmin.config.ApplicationConfig;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * 门户预定管理操作控制器类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Tag(name = "门户预定管理管理接口")
+@Slf4j
+@RestController
+@RequestMapping("/admin/app/tourBookInfo")
+public class TourBookInfoController {
+
+    @Autowired
+    private ApplicationConfig appConfig;
+    @Autowired
+    private TourBookInfoService tourBookInfoService;
+
+    /**
+     * 新增门户预定管理数据。
+     *
+     * @param tourBookInfoDto 新增对象。
+     * @return 应答结果对象,包含新增对象主键Id。
+     */
+    @ApiOperationSupport(ignoreParameters = {"tourBookInfoDto.id", "tourBookInfoDto.searchString"})
+    @SaCheckPermission("tourBookInfo.add")
+    @OperationLog(type = SysOperationLogType.ADD)
+    @PostMapping("/add")
+    public ResponseResult<Long> add(@MyRequestBody TourBookInfoDto tourBookInfoDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourBookInfoDto, false);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        TourBookInfo tourBookInfo = MyModelUtil.copyTo(tourBookInfoDto, TourBookInfo.class);
+        // 验证关联Id的数据合法性
+        CallResult callResult = tourBookInfoService.verifyRelatedData(tourBookInfo, null);
+        if (!callResult.isSuccess()) {
+            return ResponseResult.errorFrom(callResult);
+        }
+        tourBookInfo = tourBookInfoService.saveNew(tourBookInfo);
+        return ResponseResult.success(tourBookInfo.getId());
+    }
+
+    /**
+     * 更新门户预定管理数据。
+     *
+     * @param tourBookInfoDto 更新对象。
+     * @return 应答结果对象。
+     */
+    @ApiOperationSupport(ignoreParameters = {"tourBookInfoDto.searchString"})
+    @SaCheckPermission("tourBookInfo.update")
+    @OperationLog(type = SysOperationLogType.UPDATE)
+    @PostMapping("/update")
+    public ResponseResult<Void> update(@MyRequestBody TourBookInfoDto tourBookInfoDto) {
+        String errorMessage = MyCommonUtil.getModelValidationError(tourBookInfoDto, true);
+        if (errorMessage != null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
+        }
+        TourBookInfo tourBookInfo = MyModelUtil.copyTo(tourBookInfoDto, TourBookInfo.class);
+        TourBookInfo originalTourBookInfo = tourBookInfoService.getById(tourBookInfo.getId());
+        if (originalTourBookInfo == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        // 验证关联Id的数据合法性
+        CallResult callResult = tourBookInfoService.verifyRelatedData(tourBookInfo, originalTourBookInfo);
+        if (!callResult.isSuccess()) {
+            return ResponseResult.errorFrom(callResult);
+        }
+        if (!tourBookInfoService.update(tourBookInfo, originalTourBookInfo)) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 删除门户预定管理数据。
+     *
+     * @param id 删除对象主键Id。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourBookInfo.delete")
+    @OperationLog(type = SysOperationLogType.DELETE)
+    @PostMapping("/delete")
+    public ResponseResult<Void> delete(@MyRequestBody Long id) {
+        if (MyCommonUtil.existBlankArgument(id)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        return this.doDelete(id);
+    }
+
+    /**
+     * 批量删除门户预定管理数据。
+     *
+     * @param idList 待删除对象的主键Id列表。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourBookInfo.delete")
+    @OperationLog(type = SysOperationLogType.DELETE_BATCH)
+    @PostMapping("/deleteBatch")
+    public ResponseResult<Void> deleteBatch(@MyRequestBody List<Long> idList) {
+        if (MyCommonUtil.existBlankArgument(idList)) {
+            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
+        }
+        for (Long id : idList) {
+            ResponseResult<Void> responseResult = this.doDelete(id);
+            if (!responseResult.isSuccess()) {
+                return responseResult;
+            }
+        }
+        return ResponseResult.success();
+    }
+
+    /**
+     * 列出符合过滤条件的门户预定管理列表。
+     *
+     * @param tourBookInfoDtoFilter 过滤对象。
+     * @param orderParam 排序参数。
+     * @param pageParam 分页参数。
+     * @return 应答结果对象,包含查询结果集。
+     */
+    @SaCheckPermission("tourBookInfo.view")
+    @PostMapping("/list")
+    public ResponseResult<MyPageData<TourBookInfoVo>> list(
+            @MyRequestBody TourBookInfoDto tourBookInfoDtoFilter,
+            @MyRequestBody MyOrderParam orderParam,
+            @MyRequestBody MyPageParam pageParam) {
+        if (pageParam != null) {
+            PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
+        }
+        TourBookInfo tourBookInfoFilter = MyModelUtil.copyTo(tourBookInfoDtoFilter, TourBookInfo.class);
+        String orderBy = MyOrderParam.buildOrderBy(orderParam, TourBookInfo.class);
+        List<TourBookInfo> tourBookInfoList =
+                tourBookInfoService.getTourBookInfoListWithRelation(tourBookInfoFilter, orderBy);
+        return ResponseResult.success(MyPageUtil.makeResponseData(tourBookInfoList, TourBookInfoVo.class));
+    }
+
+    /**
+     * 导入主表数据列表。
+     *
+     * @param importFile 上传的文件,目前仅仅支持xlsx和xls两种格式。
+     * @return 应答结果对象。
+     */
+    @SaCheckPermission("tourBookInfo.import")
+    @OperationLog(type = SysOperationLogType.IMPORT)
+    @PostMapping("/import")
+    public ResponseResult<Void> importBatch(
+            @RequestParam Boolean skipHeader,
+            @RequestParam("importFile") MultipartFile importFile) throws IOException {
+        String filename = ImportUtil.saveImportFile(appConfig.getUploadFileBaseDir(), null, importFile);
+        // 这里可以指定需要忽略导入的字段集合。如创建时间、创建人、更新时间、更新人、主键Id和逻辑删除,
+        // 以及一些存在缺省值且无需导入的字段。其中主键字段和逻辑删除字段不需要在这里设置,批量插入逻辑会自动处理的。
+        Set<String> ignoreFieldSet = new HashSet<>();
+        ignoreFieldSet.add("createUserId");
+        ignoreFieldSet.add("createTime");
+        ignoreFieldSet.add("updateUserId");
+        ignoreFieldSet.add("updateTime");
+        List<ImportUtil.ImportHeaderInfo> headerInfoList = ImportUtil.makeHeaderInfoList(TourBookInfo.class, ignoreFieldSet);
+        // 下面是导入时需要注意的地方,如果我们缺省生成的代码,与实际情况存在差异,请手动修改。
+        // 1. 头信息数据字段,我们只是根据当前的主表实体对象生成了缺省数组,开发者可根据实际情况,对headerInfoList进行修改。
+        ImportUtil.ImportHeaderInfo[] headerInfos = headerInfoList.toArray(new ImportUtil.ImportHeaderInfo[]{});
+        // 2. 这里需要根据实际情况决定,导入文件中第一行是否为中文头信息,如果是可以跳过。这里我们默认为true。
+        // 这里根据自己的实际需求,为doImport的最后一个参数,传递需要进行字典转换的字段集合。
+        // 注意,集合中包含需要翻译的Java字段名,如: gradeId。
+        Set<String> translatedDictFieldSet = new HashSet<>();
+        List<TourBookInfo> dataList =
+                ImportUtil.doImport(headerInfos, skipHeader, filename, TourBookInfo.class, translatedDictFieldSet);
+        CallResult result = tourBookInfoService.verifyImportList(dataList, translatedDictFieldSet);
+        if (!result.isSuccess()) {
+            // result中返回了具体的验证失败对象,如果需要返回更加详细的错误,可根据实际情况手动修改。
+            return ResponseResult.errorFrom(result);
+        }
+        tourBookInfoService.saveNewBatch(dataList, -1);
+        return ResponseResult.success();
+    }
+
+    /**
+     * 导出符合过滤条件的门户预定管理列表。
+     *
+     * @param tourBookInfoDtoFilter 过滤对象。
+     * @param orderParam 排序参数。
+     * @throws IOException 文件读写失败。
+     */
+    @SaCheckPermission("tourBookInfo.export")
+    @OperationLog(type = SysOperationLogType.EXPORT, saveResponse = false)
+    @PostMapping("/export")
+    public void export(
+            @MyRequestBody TourBookInfoDto tourBookInfoDtoFilter,
+            @MyRequestBody MyOrderParam orderParam) throws IOException {
+        TourBookInfo tourBookInfoFilter = MyModelUtil.copyTo(tourBookInfoDtoFilter, TourBookInfo.class);
+        String orderBy = MyOrderParam.buildOrderBy(orderParam, TourBookInfo.class);
+        List<TourBookInfo> resultList =
+                tourBookInfoService.getTourBookInfoListWithRelation(tourBookInfoFilter, orderBy);
+        // 导出文件的标题数组
+        // NOTE: 下面的代码中仅仅导出了主表数据,主表聚合计算数据和主表关联字典的数据。
+        // 一对一从表数据的导出,可根据需要自行添加。如:headerMap.put("slaveFieldName.xxxField", "标题名称")
+        Map<String, String> headerMap = new LinkedHashMap<>(11);
+        headerMap.put("id", "主键id");
+        headerMap.put("bookMobile", "预定电话");
+        headerMap.put("bookName", "预定姓名");
+        headerMap.put("bookIp", "预定的ip");
+        headerMap.put("bookTime", "预定时间");
+        headerMap.put("isHandleDictMap.name", "是否处理(0:未处理 1:已处理)");
+        headerMap.put("createUserId", "创建者Id");
+        headerMap.put("createTime", "创建时间");
+        headerMap.put("updateUserId", "更新者Id");
+        headerMap.put("updateTime", "最后更新时间");
+        headerMap.put("deletedFlag", "删除标记(1: 正常 -1: 已删除)");
+        ExportUtil.doExport(resultList, headerMap, "tourBookInfo.xlsx");
+    }
+
+    /**
+     * 查看指定门户预定管理对象详情。
+     *
+     * @param id 指定对象主键Id。
+     * @return 应答结果对象,包含对象详情。
+     */
+    @SaCheckPermission("tourBookInfo.view")
+    @GetMapping("/view")
+    public ResponseResult<TourBookInfoVo> view(@RequestParam Long id) {
+        TourBookInfo tourBookInfo = tourBookInfoService.getByIdWithRelation(id, MyRelationParam.full());
+        if (tourBookInfo == null) {
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
+        }
+        TourBookInfoVo tourBookInfoVo = MyModelUtil.copyTo(tourBookInfo, TourBookInfoVo.class);
+        return ResponseResult.success(tourBookInfoVo);
+    }
+
+    private ResponseResult<Void> doDelete(Long id) {
+        String errorMessage;
+        // 验证关联Id的数据合法性
+        TourBookInfo originalTourBookInfo = tourBookInfoService.getById(id);
+        if (originalTourBookInfo == null) {
+            // NOTE: 修改下面方括号中的话述
+            errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        if (!tourBookInfoService.remove(id)) {
+            errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
+            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
+        }
+        return ResponseResult.success();
+    }
+}

+ 33 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/dao/TourBookInfoMapper.java

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

+ 90 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/dao/mapper/TourBookInfoMapper.xml

@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.tourism.webadmin.app.website.dao.TourBookInfoMapper">
+    <resultMap id="BaseResultMap" type="com.tourism.webadmin.app.website.model.TourBookInfo">
+        <id column="id" jdbcType="BIGINT" property="id"/>
+        <result column="book_mobile" jdbcType="VARCHAR" property="bookMobile"/>
+        <result column="book_name" jdbcType="VARCHAR" property="bookName"/>
+        <result column="book_ip" jdbcType="VARCHAR" property="bookIp"/>
+        <result column="book_time" jdbcType="TIMESTAMP" property="bookTime"/>
+        <result column="is_handle" jdbcType="CHAR" property="isHandle"/>
+        <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="deleted_flag" jdbcType="INTEGER" property="deletedFlag"/>
+    </resultMap>
+
+    <insert id="insertList">
+        INSERT INTO tour_book_info
+            (id,
+            book_mobile,
+            book_name,
+            book_ip,
+            book_time,
+            is_handle,
+            create_user_id,
+            create_time,
+            update_user_id,
+            update_time,
+            deleted_flag)
+        VALUES
+        <foreach collection="list" index="index" item="item" separator="," >
+            (#{item.id},
+            #{item.bookMobile},
+            #{item.bookName},
+            #{item.bookIp},
+            #{item.bookTime},
+            #{item.isHandle},
+            #{item.createUserId},
+            #{item.createTime},
+            #{item.updateUserId},
+            #{item.updateTime},
+            #{item.deletedFlag})
+        </foreach>
+    </insert>
+
+    <!-- 如果有逻辑删除字段过滤,请写到这里 -->
+    <sql id="filterRef">
+        <!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
+        <include refid="com.tourism.webadmin.app.website.dao.TourBookInfoMapper.inputFilterRef"/>
+        AND tour_book_info.deleted_flag = ${@com.tourism.common.core.constant.GlobalDeletedFlag@NORMAL}
+    </sql>
+
+    <!-- 这里仅包含调用接口输入的主表过滤条件 -->
+    <sql id="inputFilterRef">
+        <if test="tourBookInfoFilter != null">
+            <if test="tourBookInfoFilter.bookMobile != null and tourBookInfoFilter.bookMobile != ''">
+                <bind name = "safeTourBookInfoBookMobile" value = "'%' + tourBookInfoFilter.bookMobile + '%'" />
+                AND tour_book_info.book_mobile LIKE #{safeTourBookInfoBookMobile}
+            </if>
+            <if test="tourBookInfoFilter.bookName != null and tourBookInfoFilter.bookName != ''">
+                <bind name = "safeTourBookInfoBookName" value = "'%' + tourBookInfoFilter.bookName + '%'" />
+                AND tour_book_info.book_name LIKE #{safeTourBookInfoBookName}
+            </if>
+            <if test="tourBookInfoFilter.bookIp != null and tourBookInfoFilter.bookIp != ''">
+                AND tour_book_info.book_ip = #{tourBookInfoFilter.bookIp}
+            </if>
+            <if test="tourBookInfoFilter.bookTime != null">
+                AND tour_book_info.book_time = #{tourBookInfoFilter.bookTime}
+            </if>
+            <if test="tourBookInfoFilter.isHandle != null and tourBookInfoFilter.isHandle != ''">
+                AND tour_book_info.is_handle = #{tourBookInfoFilter.isHandle}
+            </if>
+            <if test="tourBookInfoFilter.searchString != null and tourBookInfoFilter.searchString != ''">
+                <bind name = "safeTourBookInfoSearchString" value = "'%' + tourBookInfoFilter.searchString + '%'" />
+                AND CONCAT(IFNULL(tour_book_info.book_mobile,''), IFNULL(tour_book_info.book_name,'')) LIKE #{safeTourBookInfoSearchString}
+            </if>
+        </if>
+    </sql>
+
+    <select id="getTourBookInfoList" resultMap="BaseResultMap" parameterType="com.tourism.webadmin.app.website.model.TourBookInfo">
+        SELECT * FROM tour_book_info
+        <where>
+            <include refid="filterRef"/>
+        </where>
+        <if test="orderBy != null and orderBy != ''">
+            ORDER BY ${orderBy}
+        </if>
+    </select>
+</mapper>

+ 71 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/dto/TourBookInfoDto.java

@@ -0,0 +1,71 @@
+package com.tourism.webadmin.app.website.dto;
+
+import com.tourism.common.core.validator.UpdateGroup;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.*;
+
+import java.util.Date;
+
+/**
+ * 门户预定管理Dto对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "TourBookInfoDto对象")
+@Data
+public class TourBookInfoDto {
+
+    /**
+     * 主键id。
+     */
+    @Schema(description = "主键id。", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "数据验证失败,主键id不能为空!", groups = {UpdateGroup.class})
+    private Long id;
+
+    /**
+     * 预定电话。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "预定电话。可支持等于操作符的列表数据过滤。")
+    private String bookMobile;
+
+    /**
+     * 预定姓名。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "预定姓名。可支持等于操作符的列表数据过滤。")
+    private String bookName;
+
+    /**
+     * 预定的ip。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "预定的ip。可支持等于操作符的列表数据过滤。")
+    private String bookIp;
+
+    /**
+     * 预定时间。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "预定时间。可支持等于操作符的列表数据过滤。", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "数据验证失败,预定时间不能为空!")
+    private Date bookTime;
+
+    /**
+     * 是否处理(0:未处理 1:已处理)。
+     * NOTE: 可支持等于操作符的列表数据过滤。
+     */
+    @Schema(description = "是否处理(0:未处理 1:已处理)。可支持等于操作符的列表数据过滤。")
+    private String isHandle;
+
+    /**
+     * book_mobile / book_name LIKE搜索字符串。
+     * NOTE: 可支持LIKE操作符的列表数据过滤。
+     */
+    @Schema(description = "LIKE模糊搜索字符串")
+    private String searchString;
+}

+ 82 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/model/TourBookInfo.java

@@ -0,0 +1,82 @@
+package com.tourism.webadmin.app.website.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.tourism.common.core.util.MyCommonUtil;
+import com.tourism.common.core.annotation.*;
+import com.tourism.common.core.base.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * 门户预定管理实体对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName(value = "tour_book_info")
+public class TourBookInfo extends BaseModel {
+
+    /**
+     * 主键id。
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 预定电话。
+     */
+    @TableField(value = "book_mobile")
+    private String bookMobile;
+
+    /**
+     * 预定姓名。
+     */
+    @TableField(value = "book_name")
+    private String bookName;
+
+    /**
+     * 预定的ip。
+     */
+    @TableField(value = "book_ip")
+    private String bookIp;
+
+    /**
+     * 预定时间。
+     */
+    @TableField(value = "book_time")
+    private Date bookTime;
+
+    /**
+     * 是否处理(0:未处理 1:已处理)。
+     */
+    @TableField(value = "is_handle")
+    private String isHandle;
+
+    /**
+     * 逻辑删除标记字段(1: 正常 -1: 已删除)。
+     */
+    @TableLogic
+    @TableField(value = "deleted_flag")
+    private Integer deletedFlag;
+
+    /**
+     * book_mobile / book_name LIKE搜索字符串。
+     */
+    @TableField(exist = false)
+    private String searchString;
+
+    public void setSearchString(String searchString) {
+        this.searchString = MyCommonUtil.replaceSqlWildcard(searchString);
+    }
+
+    @RelationGlobalDict(
+            masterIdField = "isHandle",
+            dictCode = "IsHandle")
+    @TableField(exist = false)
+    private Map<String, Object> isHandleDictMap;
+}

+ 49 - 2
application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/LoginToWebsiteService.java

@@ -1,5 +1,30 @@
 package com.tourism.webadmin.app.website.service;
 
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.BooleanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.tourism.common.core.constant.ApplicationConstant;
+import com.tourism.common.core.constant.ErrorCodeEnum;
+import com.tourism.common.core.object.LoginUserInfo;
+import com.tourism.common.core.object.ResponseResult;
+import com.tourism.common.core.object.TokenData;
+import com.tourism.common.core.util.*;
+import com.tourism.common.satoken.util.SaTokenUtil;
+import com.tourism.webadmin.app.website.dto.TourUserRegisterDto;
+import com.tourism.webadmin.app.website.model.TourUser;
+import com.tourism.webadmin.app.website.model.constant.TourUserStatus;
+import jakarta.servlet.http.HttpServletRequest;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
 /**
  * 注册校验方法
  * 
@@ -8,13 +33,35 @@ package com.tourism.webadmin.app.website.service;
 public interface LoginToWebsiteService
 {
     /**
-     * 校验验证码
+     * 校验图形验证码
      *
      * @param code 验证码
      * @param uuid 唯一标识
      * @return 结果
      */
     public boolean validateCaptcha(String uuid, String code);
-
+    /**
+     * 校验短信验证码
+     *
+     * @param mobile 手机号
+     * @param smsCode 短信验证码
+     * @return 结果
+     */
     public boolean validateSmsCode(String mobile,String smsCode);
+    /**
+     * 保存用户的预约信息
+     *
+     * @param bookMobile 预约手机号
+     * @param bookName 预约姓名
+     * @return 结果
+     */
+    public boolean saveBookInfo(HttpServletRequest request, String bookMobile, String bookName);
+    /**
+     * 保存用户的注册信息
+     *
+     * @param tourUserRegisterDto 预约手机号
+     * @return 结果
+     */
+    public boolean saveRegisterUserInfo(TourUserRegisterDto tourUserRegisterDto);
+
 }

+ 88 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/service/TourBookInfoService.java

@@ -0,0 +1,88 @@
+package com.tourism.webadmin.app.website.service;
+
+import com.tourism.webadmin.app.website.model.*;
+import com.tourism.common.core.object.CallResult;
+import com.tourism.common.core.base.service.IBaseService;
+
+import java.util.*;
+
+/**
+ * 门户预定管理数据操作服务接口。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+public interface TourBookInfoService extends IBaseService<TourBookInfo, Long> {
+
+    /**
+     * 保存新增对象。
+     *
+     * @param tourBookInfo 新增对象。
+     * @return 返回新增对象。
+     */
+    TourBookInfo saveNew(TourBookInfo tourBookInfo);
+
+    /**
+     * 利用数据库的insertList语法,批量插入对象列表。
+     *
+     * @param tourBookInfoList 新增对象列表。
+     */
+    void saveNewBatch(List<TourBookInfo> tourBookInfoList);
+
+    /**
+     * 利用数据库的insertList语法,批量插入对象列表。通常适用于更大的插入数据量,如批量导入。
+     *
+     * @param tourBookInfoList 新增对象列表。
+     * @param batchSize  每批插入的数量。如果该值小于等于0,则使用缺省值10000。
+     */
+    void saveNewBatch(List<TourBookInfo> tourBookInfoList, int batchSize);
+
+    /**
+     * 更新数据对象。
+     *
+     * @param tourBookInfo         更新的对象。
+     * @param originalTourBookInfo 原有数据对象。
+     * @return 成功返回true,否则false。
+     */
+    boolean update(TourBookInfo tourBookInfo, TourBookInfo originalTourBookInfo);
+
+    /**
+     * 删除指定数据。
+     *
+     * @param id 主键Id。
+     * @return 成功返回true,否则false。
+     */
+    boolean remove(Long id);
+
+    /**
+     * 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
+     * 如果需要同时获取关联数据,请移步(getTourBookInfoListWithRelation)方法。
+     *
+     * @param filter  过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<TourBookInfo> getTourBookInfoList(TourBookInfo filter, String orderBy);
+
+    /**
+     * 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
+     * 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
+     * 如果仅仅需要获取主表数据,请移步(getTourBookInfoList),以便获取更好的查询性能。
+     *
+     * @param filter 主表过滤对象。
+     * @param orderBy 排序参数。
+     * @return 查询结果集。
+     */
+    List<TourBookInfo> getTourBookInfoListWithRelation(TourBookInfo filter, String orderBy);
+
+    /**
+     * 对批量导入数据列表进行数据合法性验证。
+     * 验证逻辑主要覆盖主表的常量字典字段、字典表字典字段、数据源字段和一对一关联数据是否存在。
+     *
+     * @param dataList 主表的数据列表。
+     * @param ignoreFieldSet 需要忽略校验的字典字段集合。通常对于字典反向翻译过来的字段适用,
+     *                       避免了二次验证,以提升效率。
+     * @return 验证结果。如果失败,包含具体的错误信息和导致错误的数据对象。
+     */
+    CallResult verifyImportList(List<TourBookInfo> dataList, Set<String> ignoreFieldSet);
+}

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

@@ -1,14 +1,50 @@
 package com.tourism.webadmin.app.website.service.impl;
 
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.BooleanUtil;
+import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.tourism.common.additional.constant.CacheConstants;
 import com.tourism.common.additional.redis.RedisCache;
 import com.tourism.common.additional.utils.StringUtils;
+import com.tourism.common.core.constant.ApplicationConstant;
+import com.tourism.common.core.constant.ErrorCodeEnum;
+import com.tourism.common.core.constant.GlobalDeletedFlag;
+import com.tourism.common.core.object.LoginUserInfo;
+import com.tourism.common.core.object.ResponseResult;
+import com.tourism.common.core.object.TokenData;
+import com.tourism.common.core.util.*;
+import com.tourism.common.satoken.util.SaTokenUtil;
+import com.tourism.common.sequence.wrapper.IdGeneratorWrapper;
+import com.tourism.webadmin.app.website.dao.TourBookInfoMapper;
+import com.tourism.webadmin.app.website.dto.TourUserRegisterDto;
+import com.tourism.webadmin.app.website.model.TourBookInfo;
+import com.tourism.webadmin.app.website.model.TourUser;
+import com.tourism.webadmin.app.website.model.constant.TourUserStatus;
 import com.tourism.webadmin.app.website.service.LoginToWebsiteService;
+import com.tourism.webadmin.app.website.service.TourBookInfoService;
+import com.tourism.webadmin.app.website.service.TourUserService;
+import io.jsonwebtoken.lang.Collections;
+import jakarta.servlet.http.HttpServletRequest;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Service;
 
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
 /**
  * 注册校验方法
  * 
@@ -20,6 +56,32 @@ public class LoginToWebsiteServiceImpl implements LoginToWebsiteService
 {
     @Autowired
     private RedisCache redisCache;
+    @Autowired
+    private TourBookInfoService tourBookInfoService;
+    @Autowired
+    private TourUserService tourUserService;
+    @Autowired
+    private PasswordEncoder passwordEncoder;
+    @Autowired
+    private IdGeneratorWrapper idGenerator;
+    @Autowired
+    private TourBookInfoMapper tourBookInfoMapper;
+    /**
+     * 整个工程的实体对象中,创建者Id字段的Java对象名。
+     */
+    public static final String CREATE_USER_ID_FIELD_NAME = "createUserId";
+    /**
+     * 整个工程的实体对象中,创建时间字段的Java对象名。
+     */
+    public static final String CREATE_TIME_FIELD_NAME = "createTime";
+    /**
+     * 整个工程的实体对象中,更新者Id字段的Java对象名。
+     */
+    public static final String UPDATE_USER_ID_FIELD_NAME = "updateUserId";
+    /**
+     * 整个工程的实体对象中,更新时间字段的Java对象名。
+     */
+    public static final String UPDATE_TIME_FIELD_NAME = "updateTime";
 
     /**
      * 校验验证码
@@ -56,4 +118,86 @@ public class LoginToWebsiteServiceImpl implements LoginToWebsiteService
         }
         return true;
     }
+    /**
+     * 保存用户的预约信息
+     *
+     * @param bookMobile 预约手机号
+     * @param bookName 预约姓名
+     * @return 结果
+     */
+    @Override
+    public boolean saveBookInfo(HttpServletRequest request, String bookMobile, String bookName){
+        //在redis中查看key为该ip的缓存对象是否大于6个;>=6个则不保存了;<6个则进行保存并缓存数据(缓存超时时间为1分钟)
+        String remoteIpAddress = IpUtil.getRemoteIpAddress(request);
+        String startKey = CacheConstants.TOUR_BOOK_IP.concat(remoteIpAddress);
+        String convertStartKey = StringUtils.replacePattern(startKey, ":", "_");
+        Collection<String> keys = redisCache.keys(convertStartKey.concat("*"));
+        if(Collections.isEmpty(keys) || keys.size() < 6) {
+            String key = convertStartKey.concat(String.valueOf(System.currentTimeMillis()));
+//            String key = CacheConstants.TOUR_REGISTER_IP.concat(remoteIpAddress);
+            redisCache.setCacheObject(key, bookMobile, 1, TimeUnit.MINUTES);
+            TourBookInfo tourBookInfo = new TourBookInfo();
+            tourBookInfo.setBookMobile(bookMobile);
+            tourBookInfo.setBookTime(new Date());
+            tourBookInfo.setBookName(bookName);
+            tourBookInfo.setBookIp(remoteIpAddress);
+            tourBookInfo.setIsHandle("0");
+
+            tourBookInfoMapper.insert(buildDefaultValue(tourBookInfo));
+            return true;
+        }else {
+            return false;
+        }
+    }
+
+    private TourBookInfo buildDefaultValue(TourBookInfo tourBookInfo) {
+        if (tourBookInfo.getId() == null) {
+            tourBookInfo.setId(idGenerator.nextLongId());
+        }
+        fillCommonsForInsert(tourBookInfo);
+        tourBookInfo.setDeletedFlag(GlobalDeletedFlag.NORMAL);
+        return tourBookInfo;
+    }
+
+    /**
+     * 在插入实体对象数据之前,可以调用该方法,初始化通用字段的数据。
+     * 在登录之前的操作,所以createdId和updatedId都设置为0.
+     * @param data 实体对象。
+     * @param <M>  实体对象类型。
+     */
+    public static <M> void fillCommonsForInsert(M data) {
+        Field createdByField = ReflectUtil.getField(data.getClass(), CREATE_USER_ID_FIELD_NAME);
+        if (createdByField != null) {
+            ReflectUtil.setFieldValue(data, createdByField, 0L);
+        }
+        Field createTimeField = ReflectUtil.getField(data.getClass(), CREATE_TIME_FIELD_NAME);
+        if (createTimeField != null) {
+            ReflectUtil.setFieldValue(data, createTimeField, new Date());
+        }
+        Field updatedByField = ReflectUtil.getField(data.getClass(), UPDATE_USER_ID_FIELD_NAME);
+        if (updatedByField != null) {
+            ReflectUtil.setFieldValue(data, updatedByField, 0L);
+        }
+        Field updateTimeField = ReflectUtil.getField(data.getClass(), UPDATE_TIME_FIELD_NAME);
+        if (updateTimeField != null) {
+            ReflectUtil.setFieldValue(data, updateTimeField, new Date());
+        }
+    }
+    /**
+     * 保存用户的注册信息
+     *
+     * @param tourUserRegisterDto 预约手机号
+     * @return 结果
+     */
+    @Override
+    public boolean saveRegisterUserInfo(TourUserRegisterDto tourUserRegisterDto){
+        //存储用户信息
+        TourUser tourUser = new TourUser();
+        //手机号注册,默认用户名为手机号
+        tourUser.setLoginName(tourUserRegisterDto.getMobile());
+        tourUser.setUserStatus(TourUserStatus.STATUS_NORMAL);
+        tourUser.setPassword(passwordEncoder.encode(tourUser.getPassword()));
+        tourUserService.saveNew(tourUser);
+        return true;
+    }
 }

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

@@ -0,0 +1,156 @@
+package com.tourism.webadmin.app.website.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.tourism.webadmin.app.website.service.*;
+import com.tourism.webadmin.app.website.dao.*;
+import com.tourism.webadmin.app.website.model.*;
+import com.tourism.webadmin.config.DataSourceType;
+import com.tourism.common.core.annotation.MyDataSource;
+import com.tourism.common.core.base.dao.BaseDaoMapper;
+import com.tourism.common.core.constant.GlobalDeletedFlag;
+import com.tourism.common.core.object.MyRelationParam;
+import com.tourism.common.core.object.CallResult;
+import com.tourism.common.core.base.service.BaseService;
+import com.tourism.common.core.util.MyModelUtil;
+import com.tourism.common.sequence.wrapper.IdGeneratorWrapper;
+import com.tourism.common.dict.service.GlobalDictService;
+import com.github.pagehelper.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * 门户预定管理数据操作服务类。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Slf4j
+@MyDataSource(DataSourceType.MAIN)
+@Service("tourBookInfoService")
+public class TourBookInfoServiceImpl extends BaseService<TourBookInfo, Long> implements TourBookInfoService {
+
+    @Autowired
+    private IdGeneratorWrapper idGenerator;
+    @Autowired
+    private TourBookInfoMapper tourBookInfoMapper;
+    @Autowired
+    private GlobalDictService globalDictService;
+
+    /**
+     * 返回当前Service的主表Mapper对象。
+     *
+     * @return 主表Mapper对象。
+     */
+    @Override
+    protected BaseDaoMapper<TourBookInfo> mapper() {
+        return tourBookInfoMapper;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public TourBookInfo saveNew(TourBookInfo tourBookInfo) {
+        tourBookInfoMapper.insert(this.buildDefaultValue(tourBookInfo));
+        return tourBookInfo;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void saveNewBatch(List<TourBookInfo> tourBookInfoList) {
+        if (CollUtil.isNotEmpty(tourBookInfoList)) {
+            tourBookInfoList.forEach(this::buildDefaultValue);
+            tourBookInfoMapper.insertList(tourBookInfoList);
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void saveNewBatch(List<TourBookInfo> tourBookInfoList, int batchSize) {
+        if (CollUtil.isEmpty(tourBookInfoList)) {
+            return;
+        }
+        if (batchSize <= 0) {
+            batchSize = 10000;
+        }
+        int start = 0;
+        do {
+            int end = Math.min(tourBookInfoList.size(), start + batchSize);
+            List<TourBookInfo> subList = tourBookInfoList.subList(start, end);
+            // 如果数据量过大,同时当前表中存在createTime或updateTime等字段,可以考虑在外部创建一次 new Date(),
+            // 然后传入buildDefaultValue,这样可以减少对象的创建次数,降低GC,提升效率。橙单之所以没有这样生成,是因为
+            // 有些业务场景下需要按照这两个日期字段排序,因此我们只是在这里给出优化建议。
+            subList.forEach(this::buildDefaultValue);
+            tourBookInfoMapper.insertList(subList);
+            if (end == tourBookInfoList.size()) {
+                break;
+            }
+            start += batchSize;
+        } while (true);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean update(TourBookInfo tourBookInfo, TourBookInfo originalTourBookInfo) {
+        MyModelUtil.fillCommonsForUpdate(tourBookInfo, originalTourBookInfo);
+        // 这里重点提示,在执行主表数据更新之前,如果有哪些字段不支持修改操作,请用原有数据对象字段替换当前数据字段。
+        UpdateWrapper<TourBookInfo> uw = this.createUpdateQueryForNullValue(tourBookInfo, tourBookInfo.getId());
+        return tourBookInfoMapper.update(tourBookInfo, uw) == 1;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean remove(Long id) {
+        return tourBookInfoMapper.deleteById(id) == 1;
+    }
+
+    @Override
+    public List<TourBookInfo> getTourBookInfoList(TourBookInfo filter, String orderBy) {
+        return tourBookInfoMapper.getTourBookInfoList(filter, orderBy);
+    }
+
+    @Override
+    public List<TourBookInfo> getTourBookInfoListWithRelation(TourBookInfo filter, String orderBy) {
+        List<TourBookInfo> resultList = tourBookInfoMapper.getTourBookInfoList(filter, orderBy);
+        // 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
+        // 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
+        int batchSize = resultList instanceof Page ? 0 : 1000;
+        this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
+        return resultList;
+    }
+
+    @Override
+    public CallResult verifyImportList(List<TourBookInfo> dataList, Set<String> ignoreFieldSet) {
+        CallResult callResult;
+        if (!CollUtil.contains(ignoreFieldSet, "isHandle")) {
+            callResult = verifyImportForGlobalDict(dataList, "isHandleDictMap", TourBookInfo::getIsHandle);
+            if (!callResult.isSuccess()) {
+                return callResult;
+            }
+        }
+        return CallResult.ok();
+    }
+
+    @Override
+    public CallResult verifyRelatedData(TourBookInfo tourBookInfo, TourBookInfo originalTourBookInfo) {
+        String errorMessageFormat = "数据验证失败,关联的%s并不存在,请刷新后重试!";
+        //这里是基于字典的验证。
+        if (this.needToVerify(tourBookInfo, originalTourBookInfo, TourBookInfo::getIsHandle)
+                && !globalDictService.existDictItemFromCache("IsHandle", tourBookInfo.getIsHandle())) {
+            return CallResult.error(String.format(errorMessageFormat, "是否处理(0:未处理 1:已处理)"));
+        }
+        return CallResult.ok();
+    }
+
+    private TourBookInfo buildDefaultValue(TourBookInfo tourBookInfo) {
+        if (tourBookInfo.getId() == null) {
+            tourBookInfo.setId(idGenerator.nextLongId());
+        }
+        MyModelUtil.fillCommonsForInsert(tourBookInfo);
+        tourBookInfo.setDeletedFlag(GlobalDeletedFlag.NORMAL);
+        return tourBookInfo;
+    }
+}

+ 64 - 0
application-webadmin/src/main/java/com/tourism/webadmin/app/website/vo/TourBookInfoVo.java

@@ -0,0 +1,64 @@
+package com.tourism.webadmin.app.website.vo;
+
+import com.tourism.common.core.base.vo.BaseVo;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.joda.time.DateTime;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * 门户预定管理VO视图对象。
+ *
+ * @author 吃饭睡觉
+ * @date 2024-09-06
+ */
+@Schema(description = "TourBookInfoVO视图对象")
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TourBookInfoVo extends BaseVo {
+
+    /**
+     * 主键id。
+     */
+    @Schema(description = "主键id")
+    private Long id;
+
+    /**
+     * 预定电话。
+     */
+    @Schema(description = "预定电话")
+    private String bookMobile;
+
+    /**
+     * 预定姓名。
+     */
+    @Schema(description = "预定姓名")
+    private String bookName;
+
+    /**
+     * 预定的ip。
+     */
+    @Schema(description = "预定的ip")
+    private String bookIp;
+
+    /**
+     * 预定时间。
+     */
+    @Schema(description = "预定时间")
+    private DateTime bookTime;
+
+    /**
+     * 是否处理(0:未处理 1:已处理)。
+     */
+    @Schema(description = "是否处理(0:未处理 1:已处理)")
+    private String isHandle;
+
+    /**
+     * isHandle 全局字典关联数据。
+     */
+    @Schema(description = "isHandle 全局字典关联数据")
+    private Map<String, Object> isHandleDictMap;
+}

+ 4 - 0
common/common-additional/src/main/java/com/tourism/common/additional/constant/CacheConstants.java

@@ -41,4 +41,8 @@ public class CacheConstants
      * 登录账户密码错误次数 redis key
      */
     public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
+    /**
+     * 预定ip redis key
+     */
+    public static final String TOUR_BOOK_IP = "tour_book_ip:";
 }

+ 18 - 9
common/common-additional/src/main/java/com/tourism/common/additional/redis/RedisCache.java

@@ -1,16 +1,12 @@
 package com.tourism.common.additional.redis;
 
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.BoundSetOperations;
-import org.springframework.data.redis.core.HashOperations;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.redis.core.*;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
 import org.springframework.stereotype.Component;
 
 /**
@@ -24,6 +20,18 @@ public class RedisCache
 {
     @Autowired
     public RedisTemplate redisTemplate;
+    @Autowired
+    private StringRedisTemplate stringRedisTemplate;
+
+
+    @Bean
+    public RedisTemplate redisTemplateInit() {
+        //设置序列化Key的实例化对象
+        redisTemplate.setKeySerializer(new StringRedisSerializer());
+        //设置序列化Value的实例化对象
+        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
+        return redisTemplate;
+    }
 
     /**
      * 缓存基本的对象,Integer、String、实体类等
@@ -265,4 +273,5 @@ public class RedisCache
     {
         return redisTemplate.keys(pattern);
     }
+
 }