Procházet zdrojové kódy

优化了订单管理中规则配置接口的代码

jinshihui před 11 hodinami
rodič
revize
c8a4b168a4
22 změnil soubory, kde provedl 958 přidání a 103 odebrání
  1. 29 2
      nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/AreaController.java
  2. 84 79
      nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/HomeController.java
  3. 71 12
      nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/MaProjectController.java
  4. 10 0
      nightFragrance-common/src/main/java/com/ylx/common/core/domain/entity/SysDept.java
  5. 67 0
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/MaProjectAuditQueryDTO.java
  6. 25 0
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/MaProjectAuditSubmitDTO.java
  7. 121 0
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/vo/MaProjectAuditListVO.java
  8. 65 0
      nightFragrance-massage/src/main/java/com/ylx/massage/domain/vo/MaProjectOpenServiceVO.java
  9. 37 0
      nightFragrance-massage/src/main/java/com/ylx/massage/mapper/MaProjectMapper.java
  10. 2 0
      nightFragrance-massage/src/main/java/com/ylx/massage/service/AreaService.java
  11. 32 0
      nightFragrance-massage/src/main/java/com/ylx/massage/service/IMaProjectService.java
  12. 44 1
      nightFragrance-massage/src/main/java/com/ylx/massage/service/impl/AreaServiceImpl.java
  13. 104 0
      nightFragrance-massage/src/main/java/com/ylx/massage/service/impl/MaProjectServiceImpl.java
  14. 10 0
      nightFragrance-massage/src/main/java/com/ylx/order/controller/RegulationController.java
  15. 19 2
      nightFragrance-massage/src/main/java/com/ylx/order/domain/AutoFlowConfig.java
  16. 30 0
      nightFragrance-massage/src/main/java/com/ylx/order/domain/RefundRuleDetail.java
  17. 9 1
      nightFragrance-massage/src/main/java/com/ylx/order/domain/RefundRuleMaster.java
  18. 3 0
      nightFragrance-massage/src/main/java/com/ylx/order/domain/dto/RegulationConfigDTO.java
  19. 11 0
      nightFragrance-massage/src/main/java/com/ylx/order/enums/RefundStageTypeEnum.java
  20. 0 2
      nightFragrance-massage/src/main/java/com/ylx/order/service/impl/AutoFlowConfigServiceImpl.java
  21. 4 2
      nightFragrance-massage/src/main/java/com/ylx/order/service/impl/RefundRuleMasterServiceImpl.java
  22. 181 2
      nightFragrance-massage/src/main/resources/mapper/massage/MaProjectMapper.xml

+ 29 - 2
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/AreaController.java

@@ -128,11 +128,38 @@ public class AreaController {
         return R.ok(CollectionUtil.getFirst(list).getCode());
     }
 
+    /**
+     * 获取全量区域树形结构
+     *
+     * @return R<List<AreaTreeNode>>
+     */
     @GetMapping("/tree")
     @ApiOperation("获取全量区域树形结构")
     public R<List<AreaTreeNode>> getAreaTree() {
-        List<AreaTreeNode> tree = this.areaService.getAreaTree();
-        return R.ok(tree);
+        try {
+            List<AreaTreeNode> tree = this.areaService.getAreaTree();
+            return R.ok(tree);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
+
+     /**
+     * 获取省、市两级区域树形结构
+     *
+     * @return R<List<AreaTreeNode>>
+     */
+    @GetMapping("/provinceCityTree")
+    @ApiOperation("获取省市两级区域树形结构")
+    public R<List<AreaTreeNode>> getProvinceCityTree() {
+        try {
+            List<AreaTreeNode> tree = this.areaService.getProvinceCityTree();
+            return R.ok(tree);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
     }
 
     @PostMapping("/city")

+ 84 - 79
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/HomeController.java

@@ -60,94 +60,99 @@ public class HomeController {
 
     @Resource
     private WeChatUtil weChatUtil;
+
     @GetMapping("block")
     @ApiOperation("首页数据块")
     public HomeBlocks block(String deptId) {
+        try {
+            if (StringUtils.isBlank(deptId)) {
+                throw new ServiceException("部门Id不能为空");
+            }
 
-        if (StringUtils.isBlank(deptId)) {
-            throw new ServiceException("部门Id不能为空");
-        }
+            //获取上个月时间
+            Date update = DateTimeUtils.addMonths(new Date(), -1);
 
-        //获取上个月时间
-        Date update = DateTimeUtils.addMonths(new Date(), -1);
+            //上个月第一天
+            Date start = DateTimeUtils.getBeginDayOfMonth(update);
+            //当月最后一天
+            Date end = DateTimeUtils.getEndDayOfMonth(new Date());
 
-        //上个月第一天
-        Date start = DateTimeUtils.getBeginDayOfMonth(update);
-        //当月最后一天
-        Date end = DateTimeUtils.getEndDayOfMonth(new Date());
+            String currentMonth = DateTimeUtils.formatDate(new Date(), DateTimeUtils.DATE_NUMBER_YEAR_MONTH_FORMAT2);
+            //营业额
+            //订单量
+            List<HomeBlock> blockOrder = orderService.getBlock(start, end, deptId);
 
-        String currentMonth = DateTimeUtils.formatDate(new Date(), DateTimeUtils.DATE_NUMBER_YEAR_MONTH_FORMAT2);
-        //营业额
-        //订单量
-        List<HomeBlock> blockOrder = orderService.getBlock(start, end, deptId);
-
-        //提现
+            //提现
 //        List<HomeBlock> blockAmount = consumptionLogMapper.getBlockGetAmount(start, end, deptId);
-        List<HomeBlock> blockAmount = txRecordMapper.getBlockGetAmount(start, end, deptId);
-        //用户总数
-        List<HomeBlock> blockUser = wxUserMapper.getBlockGetUser(start, end, deptId);
-        Integer sumUser = wxUserMapper.getBlockUser();
-        //教练数量
-        List<HomeBlock> blockJs = jsMapper.getBlockGetJs(start, end, deptId);
-        Integer sumJs = jsMapper.getBlockJs(deptId);
-
-        //块
-        HomeBlocks homeBlocks = new HomeBlocks();
-        if (blockOrder.size() > 1) {
-            Optional<Integer> orderNumMax = blockOrder.stream().max(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getOrderNum()).orElse(MassageConstants.INTEGER_ZERO));
-            homeBlocks.setOrderNum(orderNumMax.orElse(MassageConstants.INTEGER_ZERO));
-            Optional<BigDecimal> turnover = blockOrder.stream().max(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getTurnover()).orElse(BigDecimal.ZERO));
-            homeBlocks.setTurnover(turnover.orElse(BigDecimal.ZERO));
-        } else {
-            homeBlocks.setOrderNum(MassageConstants.INTEGER_ZERO);
-            homeBlocks.setTurnover(BigDecimal.ZERO);
-        }
-
-        Optional<Integer> upOrderNum = blockOrder.stream().min(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getOrderNum()).orElse(MassageConstants.INTEGER_ZERO));
-        homeBlocks.setUpOrderNum(upOrderNum.orElse(MassageConstants.INTEGER_ZERO));
-
-        Optional<BigDecimal> upTurnover = blockOrder.stream().min(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getTurnover()).orElse(BigDecimal.ZERO));
-        homeBlocks.setUpTurnover(upTurnover.orElse(BigDecimal.ZERO));
-
-
-        if (blockAmount.size() > 1) {
-            Optional<BigDecimal> getAmountMax = blockAmount.stream().max(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getGetAmount()).orElse(BigDecimal.ZERO));
-            homeBlocks.setGetAmount(getAmountMax.orElse(BigDecimal.ZERO));
-        } else {
-            homeBlocks.setGetAmount(BigDecimal.ZERO);
+            List<HomeBlock> blockAmount = txRecordMapper.getBlockGetAmount(start, end, deptId);
+            //用户总数
+            List<HomeBlock> blockUser = wxUserMapper.getBlockGetUser(start, end, deptId);
+            Integer sumUser = wxUserMapper.getBlockUser();
+            //教练数量
+            List<HomeBlock> blockJs = jsMapper.getBlockGetJs(start, end, deptId);
+            Integer sumJs = jsMapper.getBlockJs(deptId);
+
+            //块
+            HomeBlocks homeBlocks = new HomeBlocks();
+            if (blockOrder.size() > 1) {
+                Optional<Integer> orderNumMax = blockOrder.stream().max(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getOrderNum()).orElse(MassageConstants.INTEGER_ZERO));
+                homeBlocks.setOrderNum(orderNumMax.orElse(MassageConstants.INTEGER_ZERO));
+                Optional<BigDecimal> turnover = blockOrder.stream().max(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getTurnover()).orElse(BigDecimal.ZERO));
+                homeBlocks.setTurnover(turnover.orElse(BigDecimal.ZERO));
+            } else {
+                homeBlocks.setOrderNum(MassageConstants.INTEGER_ZERO);
+                homeBlocks.setTurnover(BigDecimal.ZERO);
+            }
+
+            Optional<Integer> upOrderNum = blockOrder.stream().min(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getOrderNum()).orElse(MassageConstants.INTEGER_ZERO));
+            homeBlocks.setUpOrderNum(upOrderNum.orElse(MassageConstants.INTEGER_ZERO));
+
+            Optional<BigDecimal> upTurnover = blockOrder.stream().min(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getTurnover()).orElse(BigDecimal.ZERO));
+            homeBlocks.setUpTurnover(upTurnover.orElse(BigDecimal.ZERO));
+
+
+            if (blockAmount.size() > 1) {
+                Optional<BigDecimal> getAmountMax = blockAmount.stream().max(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getGetAmount()).orElse(BigDecimal.ZERO));
+                homeBlocks.setGetAmount(getAmountMax.orElse(BigDecimal.ZERO));
+            } else {
+                homeBlocks.setGetAmount(BigDecimal.ZERO);
+            }
+            Optional<BigDecimal> getupAmount = blockAmount.stream().min(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getGetAmount()).orElse(BigDecimal.ZERO));
+            homeBlocks.setUpGetAmount(getupAmount.orElse(BigDecimal.ZERO));
+
+            homeBlocks.setUserNum(sumUser);
+            //获取当月新增用户数
+            //Optional<Integer> userNumMax = blockUser.stream().max(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getUserNum()).orElse(MassageConstants.INTEGER_ZERO));
+            List<HomeBlock> currentUser = blockUser.stream().filter(i -> i.getMonth().equals(currentMonth)).collect(Collectors.toList());
+            if (CollectionUtil.isEmpty(currentUser)) {
+                homeBlocks.setUpUserNum(sumUser);
+            } else {
+                homeBlocks.setUpUserNum(sumUser - currentUser.get(0).getUserNum());
+            }
+
+
+            homeBlocks.setJsNum(sumJs);
+            //获取当前月新增的教练数量
+            List<HomeBlock> currentHomeBlock = blockJs.stream().filter(i -> i.getMonth().equals(currentMonth)).collect(Collectors.toList());
+
+            if (CollectionUtil.isEmpty(currentHomeBlock)) {
+                homeBlocks.setUpJsNum(sumJs);
+            } else {
+                homeBlocks.setUpJsNum(sumJs - currentHomeBlock.get(0).getJsNum());
+            }
+            //Optional<Integer> jsNumMax = blockJs.stream().max(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getJsNum()).orElse(MassageConstants.INTEGER_ZERO));
+            //昨日关注量
+            Date date = DateTimeUtils.addDays(new Date(), -1);
+            homeBlocks.setFollowers(weChatUtil.getFollowers(DateTimeUtils.formatDate(date), DateTimeUtils.formatDate(date)));
+
+            Integer pageViews = operatorsLogService.selectDate(DateTimeUtils.formatDate(date),DateTimeUtils.formatDate(new Date()));
+
+            homeBlocks.setPageViews(pageViews);
+            return homeBlocks;
+        } catch (ServiceException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
         }
-        Optional<BigDecimal> getupAmount = blockAmount.stream().min(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getGetAmount()).orElse(BigDecimal.ZERO));
-        homeBlocks.setUpGetAmount(getupAmount.orElse(BigDecimal.ZERO));
-
-        homeBlocks.setUserNum(sumUser);
-        //获取当月新增用户数
-        //Optional<Integer> userNumMax = blockUser.stream().max(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getUserNum()).orElse(MassageConstants.INTEGER_ZERO));
-        List<HomeBlock> currentUser = blockUser.stream().filter(i -> i.getMonth().equals(currentMonth)).collect(Collectors.toList());
-        if (CollectionUtil.isEmpty(currentUser)) {
-            homeBlocks.setUpUserNum(sumUser);
-        } else {
-            homeBlocks.setUpUserNum(sumUser - currentUser.get(0).getUserNum());
-        }
-
-
-        homeBlocks.setJsNum(sumJs);
-        //获取当前月新增的教练数量
-        List<HomeBlock> currentHomeBlock = blockJs.stream().filter(i -> i.getMonth().equals(currentMonth)).collect(Collectors.toList());
-
-        if (CollectionUtil.isEmpty(currentHomeBlock)) {
-            homeBlocks.setUpJsNum(sumJs);
-        } else {
-            homeBlocks.setUpJsNum(sumJs - currentHomeBlock.get(0).getJsNum());
-        }
-        //Optional<Integer> jsNumMax = blockJs.stream().max(Comparator.comparing(HomeBlock::getMonth)).map(i -> Optional.ofNullable(i.getJsNum()).orElse(MassageConstants.INTEGER_ZERO));
-        //昨日关注量
-        Date date = DateTimeUtils.addDays(new Date(), -1);
-        homeBlocks.setFollowers(weChatUtil.getFollowers(DateTimeUtils.formatDate(date), DateTimeUtils.formatDate(date)));
-
-        Integer pageViews = operatorsLogService.selectDate(DateTimeUtils.formatDate(date),DateTimeUtils.formatDate(new Date()));
-
-        homeBlocks.setPageViews(pageViews);
-        return homeBlocks;
     }
 
 

+ 71 - 12
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/MaProjectController.java

@@ -2,9 +2,15 @@ package com.ylx.web.controller.massage;
 
 import java.util.List;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ylx.common.core.domain.R;
 import com.ylx.common.core.domain.model.LoginUser;
 import com.ylx.massage.domain.MaProject;
+import com.ylx.massage.domain.dto.MaProjectAuditQueryDTO;
+import com.ylx.massage.domain.dto.MaProjectAuditSubmitDTO;
+import com.ylx.massage.domain.vo.MaProjectAuditListVO;
 import com.ylx.massage.domain.vo.MaProjectListVo;
+import com.ylx.massage.domain.vo.MaProjectOpenServiceVO;
 import com.ylx.massage.domain.vo.MaProjectSaveVo;
 import com.ylx.massage.service.IMaProjectService;
 import io.swagger.annotations.Api;
@@ -12,6 +18,7 @@ import io.swagger.annotations.ApiOperation;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -33,8 +40,7 @@ import com.ylx.common.core.page.TableDataInfo;
 @Api("服务项目管理")
 @RestController
 @RequestMapping("/massage/project")
-public class MaProjectController extends BaseController
-{
+public class MaProjectController extends BaseController {
     @Autowired
     private IMaProjectService maProjectService;
 
@@ -44,13 +50,69 @@ public class MaProjectController extends BaseController
     @ApiOperation("PC查询服务项目列表")
     @PreAuthorize("@ss.hasPermi('massage:project:list')")
     @GetMapping("/list")
-    public TableDataInfo list(MaProject maProject)
-    {
+    public TableDataInfo list(MaProject maProject) {
         startPage();
         List<MaProjectListVo> list = maProjectService.selectMaProjectList(maProject);
         return getDataTable(list);
     }
 
+    /**
+     * 查询技能审核列表
+     *
+     * @param page 分页参数
+     * @param dto  查询参数
+     * @return R<Page<MaProjectAuditListVO>> 分页结果
+     */
+    @ApiOperation("后台查询技能审核列表")
+    @PreAuthorize("@ss.hasPermi('massage:project:list')")
+    @GetMapping("/audit/list")
+    public R<Page<MaProjectAuditListVO>> auditList(Page<MaProjectAuditListVO> page, MaProjectAuditQueryDTO dto) {
+        try {
+            return R.ok(maProjectService.selectProjectAuditList(page, dto));
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 查询商户申请开通的项目列表
+     *
+     * @param merchantId 商户ID
+     * @return R<List<MaProjectOpenServiceVO>> 商户申请开通项目列表
+     */
+    @ApiOperation("后台查询商户申请开通的项目列表")
+    @PreAuthorize("@ss.hasPermi('massage:project:list')")
+    @GetMapping("/audit/{merchantId}/projects")
+    public R<List<MaProjectOpenServiceVO>> auditProjectList(@PathVariable("merchantId") Long merchantId) {
+        try {
+            return R.ok(maProjectService.selectMerchantOpenProjectList(merchantId));
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 审核商户申请开通的项目
+     *
+     * @param projectAuditId 技能审核记录ID
+     * @param dto            审核提交参数
+     * @return AjaxResult 审核结果
+     */
+    @ApiOperation("后台审核商户申请开通的项目")
+    @PreAuthorize("@ss.hasPermi('massage:project:edit')")
+    @Log(title = "技能开通审核", businessType = BusinessType.UPDATE)
+    @PutMapping("/audit/project/{projectAuditId}/submit")
+    public AjaxResult submitProjectAudit(@PathVariable("projectAuditId") Long projectAuditId, @RequestBody MaProjectAuditSubmitDTO dto) {
+        try {
+            LoginUser loginUser = getLoginUser();
+            return toAjax(maProjectService.submitProjectAudit(projectAuditId, dto, loginUser));
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
 
 
     /**
@@ -59,8 +121,7 @@ public class MaProjectController extends BaseController
     @ApiOperation("PC获取服务项目详细信息")
     @PreAuthorize("@ss.hasPermi('massage:project:query')")
     @GetMapping(value = "/{id}")
-    public AjaxResult getInfo(@PathVariable("id") Long id)
-    {
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
         return success(maProjectService.selectMaProjectById(id));
     }
 
@@ -71,11 +132,10 @@ public class MaProjectController extends BaseController
     @PreAuthorize("@ss.hasPermi('massage:project:add')")
     @Log(title = "服务项目", businessType = BusinessType.INSERT)
     @PostMapping("save")
-    public AjaxResult add(@RequestBody MaProjectSaveVo maProject)
-    {
+    public AjaxResult add(@RequestBody MaProjectSaveVo maProject) {
         LoginUser loginUser = getLoginUser();
 
-        return toAjax(maProjectService.insertMaProject(maProject,loginUser));
+        return toAjax(maProjectService.insertMaProject(maProject, loginUser));
     }
 
 
@@ -85,9 +145,8 @@ public class MaProjectController extends BaseController
     @ApiOperation("删除服务项目")
     @PreAuthorize("@ss.hasPermi('massage:project:remove')")
     @Log(title = "服务项目", businessType = BusinessType.DELETE)
-	@DeleteMapping("/{id}")
-    public AjaxResult remove(@PathVariable("id") Long id)
-    {
+    @DeleteMapping("/{id}")
+    public AjaxResult remove(@PathVariable("id") Long id) {
         return toAjax(maProjectService.deleteMaProjectById(id));
     }
 }

+ 10 - 0
nightFragrance-common/src/main/java/com/ylx/common/core/domain/entity/SysDept.java

@@ -51,6 +51,16 @@ public class SysDept extends BaseEntity {
     @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
     private String deptName;
 
+    /**
+     * 省份编码
+     */
+    private String provinceCode;
+
+    /**
+     * 省份名称
+     */
+    private String provinceName;
+
     /**
      * 城市编码
      */

+ 67 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/MaProjectAuditQueryDTO.java

@@ -0,0 +1,67 @@
+package com.ylx.massage.domain.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 后台技能审核查询参数。
+ */
+@Data
+@ApiModel(value = "MaProjectAuditQueryDTO", description = "后台技能审核查询参数")
+public class MaProjectAuditQueryDTO {
+
+    /**
+     * 商户姓名,支持模糊查询。
+     */
+    @ApiModelProperty("商户姓名")
+    private String merchantName;
+
+    /**
+     * 商户昵称,支持模糊查询。
+     */
+    @ApiModelProperty("商户昵称")
+    private String merchantNickName;
+
+    /**
+     * 用户类型:0-真实用户,1-虚拟用户。
+     */
+    @ApiModelProperty("用户类型:0-真实用户 1-虚拟用户")
+    private Integer techType;
+
+    /**
+     * 商户电话,支持模糊查询。
+     */
+    @ApiModelProperty("商户电话")
+    private String merchantPhone;
+
+    /**
+     * 申请开始时间,格式:yyyy-MM-dd HH:mm:ss。
+     */
+    @ApiModelProperty("申请开始时间")
+    private String beginApplyTime;
+
+    /**
+     * 申请结束时间,格式:yyyy-MM-dd HH:mm:ss。
+     */
+    @ApiModelProperty("申请结束时间")
+    private String endApplyTime;
+
+    /**
+     * 性别:0-女,1-男。
+     */
+    @ApiModelProperty("性别:0-女 1-男")
+    private Integer merchantSex;
+
+    /**
+     * 技能审核状态:0-待审核,1-审核通过,2-审核驳回。
+     */
+    @ApiModelProperty("技能审核状态:0-待审核 1-审核通过 2-审核驳回")
+    private Integer auditStatus;
+
+    /**
+     * 审核页签:0-待审核,1-审核结果。
+     */
+    @ApiModelProperty("审核页签:0-待审核 1-审核结果")
+    private Integer auditStatusGroup;
+}

+ 25 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/domain/dto/MaProjectAuditSubmitDTO.java

@@ -0,0 +1,25 @@
+package com.ylx.massage.domain.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 技能开通审核提交参数。
+ */
+@Data
+@ApiModel(value = "MaProjectAuditSubmitDTO", description = "技能开通审核提交参数")
+public class MaProjectAuditSubmitDTO {
+
+    /**
+     * 审核状态:1-审核通过,2-审核驳回。
+     */
+    @ApiModelProperty(value = "审核状态:1-审核通过 2-审核驳回", required = true)
+    private Integer auditStatus;
+
+    /**
+     * 审核备注。
+     */
+    @ApiModelProperty("审核备注")
+    private String auditRemark;
+}

+ 121 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/domain/vo/MaProjectAuditListVO.java

@@ -0,0 +1,121 @@
+package com.ylx.massage.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 后台技能审核列表展示对象。
+ */
+@Data
+@ApiModel(value = "MaProjectAuditListVO", description = "后台技能审核列表展示对象")
+public class MaProjectAuditListVO {
+
+    /**
+     * 技能审核记录ID,对应 ma_project.id。
+     */
+    @ApiModelProperty("技能审核记录ID")
+    private Long projectAuditId;
+
+    /**
+     * 业务项目ID。
+     */
+    @ApiModelProperty("业务项目ID")
+    private Long projectId;
+
+    /**
+     * 项目名称。
+     */
+    @ApiModelProperty("项目名称")
+    private String projectName;
+
+    /**
+     * 商户ID。
+     */
+    @ApiModelProperty("商户ID")
+    private Long merchantId;
+
+    /**
+     * 商户姓名。
+     */
+    @ApiModelProperty("商户姓名")
+    private String merchantName;
+
+    /**
+     * 商户昵称。
+     */
+    @ApiModelProperty("商户昵称")
+    private String merchantNickName;
+
+    /**
+     * 商户性别:0-女,1-男。
+     */
+    @ApiModelProperty("商户性别:0-女 1-男")
+    private Integer merchantSex;
+
+    /**
+     * 商户性别展示名称。
+     */
+    @ApiModelProperty("商户性别名称")
+    private String merchantSexName;
+
+    /**
+     * 商户形象照。
+     */
+    @ApiModelProperty("商户形象照")
+    private String merchantAvatar;
+
+    /**
+     * 商户电话。
+     */
+    @ApiModelProperty("商户电话")
+    private String merchantPhone;
+
+    /**
+     * 用户类型:0-真实用户,1-虚拟用户。
+     */
+    @ApiModelProperty("用户类型:0-真实用户 1-虚拟用户")
+    private Integer techType;
+
+    /**
+     * 用户类型展示名称。
+     */
+    @ApiModelProperty("用户类型名称")
+    private String techTypeName;
+
+    /**
+     * 申请时间。
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty("申请时间")
+    private Date applyTime;
+
+    /**
+     * 审批时间。
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty("审批时间")
+    private Date approveTime;
+
+    /**
+     * 注册时间。
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty("注册时间")
+    private Date registerTime;
+
+    /**
+     * 技能审核状态:0-待审核,1-审核通过,2-审核驳回。
+     */
+    @ApiModelProperty("技能审核状态:0-待审核 1-审核通过 2-审核驳回")
+    private Integer auditStatus;
+
+    /**
+     * 技能审核状态展示名称。
+     */
+    @ApiModelProperty("技能审核状态名称")
+    private String auditStatusName;
+}

+ 65 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/domain/vo/MaProjectOpenServiceVO.java

@@ -0,0 +1,65 @@
+package com.ylx.massage.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 商户申请开通项目列表展示对象。
+ */
+@Data
+@ApiModel(value = "MaProjectOpenServiceVO", description = "商户申请开通项目列表展示对象")
+public class MaProjectOpenServiceVO {
+
+    /**
+     * 技能审核记录ID,对应 ma_project.id。
+     */
+    @ApiModelProperty("技能审核记录ID")
+    private Long projectAuditId;
+
+    /**
+     * 业务项目ID。
+     */
+    @ApiModelProperty("业务项目ID")
+    private Long projectId;
+
+    /**
+     * 项目名称。
+     */
+    @ApiModelProperty("项目名称")
+    private String projectName;
+
+    /**
+     * 开通理由。
+     */
+    @ApiModelProperty("开通理由")
+    private String applyReason;
+
+    /**
+     * 申请时间。
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty("申请时间")
+    private Date applyTime;
+
+    /**
+     * 审核状态:0-待审核,1-审核通过,2-审核驳回。
+     */
+    @ApiModelProperty("审核状态:0-待审核 1-审核通过 2-审核驳回")
+    private Integer auditStatus;
+
+    /**
+     * 审核结果展示名称。
+     */
+    @ApiModelProperty("审核结果")
+    private String auditStatusName;
+
+    /**
+     * 备注。
+     */
+    @ApiModelProperty("备注")
+    private String remark;
+}

+ 37 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/mapper/MaProjectMapper.java

@@ -8,7 +8,10 @@ import com.ylx.companion.domain.dto.CompanionAllMerchantsDTO;
 import com.ylx.companion.domain.vo.CompanionAllMerchantsVo;
 import com.ylx.companion.domain.vo.HotCompanionProjectVO;
 import com.ylx.massage.domain.MaProject;
+import com.ylx.massage.domain.dto.MaProjectAuditQueryDTO;
 import com.ylx.massage.domain.dto.MassageAllMerchantsDto;
+import com.ylx.massage.domain.vo.MaProjectAuditListVO;
+import com.ylx.massage.domain.vo.MaProjectOpenServiceVO;
 import com.ylx.massage.domain.vo.MassageAllMerchantsVo;
 import com.ylx.massage.domain.vo.MassageProjectRecommendVo;
 import com.ylx.project.domain.bookMerchant.dto.BookMerchantDTO;
@@ -41,6 +44,40 @@ public interface MaProjectMapper extends BaseMapper<MaProject> {
      */
     public List<MaProject> selectMaProjectList(MaProject maProject);
 
+    /**
+     * 查询技能审核列表
+     *
+     * @param page 分页参数
+     * @param dto 查询条件
+     * @return 技能审核分页列表
+     */
+    Page<MaProjectAuditListVO> selectProjectAuditList(Page<MaProjectAuditListVO> page,
+                                                      @Param("dto") MaProjectAuditQueryDTO dto);
+
+    /**
+     * 查询商户申请开通的项目列表
+     *
+     * @param merchantId 商户ID
+     * @return 商户申请开通项目列表
+     */
+    List<MaProjectOpenServiceVO> selectMerchantOpenProjectList(@Param("merchantId") Long merchantId);
+
+    /**
+     * 查询技能审核记录
+     *
+     * @param projectAuditId 技能审核记录ID
+     * @return 技能审核记录
+     */
+    MaProject selectProjectAuditById(@Param("projectAuditId") Long projectAuditId);
+
+    /**
+     * 提交技能开通审核
+     *
+     * @param maProject 技能审核记录
+     * @return 影响行数
+     */
+    int submitProjectAudit(@Param("maProject") MaProject maProject);
+
     /**
      * 新增服务项目
      *

+ 2 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/service/AreaService.java

@@ -19,6 +19,8 @@ public interface AreaService extends IService<Area> {
 
     List<AreaTreeNode> getAreaTree();
 
+    List<AreaTreeNode> getProvinceCityTree();
+
     CityInfoVo getCityInfoByCoordinates(CoordinateDTO dto);
 
     List<CityVo> getHomeList ();

+ 32 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/service/IMaProjectService.java

@@ -6,8 +6,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ylx.common.core.domain.model.LoginUser;
 import com.ylx.massage.domain.MaProject;
+import com.ylx.massage.domain.dto.MaProjectAuditQueryDTO;
+import com.ylx.massage.domain.dto.MaProjectAuditSubmitDTO;
 import com.ylx.massage.domain.dto.MassageAllMerchantsDto;
+import com.ylx.massage.domain.vo.MaProjectAuditListVO;
 import com.ylx.massage.domain.vo.MaProjectListVo;
+import com.ylx.massage.domain.vo.MaProjectOpenServiceVO;
 import com.ylx.massage.domain.vo.MaProjectSaveVo;
 import com.ylx.massage.domain.vo.MassageAllMerchantsVo;
 import com.ylx.massage.domain.vo.MassageProjectRecommendVo;
@@ -38,6 +42,34 @@ public interface IMaProjectService extends IService<MaProject>
      */
     public List<MaProjectListVo> selectMaProjectList(MaProject maProject);
 
+    /**
+     * 查询技能审核列表
+     *
+     * @param page 分页参数
+     * @param dto 查询条件
+     * @return 技能审核分页列表
+     */
+    Page<MaProjectAuditListVO> selectProjectAuditList(Page<MaProjectAuditListVO> page,
+                                                      MaProjectAuditQueryDTO dto);
+
+    /**
+     * 查询商户申请开通的项目列表
+     *
+     * @param merchantId 商户ID
+     * @return 商户申请开通项目列表
+     */
+    List<MaProjectOpenServiceVO> selectMerchantOpenProjectList(Long merchantId);
+
+    /**
+     * 审核商户申请开通的项目
+     *
+     * @param projectAuditId 技能审核记录ID
+     * @param dto 审核提交参数
+     * @param loginUser 当前登录用户
+     * @return 影响行数
+     */
+    int submitProjectAudit(Long projectAuditId, MaProjectAuditSubmitDTO dto, LoginUser loginUser);
+
     /**
      * 新增服务项目
      *

+ 44 - 1
nightFragrance-massage/src/main/java/com/ylx/massage/service/impl/AreaServiceImpl.java

@@ -91,6 +91,49 @@ public class AreaServiceImpl extends ServiceImpl<AreaMapper, Area> implements Ar
                 .collect(Collectors.toList());
     }
 
+    /**
+     * 查询省、市两级行政区域树。
+     */
+    @Override
+    public List<AreaTreeNode> getProvinceCityTree() {
+        List<Area> areaList = this.list(Wrappers.lambdaQuery(Area.class)
+                .select(Area::getId, Area::getCode, Area::getName, Area::getParentCode, Area::getLevel)
+                .in(Area::getLevel, 1, 2)
+        );
+
+        List<AreaTreeNode> allNodes = areaList.stream()
+                .map(this::toAreaTreeNode)
+                .collect(Collectors.toList());
+
+        Map<String, AreaTreeNode> nodeMap = allNodes.stream()
+                .collect(Collectors.toMap(AreaTreeNode::getCode, node -> node, (oldNode, newNode) -> oldNode));
+
+        for (AreaTreeNode node : allNodes) {
+            if (node.getLevel() == null || node.getLevel() != 2) {
+                continue;
+            }
+            AreaTreeNode parentNode = nodeMap.get(node.getParentCode());
+            if (parentNode != null) {
+                parentNode.getChildren().add(node);
+            }
+        }
+
+        return allNodes.stream()
+                .filter(node -> Integer.valueOf(1).equals(node.getLevel()))
+                .collect(Collectors.toList());
+    }
+
+    private AreaTreeNode toAreaTreeNode(Area area) {
+        AreaTreeNode node = new AreaTreeNode();
+        node.setId(area.getId());
+        node.setCode(area.getCode());
+        node.setName(area.getName());
+        node.setParentCode(area.getParentCode());
+        node.setLevel(area.getLevel());
+        node.setChildren(new ArrayList<>());
+        return node;
+    }
+
     @Override
     public CityInfoVo getCityInfoByCoordinates(CoordinateDTO dto) {
         // 参数验证
@@ -234,4 +277,4 @@ public class AreaServiceImpl extends ServiceImpl<AreaMapper, Area> implements Ar
         }
         return cityVoList;
     }
-}
+}

+ 104 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/service/impl/MaProjectServiceImpl.java

@@ -6,10 +6,16 @@ import java.util.List;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ylx.common.core.domain.model.LoginUser;
+import com.ylx.common.exception.ServiceException;
 import com.ylx.common.utils.DateUtils;
+import com.ylx.common.utils.StringUtils;
 import com.ylx.common.utils.bean.BeanUtils;
+import com.ylx.massage.domain.dto.MaProjectAuditQueryDTO;
+import com.ylx.massage.domain.dto.MaProjectAuditSubmitDTO;
 import com.ylx.massage.domain.dto.MassageAllMerchantsDto;
+import com.ylx.massage.domain.vo.MaProjectAuditListVO;
 import com.ylx.massage.domain.vo.MaProjectListVo;
+import com.ylx.massage.domain.vo.MaProjectOpenServiceVO;
 import com.ylx.massage.domain.vo.MaProjectSaveVo;
 import com.ylx.massage.domain.vo.MassageAllMerchantsVo;
 import com.ylx.massage.domain.vo.MassageProjectRecommendVo;
@@ -74,6 +80,86 @@ public class MaProjectServiceImpl extends ServiceImpl<MaProjectMapper, MaProject
         return vos;
     }
 
+    /**
+     * 查询技能审核列表
+     *
+     * @param page 分页参数
+     * @param dto 查询条件
+     * @return 技能审核分页列表
+     */
+    @Override
+    public Page<MaProjectAuditListVO> selectProjectAuditList(Page<MaProjectAuditListVO> page, MaProjectAuditQueryDTO dto) {
+        if (dto != null) {
+            checkEnumValue(dto.getAuditStatus(), "技能审核状态", 0, 1, 2);
+            checkEnumValue(dto.getAuditStatusGroup(), "审核页签", 0, 1);
+            checkEnumValue(dto.getMerchantSex(), "性别", 0, 1);
+            checkEnumValue(dto.getTechType(), "用户类型", 0, 1);
+        }
+        Page<MaProjectAuditListVO> pageParam = page == null ? new Page<>(1, 10) : page;
+        return maProjectMapper.selectProjectAuditList(pageParam, dto);
+    }
+
+    /**
+     * 查询商户申请开通的项目列表
+     *
+     * @param merchantId 商户ID
+     * @return List<MaProjectOpenServiceVO> 商户申请开通项目列表
+     */
+    @Override
+    public List<MaProjectOpenServiceVO> selectMerchantOpenProjectList(Long merchantId) {
+        if (merchantId == null || merchantId <= 0) {
+            throw new ServiceException("商户ID不能为空");
+        }
+        return maProjectMapper.selectMerchantOpenProjectList(merchantId);
+    }
+
+    /**
+     * 审核商户申请开通的项目
+     *
+     * @param projectAuditId 技能审核记录ID
+     * @param dto 审核提交参数
+     * @param loginUser 当前登录用户
+     * @return int 影响行数
+     */
+    @Override
+    public int submitProjectAudit(Long projectAuditId, MaProjectAuditSubmitDTO dto, LoginUser loginUser) {
+        if (projectAuditId == null || projectAuditId <= 0) {
+            throw new ServiceException("技能审核记录ID不能为空");
+        }
+        if (dto == null) {
+            throw new ServiceException("审核参数不能为空");
+        }
+        checkEnumValue(dto.getAuditStatus(), "审核状态", 1, 2);
+        if (Integer.valueOf(2).equals(dto.getAuditStatus()) && StringUtils.isBlank(dto.getAuditRemark())) {
+            throw new ServiceException("审核驳回时审核备注不能为空");
+        }
+
+        MaProject exists = maProjectMapper.selectProjectAuditById(projectAuditId);
+        if (exists == null) {
+            throw new ServiceException("技能审核记录不存在或已删除");
+        }
+        if (!Integer.valueOf(0).equals(exists.getAuditStatus())) {
+            throw new ServiceException("当前项目不是待审核状态,不能重复审核");
+        }
+
+        MaProject maProject = new MaProject();
+        maProject.setId(projectAuditId);
+        maProject.setAuditStatus(dto.getAuditStatus());
+        maProject.setReason(dto.getAuditRemark());
+        maProject.setProjectIsEnable(Integer.valueOf(1).equals(dto.getAuditStatus()) ? 1 : 0);
+        maProject.setApproveTime(DateUtils.getNowDate());
+        maProject.setUpdateTime(DateUtils.getNowDate());
+        if (loginUser != null && loginUser.getUser() != null) {
+            maProject.setUpdateBy(loginUser.getUser().getUserId());
+        }
+
+        int rows = maProjectMapper.submitProjectAudit(maProject);
+        if (rows <= 0) {
+            throw new ServiceException("审核失败,当前项目状态已变更");
+        }
+        return rows;
+    }
+
     /**
      * 新增服务项目
      *
@@ -150,4 +236,22 @@ public class MaProjectServiceImpl extends ServiceImpl<MaProjectMapper, MaProject
         return maProjectMapper.selectMerchantList(page, dto);
     }
 
+    /**
+     * 校验枚举值是否在指定范围内
+     * @param value
+     * @param fieldName
+     * @param values
+     */
+    private void checkEnumValue(Integer value, String fieldName, Integer... values) {
+        if (value == null) {
+            return;
+        }
+        for (Integer item : values) {
+            if (value.equals(item)) {
+                return;
+            }
+        }
+        throw new ServiceException(fieldName + "参数不正确");
+    }
+
 }

+ 10 - 0
nightFragrance-massage/src/main/java/com/ylx/order/controller/RegulationController.java

@@ -20,6 +20,11 @@ public class RegulationController {
     @Resource
     private RegulationService regulationService;
 
+    /**
+     * 保存订单流转与退款规则配置
+     * @param dto
+     * @return R<?>
+     */
     @ApiOperation("保存订单流转与退款规则配置")
     @PostMapping("/save")
     public R<?> saveConfig(@RequestBody @Validated RegulationConfigDTO dto) {
@@ -27,6 +32,11 @@ public class RegulationController {
         return R.ok();
     }
 
+    /**
+     * 获取当前配置(用于回显)
+     *
+     * @return R<RegulationConfigDTO>
+     */
     @ApiOperation("获取当前配置(用于回显)")
     @GetMapping("/get")
     public R<RegulationConfigDTO> getConfig() {

+ 19 - 2
nightFragrance-massage/src/main/java/com/ylx/order/domain/AutoFlowConfig.java

@@ -8,28 +8,45 @@ import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.experimental.Accessors;
-
 import java.math.BigDecimal;
 
+/**
+ * 订单自动流转配置表
+ */
 @Data
 @Accessors(chain = true)
 @ApiModel(value = "AutoFlowConfig", description = "订单自动流转配置表")
 public class AutoFlowConfig extends BaseEntity {
     private static final long serialVersionUID = -8833311442205547209L;
 
+    /**
+     * 主键ID。
+     */
     @ApiModelProperty("主键ID")
     @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
+    /**
+     * 是否开启订单自动流转:0-关闭,1-开启。
+     */
     @ApiModelProperty("是否开启自动流转: 0=关闭, 1=开启")
     private Integer isEnabled;
 
+    /**
+     * 订单超时阈值,单位为小时。
+     */
     @ApiModelProperty("超时阈值(小时)")
     private BigDecimal timeoutHours;
 
-    @ApiModelProperty("系统处理动作: 0=自动退款")
+    /**
+     * 系统默认处理动作:0-自动退款 1:转为待指派订单
+     */
+    @ApiModelProperty("系统处理动作: 0=自动退款, 1=转为待指派订单")
     private Integer defaultAction;
 
+    /**
+     * 是否删除:0-否,1-是。
+     */
     @TableLogic
     @ApiModelProperty("是否删除 0=否,1=是")
     private Integer isDelete;

+ 30 - 0
nightFragrance-massage/src/main/java/com/ylx/order/domain/RefundRuleDetail.java

@@ -17,34 +17,64 @@ import java.math.BigDecimal;
 public class RefundRuleDetail extends BaseEntity {
     private static final long serialVersionUID = 4666309182130163491L;
 
+    /**
+     * 主键ID。
+     */
     @ApiModelProperty("主键ID")
     @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
+    /**
+     * 退款规则主表ID。
+     */
     @ApiModelProperty("退款规则主表ID")
     private Long masterId;
 
+    /**
+     * 阶段类型:0-技师未出发前,1-商户已出发途中,2-服务进行中。
+     */
     @ApiModelProperty("阶段类型: 0=技师未出发前, 1=商户已出发(途中), 2=服务进行中")
     private Integer stageType;
 
+    /**
+     * 距离服务开始时间的起始小时数。
+     */
     @ApiModelProperty("距离服务开始时间的起始小时数")
     private BigDecimal timeStartHours;
 
+    /**
+     * 距离服务开始时间的结束小时数。
+     */
     @ApiModelProperty("距离服务开始时间的结束小时数")
     private BigDecimal timeEndHours;
 
+    /**
+     * 退款类型:0-全额退款,1-部分退款。
+     */
     @ApiModelProperty("退款类型: 0=全额退款, 1=部分退款")
     private Integer refundType;
 
+    /**
+     * 退款百分比。
+     */
     @ApiModelProperty("退款百分比")
     private BigDecimal refundPercent;
 
+    /**
+     * 退款规则描述。
+     */
     @ApiModelProperty("商户未出发前退款规则描述,计划后端根据出发时间、结束时间和退款比例生成描述")
     private String refundDesc;
 
+    /**
+     * 前端展示排序。
+     */
     @ApiModelProperty("前端展示排序")
     private Integer sortOrder;
 
+    /**
+     * 是否删除:0-否,1-是。
+     */
     @TableLogic
     @ApiModelProperty("是否删除 0=否,1=是")
     private Integer isDelete;

+ 9 - 1
nightFragrance-massage/src/main/java/com/ylx/order/domain/RefundRuleMaster.java

@@ -15,14 +15,22 @@ import lombok.experimental.Accessors;
 public class RefundRuleMaster extends BaseEntity {
     private static final long serialVersionUID = -6366329664103203512L;
 
-
+    /**
+     * 主键ID
+     */
     @ApiModelProperty("主键ID")
     @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
+    /**
+     * 阶段类型: 0=技师未出发前, 1=商户已出发(途中), 2=服务进行中
+     */
     @ApiModelProperty("阶段类型: 0=技师未出发前, 1=商户已出发(途中), 2=服务进行中")
     private Integer stageType;
 
+    /**
+     * 是否删除 0=否,1=是
+     */
     @TableLogic
     @ApiModelProperty("是否删除 0=否,1=是")
     private Integer isDelete;

+ 3 - 0
nightFragrance-massage/src/main/java/com/ylx/order/domain/dto/RegulationConfigDTO.java

@@ -41,6 +41,9 @@ public class RegulationConfigDTO {
     // ==================== 2. 退款规则配置 ====================
     // UI 上将退款规则分为了三个主要板块,我们将其封装为内部类列表
 
+    /**
+     * 未出发阶段策略
+     */
     @NotNull(message = "未出发阶段策略不能为空")
     private Integer preDepartureStrategy; // 0 or 1
 

+ 11 - 0
nightFragrance-massage/src/main/java/com/ylx/order/enums/RefundStageTypeEnum.java

@@ -5,8 +5,19 @@ import lombok.Getter;
 @Getter
 public enum RefundStageTypeEnum {
 
+    /**
+     * 商户未出发前
+     */
     PRE_DEPARTURE(0, "商户未出发前"),
+
+    /**
+     * 商户已出发
+     */
     ON_THE_WAY(1, "商户已出发"),
+
+    /**
+     * 服务中订单
+     */
     IN_SERVICE(2, "服务中订单");
 
     private final Integer code;

+ 0 - 2
nightFragrance-massage/src/main/java/com/ylx/order/service/impl/AutoFlowConfigServiceImpl.java

@@ -18,7 +18,6 @@ public class AutoFlowConfigServiceImpl extends ServiceImpl<AutoFlowConfigMapper,
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void handleAutoFlowConfig(RegulationConfigDTO dto) {
-
         // 查询是否存在记录
         LambdaQueryWrapper<AutoFlowConfig> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(AutoFlowConfig::getIsDelete, 0);
@@ -38,7 +37,6 @@ public class AutoFlowConfigServiceImpl extends ServiceImpl<AutoFlowConfigMapper,
             }
             this.baseMapper.updateById(config);
         }
-
     }
 
     @Override

+ 4 - 2
nightFragrance-massage/src/main/java/com/ylx/order/service/impl/RefundRuleMasterServiceImpl.java

@@ -133,6 +133,10 @@ public class RefundRuleMasterServiceImpl extends ServiceImpl<RefundRuleMasterMap
     /**
      * 创建或更新主表记录
      * 逻辑:查找是否存在该 stage_type 的记录,存在则更新时间,不存在则新增
+     *
+     * @param stageType 阶段类型
+     * @param operator  操作人
+     * @return Long 主表ID
      */
     private Long createOrUpdateMaster(Integer stageType, String operator) {
 
@@ -179,13 +183,11 @@ public class RefundRuleMasterServiceImpl extends ServiceImpl<RefundRuleMasterMap
             detail.setCreateBy(operator);
             detail.setCreateTime(DateUtils.getNowDate());
             targetList.add(detail);
-
         } else if (strategy == 1) {
             // === 情况 B:部分退款(分时段) ===
             if (ObjectUtil.isEmpty(rules)) {
                 throw new ServiceException("选择部分退款时,必须配置时间段规则!");
             }
-
             rules.sort(Comparator.comparing(RegulationConfigDTO.TimeRangeRuleItem::getTimeStartHours));
 
             for (RegulationConfigDTO.TimeRangeRuleItem rule : rules) {

+ 181 - 2
nightFragrance-massage/src/main/resources/mapper/massage/MaProjectMapper.xml

@@ -6,6 +6,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <resultMap type="MaProject" id="MaProjectResult">
         <result property="id"    column="id"    />
+        <result property="projectId"    column="project_id"    />
         <result property="projectName"    column="project_name"    />
         <result property="projectDescribe"    column="project_describe"    />
         <result property="projectDuration"    column="project_duration"    />
@@ -15,8 +16,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="projectMasterImage"    column="project_master_image"    />
         <result property="projectDetailImage"    column="project_detail_image"    />
         <result property="projectIsEnable"    column="project_is_enable"    />
-        <result property="createUser"    column="create_user"    />
-        <result property="updateUser"    column="update_user"    />
+        <result property="merchantId"    column="merchant_id"    />
+        <result property="auditStatus"    column="audit_status"    />
+        <result property="applyReason"    column="apply_reason"    />
+        <result property="reason"    column="reason"    />
+        <result property="applyTime"    column="apply_time"    />
+        <result property="approveTime"    column="approve_time"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="updateBy"    column="update_by"    />
         <result property="createTime"    column="create_time"    />
         <result property="updateTime"    column="update_time"    />
         <result property="isDelete"    column="is_delete"    />
@@ -44,6 +51,178 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </where>
     </select>
 
+    <resultMap type="com.ylx.massage.domain.vo.MaProjectAuditListVO" id="MaProjectAuditListResult">
+        <result property="projectAuditId" column="project_audit_id"/>
+        <result property="projectId" column="project_id"/>
+        <result property="projectName" column="project_name"/>
+        <result property="merchantId" column="merchant_id"/>
+        <result property="merchantName" column="merchant_name"/>
+        <result property="merchantNickName" column="merchant_nick_name"/>
+        <result property="merchantSex" column="merchant_sex"/>
+        <result property="merchantSexName" column="merchant_sex_name"/>
+        <result property="merchantAvatar" column="merchant_avatar"/>
+        <result property="merchantPhone" column="merchant_phone"/>
+        <result property="techType" column="tech_type"/>
+        <result property="techTypeName" column="tech_type_name"/>
+        <result property="applyTime" column="apply_time"/>
+        <result property="approveTime" column="approve_time"/>
+        <result property="registerTime" column="register_time"/>
+        <result property="auditStatus" column="audit_status"/>
+        <result property="auditStatusName" column="audit_status_name"/>
+    </resultMap>
+
+    <!-- 查询技能审核列表 -->
+    <select id="selectProjectAuditList" resultMap="MaProjectAuditListResult">
+        SELECT
+            p.id AS project_audit_id,
+            p.project_id,
+            p.project_name,
+            p.merchant_id,
+            t.te_name AS merchant_name,
+            t.te_nick_name AS merchant_nick_name,
+            t.te_sex AS merchant_sex,
+            CASE t.te_sex
+                WHEN 0 THEN '女'
+                WHEN 1 THEN '男'
+                ELSE ''
+            END AS merchant_sex_name,
+            t.avatar AS merchant_avatar,
+            t.te_phone AS merchant_phone,
+            t.tech_type,
+            CASE t.tech_type
+                WHEN 0 THEN '真实用户'
+                WHEN 1 THEN '虚拟用户'
+                ELSE ''
+            END AS tech_type_name,
+            COALESCE(p.apply_time, p.create_time) AS apply_time,
+            p.approve_time,
+            t.create_time AS register_time,
+            p.audit_status,
+            CASE p.audit_status
+                WHEN 0 THEN '待审核'
+                WHEN 1 THEN '审核通过'
+                WHEN 2 THEN '审核驳回'
+                ELSE ''
+            END AS audit_status_name
+        FROM ma_project p
+        INNER JOIN ma_technician t ON t.id = p.merchant_id
+        <where>
+            IFNULL(p.is_delete, 0) = 0
+            AND IFNULL(t.is_delete, 0) = 0
+            <if test="dto != null">
+                <choose>
+                    <when test="dto.auditStatus != null">
+                        AND p.audit_status = #{dto.auditStatus}
+                    </when>
+
+                    <when test="dto.auditStatusGroup != null and dto.auditStatusGroup == 0">
+                        AND p.audit_status = 0
+                    </when>
+                    <when test="dto.auditStatusGroup != null and dto.auditStatusGroup == 1">
+                        AND p.audit_status IN (1, 2)
+                    </when>
+                </choose>
+                <!-- 商户名称 -->
+                <if test="dto.merchantName != null and dto.merchantName != ''">
+                    AND t.te_name LIKE CONCAT('%', #{dto.merchantName}, '%')
+                </if>
+                <!-- 商户昵称 -->
+                <if test="dto.merchantNickName != null and dto.merchantNickName != ''">
+                    AND t.te_nick_name LIKE CONCAT('%', #{dto.merchantNickName}, '%')
+                </if>
+                <!-- 商户类型 -->
+                <if test="dto.techType != null">
+                    AND t.tech_type = #{dto.techType}
+                </if>
+                <!-- 商户电话 -->
+                <if test="dto.merchantPhone != null and dto.merchantPhone != ''">
+                    AND t.te_phone LIKE CONCAT('%', #{dto.merchantPhone}, '%')
+                </if>
+                <!-- 申请开始时间 -->
+                <if test="dto.beginApplyTime != null and dto.beginApplyTime != ''">
+                    AND COALESCE(p.apply_time, p.create_time) &gt;= #{dto.beginApplyTime}
+                </if>
+                <!-- 申请结束时间 -->
+                <if test="dto.endApplyTime != null and dto.endApplyTime != ''">
+                    AND COALESCE(p.apply_time, p.create_time) &lt;= #{dto.endApplyTime}
+                </if>
+                <!-- 商户性别 -->
+                <if test="dto.merchantSex != null">
+                    AND t.te_sex = #{dto.merchantSex}
+                </if>
+            </if>
+        </where>
+        ORDER BY COALESCE(p.apply_time, p.create_time) DESC, p.id DESC
+    </select>
+
+    <resultMap type="com.ylx.massage.domain.vo.MaProjectOpenServiceVO" id="MaProjectOpenServiceResult">
+        <result property="projectAuditId" column="project_audit_id"/>
+        <result property="projectId" column="project_id"/>
+        <result property="projectName" column="project_name"/>
+        <result property="applyReason" column="apply_reason"/>
+        <result property="applyTime" column="apply_time"/>
+        <result property="auditStatus" column="audit_status"/>
+        <result property="auditStatusName" column="audit_status_name"/>
+        <result property="remark" column="remark"/>
+    </resultMap>
+
+    <!-- 查询商户申请开通的项目列表 -->
+    <select id="selectMerchantOpenProjectList" resultMap="MaProjectOpenServiceResult">
+        SELECT
+            p.id AS project_audit_id,
+            p.project_id,
+            COALESCE(NULLIF(p.project_name, ''), base_project.title, '') AS project_name,
+            p.apply_reason,
+            COALESCE(p.apply_time, p.create_time) AS apply_time,
+            p.audit_status,
+            CASE p.audit_status
+                WHEN 0 THEN '待审核'
+                WHEN 1 THEN '审核通过'
+                WHEN 2 THEN '审核驳回'
+                ELSE ''
+            END AS audit_status_name,
+            p.reason AS remark
+        FROM ma_project p
+        LEFT JOIN project base_project ON base_project.id = p.project_id
+        WHERE p.merchant_id = #{merchantId}
+          AND IFNULL(p.is_delete, 0) = 0
+        ORDER BY COALESCE(p.apply_time, p.create_time) DESC, p.id DESC
+    </select>
+
+    <!-- 查询技能审核记录 -->
+    <select id="selectProjectAuditById" resultMap="MaProjectResult">
+        SELECT
+            id,
+            project_id,
+            project_name,
+            merchant_id,
+            audit_status,
+            project_is_enable,
+            reason,
+            approve_time,
+            is_delete,
+            create_time,
+            update_time
+        FROM ma_project
+        WHERE id = #{projectAuditId}
+          AND is_delete = 0
+    </select>
+
+    <!-- 提交技能开通审核 -->
+    <update id="submitProjectAudit">
+        UPDATE ma_project
+        SET
+            audit_status = #{maProject.auditStatus},
+            reason = #{maProject.reason},
+            approve_time = #{maProject.approveTime},
+            project_is_enable = #{maProject.projectIsEnable},
+            update_by = #{maProject.updateBy},
+            update_time = #{maProject.updateTime}
+        WHERE id = #{maProject.id}
+          AND IFNULL(is_delete, 0) = 0
+          AND audit_status = 0
+    </update>
+
     <select id="selectMaProjectById" parameterType="Long" resultMap="MaProjectResult">
         <include refid="selectMaProjectVo"/>
         where is_delete !=1 and id = #{id}