zhaoyun před 3 týdny
rodič
revize
602cede405
100 změnil soubory, kde provedl 10812 přidání a 17 odebrání
  1. 16 0
      ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/controller/platform/PcShoppingController.java
  2. 73 0
      ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/controller/platform/SecondHandCategoryController.java
  3. 96 0
      ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/controller/platform/SecondHandController.java
  4. 8 1
      ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/controller/publicly/PayCallbackController.java
  5. 10 0
      ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/service/PcShoppingService.java
  6. 26 0
      ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/service/SecondHandService.java
  7. 48 0
      ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/service/impl/PcShoppingServiceImpl.java
  8. 58 0
      ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/service/impl/SecondHandServiceImpl.java
  9. 3 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/constants/GroupConfigConstants.java
  10. 3 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/constants/PayConstants.java
  11. 45 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/constants/SecondHandConstants.java
  12. 84 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/dto/SecondHandProdPageDateDto.java
  13. 3 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/community/CommunityNotes.java
  14. 1 1
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/order/OrderDetail.java
  15. 68 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandCategory.java
  16. 132 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandOrder.java
  17. 103 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandOrderDetail.java
  18. 145 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandProd.java
  19. 49 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandProdConcerned.java
  20. 147 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandRefundOrder.java
  21. 96 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandRefundOrderInfo.java
  22. 53 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandRelation.java
  23. 2 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/user/User.java
  24. 3 3
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/CommunityNoteSaveRequest.java
  25. 35 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/EditMySchoolRequest.java
  26. 49 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/SecondHandFrontSearchRequest.java
  27. 46 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/SecondHandProdSearchRequest.java
  28. 76 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/SecondHandSaveRequest.java
  29. 50 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/secondhand/CreateSecondHandOrderRequest.java
  30. 41 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/secondhand/OrderSellerRequest.java
  31. 36 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/secondhand/PreSecondHandOrderDetailRequest.java
  32. 36 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/secondhand/PreSecondHandOrderRequest.java
  33. 55 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/secondhand/SecondHandOrderSendRequest.java
  34. 2 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/CommunityNoteFrontPageResponse.java
  35. 3 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/CommunityUserHomePageResponse.java
  36. 2 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/IndexInfoResponse.java
  37. 76 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/SecondHandDetailResponse.java
  38. 100 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/SecondHandFrontDetailResponse.java
  39. 79 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/SecondHandFrontFollowResponse.java
  40. 86 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/SecondHandFrontPageResponse.java
  41. 82 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/SecondHandPageDataResponse.java
  42. 73 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/PreOrderSellerInfoResponse.java
  43. 72 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/PreOrderSellerResponse.java
  44. 61 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/PreSecondHandOrderResponse.java
  45. 99 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SecondHandOrderFrontDetailResponse.java
  46. 39 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SecondHandOrderNoResponse.java
  47. 58 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SecondHandProdTakeTheirResponse.java
  48. 99 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SecondOrderFrontDataResponse.java
  49. 69 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SecondOrderInfoFrontDataResponse.java
  50. 98 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SellerOrderFrontDetailResponse.java
  51. 37 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/vo/SecondHandConfigVo.java
  52. 75 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/vo/secondhand/PreSecondHandOrderInfoDetailVo.java
  53. 64 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/vo/secondhand/PreSecondHandOrderInfoVo.java
  54. 76 0
      ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/vo/secondhand/PreSellerOrderVo.java
  55. 7 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/CommunityUserCenterController.java
  56. 86 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/PayCallbackController.java
  57. 120 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/SecondHandController.java
  58. 149 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/SecondHandOrderController.java
  59. 54 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/SecondHandPayController.java
  60. 95 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/SecondHandRefundOrderController.java
  61. 4 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/CommunityFrontService.java
  62. 205 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/SecondHandFrontOrderService.java
  63. 117 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/SecondHandFrontService.java
  64. 16 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/impl/CommunityFrontServiceImpl.java
  65. 1190 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/impl/SecondHandFrontOrderServiceImpl.java
  66. 440 0
      ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/impl/SecondHandFrontServiceImpl.java
  67. 54 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/SecondHandOrderDetailDao.java
  68. 17 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandCategoryDao.java
  69. 25 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandDao.java
  70. 49 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandOrderDao.java
  71. 17 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandProdConcernedDao.java
  72. 41 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandRefundOrderDao.java
  73. 17 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandRefundOrderInfoDao.java
  74. 17 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandRelationDao.java
  75. 6 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/AsyncService.java
  76. 0 1
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/OrderService.java
  77. 6 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/PayCallbackService.java
  78. 1 2
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/RefundOrderManagerService.java
  79. 69 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandCategoryService.java
  80. 114 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandOrderService.java
  81. 31 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandPayService.java
  82. 65 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandProdConcernedService.java
  83. 174 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandProdService.java
  84. 27 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandRefundOrderInfoService.java
  85. 208 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandRefundOrderManagerService.java
  86. 207 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandRefundOrderService.java
  87. 51 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandRelationService.java
  88. 15 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/AsyncServiceImpl.java
  89. 10 8
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/CommunityNotesServiceImpl.java
  90. 3 1
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/MerchantServiceImpl.java
  91. 155 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/PayCallbackServiceImpl.java
  92. 216 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandCategoryServiceImpl.java
  93. 115 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandOrderDetailService.java
  94. 257 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandOrderDetailServiceImpl.java
  95. 512 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandOrderServiceImpl.java
  96. 505 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandPayServiceImpl.java
  97. 156 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandProdConcernedServiceImpl.java
  98. 715 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandProdServiceImpl.java
  99. 47 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandRefundOrderInfoServiceImpl.java
  100. 1381 0
      ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandRefundOrderManagerServiceImpl.java

+ 16 - 0
ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/controller/platform/PcShoppingController.java

@@ -256,4 +256,20 @@ public class PcShoppingController {
         }
         return CommonResult.failed().setMessage("保存失败");
     }
+    @PreAuthorize("hasAuthority('platform:pc:shopping:home:navigation:get')")
+    @ApiOperation(value = "获取二手交易首页导航配置")
+    @RequestMapping(value = "/home/secondHand/navigation/get", method = RequestMethod.GET)
+    public CommonResult<List<PcHomeNavigationVo>> getSecondHandNavigation() {
+        return CommonResult.success(pcShoppingService.getSecondHandNavigation());
+    }
+
+    @PreAuthorize("hasAuthority('platform:pc:shopping:home:navigation:save')")
+    @ApiOperation(value = "保存二手交易首页导航配置")
+    @RequestMapping(value = "/home/secondHand/navigation/save", method = RequestMethod.POST)
+    public CommonResult<Object> saveSecondHandNavigation(@RequestBody @Validated List<PcHomeNavigationVo> voListRequest) {
+        if (pcShoppingService.saveSecondHandNavigation(voListRequest)) {
+            return CommonResult.success().setMessage("保存成功");
+        }
+        return CommonResult.failed().setMessage("保存失败");
+    }
 }

+ 73 - 0
ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/controller/platform/SecondHandCategoryController.java

@@ -0,0 +1,73 @@
+package com.zbkj.admin.controller.platform;
+
+import com.zbkj.common.model.community.CommunityCategory;
+import com.zbkj.common.model.secondhand.SecondHandCategory;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.CommunityCategorySaveRequest;
+import com.zbkj.common.request.CommunityCategorySearchRequest;
+import com.zbkj.common.result.CommonResult;
+import com.zbkj.service.service.CommunityCategoryService;
+import com.zbkj.service.service.SecondHandCategoryService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @ClassName CommunityCategoryController
+ * @Description 社区分类控制器
+ * @Author HZW
+ * @Date 2023/3/7 11:32
+ * @Version 1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping("api/admin/platform/secondHand/category")
+@Api(tags = "二手交易分类管理")
+public class SecondHandCategoryController {
+
+    @Autowired
+    private SecondHandCategoryService secondHandCategoryService;
+
+    @PreAuthorize("hasAuthority('platform:secondHand:category:page:list')")
+    @ApiOperation(value = "二手交易分类分页列表")
+    @RequestMapping(value = "/page/list", method = RequestMethod.GET)
+    public CommonPage<SecondHandCategory> findPageList(@Validated CommunityCategorySearchRequest request) {
+        return CommonPage.restPage(secondHandCategoryService.findPageList(request));
+    }
+
+    @PreAuthorize("hasAuthority('platform:secondHand:category:add')")
+    @ApiOperation(value = "添加二手交易分类")
+    @RequestMapping(value = "/add", method = RequestMethod.POST)
+    public CommonResult<Object> add(@RequestBody @Validated CommunityCategorySaveRequest request) {
+        secondHandCategoryService.add(request);
+        return CommonResult.success();
+    }
+
+    @PreAuthorize("hasAuthority('platform:secondHand:category:update')")
+    @ApiOperation(value = "编辑二手交易分类")
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public CommonResult<Object> update(@RequestBody @Validated CommunityCategorySaveRequest request) {
+        secondHandCategoryService.edit(request);
+        return CommonResult.success();
+    }
+
+    @PreAuthorize("hasAuthority('platform:secondHand:category:delete')")
+    @ApiOperation(value = "删除二手交易分类")
+    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
+    public CommonResult<Object> update(@PathVariable("id") Integer id) {
+        secondHandCategoryService.deleteById(id);
+        return CommonResult.success();
+    }
+
+    @PreAuthorize("hasAuthority('platform:secondHand:category:show:switch')")
+    @ApiOperation(value = "二手交易分类显示开关")
+    @RequestMapping(value = "/show/{id}", method = RequestMethod.POST)
+    public CommonResult<Object> showSwitch(@PathVariable("id") Integer id) {
+        secondHandCategoryService.showSwitch(id);
+        return CommonResult.success();
+    }
+}

+ 96 - 0
ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/controller/platform/SecondHandController.java

@@ -0,0 +1,96 @@
+package com.zbkj.admin.controller.platform;
+
+import com.zbkj.admin.service.CommunityService;
+import com.zbkj.admin.service.SecondHandService;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.*;
+import com.zbkj.common.response.CommunityNoteDetailResponse;
+import com.zbkj.common.response.CommunityNotePageDateResponse;
+import com.zbkj.common.response.SecondHandDetailResponse;
+import com.zbkj.common.response.SecondHandPageDataResponse;
+import com.zbkj.common.result.CommonResult;
+import com.zbkj.common.vo.CommunityConfigVo;
+import com.zbkj.common.vo.SecondHandConfigVo;
+import com.zbkj.service.service.SecondHandProdService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @ClassName CommunityCategoryController
+ * @Description 社区控制器
+ * @Author HZW
+ * @Date 2023/3/7 11:32
+ * @Version 1.0
+ */
+@Slf4j
+@RestController
+@RequestMapping("api/admin/platform/secondHand")
+@Api(tags = "二手交易管理")
+public class SecondHandController {
+
+    @Autowired
+    private SecondHandService secondHandService;
+    @Autowired
+    private SecondHandProdService secondHandProdService;
+
+    @PreAuthorize("hasAuthority('platform:secondHand:get:config')")
+    @ApiOperation(value = "获取交易配置")
+    @RequestMapping(value = "/category/get/config", method = RequestMethod.GET)
+    public SecondHandConfigVo getConfig() {
+        return secondHandService.getConfig();
+    }
+
+    @PreAuthorize("hasAuthority('platform:secondHand:update:config')")
+    @ApiOperation(value = "更新交易配置")
+    @RequestMapping(value = "/category/update/config", method = RequestMethod.POST)
+    public CommonResult<Object> updateConfig(@RequestBody @Validated SecondHandConfigVo request) {
+        secondHandService.updateConfig(request);
+        return CommonResult.success();
+    }
+    @PreAuthorize("hasAuthority('platform:secondHand:prod:page:list')")
+    @ApiOperation(value = "社区笔记分页列表")
+    @RequestMapping(value = "/prod/page/list", method = RequestMethod.GET)
+    public CommonPage<SecondHandPageDataResponse> findPageList(@Validated SecondHandProdSearchRequest request) {
+        return CommonPage.restPage(secondHandProdService.findPageList(request));
+    }
+    @PreAuthorize("hasAuthority('platform:secondHand:prod:detail')")
+    @ApiOperation(value = "社区笔记详情")
+    @RequestMapping(value = "/prod/detail/{id}", method = RequestMethod.GET)
+    public SecondHandDetailResponse detail(@PathVariable("id") Integer id) {
+        return secondHandProdService.detail(id);
+    }
+
+    @PreAuthorize("hasAuthority('platform:secondHand:prod:audit')")
+    @ApiOperation(value = "社区笔记审核")
+    @RequestMapping(value = "/prod/audit", method = RequestMethod.POST)
+    public CommonResult<Object> audit(@RequestBody @Validated CommonAuditRequest request) {
+        secondHandProdService.audit(request);
+        return CommonResult.success();
+    }
+    @PreAuthorize("hasAuthority('platform:secondHand:prod:forced:down')")
+    @ApiOperation(value = "社区笔记强制下架")
+    @RequestMapping(value = "/prod/forced/down/{id}", method = RequestMethod.POST)
+    public CommonResult<Object> forcedDown(@RequestBody @Validated CommonForcedDownRequest request) {
+        secondHandProdService.forcedDown(request);
+        return CommonResult.success();
+    }
+    @PreAuthorize("hasAuthority('platform:secondHand:prod:delete')")
+    @ApiOperation(value = "社区笔记删除")
+    @RequestMapping(value = "/prod/delete/{id}", method = RequestMethod.POST)
+    public CommonResult<Object> delete(@PathVariable("id") Integer id) {
+        secondHandProdService.delete(id);
+        return CommonResult.success();
+    }
+    @PreAuthorize("hasAuthority('platform:secondHand:prod:category:batch:update')")
+    @ApiOperation(value = "社区笔记分类批量修改")
+    @RequestMapping(value = "/category/batch/update", method = RequestMethod.POST)
+    public CommonResult<Object> categoryBatchUpdate(@RequestBody @Validated CommunityNoteCategoryBatchUpdateRequest request) {
+        secondHandProdService.categoryBatchUpdate(request);
+        return CommonResult.success();
+    }
+}

+ 8 - 1
ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/controller/publicly/PayCallbackController.java

@@ -62,7 +62,14 @@ public class PayCallbackController {
         System.out.println("支付宝支付回调 request ===> " + JSON.toJSONString(request.getParameterMap()));
         return callbackService.aliPayCallback(request);
     }
-
+    @ApiOperation(value = "二手交易微信支付回调")
+    @RequestMapping(value = "/secondhand/wechat", method = RequestMethod.POST)
+    public String secondHandWeChat(@RequestBody String  request) {
+        System.out.println("微信二手交易支付回调 request ===> " + request);
+        String response = callbackService.wechatSecondhandPayCallback(request);
+        System.out.println("微信二手交易支付回调 response ===> " + response);
+        return response;
+    }
     /**
      * 微信退款回调
      */

+ 10 - 0
ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/service/PcShoppingService.java

@@ -157,4 +157,14 @@ public interface PcShoppingService {
      * @return
      */
     Boolean  saveBanner(List<PcHomeBannerVo> bannerVoList,Integer tag);
+
+    /**
+     * 获取二手交易首页导航配置
+     */
+    List<PcHomeNavigationVo> getSecondHandNavigation();
+
+    /**
+     * 保存二手交易首页导航配置
+     */
+    Boolean saveSecondHandNavigation(List<PcHomeNavigationVo> voListRequest);
 }

+ 26 - 0
ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/service/SecondHandService.java

@@ -0,0 +1,26 @@
+package com.zbkj.admin.service;
+
+import com.zbkj.common.vo.CommunityConfigVo;
+import com.zbkj.common.vo.SecondHandConfigVo;
+
+/**
+ * @ClassName CommunityService
+ * @Description 社区服务
+ * @Author HZW
+ * @Date 2023/3/9 14:38
+ * @Version 1.0
+ */
+public interface SecondHandService {
+
+    /**
+     * 获取社区配置
+     */
+    SecondHandConfigVo getConfig();
+
+    /***
+     * 更新社区配置
+     * @Author HZW
+     * @Date 2023/3/9 14:40
+     */
+    void updateConfig(SecondHandConfigVo configVo);
+}

+ 48 - 0
ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/service/impl/PcShoppingServiceImpl.java

@@ -711,6 +711,54 @@ public class PcShoppingServiceImpl implements PcShoppingService {
         return groupConfigService.saveList(configList);
     }
 
+    @Override
+    public List<PcHomeNavigationVo> getSecondHandNavigation() {
+        List<GroupConfig> configList = groupConfigService.findByTag(GroupConfigConstants.TAG_SECOND_HAND_NAVIGATION, Constants.SORT_ASC, null);
+        if (CollUtil.isEmpty(configList)) {
+            return new ArrayList<>();
+        }
+        Iterator<GroupConfig> iterator = configList.iterator();
+        List<PcHomeNavigationVo> voList = new ArrayList<>();
+        while (iterator.hasNext()) {
+            GroupConfig config = iterator.next();
+            PcHomeNavigationVo vo = new PcHomeNavigationVo();
+            vo.setId(config.getId());
+            vo.setName(config.getName());
+            vo.setLinkUrl(config.getLinkUrl());
+            vo.setSort(config.getSort());
+            vo.setStatus(config.getStatus());
+            vo.setIsHighLight(config.getIsHighLight());
+            vo.setImageUrl(config.getImageUrl());
+            voList.add(vo);
+        }
+        return voList;
+    }
+
+    @Override
+    public Boolean saveSecondHandNavigation(List<PcHomeNavigationVo> voListRequest) {
+        if (CollUtil.isEmpty(voListRequest)) {
+            groupConfigService.deleteByTag(GroupConfigConstants.TAG_SECOND_HAND_NAVIGATION, 0);
+            return Boolean.TRUE;
+        }
+        PcHomeNavigationVo pcHomeNavigationVo = voListRequest.stream().filter(e -> e.getName().length() > 10).findFirst().orElse(null);
+        if (ObjectUtil.isNotNull(pcHomeNavigationVo)) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "自定义首页导航名称最长为10个字符");
+        }
+        List<GroupConfig> configList = voListRequest.stream().map(vo -> {
+            GroupConfig groupConfig = new GroupConfig();
+            groupConfig.setTag(GroupConfigConstants.TAG_SECOND_HAND_NAVIGATION);
+            groupConfig.setMerId(0);
+            groupConfig.setName(vo.getName());
+            groupConfig.setLinkUrl(vo.getLinkUrl());
+            groupConfig.setSort(vo.getSort());
+            groupConfig.setStatus(vo.getStatus());
+            groupConfig.setIsHighLight(vo.getIsHighLight());
+            groupConfig.setImageUrl(vo.getImageUrl());
+            return groupConfig;
+        }).collect(Collectors.toList());
+        return groupConfigService.saveList(configList);
+    }
+
     /**
      * 获取检查后的商品关联数据
      * @param data 商品数据

+ 58 - 0
ydd_mer_java/crmeb-admin/src/main/java/com/zbkj/admin/service/impl/SecondHandServiceImpl.java

@@ -0,0 +1,58 @@
+package com.zbkj.admin.service.impl;
+
+import com.zbkj.admin.service.CommunityService;
+import com.zbkj.admin.service.SecondHandService;
+import com.zbkj.common.constants.CommunityConstants;
+import com.zbkj.common.constants.SecondHandConstants;
+import com.zbkj.common.exception.CrmebException;
+import com.zbkj.common.result.CommonResultCode;
+import com.zbkj.common.vo.CommunityConfigVo;
+import com.zbkj.common.vo.SecondHandConfigVo;
+import com.zbkj.service.service.SystemConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.support.TransactionTemplate;
+
+/**
+ * @ClassName CommunityServiceImpl
+ * @Description 社区服务实现类
+ * @Author HZW
+ * @Date 2023/3/9 14:39
+ * @Version 1.0
+ */
+@Service
+public class SecondHandServiceImpl implements SecondHandService {
+
+    @Autowired
+    private SystemConfigService systemConfigService;
+    @Autowired
+    private TransactionTemplate transactionTemplate;
+
+    /**
+     * 获取社区配置
+     */
+    @Override
+    public SecondHandConfigVo getConfig() {
+        SecondHandConfigVo configVo = new SecondHandConfigVo();
+        configVo.setSecondHandImageTextAuditSwitch(systemConfigService.getValueByKeyException(SecondHandConstants.SECOND_HAND_IMAGE_TEXT_AUDIT_SWITCH));
+        configVo.setSecondHandShortVideoAuditSwitch(systemConfigService.getValueByKeyException(SecondHandConstants.SECOND_HAND_SHORT_VIDEO_AUDIT_SWITCH));
+        return configVo;
+    }
+
+    /***
+     * 更新社区配置
+     * @Author HZW
+     * @Date 2023/3/9 14:40
+     */
+    @Override
+    public void updateConfig(SecondHandConfigVo configVo) {
+        Boolean execute = transactionTemplate.execute(e -> {
+            systemConfigService.updateOrSaveValueByName(SecondHandConstants.SECOND_HAND_IMAGE_TEXT_AUDIT_SWITCH, configVo.getSecondHandImageTextAuditSwitch());
+            systemConfigService.updateOrSaveValueByName(SecondHandConstants.SECOND_HAND_SHORT_VIDEO_AUDIT_SWITCH, configVo.getSecondHandShortVideoAuditSwitch());
+            return Boolean.TRUE;
+        });
+        if (!execute) {
+            throw new CrmebException(CommonResultCode.ERROR.setMessage("更新二手交易配置失败"));
+        }
+    }
+}

+ 3 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/constants/GroupConfigConstants.java

@@ -49,4 +49,7 @@ public class GroupConfigConstants {
     /** tag-代取快快banner */
     public static final Integer TAG_PICK_EXP_BANNER = 17;
 
+    /** 二手交易首页导航 */
+    public static final Integer TAG_SECOND_HAND_NAVIGATION = 18;
+
 }

+ 3 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/constants/PayConstants.java

@@ -71,6 +71,9 @@ public class PayConstants {
 
     // 微信支付回调地址
     public static final String WX_EXP_PAY_NOTIFY_API_URI = "/api/publicly/payment/callback/exp/wechat";
+
+    // 微信支付回调地址
+    public static final String WX_SECONDHAND_PAY_NOTIFY_API_URI = "/api/publicly/payment/callback/secondhand/wechat";
     // 微信退款回调地址
     public static final String WX_PAY_REFUND_NOTIFY_API_URI = "/api/publicly/payment/callback/wechat/refund";
 

+ 45 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/constants/SecondHandConstants.java

@@ -0,0 +1,45 @@
+package com.zbkj.common.constants;
+
+/**
+ * 社区常量类
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+public class SecondHandConstants {
+
+    /**
+     * ---------------------------------------
+     * --------二手交易配置------------------
+     * ---------------------------------------
+     */
+
+    /** 图文笔记审核开关 */
+    public static final String SECOND_HAND_IMAGE_TEXT_AUDIT_SWITCH = "secondHandImageTextAuditSwitch";
+    /** 短视频审核开关 */
+    public static final String SECOND_HAND_SHORT_VIDEO_AUDIT_SWITCH = "secondHandShortVideoAuditSwitch";
+
+    /** 社区笔记类型-图文 */
+    public static final Integer SECOND_HAND_TYPE_IMAGE_CONTENT = 1;
+    /** 社区笔记类型-视频 */
+    public static final Integer SECOND_HAND_TYPE_SHORT_VIDEO = 2;
+
+    /** 社区笔记审核状态-待审核 */
+    public static final Integer SECOND_HAND_AUDIT_AWAIT = 0;
+
+    /** 社区笔记审核状态-审核通过 */
+    public static final Integer SECOND_HAND_AUDIT_SUCCESS = 1;
+    /** 社区笔记审核状态-审核失败 */
+    public static final Integer SECOND_HAND_AUDIT_ERROR = 2;
+
+
+    /** 社区笔记审核状态-平台关闭 */
+    public static final Integer SECOND_HAND_AUDIT_CLOSE = 3;
+
+}

+ 84 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/dto/SecondHandProdPageDateDto.java

@@ -0,0 +1,84 @@
+package com.zbkj.common.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @ClassName CommunityNotePageDateDto
+ * @Description 社区笔记分页数据Dto对象
+ * @Author HZW
+ * @Date 2023/3/7 18:02
+ * @Version 1.0
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SecondHandProdPageDateDto对象", description="社区笔记分页数据Dto对象")
+public class SecondHandProdPageDateDto implements Serializable {
+
+    private static final long serialVersionUID = -8121525449704982702L;
+
+    @ApiModelProperty("笔记ID")
+    private Integer id;
+
+    @ApiModelProperty("标题")
+    private String title;
+    @ApiModelProperty("内容")
+    private String content;
+
+    @ApiModelProperty("作者昵称")
+    private String authorName;
+
+    @ApiModelProperty("作者ID")
+    private Integer authorId;
+
+    @ApiModelProperty("笔记类型:1-图文,2-视频")
+    private Integer type;
+
+    @ApiModelProperty("封面")
+    private String cover;
+
+    @ApiModelProperty("社区分类ID")
+    private Integer categoryId;
+
+    @ApiModelProperty("话题ID,英文逗号拼接")
+    private String topicIds;
+
+    @ApiModelProperty("星级排序:1-5")
+    private Integer star;
+
+    @ApiModelProperty("审核状态:0-待审核,1-审核通过,2-审核失败,3-平台关闭")
+    private Integer auditStatus;
+
+    @ApiModelProperty("拒绝理由")
+    private String refusal;
+
+    @ApiModelProperty("点赞数")
+    private Integer likeNum;
+
+    @ApiModelProperty("评论数")
+    private Integer replyNum;
+
+    @ApiModelProperty("是否开启评论,1-开启,2-关闭,3-平台关闭")
+    private Integer replyStatus;
+
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+
+    @ApiModelProperty("价格")
+    private BigDecimal price;
+
+    private String school;
+    @ApiModelProperty("城市")
+    private String city;
+    @ApiModelProperty("售卖状态:0-待售,1-已售,2-下架")
+    private Integer saleStatus;
+
+}

+ 3 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/community/CommunityNotes.java

@@ -124,6 +124,9 @@ public class CommunityNotes implements Serializable {
     @ApiModelProperty("标签路径")
     @TableField(exist = false)
     private String icon;
+    @ApiModelProperty("学校")
+    @TableField("school")
+    private String school;
 
 
 }

+ 1 - 1
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/order/OrderDetail.java

@@ -107,7 +107,7 @@ public class OrderDetail implements Serializable {
     @ApiModelProperty(value = "赠送积分")
     private Integer gainIntegral;
 
-    @ApiModelProperty(value = "基础类型:0=普通商品,1-积分商品,2-虚拟商品,4=视频号,5-云盘商品,6-卡密商品")
+    @ApiModelProperty(value = "商品类型:潮玩")
     private Integer productType;
 
     @ApiModelProperty(value = "营销类型:0=基础商品,1=秒杀,2=拼团")

+ 68 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandCategory.java

@@ -0,0 +1,68 @@
+package com.zbkj.common.model.secondhand;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 社区分类表
+ * </p>
+ *
+ * @author HZW
+ * @since 2023-03-07
+ */
+@Getter
+@Setter
+@Accessors(chain = true)
+@TableName("eb_second_hand_category")
+@ApiModel(value = "SecondHandCategory对象", description = "二手交易分类表")
+public class SecondHandCategory implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty("父级ID")
+    @TableField("pid")
+    private Integer pid;
+
+    @ApiModelProperty("分类名称")
+    @TableField("`name`")
+    private String name;
+
+    @ApiModelProperty("是否显示:1-显示,0-不显示")
+    @TableField("is_show")
+    private Integer isShow;
+
+    @ApiModelProperty("排序")
+    @TableField("sort")
+    private Integer sort;
+
+    @ApiModelProperty("是否删除,0-未删除,1-删除")
+    @TableField("is_del")
+    private Integer isDel;
+
+    @ApiModelProperty("创建时间")
+    @TableField("create_time")
+    private Date createTime;
+
+    @ApiModelProperty("更新时间")
+    @TableField("update_time")
+    private Date updateTime;
+    @TableField("icon")
+    @ApiModelProperty(value = "图片地址")
+    private String icon;
+
+
+}

+ 132 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandOrder.java

@@ -0,0 +1,132 @@
+package com.zbkj.common.model.secondhand;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * <p>
+ * 订单表
+ * </p>
+ *
+ * @author HZW
+ * @since 2022-09-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("eb_second_hand_order")
+@ApiModel(value = "SecondHandOrder对象", description = "订单表")
+public class SecondHandOrder implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "订单ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "订单号")
+    private String orderNo;
+
+    @ApiModelProperty(value = "卖家ID,商户订单等级有值")
+    private Integer sellerId;
+
+    @ApiModelProperty(value = "用户id")
+    private Integer uid;
+
+    @ApiModelProperty(value = "收货人姓名")
+    private String realName;
+
+    @ApiModelProperty(value = "收货人电话")
+    private String userPhone;
+
+    @ApiModelProperty(value = "收货详细地址")
+    private String userAddress;
+
+    @ApiModelProperty(value = "订单商品总数")
+    private Integer totalNum;
+
+    @ApiModelProperty(value = "商品总价")
+    private BigDecimal proTotalPrice;
+
+    @ApiModelProperty(value = "邮费")
+    private BigDecimal totalPostage;
+
+    @ApiModelProperty(value = "订单总价")
+    private BigDecimal totalPrice;
+
+
+    @ApiModelProperty(value = "实际支付金额")
+    private BigDecimal payPrice;
+
+    @ApiModelProperty(value = "支付邮费")
+    private BigDecimal payPostage;
+
+    @ApiModelProperty(value = "支付状态")
+    private Boolean paid;
+
+    @ApiModelProperty(value = "支付时间")
+    private Date payTime;
+
+    @ApiModelProperty(value = "支付方式:weixin,alipay,yue")
+    private String payType;
+
+    @ApiModelProperty(value = "支付渠道:public-公众号,mini-小程序,h5-网页支付,yue-余额,wechatIos-微信Ios,wechatAndroid-微信Android,alipay-支付宝,alipayApp-支付宝App")
+    private String payChannel;
+
+    @ApiModelProperty(value = "用户备注")
+    private String userRemark;
+    @ApiModelProperty(value = "配送方式 1=快递 ,2=自提,3-虚拟发货")
+    private Integer shippingType;
+
+    @ApiModelProperty(value = "订单状态(0:待支付,1:待发货,2:部分发货, 3:待核销,4:待收货,5:已收货,6:已完成,9:已取消)")
+    private Integer status;
+
+    @ApiModelProperty(value = "退款状态:0 未退款 1 申请中 2 部分退款 3 已退款")
+    private Integer refundStatus;
+
+    @ApiModelProperty(value = "取消状态:0-未取消,1-系统取消,2-用户取消")
+    private Integer cancelStatus;
+
+    @ApiModelProperty(value = "用户是否删除")
+    private Boolean isUserDel;
+
+    @ApiModelProperty(value = "商户是否删除")
+    private Boolean isSellerDel;
+
+    @ApiModelProperty(value = "商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号")
+    private String outTradeNo;
+
+    @ApiModelProperty(value = "支付重定向地址")
+    private String redirect;
+
+    @ApiModelProperty(value = "订单类型:0-基础订单,1-秒杀订单,2-拼团订单")
+    private Integer type;
+
+    @ApiModelProperty(value = "订单等级:0-平台订单,1-商户订单")
+    private Integer level;
+
+    @ApiModelProperty(value = "平台订单号")
+    private String platOrderNo;
+
+    @ApiModelProperty(value = "是否删除")
+    private Boolean isDel;
+
+    @ApiModelProperty(value = "收货时间")
+    private Date receivingTime;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @ApiModelProperty(value = "更新时间")
+    private Date updateTime;
+}

+ 103 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandOrderDetail.java

@@ -0,0 +1,103 @@
+package com.zbkj.common.model.secondhand;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * <p>
+ * 订单详情表
+ * </p>
+ *
+ * @author HZW
+ * @since 2022-09-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("eb_second_hand_order_detail")
+@ApiModel(value = "SecondHandOrderDetail对象", description = "订单详情表")
+public class SecondHandOrderDetail implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "订单号")
+    private String orderNo;
+
+    @ApiModelProperty(value = "商户ID")
+    private Integer sellerId;
+
+    @ApiModelProperty(value = "用户id")
+    private Integer uid;
+
+    @ApiModelProperty(value = "商品ID")
+    private Integer productId;
+
+    @ApiModelProperty(value = "商品名称")
+    private String productName;
+
+    @ApiModelProperty(value = "商品图片")
+    private String image;
+
+    @ApiModelProperty(value = "商品单价")
+    private BigDecimal price;
+
+    @ApiModelProperty(value = "实际支付金额")
+    private BigDecimal payPrice;
+
+    @ApiModelProperty(value = "购买数量")
+    private Integer payNum;
+
+    @ApiModelProperty(value = "重量")
+    private BigDecimal weight;
+
+    @ApiModelProperty(value = "体积")
+    private BigDecimal volume;
+
+    @ApiModelProperty(value = "是否收货,0-未收货,1-已收货")
+    private Boolean isReceipt;
+
+    @ApiModelProperty(value = "运费金额")
+    private BigDecimal freightFee;
+
+
+    @ApiModelProperty(value = "基础类型:0=普通商品,1-积分商品,2-虚拟商品,4=视频号,5-云盘商品,6-卡密商品")
+    private Integer productType;
+
+    @ApiModelProperty(value = "发货数量")
+    private Integer  deliveryNum;
+
+    @ApiModelProperty(value = "申请退款数量")
+    private Integer applyRefundNum;
+
+    @ApiModelProperty(value = "退款数量")
+    private Integer refundNum;
+
+    @ApiModelProperty(value = "退款金额")
+    private BigDecimal refundPrice;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @ApiModelProperty(value = "更新时间")
+    private Date updateTime;
+    @ApiModelProperty(value = "商户名称")
+    private String sellerName;
+    @ApiModelProperty(value = "退运费金额")
+    private BigDecimal refundFreightFee;
+
+}

+ 145 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandProd.java

@@ -0,0 +1,145 @@
+package com.zbkj.common.model.secondhand;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * <p>
+ * 社区笔记表
+ * </p>
+ *
+ * @author HZW
+ * @since 2023-03-07
+ */
+@Getter
+@Setter
+@Accessors(chain = true)
+@TableName("eb_second_hand_prod")
+@ApiModel(value = "SecondHand对象", description = "社区笔记表")
+public class SecondHandProd implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty("标题")
+    @TableField("title")
+    private String title;
+
+    @ApiModelProperty("笔记类型:1-图文,2-视频")
+    @TableField("`type`")
+    private Integer type;
+
+    @ApiModelProperty("封面")
+    @TableField("cover")
+    private String cover;
+
+    @ApiModelProperty("图片")
+    @TableField("image")
+    private String image;
+
+    @ApiModelProperty("视频链接")
+    @TableField("video")
+    private String video;
+
+    @ApiModelProperty("笔记正文")
+    @TableField("content")
+    private String content;
+
+    @ApiModelProperty("社区分类ID")
+    @TableField("category_id")
+    private Integer categoryId;
+
+    @ApiModelProperty("话题ID,英文逗号拼接")
+    @TableField("topic_ids")
+    private String topicIds;
+
+    @ApiModelProperty("用户ID")
+    @TableField("uid")
+    private Integer uid;
+
+    @ApiModelProperty("星级排序:1-5")
+    @TableField("star")
+    private Integer star;
+
+    @ApiModelProperty("审核状态:0-待审核,1-审核通过,2-审核失败,3-平台关闭")
+    @TableField("audit_status")
+    private Integer auditStatus;
+
+    @ApiModelProperty("拒绝理由")
+    @TableField("refusal")
+    private String refusal;
+
+    @ApiModelProperty("点赞数")
+    @TableField("like_num")
+    private Integer likeNum;
+
+    @ApiModelProperty("评论数")
+    @TableField("reply_num")
+    private Integer replyNum;
+
+    @ApiModelProperty("分享数")
+    @TableField("share_num")
+    private Integer shareNum;
+
+    @ApiModelProperty("浏览量")
+    @TableField("views")
+    private Integer views;
+
+    @ApiModelProperty("排序")
+    @TableField("sort")
+    private Integer sort;
+
+    @ApiModelProperty("是否开启评论,1-开启,2-关闭,3-平台关闭")
+    @TableField("reply_status")
+    private Integer replyStatus;
+
+    @ApiModelProperty("是否删除,0-未删除,1-删除")
+    @TableField("is_del")
+    private Integer isDel;
+
+    @ApiModelProperty("操作时间")
+    @TableField("operate_time")
+    private Date operateTime;
+
+    @ApiModelProperty("创建时间")
+    @TableField("create_time")
+    private Date createTime;
+
+    @ApiModelProperty("更新时间")
+    @TableField("update_time")
+    private Date updateTime;
+
+    @ApiModelProperty("标签路径")
+    @TableField(exist = false)
+    private String icon;
+    @ApiModelProperty("学校")
+    @TableField("school")
+    private String school;
+    @ApiModelProperty("价格")
+    @TableField("price")
+    private BigDecimal price;
+    @TableField("city")
+    private  String city;
+    @ApiModelProperty("售卖状态0-上架,1-已售,2-下架")
+    @TableField("sale_status")
+    private Integer saleStatus;
+    @ApiModelProperty(value = "经度")
+    private String longitude;
+    @ApiModelProperty(value = "纬度")
+    private String latitude;
+    @ApiModelProperty(value = "联系地址")
+    private Integer addressId;
+}

+ 49 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandProdConcerned.java

@@ -0,0 +1,49 @@
+package com.zbkj.common.model.secondhand;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 社区作者关注表
+ * </p>
+ *
+ * @author HZW
+ * @since 2023-03-07
+ */
+@Getter
+@Setter
+@Accessors(chain = true)
+@TableName("eb_second_hand_concerned")
+@ApiModel(value = "SecondHandProdConcerned对象", description = "商品关注表")
+public class SecondHandProdConcerned implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty("作者ID")
+    @TableField("second_hand_id")
+    private Integer secondHandId;
+
+    @ApiModelProperty("用户ID")
+    @TableField("uid")
+    private Integer uid;
+
+    @ApiModelProperty("创建时间")
+    @TableField("create_time")
+    private Date createTime;
+
+
+}

+ 147 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandRefundOrder.java

@@ -0,0 +1,147 @@
+package com.zbkj.common.model.secondhand;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * <p>
+ * 退款单表
+ * </p>
+ *
+ * @author HZW
+ * @since 2022-09-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("eb_secondhand_refund_order")
+@ApiModel(value="SecondHandRefundOrder对象", description="退款单表")
+public class SecondHandRefundOrder implements Serializable {
+
+    private static final long serialVersionUID=1L;
+
+    @ApiModelProperty(value = "订单ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "退款订单号")
+    private String refundOrderNo;
+
+    @ApiModelProperty(value = "主订单号")
+    private String orderNo;
+
+    @ApiModelProperty(value = "商户ID")
+    private Integer merId;
+
+    @ApiModelProperty(value = "用户id")
+    private Integer uid;
+
+    @ApiModelProperty(value = "收货人姓名")
+    private String realName;
+
+    @ApiModelProperty(value = "收货人电话")
+    private String userPhone;
+
+    @ApiModelProperty(value = "收货人详细地址")
+    private String userAddress;
+
+    @ApiModelProperty(value = "退款单商品总数")
+    private Integer totalNum;
+
+    @ApiModelProperty(value = "退款原因")
+    private String refundReasonWap;
+
+    @ApiModelProperty(value = "退款图片")
+    private String refundReasonWapImg;
+
+    @ApiModelProperty(value = "退款用户说明")
+    private String refundReasonWapExplain;
+
+    @ApiModelProperty(value = "是否整单退款")
+    private Boolean isAll;
+
+    @ApiModelProperty(value = "售后状态:0:待审核 1:商家拒绝 2:退款中 3:已退款 4:用户退货 5:商家待收货 6:已撤销")
+    private Integer refundStatus;
+
+    @ApiModelProperty(value = "退运费金额")
+    private BigDecimal refundFreightFee;
+
+    @ApiModelProperty(value = "拒绝退款说明")
+    private String refundReason;
+
+    @ApiModelProperty(value = "退款金额")
+    private BigDecimal refundPrice;
+
+    @ApiModelProperty(value = "商家退款金额")
+    private BigDecimal merchantRefundPrice;
+
+    @ApiModelProperty(value = "平台退款金额")
+    private BigDecimal platformRefundPrice;
+
+    @ApiModelProperty(value = "退款时间")
+    private Date refundTime;
+
+    @ApiModelProperty(value = "退款渠道类型:weixin,alipay,yue")
+    private String refundPayType;
+
+    @ApiModelProperty(value = "商户备注")
+    private String merRemark;
+
+    @ApiModelProperty(value = "平台备注")
+    private String platformRemark;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @ApiModelProperty(value = "更新时间")
+    private Date updateTime;
+
+    @ApiModelProperty(value = "售后类型:1-仅退款,2-退货退款")
+    private Integer afterSalesType;
+
+    @ApiModelProperty(value = "退货类型:0-不退货 1-快递退回,2-到店退货")
+    private Integer returnGoodsType;
+
+    @ApiModelProperty(value = "收货人姓名")
+    private String receiver;
+
+    @ApiModelProperty(value = "收货人电话")
+    private String receiverPhone;
+
+    @ApiModelProperty(value = "收货人详细地址")
+    private String receiverAddressDetail;
+
+    @ApiModelProperty(value = "物流公司名称")
+    private String expressName;
+
+    @ApiModelProperty(value = "运单号")
+    private String trackingNumber;
+
+    @ApiModelProperty(value = "用户联系电话")
+    private String telephone;
+
+    @ApiModelProperty(value = "是否强制退款")
+    private Boolean isCompulsoryRefund;
+
+    @ApiModelProperty(value = "强制操作账户ID")
+    private Integer compulsoryAdminId;
+
+    @ApiModelProperty(value = "是否用户撤销")
+    private Boolean isUserRevoke;
+
+    @ApiModelProperty(value = "退款发起方:user-用户,merchant-商户")
+    private String promoterType;
+
+    @ApiModelProperty(value = "第三方退款订单号")
+    private String outRefundNo;
+}

+ 96 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandRefundOrderInfo.java

@@ -0,0 +1,96 @@
+package com.zbkj.common.model.secondhand;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * <p>
+ * 退款订单详情表
+ * </p>
+ *
+ * @author HZW
+ * @since 2022-09-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("eb_secondhand_refund_order_info")
+@ApiModel(value="SecondHandRefundOrderInfo对象", description="退款订单详情表")
+public class SecondHandRefundOrderInfo implements Serializable {
+
+    private static final long serialVersionUID=1L;
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "退款订单号")
+    private String refundOrderNo;
+
+    @ApiModelProperty(value = "商户ID")
+    private Integer merId;
+
+    @ApiModelProperty(value = "订单商品表ID")
+    private Integer orderDetailId;
+
+    @ApiModelProperty(value = "商品ID")
+    private Integer productId;
+
+    @ApiModelProperty(value = "商品名称")
+    private String productName;
+
+    @ApiModelProperty(value = "商品图片")
+    private String image;
+
+    @ApiModelProperty(value = "商品规格值 ID")
+    private Integer attrValueId;
+
+    @ApiModelProperty(value = "商品sku")
+    private String sku;
+
+    @ApiModelProperty(value = "商品单价")
+    private BigDecimal price;
+
+    @ApiModelProperty(value = "支付金额")
+    private BigDecimal payPrice;
+
+    @ApiModelProperty(value = "购买数量")
+    private Integer payNum;
+
+    @ApiModelProperty(value = "商品类型:0-普通,1-秒杀,2-砍价,3-拼团,4-视频号")
+    private Integer productType;
+
+    @ApiModelProperty(value = "申请退款数量")
+    private Integer applyRefundNum;
+
+    @ApiModelProperty(value = "退款金额")
+    private BigDecimal refundPrice;
+
+    @ApiModelProperty(value = "商家退款金额")
+    private BigDecimal MerchantRefundPrice;
+
+    @ApiModelProperty(value = "平台退款金额")
+    private BigDecimal platformRefundPrice;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @ApiModelProperty(value = "更新时间")
+    private Date updateTime;
+
+    @ApiModelProperty(value = "退还平台优惠券补贴金额")
+    private BigDecimal refundPlatCouponPrice;
+
+    @ApiModelProperty(value = "退运费金额")
+    private BigDecimal refundFreightFee;
+}

+ 53 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/secondhand/SecondHandRelation.java

@@ -0,0 +1,53 @@
+package com.zbkj.common.model.secondhand;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 社区笔记关系表
+ * </p>
+ *
+ * @author HZW
+ * @since 2023-03-07
+ */
+@Getter
+@Setter
+@Accessors(chain = true)
+@TableName("eb_second_hand_relation")
+@ApiModel(value = "SecondHandRelation对象", description = "关系表")
+public class SecondHandRelation implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty("笔记ID")
+    @TableField("second_hand_id")
+    private Integer secondHandId;
+
+    @ApiModelProperty("用户ID")
+    @TableField("uid")
+    private Integer uid;
+
+    @ApiModelProperty("关联类型(收藏(collect)、点赞(like))")
+    @TableField("`type`")
+    private String type;
+
+    @ApiModelProperty("创建时间")
+    @TableField("create_time")
+    private Date createTime;
+
+
+}

+ 2 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/model/user/User.java

@@ -175,4 +175,6 @@ public class User implements Serializable {
     private Boolean isRider;
     @ApiModelProperty(value = "成为分骑手时间")
     private Date riderTime;
+    @ApiModelProperty(value = "归属学校")
+    private String school;
 }

+ 3 - 3
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/CommunityNoteSaveRequest.java

@@ -40,12 +40,12 @@ public class CommunityNoteSaveRequest implements Serializable {
     private String title;
 
     @ApiModelProperty("笔记类型:1-图文,2-视频")
-    @NotNull(message = "请选择笔记类型")
-    @Range(min = 1, max = 2, message = "未知的笔记类型")
+    //@NotNull(message = "请选择笔记类型")
+    //@Range(min = 1, max = 2, message = "未知的笔记类型")
     private Integer type;
 
     @ApiModelProperty("封面")
-    @NotBlank(message = "请先上传封面")
+    //@NotBlank(message = "请先上传封面")
     private String cover;
 
     @ApiModelProperty("图片")

+ 35 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/EditMySchoolRequest.java

@@ -0,0 +1,35 @@
+package com.zbkj.common.request;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.hibernate.validator.constraints.Length;
+
+import java.io.Serializable;
+
+/**
+ * 编辑个性签名请求对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "EditMySchoolRequest对象", description = "编辑学校请求对象")
+public class EditMySchoolRequest implements Serializable {
+
+    private static final long serialVersionUID = 7981254019236947138L;
+
+    @ApiModelProperty(value = "学校")
+    @Length(max = 100, message = "学校最多不能超过100个字符")
+    private String school;
+}

+ 49 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/SecondHandFrontSearchRequest.java

@@ -0,0 +1,49 @@
+package com.zbkj.common.request;
+
+import com.zbkj.common.annotation.StringContains;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+
+/**
+ * @ClassName CommunityNoteFrontSearchRequest
+ * @Description 社区笔记移动端查询请求对象
+ * @Author HZW
+ * @Date 2023/3/7 11:32
+ * @Version 1.0
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "CommunityNoteFrontSearchRequest对象", description = "社区笔记移动端查询请求对象")
+public class SecondHandFrontSearchRequest extends PageParamRequest {
+
+    @ApiModelProperty("标题")
+    private String title;
+
+    @ApiModelProperty("社区分类ID")
+    private Integer categoryId;
+
+    @ApiModelProperty("作者ID")
+    private Integer uid;
+
+    @ApiModelProperty("审核状态:0-待审核,1-审核通过,2-审核失败,3-平台关闭")
+    private Integer auditStatus;
+
+    @ApiModelProperty("排序规则(默认id倒序):star-星级排序,hot-最热排序")
+    private String collation = "id";
+    @ApiModelProperty("关键字")
+    private String keywords;
+    @ApiModelProperty("范围")
+    @StringContains(limitValues = {"school", "city","all"}, message = "未知的范围")
+    private String range;
+    @ApiModelProperty("城市")
+    private String city;
+    @ApiModelProperty("售卖状态0-待售,1-已售")
+    private Integer saleStatus;
+
+
+}

+ 46 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/SecondHandProdSearchRequest.java

@@ -0,0 +1,46 @@
+package com.zbkj.common.request;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+
+/**
+ * @ClassName CommunityNoteSearchRequest
+ * @Description 社区笔记查询请求对象
+ * @Author HZW
+ * @Date 2023/3/7 11:32
+ * @Version 1.0
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "SecondHandProdSearchRequestt对象", description = "社区笔记查询请求对象")
+public class SecondHandProdSearchRequest extends UserCommonSearchRequest {
+
+    private static final long serialVersionUID = 1567311735344286591L;
+
+    @ApiModelProperty("标题")
+    private String title;
+
+    @ApiModelProperty("笔记类型:1-图文,2-视频")
+    private Integer type;
+
+    @ApiModelProperty("社区分类ID")
+    private Integer categoryId;
+
+    @ApiModelProperty("话题ID")
+    private Integer topicId;
+
+    @ApiModelProperty("审核状态,全部不传: 0-待审核,1-审核通过,2-审核失败,3-平台关闭")
+    private Integer auditStatus;
+
+    @ApiModelProperty("售卖状态:0-待售,1-已售,2-下架")
+    private Integer saleStatus;
+    @ApiModelProperty("城市")
+    private  String city;
+    @ApiModelProperty("学校")
+    private String school;
+}

+ 76 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/SecondHandSaveRequest.java

@@ -0,0 +1,76 @@
+package com.zbkj.common.request;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.hibernate.validator.constraints.Length;
+import org.hibernate.validator.constraints.Range;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 社区笔记保存对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "SecondHandSaveRequestt对象", description = "二手商品保存对象")
+public class SecondHandSaveRequest implements Serializable {
+
+    private static final long serialVersionUID = 3362714265772774491L;
+
+    @ApiModelProperty("ID, 编辑时必填")
+    private Integer id;
+
+    @ApiModelProperty("标题")
+    @Length(max = 20, message = "标题不能超过20个字符")
+    private String title;
+
+    @ApiModelProperty("笔记类型:1-图文,2-视频")
+    //@NotNull(message = "请选择笔记类型")
+    //@Range(min = 1, max = 2, message = "未知的笔记类型")
+    private Integer type;
+
+    @ApiModelProperty("封面")
+    //@NotBlank(message = "请先上传封面")
+    private String cover;
+
+    @ApiModelProperty("图片")
+    private String image;
+
+    @ApiModelProperty("视频链接")
+    private String video;
+
+    @ApiModelProperty("正文")
+    private String content;
+
+    @ApiModelProperty("分类ID")
+    @NotNull(message = "请选择分类")
+    private Integer categoryId;
+    @ApiModelProperty("价格")
+    @NotNull(message = "价格不能为空")
+    private BigDecimal price;
+    @ApiModelProperty("城市")
+    private String city;
+    @ApiModelProperty("售卖状态:0-待售,1-已售,2-下架")
+    private Integer saleStatus;
+    @ApiModelProperty(value = "经度")
+    private String longitude;
+    @ApiModelProperty(value = "纬度")
+    private String latitude;
+    @ApiModelProperty(value = "联系地址")
+    private Integer addressId;
+}

+ 50 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/secondhand/CreateSecondHandOrderRequest.java

@@ -0,0 +1,50 @@
+package com.zbkj.common.request.secondhand;
+
+import com.zbkj.common.request.OrderMerchantRequest;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 创建订单请求对象
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="CreateSecondHandOrderRequest对象", description="创建订单请求对象")
+public class CreateSecondHandOrderRequest implements Serializable {
+
+    private static final long serialVersionUID = -6133994384185333872L;
+
+    @ApiModelProperty(value = "预下单订单号", required = true)
+    @NotBlank(message = "预下单订单号不能为空")
+    private String preOrderNo;
+
+    @ApiModelProperty(value = "收货地址id")
+    //@NotNull(message = "请选择收货地址")
+    private Integer addressId;
+
+    @ApiModelProperty(value = "订单商户对象", required = true)
+    @NotEmpty(message = "订单商户对象不能为空")
+    @Valid
+    private List<OrderSellerRequest> orderMerchantRequestList;
+
+}

+ 41 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/secondhand/OrderSellerRequest.java

@@ -0,0 +1,41 @@
+package com.zbkj.common.request.secondhand;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.hibernate.validator.constraints.Range;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 订单商户请求对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "OrderSellerRequest", description = "订单商户请求对象")
+public class OrderSellerRequest {
+
+    @ApiModelProperty(value = "商户id")
+    @NotNull(message = "订单卖家id不能为空")
+    private Integer sellerId;
+
+    @ApiModelProperty(value = "快递类型: 1-快递配送,2-自提", required = true)
+    @NotNull(message = "快递类型不能为空")
+    @Range(min = 1, max = 3, message = "未知的快递类型")
+    private Integer shippingType;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+}

+ 36 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/secondhand/PreSecondHandOrderDetailRequest.java

@@ -0,0 +1,36 @@
+package com.zbkj.common.request.secondhand;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * 预下单详情请求对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "PreOrderRequest对象", description = "预下单详情请求对象")
+public class PreSecondHandOrderDetailRequest {
+
+    @ApiModelProperty(value = "商品id(必填)")
+    private Integer productId;
+
+    @ApiModelProperty(value = "商品数量(购买必填)")
+    private Integer productNum;
+
+    @ApiModelProperty(value = "订单编号(再次购买必填)")
+    private String orderNo;
+
+}

+ 36 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/secondhand/PreSecondHandOrderRequest.java

@@ -0,0 +1,36 @@
+package com.zbkj.common.request.secondhand;
+
+import com.zbkj.common.annotation.StringContains;
+import com.zbkj.common.request.PreOrderDetailRequest;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 预下单请求对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "PreSecondHandOrderRequest对象", description = "预下单请求对象")
+public class PreSecondHandOrderRequest {
+    @ApiModelProperty(value = "下单详情列表", required = true)
+    @NotEmpty(message = "下单详情列表不能为空")
+    private List<PreSecondHandOrderDetailRequest> orderDetails;
+
+}

+ 55 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/request/secondhand/SecondHandOrderSendRequest.java

@@ -0,0 +1,55 @@
+package com.zbkj.common.request.secondhand;
+
+import com.zbkj.common.annotation.StringContains;
+import com.zbkj.common.request.SplitOrderSendDetailRequest;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 订单发货对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "SecondHandOrderSendRequest对象", description = "订单发货对象")
+public class SecondHandOrderSendRequest implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "订单编号", required = true)
+    @NotBlank(message = "订单编号不能为空")
+    private String orderNo;
+
+    @ApiModelProperty(value = "发货类型:express-快递,merchant-商家配送,noNeed-无需发货,takeout-外卖配送", allowableValues = "range[express,merchant,noNeed]", required = true)
+    @NotBlank(message = "请选择发货类型")
+    @StringContains(limitValues = {"express","merchant","noNeed","takeout"}, message = "未知的发货类型")
+    private String deliveryType;
+
+    @ApiModelProperty(value = "快递公司")
+    private String expressCompy;
+
+    @ApiModelProperty(value = "快递单号")
+    private String expressNumber;
+
+    @ApiModelProperty(value = "发货备注")
+    @Length(max = 250, message = "备注最多250个字符")
+    private String deliveryMark;
+}

+ 2 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/CommunityNoteFrontPageResponse.java

@@ -49,6 +49,8 @@ public class CommunityNoteFrontPageResponse implements Serializable {
 
     @ApiModelProperty("点赞数")
     private Integer likeNum;
+    @ApiModelProperty("评论数")
+    private Integer replyNum;
 
     @ApiModelProperty("用户是否点赞")
     private Boolean userIsLike = false;

+ 3 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/CommunityUserHomePageResponse.java

@@ -50,4 +50,7 @@ public class CommunityUserHomePageResponse implements Serializable {
     @ApiModelProperty("获赞数")
     private Integer likeNum;
 
+    @ApiModelProperty("归属学校")
+    private String school;
+
 }

+ 2 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/IndexInfoResponse.java

@@ -71,4 +71,6 @@ public class IndexInfoResponse implements Serializable {
     private List<PcHomeNavigationVo> navigatList;
     @ApiModelProperty(value = "首页默认大类id")
     private Integer cateId;
+    @ApiModelProperty(value = "归属学校")
+    private String school;
 }

+ 76 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/SecondHandDetailResponse.java

@@ -0,0 +1,76 @@
+package com.zbkj.common.response;
+
+import com.zbkj.common.model.community.CommunityNotesProduct;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @ClassName CommunityNoteDetailResponse
+ * @Description 社区笔记详情响应对象
+ * @Author HZW
+ * @Date 2023/3/7 18:02
+ * @Version 1.0
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SecondHandDetailResponse对象", description="发布商品详情响应对象")
+public class SecondHandDetailResponse implements Serializable {
+
+    private static final long serialVersionUID = -8121525449704982702L;
+
+    @ApiModelProperty("笔记ID")
+    private Integer id;
+
+    @ApiModelProperty("标题")
+    private String title;
+
+    @ApiModelProperty("笔记类型:1-图文,2-视频")
+    private Integer type;
+
+    @ApiModelProperty("封面")
+    private String cover;
+
+    @ApiModelProperty("图片")
+    private String image;
+
+    @ApiModelProperty("视频链接")
+    private String video;
+
+    @ApiModelProperty("笔记正文")
+    private String content;
+
+    @ApiModelProperty("审核状态:0-待审核,1-审核通过,2-审核失败,3-平台关闭")
+    private Integer auditStatus;
+
+    @ApiModelProperty("拒绝理由")
+    private String refusal;
+
+    @ApiModelProperty("操作时间")
+    private Date operateTime;
+
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+
+    @ApiModelProperty("作者昵称")
+    private String authorName;
+
+    @ApiModelProperty("作者ID")
+    private Integer authorId;
+    @ApiModelProperty("城市")
+    private String city;
+    @ApiModelProperty("价格")
+    private BigDecimal price;
+    @ApiModelProperty("学校")
+    private String school;
+    @ApiModelProperty("售卖状态:0-待售,1-已售,2-下架")
+    private Integer saleStatus;
+}

+ 100 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/SecondHandFrontDetailResponse.java

@@ -0,0 +1,100 @@
+package com.zbkj.common.response;
+
+import com.zbkj.common.model.community.CommunityNotesProduct;
+import com.zbkj.common.model.community.CommunityTopic;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @ClassName CommunityNoteFrontDetailResponse
+ * @Description 社区笔记移动端详情响应对象
+ * @Author HZW
+ * @Date 2023/3/7 18:02
+ * @Version 1.0
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SecondHandFrontDetailResponse", description="移动端详情响应对象")
+public class SecondHandFrontDetailResponse implements Serializable {
+
+    private static final long serialVersionUID = -8121525449704982702L;
+
+    @ApiModelProperty("作者ID")
+    private Integer authorId;
+
+    @ApiModelProperty("作者头像")
+    private String authorAvatar;
+
+    @ApiModelProperty("作者昵称")
+    private String authorName;
+
+    @ApiModelProperty("作者等级图标")
+    private String authorLevelIcon;
+
+    @ApiModelProperty("笔记ID")
+    private Integer id;
+
+    @ApiModelProperty("标题")
+    private String title;
+
+    @ApiModelProperty("笔记类型:1-图文,2-视频")
+    private Integer type;
+
+    @ApiModelProperty("封面")
+    private String cover;
+
+    @ApiModelProperty("图片")
+    private String image;
+
+    @ApiModelProperty("视频链接")
+    private String video;
+
+    @ApiModelProperty("笔记正文")
+    private String content;
+
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+
+    @ApiModelProperty("点赞数")
+    private Integer likeNum;
+
+    @ApiModelProperty("评论数")
+    private Integer replyNum;
+
+    @ApiModelProperty("用户是否点赞")
+    private Boolean userIsLike = false;
+
+    @ApiModelProperty("审核状态:0-待审核,1-审核通过,2-审核失败,3-平台关闭")
+    private Integer auditStatus;
+
+    @ApiModelProperty("拒绝理由")
+    private String refusal;
+    @ApiModelProperty("价格")
+    private BigDecimal price;
+
+    @ApiModelProperty("是否关注")
+    private Boolean isConcerned = false;
+
+    @ApiModelProperty("社区分类ID")
+    private Integer categoryId;
+
+    @ApiModelProperty("社区分类名称")
+    private String categoryName;
+    @ApiModelProperty("售卖状态:0-待售,1-已售,2-下架")
+    private Integer saleStatus;
+    @ApiModelProperty("学校")
+    private String school;
+    @ApiModelProperty("城市")
+    private String city;
+    @ApiModelProperty("联系地址")
+    private Integer addressId;
+}

+ 79 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/SecondHandFrontFollowResponse.java

@@ -0,0 +1,79 @@
+package com.zbkj.common.response;
+
+import com.zbkj.common.model.community.CommunityNotesProduct;
+import com.zbkj.common.model.community.CommunityTopic;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @ClassName CommunityNoteFrontFollowResponse
+ * @Description 社区笔记移动端关注分页响应对象
+ * @Author HZW
+ * @Date 2023/3/7 18:02
+ * @Version 1.0
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SecondHandFrontFollowResponse对象", description="移动端关注分页响应对象")
+public class SecondHandFrontFollowResponse implements Serializable {
+
+    private static final long serialVersionUID = -8121525449704982702L;
+
+    @ApiModelProperty("笔记ID")
+    private Integer id;
+
+    @ApiModelProperty("标题")
+    private String title;
+
+    @ApiModelProperty("笔记类型:1-图文,2-视频")
+    private Integer type;
+
+    @ApiModelProperty("封面")
+    private String cover;
+
+    @ApiModelProperty("图片")
+    private String image;
+
+    @ApiModelProperty("视频链接")
+    private String video;
+
+    @ApiModelProperty("笔记正文")
+    private String content;
+
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+
+    @ApiModelProperty("作者头像")
+    private String authorAvatar;
+
+    @ApiModelProperty("作者昵称")
+    private String authorName;
+
+    @ApiModelProperty("作者ID")
+    private Integer authorId;
+
+    @ApiModelProperty("点赞数")
+    private Integer likeNum;
+
+    @ApiModelProperty("用户是否点赞")
+    private Boolean userIsLike = false;
+
+    @ApiModelProperty(value = "作者等级图标")
+    private String authorLevelIcon;
+
+    @ApiModelProperty("评论数")
+    private Integer replyNum;
+    @ApiModelProperty(value = "价格")
+    private BigDecimal price;
+    @ApiModelProperty("售卖状态:0-待售,1-已售,2-下架")
+    private Integer saleStatus;
+}

+ 86 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/SecondHandFrontPageResponse.java

@@ -0,0 +1,86 @@
+package com.zbkj.common.response;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @ClassName CommunityNoteFrontPageResponse
+ * @Description 社区笔记移动端分页数据响应对象
+ * @Author HZW
+ * @Date 2023/3/7 18:02
+ * @Version 1.0
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SecondHandFrontPageResponse对象", description="移动端分页数据响应对象")
+public class SecondHandFrontPageResponse implements Serializable {
+
+    private static final long serialVersionUID = -8121525449704982702L;
+
+    @ApiModelProperty("笔记ID")
+    private Integer id;
+
+    @ApiModelProperty("标题")
+    private String title;
+
+    @ApiModelProperty("作者昵称")
+    private String authorName;
+
+    @ApiModelProperty("作者头像")
+    private String authorAvatar;
+
+    @ApiModelProperty("作者ID")
+    private Integer authorId;
+
+    @ApiModelProperty("笔记类型:1-图文,2-视频")
+    private Integer type;
+
+    @ApiModelProperty("封面")
+    private String cover;
+
+    @ApiModelProperty("点赞数")
+    private Integer likeNum;
+    @ApiModelProperty("评论数")
+    private Integer replyNum;
+
+    @ApiModelProperty("用户是否点赞")
+    private Boolean userIsLike = false;
+
+    @ApiModelProperty(value = "用户等级图标")
+    private String userLevelIcon;
+
+    @ApiModelProperty("审核状态:0-待审核,1-审核通过,2-审核失败,3-平台关闭")
+    private Integer auditStatus;
+
+    @ApiModelProperty("拒绝理由")
+    private String refusal;
+    @ApiModelProperty("正文")
+    private String content;
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+    @ApiModelProperty("学校")
+    private String school;
+    @ApiModelProperty("类别")
+    private Integer categoryId;
+    @ApiModelProperty("标签图表")
+    private String icon;
+    @ApiModelProperty("价格")
+    private BigDecimal price;
+    @ApiModelProperty("是否关注")
+    private Boolean isConcerned;
+    @ApiModelProperty(value = "作者等级图标")
+    private String authorLevelIcon;
+    @ApiModelProperty("图片")
+    private String image;
+    @ApiModelProperty("售卖状态:0-待售,1-已售,2-下架")
+    private Integer saleStatus;
+}

+ 82 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/SecondHandPageDataResponse.java

@@ -0,0 +1,82 @@
+package com.zbkj.common.response;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @ClassName CommunityNotePageDateResponse
+ * @Description 社区笔记分页数据响应对象
+ * @Author HZW
+ * @Date 2023/3/7 18:02
+ * @Version 1.0
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SecondHandPageDataResponse对象", description="分页数据响应对象")
+public class SecondHandPageDataResponse implements Serializable {
+
+    private static final long serialVersionUID = -8121525449704982702L;
+
+    @ApiModelProperty("笔记ID")
+    private Integer id;
+
+    @ApiModelProperty("标题")
+    private String title;
+
+    @ApiModelProperty("内容")
+    private String content;
+
+    @ApiModelProperty("作者昵称")
+    private String authorName;
+
+    @ApiModelProperty("作者ID")
+    private Integer authorId;
+
+    @ApiModelProperty("笔记类型:1-图文,2-视频")
+    private Integer type;
+
+    @ApiModelProperty("封面")
+    private String cover;
+
+    @ApiModelProperty("社区分类名称")
+    private String categoryName;
+
+    @ApiModelProperty("星级排序:1-5")
+    private Integer star;
+
+    @ApiModelProperty("审核状态:0-待审核,1-审核通过,2-审核失败,3-平台关闭")
+    private Integer auditStatus;
+
+    @ApiModelProperty("拒绝理由")
+    private String refusal;
+
+    @ApiModelProperty("点赞数")
+    private Integer likeNum;
+
+    @ApiModelProperty("评论数")
+    private Integer replyNum;
+
+    @ApiModelProperty("是否开启评论,1-开启,2-关闭,3-平台关闭")
+    private Integer replyStatus;
+
+    @ApiModelProperty("创建时间")
+    private Date createTime;
+    @ApiModelProperty("学校")
+    private String school;
+    @ApiModelProperty("城市")
+    private String city;
+    @ApiModelProperty("售卖状态:0-待售,1-已售,2-下架")
+    private Integer saleStatus;
+    @ApiModelProperty("价格")
+    private BigDecimal price;
+
+}

+ 73 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/PreOrderSellerInfoResponse.java

@@ -0,0 +1,73 @@
+package com.zbkj.common.response.secondhand;
+
+import com.zbkj.common.model.coupon.CouponUser;
+import com.zbkj.common.vo.PreOrderInfoDetailVo;
+import com.zbkj.common.vo.secondhand.PreSecondHandOrderInfoDetailVo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 预下单商户部分响应对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "PreOrderSellerInfoResponse对象", description = "预下单商户部分响应对象")
+public class PreOrderSellerInfoResponse implements Serializable {
+
+    private static final long serialVersionUID = 7282892323898493847L;
+
+    @ApiModelProperty(value = "商户id")
+    private Integer sellerId;
+
+    @ApiModelProperty(value = "商户名称")
+    private String sellerName;
+
+    @ApiModelProperty(value = "商品总数")
+    private Integer proTotalNum;
+
+    @ApiModelProperty(value = "商品总计金额")
+    private BigDecimal proTotalFee;
+
+    @ApiModelProperty(value = "运费金额")
+    private BigDecimal freightFee;
+
+    @ApiModelProperty(value = "快递类型: 1-快递配送,2-自提,3-虚拟发货")
+    private Integer shippingType = 1;
+
+    @ApiModelProperty(value = "收货人姓名")
+    private String realName;
+
+    @ApiModelProperty(value = "收货人电话")
+    private String userPhone;
+
+    @ApiModelProperty(value = "收货详细地址")
+    private String userAddress;
+
+    @ApiModelProperty(value = "商户订单详情数组")
+    private List<PreSecondHandOrderInfoDetailVo> orderInfoList;
+    @ApiModelProperty(value = "订单类型:0-基础订单,1-秒杀订单,2-拼团订单")
+    private Integer type;
+
+    @ApiModelProperty(value = "商家配送方式:1-商家配送,2-到店核销,逗号分隔")
+    private String deliveryMethodMer;
+    @ApiModelProperty(value = "自提开关:0-关闭,1-开启")
+    private Boolean takeTheirSwitch;
+
+}

+ 72 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/PreOrderSellerResponse.java

@@ -0,0 +1,72 @@
+package com.zbkj.common.response.secondhand;
+
+import com.zbkj.common.model.coupon.CouponUser;
+import com.zbkj.common.response.PreOrderMerchantInfoResponse;
+import com.zbkj.common.vo.PreOrderInfoDetailVo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 预下单商户部分响应对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "PreOrderSellerResponse对象", description = "预下单商户部分响应对象")
+public class PreOrderSellerResponse implements Serializable {
+
+    private static final long serialVersionUID = 7282892323898493847L;
+
+    @ApiModelProperty(value = "商户id")
+    private Integer sellerId;
+
+    @ApiModelProperty(value = "商户名称")
+    private String sellerName;
+
+    @ApiModelProperty(value = "商品总数")
+    private Integer proTotalNum;
+
+    @ApiModelProperty(value = "商品总计金额")
+    private BigDecimal proTotalFee;
+
+    @ApiModelProperty(value = "运费金额")
+    private BigDecimal freightFee;
+
+    @ApiModelProperty(value = "快递类型: 1-快递配送,2-自提")
+    private Integer shippingType = 1;
+
+    @ApiModelProperty(value = "收货人姓名")
+    private String realName;
+
+    @ApiModelProperty(value = "收货人电话")
+    private String userPhone;
+
+    @ApiModelProperty(value = "收货详细地址")
+    private String userAddress;
+
+    @ApiModelProperty(value = "订单类型:0-基础订单,1-秒杀订单,2-拼团订单")
+    private Integer type;
+
+    @ApiModelProperty(value = "订单二级类型:0-普通订单,1-积分订单,2-虚拟订单,4-视频号订单,5-云盘订单,6-卡密订单")
+    private Integer secondType;
+
+    @ApiModelProperty(value = "商户订单数组")
+    private List<PreOrderSellerInfoResponse> merchantInfoList;
+
+}

+ 61 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/PreSecondHandOrderResponse.java

@@ -0,0 +1,61 @@
+package com.zbkj.common.response.secondhand;
+
+import com.zbkj.common.model.coupon.CouponUser;
+import com.zbkj.common.response.PreOrderMerchantInfoResponse;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 预下单响应对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "PreSecondHandOrderResponse对象", description = "预下单响应对象")
+public class PreSecondHandOrderResponse implements Serializable {
+
+    private static final long serialVersionUID = 7282892323898493847L;
+
+    @ApiModelProperty(value = "商品总计金额")
+    private BigDecimal proTotalFee;
+
+    @ApiModelProperty(value = "订单商品数量")
+    private Integer orderProNum;
+
+    @ApiModelProperty(value = "运费金额")
+    private BigDecimal freightFee = BigDecimal.ZERO;
+
+
+    @ApiModelProperty(value = "实际支付金额")
+    private BigDecimal payFee;
+
+
+    @ApiModelProperty(value = "地址id")
+    private Integer addressId;
+
+    @ApiModelProperty(value = "用户剩余积分")
+    private Integer userIntegral;
+
+    @ApiModelProperty(value = "用户可用余额")
+    private BigDecimal userBalance;
+
+    @ApiModelProperty(value = "商户订单数组")
+    private List<PreOrderMerchantInfoResponse> merchantInfoList;
+
+}

+ 99 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SecondHandOrderFrontDetailResponse.java

@@ -0,0 +1,99 @@
+package com.zbkj.common.response.secondhand;
+
+import com.zbkj.common.model.order.OrderInvoice;
+import com.zbkj.common.response.MerchantOrderFrontDetailResponse;
+import com.zbkj.common.response.OrderInvoiceResponse;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 订单移动端详情响应对象
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SecondHandOrderFrontDetailResponse对象", description="订单移动端详情响应对象")
+public class SecondHandOrderFrontDetailResponse implements Serializable {
+
+    private static final long serialVersionUID = -4324222121352855551L;
+
+    @ApiModelProperty(value = "订单ID")
+    private Integer id;
+
+    @ApiModelProperty(value = "订单号")
+    private String orderNo;
+
+    @ApiModelProperty(value = "商户ID")
+    private Integer sellerId;
+
+    @ApiModelProperty(value = "用户id")
+    private Integer uid;
+
+    @ApiModelProperty(value = "订单商品总数")
+    private Integer totalNum;
+
+    @ApiModelProperty(value = "商品总价")
+    private BigDecimal proTotalPrice;
+
+    @ApiModelProperty(value = "邮费")
+    private BigDecimal totalPostage;
+
+    @ApiModelProperty(value = "订单总价")
+    private BigDecimal totalPrice;
+
+
+    @ApiModelProperty(value = "实际支付金额")
+    private BigDecimal payPrice;
+
+    @ApiModelProperty(value = "支付邮费")
+    private BigDecimal payPostage;
+
+    @ApiModelProperty(value = "支付状态")
+    private Boolean paid;
+
+    @ApiModelProperty(value = "支付时间")
+    private Date payTime;
+
+    @ApiModelProperty(value = "支付方式:weixin,alipay,yue")
+    private String payType;
+
+    @ApiModelProperty(value = "订单状态(0:待支付,1:待发货,2:部分发货, 3:待核销,4:待收货,5:已收货,6:已完成,9:已取消)")
+    private Integer status;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @ApiModelProperty(value = "订单类型:0-基础订单,1-秒杀订单,2-拼团订单")
+    private Integer type;
+
+    @ApiModelProperty(value = "订单详情")
+    private List<SellerOrderFrontDetailResponse> merchantOrderList;
+
+    @ApiModelProperty(value = "过期时间")
+    private Long cancelTime;
+
+    @ApiModelProperty(value = "退款状态:0 未退款 1 申请中 2 部分退款 3 已退款")
+    private Integer refundStatus;
+
+    @ApiModelProperty(value = "过期时间")
+    private String expirationTime;
+    @ApiModelProperty(value = "快递详情")
+    private List<OrderInvoiceResponse> orderInvoiceList;
+}

+ 39 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SecondHandOrderNoResponse.java

@@ -0,0 +1,39 @@
+package com.zbkj.common.response.secondhand;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 订单号响应对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SecondHandOrderNoResponse对象", description="订单号响应对象")
+public class SecondHandOrderNoResponse implements Serializable {
+
+    private static final long serialVersionUID = 5527685476730836401L;
+
+    @ApiModelProperty(value = "订单号(预下单时为预下单单号)")
+    private String orderNo;
+
+    @ApiModelProperty(value = "支付金额")
+    private BigDecimal payPrice;
+
+}

+ 58 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SecondHandProdTakeTheirResponse.java

@@ -0,0 +1,58 @@
+package com.zbkj.common.response.secondhand;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 商户自提信息响应对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "SecondHandProdTakeTheirResponse对象", description = "自提信息响应对象")
+public class SecondHandProdTakeTheirResponse implements Serializable {
+
+    private static final long serialVersionUID = 4230168203926975844L;
+
+    @ApiModelProperty(value = "商户ID")
+    private Integer id;
+
+    @ApiModelProperty(value = "商户名称")
+    private String name;
+
+    @ApiModelProperty(value = "商户手机号")
+    private String phone;
+
+    @ApiModelProperty(value = "省")
+    private String province;
+
+    @ApiModelProperty(value = "市")
+    private String city;
+
+    @ApiModelProperty(value = "区")
+    private String district;
+
+    @ApiModelProperty(value = "商户详细地址")
+    private String addressDetail;
+
+    @ApiModelProperty(value = "纬度")
+    private String latitude;
+
+    @ApiModelProperty(value = "经度")
+    private String longitude;
+}

+ 99 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SecondOrderFrontDataResponse.java

@@ -0,0 +1,99 @@
+package com.zbkj.common.response.secondhand;
+
+import com.zbkj.common.response.OrderInfoFrontDataResponse;
+import com.zbkj.common.response.groupbuy.GroupBuyActivityRecordForFrontShareUse;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 订单移动端列表数据响应对象
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SecondOrderFrontDataResponse对象", description="订单移动端列表数据响应对象")
+public class SecondOrderFrontDataResponse implements Serializable {
+
+    private static final long serialVersionUID = 1387727608277207652L;
+
+    @ApiModelProperty(value = "订单id")
+    private Integer id;
+
+    @ApiModelProperty(value = "订单号")
+    private String orderNo;
+
+    @ApiModelProperty(value = "商户ID")
+    private Integer sellerId;
+
+    @ApiModelProperty(value = "支付状态")
+    private Boolean paid;
+
+    @ApiModelProperty(value = "支付时间")
+    private Date payTime;
+
+    @ApiModelProperty(value = "支付金额")
+    private BigDecimal payPrice;
+
+    @ApiModelProperty(value = "订单状态(0:待支付,1:待发货,2:部分发货, 3:待核销,4:待收货,5:已收货,6:已完成,9:已取消)")
+    private Integer status;
+
+    @ApiModelProperty(value = "取消状态:0-未取消,1-系统取消,2-用户取消")
+    private Integer cancelStatus;
+
+    @ApiModelProperty(value = "订单商品总数")
+    private Integer totalNum;
+
+    @ApiModelProperty(value = "商品总价")
+    private BigDecimal proTotalPrice;
+
+    @ApiModelProperty(value = "订单总价")
+    private BigDecimal totalPrice;
+
+    @ApiModelProperty(value = "支付邮费")
+    private BigDecimal payPostage;
+
+
+    @ApiModelProperty(value = "订单详情对象列表")
+    private List<SecondOrderInfoFrontDataResponse> orderInfoList;
+
+    @ApiModelProperty(value = "商户名称")
+    private String sellerName;
+
+    @ApiModelProperty(value = "订单类型:0-基础订单,1-秒杀订单,2-拼团订单")
+    private Integer type;
+
+    @ApiModelProperty(value = "过期时间")
+    private Long cancelTime;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @ApiModelProperty(value = "退款状态:0 未退款 1 申请中 2 部分退款 3 已退款")
+    private Integer refundStatus;
+
+    @ApiModelProperty(value = "过期时间")
+    private String expirationTime;
+    @ApiModelProperty(value = "商家电话")
+    private String sellerPhone;
+    @ApiModelProperty(value = "商家地址")
+    private String sellerAddress;
+    @ApiModelProperty(value = "用户地址")
+    private String userAddress;
+}

+ 69 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SecondOrderInfoFrontDataResponse.java

@@ -0,0 +1,69 @@
+package com.zbkj.common.response.secondhand;
+
+import com.zbkj.common.model.cdkey.CardSecret;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 订单详情移动端数据响应对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SecondOrderInfoFrontDataResponse对象", description="订单详情移动端数据响应对象")
+public class SecondOrderInfoFrontDataResponse implements Serializable {
+
+    private static final long serialVersionUID=1L;
+
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+
+    @ApiModelProperty(value = "商户ID")
+    private Integer sellerId;
+
+    @ApiModelProperty(value = "商品ID")
+    private Integer productId;
+
+    @ApiModelProperty(value = "商品名称")
+    private String productName;
+
+    @ApiModelProperty(value = "商品图片")
+    private String image;
+
+    @ApiModelProperty(value = "商品单价")
+    private BigDecimal price;
+
+    @ApiModelProperty(value = "购买数量")
+    private Integer payNum;
+
+    @ApiModelProperty(value = "实际支付金额")
+    private BigDecimal payPrice;
+
+    @ApiModelProperty(value = "申请退款数量")
+    private Integer applyRefundNum;
+
+    @ApiModelProperty(value = "退款数量")
+    private Integer refundNum;
+
+    @ApiModelProperty(value = "发货数量")
+    private Integer  deliveryNum;
+
+    @ApiModelProperty(value = "基础类型:0=普通商品,1-积分商品,2-虚拟商品,4=视频号,5-云盘商品,6-卡密商品")
+    private Integer productType;
+}

+ 98 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/response/secondhand/SellerOrderFrontDetailResponse.java

@@ -0,0 +1,98 @@
+package com.zbkj.common.response.secondhand;
+
+import com.zbkj.common.response.OrderInfoFrontDataResponse;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 订单移动端商户详情响应对象
+ *  +----------------------------------------------------------------------
+ *  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ *  +----------------------------------------------------------------------
+ *  | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ *  +----------------------------------------------------------------------
+ *  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ *  +----------------------------------------------------------------------
+ *  | Author: CRMEB Team <admin@crmeb.com>
+ *  +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SellerOrderFrontDetailResponse对象", description="订单移动端商户详情响应对象")
+public class SellerOrderFrontDetailResponse implements Serializable {
+
+    private static final long serialVersionUID = -4324222121352855551L;
+
+    @ApiModelProperty(value = "商户ID")
+    private Integer sellerId;
+
+    @ApiModelProperty(value = "收货人姓名")
+    private String realName;
+
+    @ApiModelProperty(value = "收货人电话")
+    private String userPhone;
+
+    @ApiModelProperty(value = "收货详细地址")
+    private String userAddress;
+
+    @ApiModelProperty(value = "订单商品总数")
+    private Integer totalNum;
+
+    @ApiModelProperty(value = "商品总价")
+    private BigDecimal proTotalPrice;
+
+    @ApiModelProperty(value = "邮费")
+    private BigDecimal totalPostage;
+
+    @ApiModelProperty(value = "订单总价")
+    private BigDecimal totalPrice;
+
+    @ApiModelProperty(value = "实际支付金额")
+    private BigDecimal payPrice;
+
+    @ApiModelProperty(value = "支付邮费")
+    private BigDecimal payPostage;
+
+    @ApiModelProperty(value = "用户备注")
+    private String userRemark;
+
+    @ApiModelProperty(value = "配送方式 1=快递 ,2=自提,3-虚拟发货")
+    private Integer shippingType;
+
+
+    @ApiModelProperty(value = "商户名称")
+    private String merName;
+
+    @ApiModelProperty(value = "商户手机号")
+    private String  merPhone;
+
+    @ApiModelProperty(value = "省")
+    private String  merProvince;
+
+    @ApiModelProperty(value = "市")
+    private String merCity;
+
+    @ApiModelProperty(value = "区")
+    private String  merDistrict;
+
+    @ApiModelProperty(value = "商户详细地址")
+    private String  merAddressDetail;
+
+    @ApiModelProperty(value = "纬度")
+    private String  merLatitude;
+
+    @ApiModelProperty(value = "经度")
+    private String  merLongitude;
+
+    @ApiModelProperty(value = "订单详情")
+    private List<SecondOrderInfoFrontDataResponse> orderInfoList;
+
+}

+ 37 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/vo/SecondHandConfigVo.java

@@ -0,0 +1,37 @@
+package com.zbkj.common.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * 社区配置VO对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="SecondHandConfigVo对象", description="二手交易配置VO对象")
+public class SecondHandConfigVo implements Serializable {
+    private static final long serialVersionUID = 2543708543623796607L;
+    @ApiModelProperty(value = "交易图文笔记审核开关", required = true)
+    @NotBlank(message = "交易图文笔记审核开关不能为空")
+    private String secondHandImageTextAuditSwitch;
+
+    @ApiModelProperty(value = "交易短视频审核开关", required = true)
+    @NotBlank(message = "交易短视频审核开关不能为空")
+    private String secondHandShortVideoAuditSwitch;
+}

+ 75 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/vo/secondhand/PreSecondHandOrderInfoDetailVo.java

@@ -0,0 +1,75 @@
+package com.zbkj.common.vo.secondhand;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+
+/**
+ * 订单详情Vo对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "PreOrderInfoDetailVo对象", description = "预下单订单详情Vo对象")
+public class PreSecondHandOrderInfoDetailVo {
+
+    @ApiModelProperty(value = "商品id")
+    private Integer productId;
+    @ApiModelProperty(value = "商品类型")
+    private Integer productType;
+
+    @ApiModelProperty(value = "商品名称")
+    private String productName;
+
+    @ApiModelProperty(value = "商品描述")
+    private String productDesc;
+
+    @ApiModelProperty(value = "商品图片")
+    private String image;
+
+    @ApiModelProperty(value = "单价")
+    private BigDecimal price;
+
+    @ApiModelProperty(value = "实际支付金额")
+    private BigDecimal payPrice;
+
+    @ApiModelProperty(value = "购买数量")
+    private Integer payNum;
+
+    @ApiModelProperty(value = "重量")
+    private BigDecimal weight;
+
+    @ApiModelProperty(value = "体积")
+    private BigDecimal volume;
+
+    @ApiModelProperty(value = "运费模板ID")
+    private Integer tempId;
+
+    @ApiModelProperty(value = "运费金额")
+    private BigDecimal freightFee = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "使用积分")
+    private Integer useIntegral = 0;
+
+    @ApiModelProperty(value = "配送方式:1-商家配送,2-自提")
+    private String deliveryMethod;
+
+    @ApiModelProperty(value = "商品是否支持退款")
+    private Boolean proRefundSwitch;
+
+    @ApiModelProperty(value = "兑换积分")
+    private Integer redeemIntegral = 0;
+}

+ 64 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/vo/secondhand/PreSecondHandOrderInfoVo.java

@@ -0,0 +1,64 @@
+package com.zbkj.common.vo.secondhand;
+
+import com.zbkj.common.vo.PreMerchantOrderVo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 预下单Vo对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "PreSecondHandOrderInfoVo对象", description = "预下单Vo对象")
+public class PreSecondHandOrderInfoVo implements Serializable {
+
+    private static final long serialVersionUID = 567452850314559079L;
+
+    @ApiModelProperty(value = "商品总计金额")
+    private BigDecimal proTotalFee;
+
+    @ApiModelProperty(value = "订单商品数量")
+    private Integer orderProNum;
+
+    @ApiModelProperty(value = "运费金额")
+    private BigDecimal freightFee = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "实际支付金额")
+    private BigDecimal payFee;
+
+    @ApiModelProperty(value = "地址id")
+    private Integer addressId;
+
+    @ApiModelProperty(value = "用户剩余积分")
+    private Integer userIntegral;
+
+    @ApiModelProperty(value = "用户可用余额")
+    private BigDecimal userBalance;
+    @ApiModelProperty(value = "订单类型:0-基础订单,1-秒杀订单,2-拼团订单")
+    private Integer type;
+
+    @ApiModelProperty(value = "订单二级类型:0-普通订单,1-积分订单,2-虚拟订单,4-视频号订单,5-云盘订单,6-卡密订单")
+    private Integer secondType;
+
+    @ApiModelProperty(value = "卖家订单数组")
+    private List<PreSellerOrderVo> sellerOrderVoList;
+
+    private Integer sellerId;
+}

+ 76 - 0
ydd_mer_java/crmeb-common/src/main/java/com/zbkj/common/vo/secondhand/PreSellerOrderVo.java

@@ -0,0 +1,76 @@
+package com.zbkj.common.vo.secondhand;
+
+import com.zbkj.common.response.secondhand.PreOrderSellerInfoResponse;
+import com.zbkj.common.vo.PreOrderInfoDetailVo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 预下单商户订单Vo对象
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "PreMerchantOrderVo对象", description = "预下单商户订单Vo对象")
+public class PreSellerOrderVo implements Serializable {
+
+    private static final long serialVersionUID = 7282892323898493847L;
+
+    @ApiModelProperty(value = "卖家id")
+    private Integer sellerId;
+
+    @ApiModelProperty(value = "卖家名称")
+    private String sellerName;
+    @ApiModelProperty(value = "卖家电话")
+    private String sellerPhone;
+    @ApiModelProperty(value = "卖家地址")
+    private String sellerAddress;
+    @ApiModelProperty(value = "商品总数")
+    private Integer proTotalNum;
+
+    @ApiModelProperty(value = "商品总计金额")
+    private BigDecimal proTotalFee;
+
+    @ApiModelProperty(value = "运费金额")
+    private BigDecimal freightFee;
+
+    @ApiModelProperty(value = "快递类型: 1-快递,2-自提")
+    private Integer shippingType = 1;
+
+    @ApiModelProperty(value = "收货人姓名")
+    private String realName;
+
+    @ApiModelProperty(value = "收货人电话")
+    private String userPhone;
+
+    @ApiModelProperty(value = "收货详细地址")
+    private String userAddress;
+
+    @ApiModelProperty(value = "使用积分")
+    private Integer useIntegral = 0;
+
+
+    @ApiModelProperty(value = "自提开关:0-关闭,1-开启")
+    private Boolean takeTheirSwitch;
+
+    @ApiModelProperty(value = "卖家订单详情数组")
+    private List<PreSecondHandOrderInfoDetailVo> orderInfoList;
+
+
+}

+ 7 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/CommunityUserCenterController.java

@@ -1,6 +1,7 @@
 package com.zbkj.front.controller;
 
 import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.EditMySchoolRequest;
 import com.zbkj.common.request.EditMySignatureRequest;
 import com.zbkj.common.request.PageParamRequest;
 import com.zbkj.common.response.CommunityUserHomePageResponse;
@@ -56,4 +57,10 @@ public class CommunityUserCenterController {
         communityFrontService.editMySignature(request);
         return "编辑个性签名成功";
     }
+    @ApiOperation(value = "编辑学校")
+    @RequestMapping(value = "/edit/school", method = RequestMethod.POST)
+    public String editMySchool(@RequestBody @Validated EditMySchoolRequest request) {
+        communityFrontService.editMySchool(request);
+        return "编辑学校成功";
+    }
 }

+ 86 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/PayCallbackController.java

@@ -0,0 +1,86 @@
+package com.zbkj.front.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.zbkj.common.annotation.CustomResponseAnnotation;
+import com.zbkj.service.service.PayCallbackService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+/**
+ * 支付回调
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Slf4j
+@RestController
+@RequestMapping("api/publicly/payment/callback")
+@Api(tags = "支付回调控制器")
+@CustomResponseAnnotation
+public class PayCallbackController {
+
+    @Autowired
+    private PayCallbackService callbackService;
+
+    @ApiOperation(value = "微信支付回调")
+    @RequestMapping(value = "/wechat", method = RequestMethod.POST)
+    public String weChat(@RequestBody String  request) {
+        System.out.println("微信支付回调 request ===> " + request);
+        String response = callbackService.wechatPayCallback(request);
+        System.out.println("微信支付回调 response ===> " + response);
+        return response;
+    }
+    @ApiOperation(value = "快递微信支付回调")
+    @RequestMapping(value = "/exp/wechat", method = RequestMethod.POST)
+    public String expWeChat(@RequestBody String  request) {
+        System.out.println("微信快递支付回调 request ===> " + request);
+        String response = callbackService.wechatExpPayCallback(request);
+        System.out.println("微信快递支付回调 response ===> " + response);
+        return response;
+    }
+
+    @ApiOperation(value = "支付宝支付回调 ")
+    @RequestMapping(value = "/alipay", method = RequestMethod.POST)
+    public String aliPay(HttpServletRequest request){
+        //支付宝支付回调
+        System.out.println("支付宝支付回调 request ===> " + JSON.toJSONString(request.getParameterMap()));
+        return callbackService.aliPayCallback(request);
+    }
+    @ApiOperation(value = "二手交易微信支付回调")
+    @RequestMapping(value = "/secondhand/wechat", method = RequestMethod.POST)
+    public String secondHandWeChat(@RequestBody String  request) {
+        System.out.println("微信二手交易支付回调 request ===> " + request);
+        String response = callbackService.wechatSecondhandPayCallback(request);
+        System.out.println("微信二手交易支付回调 response ===> " + response);
+        return response;
+    }
+    /**
+     * 微信退款回调
+     */
+    @ApiOperation(value = "微信退款回调")
+    @RequestMapping(value = "/wechat/refund", method = RequestMethod.POST)
+    public String weChatRefund(@RequestBody String request) {
+        System.out.println("微信退款回调 request ===> " + request);
+        String response = callbackService.weChatRefund(request);
+        System.out.println("微信退款回调 response ===> " + response);
+        return response;
+    }
+}
+
+
+

+ 120 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/SecondHandController.java

@@ -0,0 +1,120 @@
+package com.zbkj.front.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import com.zbkj.common.constants.Constants;
+import com.zbkj.common.constants.GroupConfigConstants;
+import com.zbkj.common.model.system.GroupConfig;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.*;
+import com.zbkj.common.response.*;
+import com.zbkj.common.response.secondhand.SecondHandProdTakeTheirResponse;
+import com.zbkj.common.result.CommonResult;
+import com.zbkj.common.vo.PcHomeBannerVo;
+import com.zbkj.common.vo.PcHomeNavigationVo;
+import com.zbkj.front.service.SecondHandFrontService;
+import com.zbkj.service.service.GroupConfigService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * 二手交易控制器
+ *
+ * @author Hzw
+ * @version 1.0.0
+ * @Date 2023/12/9
+ */
+@Slf4j
+@RestController
+@RequestMapping("api/front/secondHand")
+@Api(tags = "二手交易控制器")
+public class SecondHandController {
+    @Autowired
+    private SecondHandFrontService secondHandFrontService;
+    @ApiOperation(value = "首页数据")
+    @RequestMapping(value = "/info", method = RequestMethod.GET)
+    public CommonResult<IndexInfoResponse> getIndexInfo() {
+        return CommonResult.success(secondHandFrontService.getIndexInfo());
+    }
+
+    @ApiOperation(value = "商品发布内容列表")
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public CommonPage<SecondHandFrontPageResponse> findDiscoverNoteList(@ModelAttribute @Validated SecondHandFrontSearchRequest request) {
+        return CommonPage.restPage(secondHandFrontService.findDiscoverNoteList(request));
+    }
+    @ApiOperation(value = "创建发布内容")
+    @RequestMapping(value = "/add", method = RequestMethod.POST)
+    public CommonResult<Object> createNote(@RequestBody @Validated SecondHandSaveRequest request) {
+        secondHandFrontService.createNote(request);
+        return CommonResult.success();
+    }
+    @ApiOperation(value = "编辑发布内容")
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public CommonResult<Object> updateNote(@RequestBody @Validated SecondHandSaveRequest request) {
+        secondHandFrontService.updateNote(request);
+        return CommonResult.success();
+    }
+    @ApiOperation(value = "我的发布内容列表")
+    @RequestMapping(value = "/my/list", method = RequestMethod.GET)
+    public CommonPage<SecondHandFrontPageResponse> findMyNoteList(PageParamRequest request) {
+        return CommonPage.restPage(secondHandFrontService.findMyNoteList(request));
+    }
+    @ApiOperation(value = "发布内容删除")
+    @RequestMapping(value = "/delete/{secondHandId}", method = RequestMethod.POST)
+    public CommonResult<Object> deleteNote(@PathVariable("secondHandId") Integer secondHandId) {
+        secondHandFrontService.deleteNote(secondHandId);
+        return CommonResult.success();
+    }
+    @ApiOperation(value = "发布内容推荐列表")
+    @RequestMapping(value = "/recommend/list", method = RequestMethod.GET)
+    public CommonPage<SecondHandFrontPageResponse> findRecommendList(@ModelAttribute @Validated SecondHandFrontSearchRequest request) {
+        return CommonPage.restPage(secondHandFrontService.findRecommendList(request));
+    }
+    @ApiOperation(value = "发布内容详情")
+    @RequestMapping(value = "/detail/{secondHandId}", method = RequestMethod.GET)
+    public SecondHandFrontDetailResponse getUserNoteDetail(@PathVariable("secondHandId") Integer secondHandId) {
+        return secondHandFrontService.getUserNoteDetail(secondHandId);
+    }
+    @ApiOperation(value = "商品列表")
+    @RequestMapping(value = "/prod/list", method = RequestMethod.GET)
+    public CommonPage<SecondHandFrontPageResponse> findProdList(@ModelAttribute @Validated SecondHandFrontSearchRequest request) {
+        return CommonPage.restPage(secondHandFrontService.findProdList(request));
+    }
+    @ApiOperation(value = "关注/取关")
+    @RequestMapping(value = "/concerned/{secondHandProdId}", method = RequestMethod.POST)
+    public CommonResult<Object> concernedProd(@PathVariable("secondHandProdId") Integer secondHandProdId) {
+        secondHandFrontService.concernedProd(secondHandProdId);
+        return CommonResult.success();
+    }
+    @ApiOperation(value = "关注列表")
+    @RequestMapping(value = "/follow/list", method = RequestMethod.GET)
+    public CommonPage<SecondHandFrontFollowResponse> findFollowNoteList(@ModelAttribute @Validated PageParamRequest request) {
+        return CommonPage.restPage(secondHandFrontService.findFollowNoteList(request));
+    }
+    @ApiOperation(value = "点赞/取消")
+    @RequestMapping(value = "/like/{secondHandProdId}", method = RequestMethod.POST)
+    public CommonResult<Object> likeNote(@PathVariable("secondHandProdId") Integer secondHandProdId) {
+        secondHandFrontService.likeNote(secondHandProdId);
+        return CommonResult.success();
+    }
+    @ApiOperation(value = "我的点赞列表")
+    @RequestMapping(value = "/my/like/list", method = RequestMethod.GET)
+    public CommonPage<SecondHandFrontPageResponse> findMyLikeNoteList(PageParamRequest request) {
+        return CommonPage.restPage(secondHandFrontService.findMyLikeNoteList(request));
+    }
+    @ApiOperation(value = "获取用户自提")
+    @RequestMapping(value = "/get/take/their/{id}", method = RequestMethod.GET)
+    public CommonResult<SecondHandProdTakeTheirResponse> getTakeTheir(@PathVariable(value = "id") Integer id) {
+        return CommonResult.success(secondHandFrontService.getTakeTheir(id));
+    }
+}

+ 149 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/SecondHandOrderController.java

@@ -0,0 +1,149 @@
+package com.zbkj.front.controller;
+
+import com.zbkj.common.annotation.LogControllerAnnotation;
+import com.zbkj.common.enums.MethodType;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.*;
+import com.zbkj.common.request.secondhand.CreateSecondHandOrderRequest;
+import com.zbkj.common.request.secondhand.PreSecondHandOrderRequest;
+import com.zbkj.common.request.secondhand.SecondHandOrderSendRequest;
+import com.zbkj.common.response.*;
+import com.zbkj.common.response.secondhand.*;
+import com.zbkj.common.result.CommonResult;
+import com.zbkj.common.vo.LogisticsResultVo;
+import com.zbkj.front.service.FrontOrderService;
+import com.zbkj.front.service.SecondHandFrontOrderService;
+import com.zbkj.front.service.SecondHandFrontService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * H5端订单操作
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Slf4j
+@RestController
+@RequestMapping("api/front/secondHand/order")
+@Api(tags = "二手交易订单")
+public class SecondHandOrderController {
+
+    @Autowired
+    private SecondHandFrontOrderService orderService;
+
+    @ApiOperation(value = "预下单")
+    @RequestMapping(value = "/pre/order", method = RequestMethod.POST)
+    public CommonResult<SecondHandOrderNoResponse> preOrder(@RequestBody @Validated PreSecondHandOrderRequest request) {
+        return CommonResult.success(orderService.preOrder(request));
+    }
+
+    @ApiOperation(value = "加载预下单")
+    @RequestMapping(value = "load/pre/{preOrderNo}", method = RequestMethod.GET)
+    public CommonResult<PreOrderSellerResponse> loadPreOrder(@PathVariable String preOrderNo) {
+        return CommonResult.success(orderService.loadPreOrder(preOrderNo));
+    }
+
+    @ApiOperation(value = "计算订单价格")
+    @RequestMapping(value = "/computed/price", method = RequestMethod.POST)
+    public CommonResult<ComputedOrderPriceResponse> computedPrice(@Validated @RequestBody OrderComputedPriceRequest request) {
+        return CommonResult.success(orderService.computedOrderPrice(request));
+    }
+
+    @ApiOperation(value = "创建订单")
+    @RequestMapping(value = "/create", method = RequestMethod.POST)
+    public CommonResult<SecondHandOrderNoResponse> createOrder(@Validated @RequestBody CreateSecondHandOrderRequest orderRequest) {
+        return CommonResult.success(orderService.createOrder(orderRequest));
+    }
+
+    @ApiOperation(value = "订单列表")
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public CommonResult<CommonPage<SecondOrderFrontDataResponse>> orderList(@ModelAttribute @Validated OrderFrontListRequest request) {
+        return CommonResult.success(CommonPage.restPage(orderService.list_v1_4(request)));
+    }
+
+    @ApiOperation(value = "订单详情")
+    @RequestMapping(value = "/detail/{orderNo}", method = RequestMethod.GET)
+    public CommonResult<SecondHandOrderFrontDetailResponse> orderDetail(@PathVariable String orderNo) {
+        return CommonResult.success(orderService.frontDetail(orderNo));
+    }
+
+    @ApiOperation(value = "订单取消")
+    @RequestMapping(value = "/cancel/{orderNo}", method = RequestMethod.POST)
+    public CommonResult<Boolean> cancel(@PathVariable(value = "orderNo") String orderNo) {
+        if (orderService.cancel(orderNo)) {
+            return CommonResult.success();
+        }
+        return CommonResult.failed();
+    }
+
+    @ApiOperation(value = "删除订单")
+    @RequestMapping(value = "/delete/{orderNo}", method = RequestMethod.POST)
+    public CommonResult<Boolean> delete(@PathVariable(value = "orderNo") String orderNo) {
+        if (orderService.delete(orderNo)) {
+            return CommonResult.success();
+        }
+        return CommonResult.failed();
+    }
+
+    @ApiOperation(value = "订单收货")
+    @RequestMapping(value = "/take/delivery/{orderNo}", method = RequestMethod.POST)
+    public CommonResult<String> take(@PathVariable(value = "orderNo") String orderNo) {
+        if (orderService.takeDelivery(orderNo)) {
+            return CommonResult.success("订单收货成功");
+        }
+        return CommonResult.failed("订单收货失败");
+    }
+
+    @ApiOperation(value = "获取订单发货单列表")
+    @RequestMapping(value = "/{orderNo}/invoice/list", method = RequestMethod.GET)
+    public CommonResult<OrderInvoiceFrontResponse> getInvoiceList(@PathVariable(value = "orderNo") String orderNo) {
+        return CommonResult.success(orderService.getInvoiceList(orderNo));
+    }
+
+    @ApiOperation(value = "物流信息查询")
+    @RequestMapping(value = "/logistics/{invoiceId}", method = RequestMethod.GET)
+    public CommonResult<LogisticsResultVo> getLogisticsInfo(@PathVariable(value = "invoiceId") Integer invoiceId) {
+        return CommonResult.success(orderService.getLogisticsInfo(invoiceId));
+    }
+
+    @ApiOperation(value = "获取订单状态图")
+    @RequestMapping(value = "/status/image", method = RequestMethod.GET)
+    public CommonResult<List<HashMap<String, Object>>> getOrderStatusImage() {
+        return CommonResult.success(orderService.getOrderStatusImage());
+    }
+    @ApiOperation(value = "订单列表")
+    @RequestMapping(value = "/deliveTime", method = RequestMethod.GET)
+    public CommonResult<RiderDeliveTimeResponse> deliveTime() {
+        return CommonResult.success(orderService.deliveTime());
+    }
+    @LogControllerAnnotation(intoDB = true, methodType = MethodType.UPDATE, description = "订单发货")
+    @ApiOperation(value = "订单发货")
+    @RequestMapping(value = "/send", method = RequestMethod.POST)
+    public CommonResult<Boolean> send(@RequestBody @Validated SecondHandOrderSendRequest request) {
+        if (orderService.send(request)) {
+            return CommonResult.success();
+        }
+        return CommonResult.failed();
+    }
+
+    @ApiOperation(value = "根据id查询订单")
+    @RequestMapping(value = "/get/detail/{productId}", method = RequestMethod.GET)
+    public CommonResult<String> getOrderDetail(@PathVariable Integer productId) {
+        return CommonResult.success(orderService.frontDetailByProductId(productId));
+    }
+}

+ 54 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/SecondHandPayController.java

@@ -0,0 +1,54 @@
+package com.zbkj.front.controller;
+
+import com.zbkj.common.request.OrderPayRequest;
+import com.zbkj.common.request.WechatPaymentQueryRequest;
+import com.zbkj.common.response.OrderPayResultResponse;
+import com.zbkj.common.result.CommonResult;
+import com.zbkj.service.service.ExpressPayService;
+import com.zbkj.service.service.SecondHandPayService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 支付控制器
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Slf4j
+@RestController
+@RequestMapping("api/front/pay/secondHand")
+@Api(tags = "二手交易订单支付管理")
+public class SecondHandPayController {
+
+    @Autowired
+    private SecondHandPayService payService;
+
+    @ApiOperation(value = "订单支付")
+    @RequestMapping(value = "/payment", method = RequestMethod.POST)
+    public CommonResult<OrderPayResultResponse> payment(@RequestBody @Validated OrderPayRequest orderPayRequest) {
+        return CommonResult.success(payService.payment(orderPayRequest));
+    }
+
+    @ApiOperation(value = "查询订单微信支付结果")
+    @RequestMapping(value = "/query/wechat/pay/result/{orderNo}", method = RequestMethod.GET)
+    public CommonResult<Boolean> queryPayResult(@PathVariable(value = "orderNo") String orderNo) {
+        return CommonResult.success(payService.queryWechatPayResult(orderNo));
+    }
+
+    @ApiOperation(value = "查询微信支付结果")
+    @RequestMapping(value = "/query/wechat/payment/result", method = RequestMethod.GET)
+    public CommonResult<Boolean> queryWechatPaymentResult(@Validated WechatPaymentQueryRequest request) {
+        return CommonResult.success(payService.queryWechatPaymentResult(request));
+    }
+}

+ 95 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/SecondHandRefundOrderController.java

@@ -0,0 +1,95 @@
+package com.zbkj.front.controller;
+
+import com.zbkj.common.model.order.OrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.CommonSearchRequest;
+import com.zbkj.common.request.OrderAfterSalesSearchRequest;
+import com.zbkj.common.request.OrderRefundApplyRequest;
+import com.zbkj.common.request.OrderRefundReturningGoodsRequest;
+import com.zbkj.common.response.RefundOrderInfoResponse;
+import com.zbkj.common.response.RefundOrderResponse;
+import com.zbkj.common.result.CommonResult;
+import com.zbkj.front.service.FrontOrderService;
+import com.zbkj.front.service.SecondHandFrontOrderService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * H5端订单操作
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Slf4j
+@RestController
+@RequestMapping("api/front/refund/secondhand")
+@Api(tags = "二手交易售后订单控制器")
+public class SecondHandRefundOrderController {
+
+    @Autowired
+    private SecondHandFrontOrderService orderService;
+
+    @ApiOperation(value = "售后申请列表(可申请售后列表)")
+    @RequestMapping(value = "/after/sale/apply/list", method = RequestMethod.GET)
+    public CommonResult<CommonPage<SecondHandOrderDetail>> afterSaleApplyList(@ModelAttribute CommonSearchRequest request) {
+        return CommonResult.success(CommonPage.restPage(orderService.getAfterSaleApplyList(request)));
+    }
+
+    @ApiOperation(value = "订单退款申请")
+    @RequestMapping(value = "/apply", method = RequestMethod.POST)
+    public CommonResult<Boolean> refundApply(@RequestBody @Validated OrderRefundApplyRequest request) {
+        if(orderService.refundApply(request)) {
+            return CommonResult.success();
+        }
+        return CommonResult.failed();
+    }
+
+    @ApiOperation(value = "订单退款理由(平台提供)")
+    @RequestMapping(value = "/reason", method = RequestMethod.GET)
+    public CommonResult<List<String>> refundReason() {
+        return CommonResult.success(orderService.getRefundReason());
+    }
+
+    @ApiOperation(value = "退款订单详情")
+    @RequestMapping(value = "/detail/{refundOrderNo}", method = RequestMethod.GET)
+    public CommonResult<RefundOrderInfoResponse> refundOrderDetail(@PathVariable String refundOrderNo) {
+        return CommonResult.success(orderService.refundOrderDetail(refundOrderNo));
+    }
+
+    @ApiOperation(value = "退款订单列表")
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public CommonResult<CommonPage<RefundOrderResponse>> refundOrderList(@ModelAttribute @Validated OrderAfterSalesSearchRequest request) {
+        return CommonResult.success(CommonPage.restPage(orderService.getRefundOrderList(request)));
+    }
+
+    @ApiOperation(value = "退款单退回商品")
+    @RequestMapping(value = "/returning/goods", method = RequestMethod.POST)
+    public CommonResult<Boolean> returningGoods(@RequestBody @Validated OrderRefundReturningGoodsRequest request) {
+        if(orderService.returningGoods(request)) {
+            return CommonResult.success();
+        }
+        return CommonResult.failed();
+    }
+
+    @ApiOperation(value = "撤销退款单")
+    @RequestMapping(value = "/revoke/{refundOrderNo}", method = RequestMethod.POST)
+    public CommonResult<Boolean> revoke(@PathVariable String refundOrderNo) {
+        if(orderService.revoke(refundOrderNo)) {
+            return CommonResult.success();
+        }
+        return CommonResult.failed();
+    }
+}

+ 4 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/CommunityFrontService.java

@@ -182,6 +182,10 @@ public interface CommunityFrontService {
      * 编辑个性签名
      */
     void editMySignature(EditMySignatureRequest request);
+    /**
+     * 编辑学校
+     */
+    void editMySchool(EditMySchoolRequest request);
 
     /**
      * 获取社区笔记评论平台开关设置

+ 205 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/SecondHandFrontOrderService.java

@@ -0,0 +1,205 @@
+package com.zbkj.front.service;
+
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.model.admin.SystemAdmin;
+import com.zbkj.common.model.order.OrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import com.zbkj.common.model.user.UserAddress;
+import com.zbkj.common.request.*;
+import com.zbkj.common.request.secondhand.CreateSecondHandOrderRequest;
+import com.zbkj.common.request.secondhand.PreSecondHandOrderRequest;
+import com.zbkj.common.request.secondhand.SecondHandOrderSendRequest;
+import com.zbkj.common.response.*;
+import com.zbkj.common.response.secondhand.*;
+import com.zbkj.common.utils.SecurityUtil;
+import com.zbkj.common.vo.LogisticsResultVo;
+import com.zbkj.common.vo.PreOrderInfoVo;
+import com.zbkj.common.vo.secondhand.PreSecondHandOrderInfoVo;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * 移动端端订单操作
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+public interface SecondHandFrontOrderService {
+
+    /**
+     * 预下单V
+     * @param request 预下单请求参数
+     * @return PreOrderResponse
+     */
+    SecondHandOrderNoResponse preOrder(PreSecondHandOrderRequest request);
+
+
+    /**
+     * 加载预下单信息
+     * @param preOrderNo 预下单号
+     * @return 预下单信息
+     */
+    PreOrderSellerResponse loadPreOrder(String preOrderNo);
+
+    /**
+     * 计算订单价格
+     * @param request 计算订单价格请求对象
+     * @return ComputedOrderPriceResponse
+     */
+    ComputedOrderPriceResponse computedOrderPrice(OrderComputedPriceRequest request);
+
+    /**
+     * 创建订单
+     * @param orderRequest 创建订单请求参数
+     * @return OrderNoResponse 订单编号
+     */
+    SecondHandOrderNoResponse createOrder(CreateSecondHandOrderRequest orderRequest);
+
+    /**
+     * 移动端订单详情
+     * @param orderNo 订单编号
+     * @return OrderFrontDetailResponse
+     */
+    SecondHandOrderFrontDetailResponse frontDetail(String orderNo);
+
+    /**
+     * 移动端订单详情
+     * @param productId 订单编号
+     * @return OrderFrontDetailResponse
+     */
+    String frontDetailByProductId(Integer productId);
+
+    /**
+     * 取消订单
+     * @param orderNo 订单编号
+     */
+    Boolean cancel(String orderNo);
+
+    /**
+     * 订单收货
+     * @param orderNo 订单号
+     * @return Boolean
+     */
+    Boolean takeDelivery(String orderNo);
+
+    /**
+     * 删除订单
+     * @param orderNo 订单号
+     * @return Boolean
+     */
+    Boolean delete(String orderNo);
+
+    /**
+     * 售后申请列表(可申请售后列表)
+     * @param request 搜索参数
+     */
+    PageInfo<SecondHandOrderDetail> getAfterSaleApplyList(CommonSearchRequest request);
+
+    /**
+     * 查询退款理由
+     * @return 退款理由集合
+     */
+    //List<String> getRefundReason();
+
+    /**
+     * 订单退款申请
+     * @param request 申请参数
+     * @return Boolean
+     */
+    //Boolean refundApply(OrderRefundApplyRequest request);
+
+    /**
+     * 退款订单列表
+     * @param request 搜索参数
+     * @return PageInfo
+     */
+    PageInfo<RefundOrderResponse> getRefundOrderList(OrderAfterSalesSearchRequest request);
+
+    /**
+     * 退款订单详情
+     * @param refundOrderNo 退款订单号
+     * @return RefundOrderInfoResponse
+     */
+    RefundOrderInfoResponse refundOrderDetail(String refundOrderNo);
+
+    /**
+     * 订单物流详情
+     */
+    LogisticsResultVo getLogisticsInfo(Integer invoiceId);
+
+    /**
+     * 获取发货单列表
+     * @param orderNo 订单号
+     * @return 发货单列表
+     */
+    OrderInvoiceFrontResponse getInvoiceList(String orderNo);
+
+    /**
+     * 获取个人中心订单数量
+     */
+    OrderCenterNumResponse userCenterNum();
+
+    /**
+     * 获取订单状态图
+     */
+    List<HashMap<String, Object>> getOrderStatusImage();
+
+    /**
+     * 计算订单运费
+     */
+    void getFreightFee(PreSecondHandOrderInfoVo orderInfoVo, UserAddress userAddress, Boolean userIsPaidMember);
+
+
+    /**
+     * 退款单退回商品
+     */
+    Boolean returningGoods(OrderRefundReturningGoodsRequest request);
+
+    /**
+     * 撤销退款单
+     * @param refundOrderNo 退款单号
+     */
+    Boolean revoke(String refundOrderNo);
+
+    /**
+     * 订单列表(v1.4.0)
+     * @param request 搜索参数
+     * @return PageInfo
+     */
+    PageInfo<SecondOrderFrontDataResponse> list_v1_4(OrderFrontListRequest request);
+
+    /**
+     *配送时间
+     * @return
+     */
+    RiderDeliveTimeResponse deliveTime();
+
+    /**
+     * 订单法国
+     * @param request
+     * @return
+     */
+     Boolean send(SecondHandOrderSendRequest request);
+
+
+    /**
+     * 订单退款申请
+     * @param request 申请参数
+     * @return Boolean
+     */
+    Boolean refundApply(OrderRefundApplyRequest request);
+
+    /**
+     * 查询退款理由
+     * @return 退款理由集合
+     */
+    List<String> getRefundReason();
+
+}

+ 117 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/SecondHandFrontService.java

@@ -0,0 +1,117 @@
+package com.zbkj.front.service;
+
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.model.community.CommunityCategory;
+import com.zbkj.common.model.community.CommunityTopic;
+import com.zbkj.common.model.secondhand.SecondHandCategory;
+import com.zbkj.common.request.*;
+import com.zbkj.common.response.*;
+import com.zbkj.common.response.secondhand.SecondHandProdTakeTheirResponse;
+
+import java.util.List;
+
+/**
+ * @ClassName CommunityService
+ * @Description 社区服务
+ * @Author HZW
+ * @Date 2023/3/9 14:38
+ * @Version 1.0
+ */
+public interface SecondHandFrontService {
+    /**
+     * 首页信息
+     * @return IndexInfoResponse
+     */
+    IndexInfoResponse getIndexInfo();
+
+    /**
+     * 获取所有社区分类
+     */
+    List<SecondHandCategory> getAllCategory();
+
+    /**
+     * 社区笔记发现列表
+     * @param request 搜索参数
+     * @return PageInfo
+     */
+    PageInfo<SecondHandFrontPageResponse> findDiscoverNoteList(SecondHandFrontSearchRequest request);
+
+
+
+
+    /**
+     * 社区用户笔记详情
+     * @param noteId 文章ID
+     */
+    SecondHandFrontDetailResponse getUserNoteDetail(Integer noteId);
+
+
+
+    /**
+     * 创建社区笔记
+     */
+    void createNote(SecondHandSaveRequest request);
+
+    /**
+     * 编辑社区笔记
+     */
+    void updateNote(SecondHandSaveRequest request);
+
+    /**
+     * 删除
+     * @param noteId
+     */
+    void deleteNote(Integer noteId);
+
+
+
+
+    /**
+     * 社区之我的笔记列表
+     */
+    PageInfo<SecondHandFrontPageResponse> findMyNoteList(PageParamRequest request);
+
+    /**
+     * 社区笔记发现推荐列表
+     * @param request 分页参数
+     */
+    PageInfo<SecondHandFrontPageResponse> findRecommendList(SecondHandFrontSearchRequest request);
+
+    /**
+     * 社区笔记发现推荐列表
+     * @param request 分页参数
+     */
+    PageInfo<SecondHandFrontPageResponse> findProdList(SecondHandFrontSearchRequest request);
+    /**
+     * 社区关注/取关
+     * @param prodId 产品id
+     */
+    void concernedProd(Integer prodId);
+
+    /**
+     * 关注列表
+     * @param request
+     * @return
+     */
+    PageInfo<SecondHandFrontFollowResponse> findFollowNoteList(PageParamRequest request);
+
+    /**
+     * 社区笔记点赞/取消
+     * @param noteId 笔记ID
+     */
+    void likeNote(Integer noteId);
+
+    /**
+     * 我想要的
+     * @param request
+     * @return
+     */
+    PageInfo<SecondHandFrontPageResponse> findMyLikeNoteList(PageParamRequest request);
+
+    /**
+     * 自提数据
+     * @param id
+     * @return
+     */
+    SecondHandProdTakeTheirResponse getTakeTheir(Integer id);
+}

+ 16 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/impl/CommunityFrontServiceImpl.java

@@ -79,6 +79,7 @@ public class CommunityFrontServiceImpl implements CommunityFrontService {
         IndexInfoResponse indexInfoResponse = new IndexInfoResponse();
         indexInfoResponse.setBanner(getBanner());
         indexInfoResponse.setHeadline(getHeadLine());
+        indexInfoResponse.setSchool(userService.getInfo().getSchool());
         return indexInfoResponse;
     }
 
@@ -432,6 +433,7 @@ public class CommunityFrontServiceImpl implements CommunityFrontService {
         response.setNickname(user.getNickname());
         response.setAvatar(user.getAvatar());
         response.setSignature(user.getSignature());
+        response.setSchool(user.getSchool());
         if (user.getLevel() > 0) {
             String levelSwitch = systemConfigService.getValueByKey(UserLevelConstants.SYSTEM_USER_LEVEL_SWITCH);
             if (Constants.COMMON_SWITCH_OPEN.equals(levelSwitch)) {
@@ -738,6 +740,18 @@ public class CommunityFrontServiceImpl implements CommunityFrontService {
         }
     }
 
+    @Override
+    public void editMySchool(EditMySchoolRequest request) {
+        Integer userId = userService.getUserIdException();
+        User user = new User();
+        user.setId(userId);
+        user.setSchool(StrUtil.isBlank(request.getSchool()) ? "" : request.getSchool());
+        boolean update = userService.updateById(user);
+        if (!update) {
+            throw new CrmebException(CommonResultCode.ERROR.setMessage("编辑学校失败"));
+        }
+    }
+
     /**
      * 获取社区笔记评论平台开关设置
      */
@@ -763,6 +777,8 @@ public class CommunityFrontServiceImpl implements CommunityFrontService {
             response.setCreateTime(note.getCreateTime());
             response.setCategoryId(note.getCategoryId());
             response.setIcon(note.getIcon());
+            response.setReplyNum(note.getReplyNum());
+            response.setSchool(note.getSchool());
             if (ObjectUtil.isNotNull(userId) && userId > 0) {
                 response.setUserIsLike(communityNotesRelationService.isLikeByUid(note.getId(), userId));
             }

+ 1190 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/impl/SecondHandFrontOrderServiceImpl.java

@@ -0,0 +1,1190 @@
+package com.zbkj.front.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.config.CrmebConfig;
+import com.zbkj.common.constants.*;
+import com.zbkj.common.enums.GroupBuyRecordEnum;
+import com.zbkj.common.exception.CrmebException;
+import com.zbkj.common.model.cat.Cart;
+import com.zbkj.common.model.cdkey.CardSecret;
+import com.zbkj.common.model.coupon.Coupon;
+import com.zbkj.common.model.coupon.CouponProduct;
+import com.zbkj.common.model.coupon.CouponUser;
+import com.zbkj.common.model.express.ShippingTemplates;
+import com.zbkj.common.model.express.ShippingTemplatesFree;
+import com.zbkj.common.model.express.ShippingTemplatesRegion;
+import com.zbkj.common.model.groupbuy.GroupBuyActivitySku;
+import com.zbkj.common.model.groupbuy.GroupBuyRecord;
+import com.zbkj.common.model.groupbuy.GroupBuyUser;
+import com.zbkj.common.model.merchant.Merchant;
+import com.zbkj.common.model.merchant.MerchantMarket;
+import com.zbkj.common.model.order.*;
+import com.zbkj.common.model.product.Product;
+import com.zbkj.common.model.product.ProductAttrValue;
+import com.zbkj.common.model.product.ProductCategory;
+import com.zbkj.common.model.product.ProductReply;
+import com.zbkj.common.model.rider.RiderFeeConfig;
+import com.zbkj.common.model.seckill.SeckillProduct;
+import com.zbkj.common.model.secondhand.*;
+import com.zbkj.common.model.system.SystemForm;
+import com.zbkj.common.model.user.User;
+import com.zbkj.common.model.user.UserAddress;
+import com.zbkj.common.model.user.UserIntegralRecord;
+import com.zbkj.common.model.wechat.video.PayComponentProduct;
+import com.zbkj.common.model.wechat.video.PayComponentProductSku;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.*;
+import com.zbkj.common.request.secondhand.*;
+import com.zbkj.common.response.*;
+import com.zbkj.common.response.groupbuy.GroupBuyActivityRecordForFrontShareUse;
+import com.zbkj.common.response.secondhand.*;
+import com.zbkj.common.result.CommonResultCode;
+import com.zbkj.common.result.MerchantResultCode;
+import com.zbkj.common.result.OrderResultCode;
+import com.zbkj.common.utils.CrmebDateUtil;
+import com.zbkj.common.utils.CrmebUtil;
+import com.zbkj.common.utils.GeoUtils;
+import com.zbkj.common.utils.RedisUtil;
+import com.zbkj.common.vo.*;
+import com.zbkj.common.vo.secondhand.PreSecondHandOrderInfoDetailVo;
+import com.zbkj.common.vo.secondhand.PreSecondHandOrderInfoVo;
+import com.zbkj.common.vo.secondhand.PreSellerOrderVo;
+import com.zbkj.front.service.FrontOrderService;
+import com.zbkj.front.service.SeckillService;
+import com.zbkj.front.service.SecondHandFrontOrderService;
+import com.zbkj.service.service.*;
+import com.zbkj.service.service.groupbuy.GroupBuyActivitySkuService;
+import com.zbkj.service.service.groupbuy.GroupBuyRecordService;
+import com.zbkj.service.service.groupbuy.GroupBuyUserService;
+import com.zbkj.service.service.impl.SecondHandOrderDetailService;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * H5端订单操作
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Service
+public class SecondHandFrontOrderServiceImpl implements SecondHandFrontOrderService {
+
+    private final Logger logger = LoggerFactory.getLogger(SecondHandFrontOrderServiceImpl.class);
+
+    @Autowired
+    private UserService userService;
+    @Autowired
+    private SecondHandProdService prodService;
+
+    @Autowired
+    private SecondHandOrderService secondHandOrderService;
+    @Autowired
+    private UserAddressService userAddressService;
+
+    @Autowired
+    private RedisUtil redisUtil;
+    @Autowired
+    private ShippingTemplatesService shippingTemplatesService;
+    @Autowired
+    private ShippingTemplatesFreeService shippingTemplatesFreeService;
+    @Autowired
+    private ShippingTemplatesRegionService shippingTemplatesRegionService;
+
+    @Autowired
+    private TransactionTemplate transactionTemplate;
+
+    @Autowired
+    private SecondHandOrderDetailService orderDetailService;
+    @Autowired
+    private OrderStatusService orderStatusService;
+    @Autowired
+    private SystemAttachmentService systemAttachmentService;
+    @Autowired
+    private ProductReplyService productReplyService;
+    @Autowired
+    private SecondHandRefundOrderService refundOrderService;
+    @Autowired
+    private SecondHandRefundOrderInfoService refundOrderInfoService;
+    @Autowired
+    private PayComponentProductService payComponentProductService;
+    @Autowired
+    private PayComponentProductSkuService payComponentProductSkuService;
+    @Autowired
+    private SystemConfigService systemConfigService;
+    @Autowired
+    private SystemGroupDataService systemGroupDataService;
+
+    @Autowired
+    private RefundOrderStatusService refundOrderStatusService;
+    @Autowired
+    private CrmebConfig crmebConfig;
+    @Autowired
+    private RiderDeliveTimeService riderDeliveTimeService;
+
+    @Autowired
+    private OrderInvoiceService orderInvoiceService;
+    /**
+     * 预下单V1.7
+     * @param request 预下单请求参数
+     * @return PreOrderResponse
+     */
+    @Override
+    public SecondHandOrderNoResponse preOrder(PreSecondHandOrderRequest request) {
+        User user = userService.getInfo();
+        // 校验预下单商品信息
+        PreSecondHandOrderInfoVo preOrderInfoVo = validatePreOrderRequest(request, user);
+        List<PreSecondHandOrderInfoDetailVo> orderInfoList = new ArrayList<>();
+        for (PreSellerOrderVo merchantOrderVo : preOrderInfoVo.getSellerOrderVoList()) {
+            orderInfoList.addAll(merchantOrderVo.getOrderInfoList());
+            BigDecimal merTotalPrice = merchantOrderVo.getOrderInfoList().stream()
+                    .map(e -> e.getPrice().multiply(new BigDecimal(e.getPayNum())))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            merchantOrderVo.setProTotalFee(merTotalPrice);
+            merchantOrderVo.setProTotalNum(merchantOrderVo.getOrderInfoList().stream().mapToInt(PreSecondHandOrderInfoDetailVo::getPayNum).sum());
+        }
+        // 商品总计金额
+        BigDecimal totalPrice = orderInfoList.stream().map(e -> e.getPrice().multiply(new BigDecimal(e.getPayNum()))).reduce(BigDecimal.ZERO, BigDecimal::add);
+        preOrderInfoVo.setProTotalFee(totalPrice);
+        // 购买商品总数量
+        int orderProNum = orderInfoList.stream().mapToInt(PreSecondHandOrderInfoDetailVo::getPayNum).sum();
+        preOrderInfoVo.setOrderProNum(orderProNum);
+        // 获取默认地址
+        UserAddress userAddress = userAddressService.getDefaultByUid(user.getId());
+        // 运费计算
+        if (ObjectUtil.isNotNull(userAddress)) {
+            // 计算运费
+            getFreightFee(preOrderInfoVo, userAddress, user.getIsPaidMember());
+            preOrderInfoVo.setAddressId(userAddress.getId());
+        } else {
+            preOrderInfoVo.setFreightFee(BigDecimal.ZERO);
+            preOrderInfoVo.setAddressId(0);
+        }
+        // 实际支付金额
+        preOrderInfoVo.setPayFee(preOrderInfoVo.getProTotalFee().add(preOrderInfoVo.getFreightFee()));
+        preOrderInfoVo.setType(0);//基础订单
+        preOrderInfoVo.setSecondType(0);//基础订单
+        preOrderInfoVo.setUserIntegral(user.getIntegral());
+        preOrderInfoVo.setUserBalance(user.getNowMoney());
+        BigDecimal proPayFee = preOrderInfoVo.getProTotalFee();
+        preOrderInfoVo.setPayFee(proPayFee.add(preOrderInfoVo.getFreightFee()));
+        return createPreOrderResponse(user.getId(), preOrderInfoVo);
+    }
+    private SecondHandOrderNoResponse createPreOrderResponse(Integer userId,  PreSecondHandOrderInfoVo preOrderInfoVo) {
+        String key = userId + CrmebDateUtil.getNowTime().toString() + CrmebUtil.getUuid();
+        redisUtil.set(OrderConstants.PRE_ORDER_CACHE_PREFIX + key, JSONObject.toJSONString(preOrderInfoVo), OrderConstants.PRE_ORDER_CACHE_TIME, TimeUnit.MINUTES);
+        SecondHandOrderNoResponse response = new SecondHandOrderNoResponse();
+        response.setOrderNo(key);
+        return response;
+    }
+    /**
+     * 加载预下单信息
+     *
+     * @param preOrderNo 预下单号
+     * @return 预下单信息
+     */
+    @Override
+    public PreOrderSellerResponse loadPreOrder(String preOrderNo) {
+        Integer userId = userService.getUserIdException();
+        User user = userService.getById(userId);
+        // 通过缓存获取预下单对象
+        String key = OrderConstants.PRE_ORDER_CACHE_PREFIX + preOrderNo;
+        boolean exists = redisUtil.exists(key);
+        if (!exists) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "预下单订单不存在");
+        }
+        String orderVoString = redisUtil.get(key);
+        PreSecondHandOrderInfoVo orderInfoVo = JSONObject.parseObject(orderVoString, PreSecondHandOrderInfoVo.class);
+        PreOrderSellerResponse preOrderResponse = new PreOrderSellerResponse();
+        BeanUtils.copyProperties(orderInfoVo, preOrderResponse);
+        List<PreOrderSellerInfoResponse> infoResponseList = new ArrayList<>();
+        List<PreSellerOrderVo> merchantOrderVoList = orderInfoVo.getSellerOrderVoList();
+        for (PreSellerOrderVo merchantOrderVo : merchantOrderVoList) {
+            PreOrderSellerInfoResponse infoResponse = new PreOrderSellerInfoResponse();
+            BeanUtils.copyProperties(merchantOrderVo, infoResponse);
+            infoResponseList.add(infoResponse);
+        }
+        preOrderResponse.setMerchantInfoList(infoResponseList);
+        return preOrderResponse;
+    }
+
+    /**
+     * 计算订单价格
+     *
+     * @param request 计算订单价格请求对象
+     * @return ComputedOrderPriceResponse
+     */
+    @Override
+    public ComputedOrderPriceResponse computedOrderPrice(OrderComputedPriceRequest request) {
+        // 通过缓存获取预下单对象
+        String key = OrderConstants.PRE_ORDER_CACHE_PREFIX + request.getPreOrderNo();
+        boolean exists = redisUtil.exists(key);
+        if (!exists) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "预下单订单不存在");
+        }
+        List<OrderMerchantRequest> orderMerchantRequestList = request.getOrderMerchantRequestList();
+//        if (orderMerchantRequestList.stream().anyMatch(e -> e.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP))) {
+//            orderMerchantRequestList.forEach(m -> {
+//                if (m.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP)) {
+//                    Merchant merchant = merchantService.getByIdException(m.getMerId());
+//                    if (!merchant.getIsTakeTheir()) {
+//                        throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "请先联系商户管理员开启门店自提");
+//                    }
+//                }
+//            });
+//        }
+
+        String orderVoString = redisUtil.get(key).toString();
+        PreOrderInfoVo orderInfoVo = JSONObject.parseObject(orderVoString, PreOrderInfoVo.class);
+        User user = userService.getInfo();
+
+        return null;
+    }
+
+    /**
+     * 创建订单
+     *
+     * @param orderRequest 创建订单请求参数
+     * @return OrderNoResponse 订单编号
+     */
+    @Override
+    public SecondHandOrderNoResponse createOrder(CreateSecondHandOrderRequest orderRequest) {
+        User user = userService.getInfo();
+        // 通过缓存获取预下单对象
+        String key = OrderConstants.PRE_ORDER_CACHE_PREFIX + orderRequest.getPreOrderNo();
+        boolean exists = redisUtil.exists(key);
+        if (!exists) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "预下单订单不存在");
+        }
+        String orderVoString = redisUtil.get(key).toString();
+        UserAddress  userAddress=null;
+        PreSecondHandOrderInfoVo orderInfoVo = JSONObject.parseObject(orderVoString, PreSecondHandOrderInfoVo.class);
+        List<OrderSellerRequest> orderMerchantRequestList = orderRequest.getOrderMerchantRequestList();
+//            if (orderMerchantRequestList.stream().anyMatch(e -> (e.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_EXPRESS)))) {
+//                if (ObjectUtil.isNull(orderRequest.getAddressId())) {
+//                    throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "请选择收货地址");
+//                }
+//                  userAddress = userAddressService.getById(orderRequest.getAddressId());
+//                if (ObjectUtil.isNull(userAddress) || userAddress.getIsDel()) {
+//                    throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "收货地址有误");
+//                }
+//            }
+            if (ObjectUtil.isNull(orderRequest.getAddressId())) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "请选择收货地址");
+            }
+            userAddress = userAddressService.getById(orderRequest.getAddressId());
+            if (ObjectUtil.isNull(userAddress) || userAddress.getIsDel()) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "收货地址有误");
+            }
+            if (orderMerchantRequestList.stream().anyMatch(e -> e.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP))) {
+                orderMerchantRequestList.forEach(m -> {
+                    if (m.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP)) {
+                        UserAddress   sellerUserAddress = userAddressService.getById(orderInfoVo.getAddressId());
+                        if (ObjectUtil.isNull(sellerUserAddress)) {
+                            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, StrUtil.format("卖家没有店铺地址,请联系客服"));
+                        }
+                    }
+                });
+            }
+
+        orderInfoVo.getSellerOrderVoList().forEach(e -> {
+            orderMerchantRequestList.forEach(o -> {
+                if (o.getSellerId().equals(e.getSellerId())) {
+                    e.setShippingType(o.getShippingType());
+                }
+            });
+        });
+        // 计算订单各种价格
+        getFreightFee(orderInfoVo, userAddress, user.getIsPaidMember());
+        List<PreSellerOrderVo> merchantOrderVoList = orderInfoVo.getSellerOrderVoList();
+        // 平台订单
+        String orderNo = CrmebUtil.getOrderNo(OrderConstants.ORDER_PREFIX_PLATFORM);
+        List<SecondHandOrder> merchantOrderList = new ArrayList<>();
+        List<SecondHandOrderDetail> orderDetailList = new ArrayList<>();
+        for (PreSellerOrderVo merchantOrderVo : merchantOrderVoList) {
+            SecondHandOrder merchantOrder = new SecondHandOrder();
+            merchantOrder.setOrderNo(orderNo);
+            merchantOrder.setSellerId(orderInfoVo.getSellerId());
+            merchantOrder.setUid(user.getId());
+            merchantOrder.setPaid(false);
+            merchantOrder.setTotalNum(merchantOrderVo.getProTotalNum());
+            merchantOrder.setProTotalPrice(merchantOrderVo.getProTotalFee());
+            merchantOrder.setTotalPostage(merchantOrderVo.getFreightFee());
+            merchantOrder.setTotalPrice(merchantOrder.getProTotalPrice().add(merchantOrder.getTotalPostage()));
+            merchantOrder.setPayPrice(merchantOrder.getTotalPrice());
+            merchantOrder.setType(0);
+            merchantOrder.setPayPostage(merchantOrder.getTotalPostage());
+            merchantOrder.setCancelStatus(OrderConstants.ORDER_CANCEL_STATUS_NORMAL);
+            merchantOrder.setLevel(OrderConstants.ORDER_LEVEL_PLATFORM);
+            if(ObjectUtil.isNotNull(userAddress)) {
+                merchantOrder.setRealName(userAddress.getRealName());
+                merchantOrder.setUserPhone(userAddress.getPhone());
+                merchantOrder.setCreateTime(DateUtil.date());
+                if (ObjectUtil.isNotNull(userAddress)) {
+                    String userAddressStr = userAddress.getProvince() + userAddress.getCity() + userAddress.getDistrict() + userAddress.getStreet() + userAddress.getDetail();
+                    merchantOrder.setUserAddress(userAddressStr);
+                }
+            }else{
+                merchantOrder.setRealName(StringUtils.isNotEmpty(user.getRealName())?user.getRealName():user.getNickname());
+                merchantOrder.setUserPhone(user.getPhone());
+            }
+            for (OrderSellerRequest om : orderMerchantRequestList) {
+                if (om.getSellerId().equals(merchantOrderVo.getSellerId())) {
+                    if (StrUtil.isNotBlank(om.getRemark())) {
+                        merchantOrder.setUserRemark(om.getRemark());
+                    }
+                    merchantOrder.setShippingType(om.getShippingType());
+                    break;
+                }
+            }
+            List<PreSecondHandOrderInfoDetailVo> detailVoList = merchantOrderVo.getOrderInfoList();
+            merchantOrderList.add(merchantOrder);
+            for (PreSecondHandOrderInfoDetailVo detailVo : detailVoList) {
+                SecondHandOrderDetail orderDetail = new SecondHandOrderDetail();
+                orderDetail.setOrderNo(orderNo);
+                orderDetail.setSellerId(merchantOrder.getSellerId());
+                orderDetail.setUid(user.getId());
+                orderDetail.setProductId(detailVo.getProductId());
+                orderDetail.setProductName(detailVo.getProductName());
+                orderDetail.setImage(detailVo.getImage());
+                orderDetail.setPrice(detailVo.getPrice());
+                orderDetail.setPayNum(detailVo.getPayNum());
+                orderDetail.setWeight(detailVo.getWeight());
+                orderDetail.setVolume(detailVo.getVolume());
+                orderDetail.setProductType(detailVo.getProductType());
+                orderDetail.setFreightFee(detailVo.getFreightFee());
+                orderDetail.setPayPrice(BigDecimal.ZERO);
+                BigDecimal
+                    detailPayPrice = orderDetail.getPrice().multiply(new BigDecimal(orderDetail.getPayNum().toString())).add(orderDetail.getFreightFee());
+                if (detailPayPrice.compareTo(BigDecimal.ZERO) < 0) {
+                    throw new CrmebException("订单详情价格计算错误,详情价格不能小于0");
+                }
+                orderDetail.setPayPrice(detailPayPrice);
+                orderDetailList.add(orderDetail);
+            }
+        }
+
+
+        Boolean execute = transactionTemplate.execute(e -> {
+            Boolean result = false;
+            secondHandOrderService.saveBatch(merchantOrderList);
+            orderDetailService.saveBatch(orderDetailList);
+            // 生成订单日志
+            orderStatusService.createLog(orderNo, OrderStatusConstants.ORDER_STATUS_CREATE, OrderStatusConstants.ORDER_LOG_MESSAGE_CREATE);
+            return Boolean.TRUE;
+        });
+        if (!execute) {
+            throw new CrmebException("订单生成失败");
+        }
+
+        // 删除缓存订单
+        if (redisUtil.exists(key)) {
+            redisUtil.delete(key);
+        }
+        SecondHandOrder order=merchantOrderList.get(0);
+            // 加入自动未支付自动取消队列
+        redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AUTO_CANCEL_KEY, orderNo);
+            // 设置自动过期时间 2025-02-11
+        Integer orderCancelTimeMinute = crmebConfig.getOrderCancelTime();
+        DateTime expirationTime = DateUtil.offset(order.getCreateTime()==null?new Date():order.getCreateTime(), DateField.MINUTE, crmebConfig.getOrderCancelTime());
+        Long expireTime = (long) orderCancelTimeMinute * 60;
+        redisUtil.set(StrUtil.format(RedisConstants.ORDER_EXPIRE_TIME, order.getOrderNo()), expirationTime.toString(), expireTime);
+        SecondHandOrderNoResponse response = new SecondHandOrderNoResponse();
+        response.setOrderNo(orderNo);
+        response.setPayPrice(order.getPayPrice());
+        return response;
+    }
+
+
+
+
+    /**
+     * 退款单退回商品
+     */
+    @Override
+    public Boolean returningGoods(OrderRefundReturningGoodsRequest request) {
+        SecondHandRefundOrder refundOrder = refundOrderService.getByRefundOrderNo(request.getRefundOrderNo());
+        if (ObjectUtil.isNull(refundOrder)) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_NOT_EXIST);
+        }
+        if (refundOrder.getRefundStatus() != 4) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_STATUS_ABNORMAL);
+        }
+        if (refundOrder.getReturnGoodsType() == 1) {
+            if (StrUtil.isBlank(request.getExpressName())) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "请选择快递公司");
+            }
+            if (StrUtil.isBlank(request.getTrackingNumber())) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "请填写运单号");
+            }
+            refundOrder.setExpressName(request.getExpressName());
+            refundOrder.setTrackingNumber(request.getTrackingNumber());
+        }
+        refundOrder.setTelephone(request.getTelephone());
+        refundOrder.setRefundStatus(5);
+
+        return transactionTemplate.execute(e -> {
+            refundOrderService.updateById(refundOrder);
+            refundOrderStatusService.add(refundOrder.getRefundOrderNo(), RefundOrderConstants.REFUND_ORDER_LOG_RETURNING_GOODS, "售后单用户退回商品");
+            return Boolean.TRUE;
+        });
+    }
+
+    /**
+     * 撤销退款单
+     * @param refundOrderNo 退款单号
+     */
+    @Override
+    public Boolean revoke(String refundOrderNo) {
+        return refundOrderService.revoke(refundOrderNo);
+    }
+
+    /**
+     * 订单列表(v1.4.0)
+     * @param request 搜索参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondOrderFrontDataResponse> list_v1_4(OrderFrontListRequest request) {
+        Integer userId = userService.getUserIdException();
+        PageInfo<SecondHandOrder> pageInfo = secondHandOrderService.getUserOrderList_v1_4(userId, request);
+        List<SecondHandOrder> orderList = pageInfo.getList();
+        if (CollUtil.isEmpty(orderList)) {
+            return CommonPage.copyPageInfo(pageInfo, CollUtil.newArrayList());
+        }
+        //List<Integer> merIdList = orderList.stream().map(SecondHandOrder::getSellerId).filter(i -> i > 0).distinct().collect(Collectors.toList());
+        List<SecondOrderFrontDataResponse> responseList = CollUtil.newArrayList();
+        DateTime cancelTime;
+        for (SecondHandOrder order : orderList) {
+            SecondOrderFrontDataResponse infoResponse = new SecondOrderFrontDataResponse();
+            BeanUtils.copyProperties(order, infoResponse);
+            // 订单详情对象列表
+            List<SecondHandOrderDetail> orderDetailList = orderDetailService.getByOrderNo(order.getOrderNo());
+            List<SecondOrderInfoFrontDataResponse> infoResponseList = CollUtil.newArrayList();
+            orderDetailList.forEach(e -> {
+                SecondOrderInfoFrontDataResponse orderInfoResponse = new SecondOrderInfoFrontDataResponse();
+                BeanUtils.copyProperties(e, orderInfoResponse);
+                infoResponseList.add(orderInfoResponse);
+            });
+            infoResponse.setOrderInfoList(infoResponseList);
+            if (!order.getPaid()) {
+                cancelTime = DateUtil.offset(order.getCreateTime(), DateField.MINUTE, crmebConfig.getOrderCancelTime());
+                infoResponse.setCancelTime(cancelTime.getTime());
+                // 返回订单过期时间 2025-02-12
+                if (redisUtil.exists(StrUtil.format(RedisConstants.ORDER_EXPIRE_TIME, order.getOrderNo()))) {
+                    String expireTime = redisUtil.get(StrUtil.format(RedisConstants.ORDER_EXPIRE_TIME, order.getOrderNo()));
+                    infoResponse.setExpirationTime(expireTime);
+                }
+            }
+            responseList.add(infoResponse);
+        }
+        return CommonPage.copyPageInfo(pageInfo, responseList);
+    }
+
+    @Override
+    public RiderDeliveTimeResponse deliveTime() {
+        return riderDeliveTimeService.chose();
+    }
+
+    @Override
+    public Boolean send(SecondHandOrderSendRequest request) {
+        return secondHandOrderService.send(request);
+    }
+
+    @Override
+    public Boolean refundApply(OrderRefundApplyRequest request) {
+        Integer uid = userService.getUserIdException();
+        SecondHandOrder order = secondHandOrderService.getByOrderNo(request.getOrderNo());
+        if (!order.getUid().equals(uid) || order.getIsUserDel()) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST);
+        }
+        if (order.getCancelStatus() > OrderConstants.ORDER_CANCEL_STATUS_NORMAL) {
+            throw new CrmebException(OrderResultCode.ORDER_CANCEL);
+        }
+        if (!order.getPaid()) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_PAID);
+        }
+        if (order.getRefundStatus().equals(OrderConstants.ORDER_REFUND_STATUS_ALL)) {
+            throw new CrmebException(OrderResultCode.ORDER_REFUND_ED);
+        }
+        if (order.getStatus().equals(OrderConstants.ORDER_STATUS_COMPLETE)) {
+            throw new CrmebException(OrderResultCode.ORDER_STATUS_ABNORMAL, "已完成订单无法申请退款");
+        }
+        SecondHandOrderDetail orderDetail = orderDetailService.getById(request.getOrderDetailId());
+        if (ObjectUtil.isNull(orderDetail) || !orderDetail.getOrderNo().equals(order.getOrderNo())) {
+            throw new CrmebException(OrderResultCode.ORDER_DETAIL_NOT_EXIST);
+        }
+
+        SecondHandRefundOrder refundOrder = new SecondHandRefundOrder();
+        refundOrder.setRefundOrderNo(CrmebUtil.getOrderNo(OrderConstants.ORDER_PREFIX_REFUND));
+        refundOrder.setOrderNo(order.getOrderNo());
+        refundOrder.setMerId(order.getSellerId());
+        refundOrder.setUid(order.getUid());
+        refundOrder.setRealName(order.getRealName());
+        refundOrder.setUserPhone(order.getUserPhone());
+        refundOrder.setUserAddress(order.getUserAddress());
+        refundOrder.setRefundPrice(order.getPayPrice());
+        refundOrder.setTotalNum(request.getNum());
+        refundOrder.setRefundReasonWap(request.getText());
+        refundOrder.setRefundReasonWapImg(systemAttachmentService.clearPrefix(request.getReasonImage()));
+        refundOrder.setRefundReasonWapExplain(request.getExplain());
+        refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_APPLY);
+        refundOrder.setAfterSalesType(request.getAfterSalesType());
+        refundOrder.setReturnGoodsType(request.getReturnGoodsType());
+
+        SecondHandRefundOrderInfo refundOrderInfo = new SecondHandRefundOrderInfo();
+        refundOrderInfo.setRefundOrderNo(refundOrder.getRefundOrderNo());
+        refundOrderInfo.setMerId(orderDetail.getSellerId());
+        refundOrderInfo.setOrderDetailId(orderDetail.getId());
+        refundOrderInfo.setProductId(orderDetail.getProductId());
+        refundOrderInfo.setProductName(orderDetail.getProductName());
+        refundOrderInfo.setImage(orderDetail.getImage());
+        refundOrderInfo.setPrice(orderDetail.getPrice());
+        refundOrderInfo.setPayNum(orderDetail.getPayNum());
+        refundOrderInfo.setProductType(orderDetail.getProductType());
+        refundOrderInfo.setPayPrice(orderDetail.getPayPrice());
+        refundOrderInfo.setApplyRefundNum(request.getNum());
+        // 临时性计算退款金额、积分
+        if (request.getNum().equals(orderDetail.getPayNum())) {
+            refundOrderInfo.setRefundPrice(orderDetail.getPayPrice());
+            refundOrderInfo.setRefundFreightFee(orderDetail.getFreightFee());
+        }
+
+        refundOrder.setRefundPrice(refundOrderInfo.getRefundPrice());
+        refundOrder.setRefundFreightFee(refundOrderInfo.getRefundFreightFee());
+        order.setRefundStatus(OrderConstants.ORDER_REFUND_STATUS_APPLY);
+        orderDetail.setApplyRefundNum(orderDetail.getApplyRefundNum() + request.getNum());
+
+        String outRefundNo = CrmebUtil.getOrderNo(OrderConstants.ORDER_PREFIX_REFUND);
+        refundOrder.setOutRefundNo(outRefundNo);
+        Boolean execute = transactionTemplate.execute(e -> {
+            secondHandOrderService.updateById(order);
+            orderDetailService.updateById(orderDetail);
+            refundOrderService.save(refundOrder);
+            refundOrderInfoService.save(refundOrderInfo);
+            refundOrderStatusService.add(refundOrder.getRefundOrderNo(), RefundOrderConstants.REFUND_ORDER_LOG_APPLY, "用户发起退款单申请");
+            return Boolean.TRUE;
+        });
+        if (Boolean.FALSE.equals(execute)) throw new CrmebException("申请退款失败");
+        return execute;
+    }
+
+    @Override
+    public List<String> getRefundReason() {
+        String reasonString = systemConfigService.getValueByKey(SysConfigConstants.CONFIG_KEY_STOR_REASON);
+        reasonString = CrmebUtil.UnicodeToCN(reasonString);
+        reasonString = reasonString.replace("rn", "n");
+        return Arrays.asList(reasonString.split("\\n"));
+    }
+
+
+    /**
+     * 移动端订单详情
+     *
+     * @param orderNo 订单编号
+     * @return OrderFrontDetailResponse
+     */
+    @Override
+    public SecondHandOrderFrontDetailResponse frontDetail(String orderNo) {
+        User currentUser = userService.getInfo();
+        SecondHandOrder order = secondHandOrderService.getByOrderNo(orderNo);
+//        if (order.getIsUserDel() || order.getIsSellerDel() || !order.getUid().equals(currentUser.getId())) {
+//            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST);
+//        }
+        if (order.getIsUserDel() || order.getIsSellerDel()) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST);
+        }
+        SecondHandOrderFrontDetailResponse response = new SecondHandOrderFrontDetailResponse();
+        BeanUtils.copyProperties(order, response);
+        List<SecondHandOrderDetail> orderDetailList = orderDetailService.getByOrderNo(orderNo);
+        Map<Integer, List<SecondHandOrderDetail>> orderDetailMap = orderDetailList.stream().collect(Collectors.groupingBy(SecondHandOrderDetail::getSellerId));
+        List<SellerOrderFrontDetailResponse> merDetailResponseList = CollUtil.newArrayList();
+        SellerOrderFrontDetailResponse merDetailResponse = new SellerOrderFrontDetailResponse();
+            BeanUtils.copyProperties(order, merDetailResponse);
+            List<SecondHandOrderDetail> detailList = orderDetailMap.get(order.getSellerId());
+            List<SecondOrderInfoFrontDataResponse> dataResponseList = detailList.stream().map(d -> {
+                SecondOrderInfoFrontDataResponse dataResponse = new SecondOrderInfoFrontDataResponse();
+                BeanUtils.copyProperties(d, dataResponse);
+                SecondHandProd prod= prodService.getById(d.getProductId());
+                merDetailResponse.setMerLatitude(prod.getLatitude());
+                merDetailResponse.setMerLongitude(prod.getLongitude());
+                UserAddress userAddress=userAddressService.getById(prod.getAddressId());
+                merDetailResponse.setMerProvince(userAddress.getProvince());
+                merDetailResponse.setMerCity(userAddress.getCity());
+                merDetailResponse.setMerDistrict(userAddress.getDistrict());
+                merDetailResponse.setMerAddressDetail(userAddress.getDetail());
+                merDetailResponse.setMerName(userAddress.getRealName());
+                merDetailResponse.setMerPhone(userAddress.getPhone());
+                return dataResponse;
+            }).collect(Collectors.toList());
+            merDetailResponse.setOrderInfoList(dataResponseList);
+            merDetailResponseList.add(merDetailResponse);
+        response.setMerchantOrderList(merDetailResponseList);
+        if (!order.getPaid()) {
+            DateTime cancelTime = DateUtil.offset(order.getCreateTime(), DateField.MINUTE, crmebConfig.getOrderCancelTime());
+            response.setCancelTime(cancelTime.getTime());
+            // 返回订单过期时间 2025-02-12
+            if (redisUtil.exists(StrUtil.format(RedisConstants.ORDER_EXPIRE_TIME, order.getOrderNo()))) {
+                String expireTime = redisUtil.get(StrUtil.format(RedisConstants.ORDER_EXPIRE_TIME, order.getOrderNo()));
+                response.setExpirationTime(expireTime);
+            }
+        }
+        List<OrderInvoiceResponse> orderInvoiceList=orderInvoiceService.findByOrderNo(orderNo);
+        if(CollUtil.isNotEmpty(orderInvoiceList)) {
+            response.setOrderInvoiceList(orderInvoiceList);
+        }
+        return response;
+    }
+
+    @Override
+    public String frontDetailByProductId(Integer productId) {
+        Integer userId=userService.getUserId();
+        List<SecondHandOrderDetail> orderDetailList=  orderDetailService.findList(userId,productId);
+        if(CollUtil.isNotEmpty(orderDetailList)){
+            return orderDetailList.get(0).getOrderNo();
+
+        }
+        return "";
+    }
+
+
+    /**
+     * 取消订单
+     *
+     * @param orderNo 订单编号
+     */
+    @Override
+    public Boolean cancel(String orderNo) {
+        Integer uid = userService.getUserIdException();
+        SecondHandOrder order = secondHandOrderService.getByOrderNo(orderNo);
+        if (!order.getUid().equals(uid)) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST);
+        }
+        if (order.getPaid()) {
+            throw new CrmebException(OrderResultCode.ORDER_PAID);
+        }
+        if (order.getStatus().equals(OrderConstants.ORDER_STATUS_CANCEL)) {
+            throw new CrmebException(OrderResultCode.ORDER_CANCEL);
+        }
+        Boolean cancel = secondHandOrderService.cancel(orderNo, true);
+        if (cancel) {
+            redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AFTER_CANCEL_BY_USER, order.getOrderNo());
+        }
+        return cancel;
+    }
+
+    /**
+     * 订单收货
+     *
+     * @param orderNo 订单号
+     * @return Boolean
+     */
+    @Override
+    public Boolean takeDelivery(String orderNo) {
+        Integer userId = userService.getUserIdException();
+        SecondHandOrder order = secondHandOrderService.getByOrderNo(orderNo);
+        if (!order.getUid().equals(userId)) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST);
+        }
+        if (!order.getCancelStatus().equals(OrderConstants.ORDER_CANCEL_STATUS_NORMAL)) {
+            throw new CrmebException(OrderResultCode.ORDER_CANCEL);
+        }
+        if (order.getRefundStatus().equals(OrderConstants.ORDER_REFUND_STATUS_ALL)) {
+            throw new CrmebException(OrderResultCode.ORDER_STATUS_ABNORMAL, "已退款订单无法收货");
+        }
+        if(order.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP)){
+            if (!order.getStatus().equals(OrderConstants.ORDER_STATUS_WAIT_SHIPPING)) {
+                throw new CrmebException(OrderResultCode.ORDER_STATUS_ABNORMAL);
+            }
+        }else {
+            if (!order.getStatus().equals(OrderConstants.ORDER_STATUS_WAIT_RECEIPT)) {
+                throw new CrmebException(OrderResultCode.ORDER_STATUS_ABNORMAL);
+            }
+        }
+        if (order.getRefundStatus().equals(OrderConstants.ORDER_REFUND_STATUS_APPLY)) {
+            throw new CrmebException(OrderResultCode.ORDER_STATUS_ABNORMAL, "请先撤销售后,再进行收货操作");
+        }
+        Boolean execute = transactionTemplate.execute(e -> {
+            secondHandOrderService.takeDelivery(orderNo);
+            orderDetailService.takeDelivery(orderNo);
+            prodService.updateStatusByOrderNo(orderNo,1);
+            //orderStatusService.createLog(order.getOrderNo(), OrderStatusConstants.ORDER_STATUS_USER_TAKE_DELIVERY, OrderStatusConstants.ORDER_LOG_USER_RECEIPT);
+            return Boolean.TRUE;
+        });
+        if (execute) {
+            //后续操作放入redis
+            redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AFTER_TAKE_BY_USER, orderNo);
+        }
+        return execute;
+    }
+
+    /**
+     * 删除订单
+     *
+     * @param orderNo 订单号
+     * @return Boolean
+     */
+    @Override
+    public Boolean delete(String orderNo) {
+        Integer userId = userService.getUserIdException();
+        SecondHandOrder order = secondHandOrderService.getByOrderNo(orderNo);
+        if (!order.getUid().equals(userId)) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST);
+        }
+        if (!(order.getStatus().equals(OrderConstants.ORDER_STATUS_COMPLETE) || order.getStatus().equals(OrderConstants.ORDER_STATUS_CANCEL))) {
+            throw new CrmebException(OrderResultCode.ORDER_STATUS_ABNORMAL, "未完成订单无法删除");
+        }
+        if (order.getIsUserDel()) {
+            throw new CrmebException(OrderResultCode.ORDER_DELETE);
+        }
+        order.setIsUserDel(true);
+        return transactionTemplate.execute(e -> {
+            secondHandOrderService.updateById(order);
+            orderStatusService.createLog(orderNo, OrderStatusConstants.ORDER_STATUS_USER_DELETE, OrderStatusConstants.ORDER_LOG_USER_DELETE);
+            return Boolean.TRUE;
+        });
+    }
+
+    /**
+     * 售后申请列表(可申请售后列表)
+     *
+     * @param request 搜索参数
+     */
+    @Override
+    public PageInfo<SecondHandOrderDetail> getAfterSaleApplyList(CommonSearchRequest request) {
+        Integer uid = userService.getUserIdException();
+        PageInfo<SecondHandOrderDetail> pageInfo = orderDetailService.findAfterSaleApplyList(uid, request);
+        List<SecondHandOrderDetail> orderDetailList = pageInfo.getList();
+        if (CollUtil.isEmpty(orderDetailList)) {
+            return pageInfo;
+        }
+        //List<Integer> merIdList = orderDetailList.stream().map(SecondHandOrderDetail::getSellerId).distinct().collect(Collectors.toList());
+       // Map<Integer, Merchant> merchantMap = merchantService.getMapByIdList(merIdList);
+//        orderDetailList.forEach(o -> {
+//            o.setSellerName(merchantMap.get(o.getSellerId()).getName());
+//        });
+        return pageInfo;
+    }
+
+
+    /**
+     * 退款订单列表
+     *
+     * @param request 搜索参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<RefundOrderResponse> getRefundOrderList(OrderAfterSalesSearchRequest request) {
+        return refundOrderService.getH5List(request);
+    }
+
+    /**
+     * 退款订单详情
+     *
+     * @param refundOrderNo 退款订单号
+     * @return RefundOrderInfoResponse
+     */
+    @Override
+    public RefundOrderInfoResponse refundOrderDetail(String refundOrderNo) {
+        return refundOrderService.getRefundOrderDetailByRefundOrderNo(refundOrderNo);
+    }
+
+    @Override
+    public LogisticsResultVo getLogisticsInfo(Integer invoiceId) {
+        return null;
+    }
+
+    @Override
+    public OrderInvoiceFrontResponse getInvoiceList(String orderNo) {
+        return null;
+    }
+
+//    /**
+//     * 订单物流详情
+//     */
+//    @Override
+//    public LogisticsResultVo getLogisticsInfo(Integer invoiceId) {
+//        return secondHandOrderService.getLogisticsInfo(invoiceId);
+//    }
+
+    /**
+     * 获取发货单列表
+     *
+     * @param orderNo 订单号
+     * @return 发货单列表
+     */
+//    @Override
+//    public OrderInvoiceFrontResponse getInvoiceList(String orderNo) {
+//        SecondHandOrder order = secondHandOrderService.getByOrderNo(orderNo);
+//        List<OrderInvoiceResponse> invoiceList = secondHandOrderService.getInvoiceList(orderNo);
+//        OrderInvoiceFrontResponse response = new OrderInvoiceFrontResponse();
+//        response.setInvoiceList(invoiceList);
+//        if (CollUtil.isEmpty(invoiceList)) {
+//            response.setNum(1);
+//            response.setDeliveryNum(0);
+//            return response;
+//        }
+//        response.setNum(order.getStatus().equals(OrderConstants.ORDER_STATUS_PART_SHIPPING) ? invoiceList.size() + 1 : invoiceList.size());
+//        response.setDeliveryNum(invoiceList.size());
+//        return response;
+//    }
+
+    /**
+     * 获取个人中心订单数量
+     */
+    @Override
+    public OrderCenterNumResponse userCenterNum() {
+        Integer userId = userService.getUserIdException();
+        OrderCenterNumResponse response = new OrderCenterNumResponse();
+        response.setAwaitPayCount(secondHandOrderService.getCountByStatusAndUid(OrderConstants.ORDER_STATUS_WAIT_PAY, userId));
+        response.setAwaitShippedCount(secondHandOrderService.getCountByStatusAndUid(OrderConstants.ORDER_STATUS_WAIT_SHIPPING, userId));
+        response.setReceiptCount(secondHandOrderService.getCountByStatusAndUid(OrderConstants.ORDER_STATUS_WAIT_RECEIPT, userId));
+        response.setVerificationCount(secondHandOrderService.getCountByStatusAndUid(OrderConstants.ORDER_STATUS_AWAIT_VERIFICATION, userId));
+        response.setAwaitReplyCount(orderDetailService.getAwaitReplyCount(userId));
+        response.setRefundCount(refundOrderService.getRefundingCount(userId));
+        return response;
+    }
+
+    /**
+     * 获取订单状态图
+     */
+    @Override
+    public List<HashMap<String, Object>> getOrderStatusImage() {
+        List<HashMap<String, Object>> mapList = systemGroupDataService.getListMapByGid(GroupDataConstants.GROUP_DATA_ID_ORDER_STATUS_IMAGE);
+        return mapList;
+    }
+
+    /**
+     * 计算订单运费
+     */
+    @Override
+    public void getFreightFee(PreSecondHandOrderInfoVo orderInfoVo, UserAddress userAddress, Boolean userIsPaidMember) {
+        BigDecimal freightFee = BigDecimal.ZERO;
+        List<PreSellerOrderVo> merchantOrderVoList = orderInfoVo.getSellerOrderVoList();
+        for (PreSellerOrderVo merchantOrderVo : merchantOrderVoList) {
+            BigDecimal storePostage = BigDecimal.ZERO;
+            if (merchantOrderVo.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP)) {
+                merchantOrderVo.setFreightFee(storePostage);
+                merchantOrderVo.getOrderInfoList().forEach(info -> info.setFreightFee(BigDecimal.ZERO));
+                continue;
+            }
+            if (ObjectUtil.isNull(userAddress) || userAddress.getCityId() <= 0) {
+                merchantOrderVo.setFreightFee(storePostage);
+                merchantOrderVo.getOrderInfoList().forEach(info -> info.setFreightFee(BigDecimal.ZERO));
+                continue;
+            }
+            // 按模板构建MAP
+            Map<Integer, MyRecord> tempMap = CollUtil.newHashMap();
+            // 运费根据商品计算
+//            Map<Integer, MyRecord> proMap = CollUtil.newHashMap();
+            merchantOrderVo.getOrderInfoList().forEach(e -> {
+                Integer tempId = e.getTempId();
+                BigDecimal proPrice;
+                proPrice = e.getPrice().multiply(BigDecimal.valueOf(e.getPayNum()));
+                if (tempMap.containsKey(tempId)) {
+                    MyRecord record = tempMap.get(tempId);
+                    record.set("totalPrice", record.getBigDecimal("totalPrice").add(proPrice));
+                    record.set("totalNum", record.getInt("totalNum") + e.getPayNum());
+                    BigDecimal weight = e.getWeight().multiply(BigDecimal.valueOf(e.getPayNum()));
+                    record.set("weight", record.getBigDecimal("weight").add(weight));
+                    BigDecimal volume = e.getVolume().multiply(BigDecimal.valueOf(e.getPayNum()));
+                    record.set("volume", record.getBigDecimal("volume").add(volume));
+                } else {
+                    MyRecord record = new MyRecord();
+                    record.set("totalPrice", proPrice);
+                    record.set("totalNum", e.getPayNum());
+                    record.set("tempId", tempId);
+                    BigDecimal weight = e.getWeight().multiply(BigDecimal.valueOf(e.getPayNum()));
+                    record.set("weight", weight);
+                    BigDecimal volume = e.getVolume().multiply(BigDecimal.valueOf(e.getPayNum()));
+                    record.set("volume", volume);
+                    tempMap.put(tempId, record);
+                }
+            });
+
+            // 指定包邮(单品运费模板)> 指定区域配送(单品运费模板)
+            int districtId = userAddress.getDistrictId();
+            for (Map.Entry<Integer, MyRecord> m : tempMap.entrySet()) {
+                MyRecord record = m.getValue();
+                Integer tempId = record.getInt("tempId");
+                ShippingTemplates shippingTemplate = shippingTemplatesService.getById(tempId);
+                if (ObjectUtil.isNull(shippingTemplate) || shippingTemplate.getAppoint().equals(ShippingTemplatesConstants.APPOINT_TYPE_ALL)) {
+                    merchantOrderVo.getOrderInfoList().stream()
+//                            .filter(e ->m.getKey().equals(e.getTempId()))
+                            .forEach(info -> info.setFreightFee(BigDecimal.ZERO));
+                    continue;
+                }
+                if (shippingTemplate.getAppoint().equals(ShippingTemplatesConstants.APPOINT_TYPE_DEFINED)) {
+                    ShippingTemplatesFree shippingTemplatesFree = shippingTemplatesFreeService.getByTempIdAndCityId(tempId, districtId);
+                    if (ObjectUtil.isNotNull(shippingTemplatesFree)) {
+                        BigDecimal totalPrice = record.getBigDecimal("totalPrice");
+                        if (totalPrice.compareTo(shippingTemplatesFree.getPrice()) >= 0) {
+                            merchantOrderVo.getOrderInfoList().stream()
+                                    //.filter(e -> m.getKey().equals(e.getTempId()))
+                                    .forEach(info -> info.setFreightFee(BigDecimal.ZERO));
+                            continue;
+                        }
+                        if (shippingTemplate.getType().equals(ShippingTemplatesConstants.CHARGE_MODE_TYPE_NUMBER)) {
+                            if (BigDecimal.valueOf(record.getInt("totalNum")).compareTo(shippingTemplatesFree.getNumber()) >= 0) {
+                                merchantOrderVo.getOrderInfoList().stream()
+                                       // .filter(e -> m.getKey().equals(e.getTempId()))
+                                        .forEach(info -> info.setFreightFee(BigDecimal.ZERO));
+                                continue;
+                            }
+                        }
+                        BigDecimal surplus = shippingTemplate.getType().equals(ShippingTemplatesConstants.CHARGE_MODE_TYPE_WEIGHT)
+                                ? record.getBigDecimal("weight") : record.getBigDecimal("volume");
+                        if (surplus.compareTo(shippingTemplatesFree.getNumber()) >= 0) {
+                            merchantOrderVo.getOrderInfoList().stream()
+                                    //.filter(e -> m.getKey().equals(e.getTempId()))
+                                    .forEach(info -> info.setFreightFee(BigDecimal.ZERO));
+                            continue;
+                        }
+                    }
+                }
+                ShippingTemplatesRegion shippingTemplatesRegion = shippingTemplatesRegionService.getByTempIdAndCityId(tempId, districtId);
+                if (ObjectUtil.isNull(shippingTemplatesRegion)) {
+                    shippingTemplatesRegion = shippingTemplatesRegionService.getByTempIdAndCityId(tempId, 0);
+                }
+                if (shippingTemplate.getAppoint().equals(ShippingTemplatesConstants.APPOINT_TYPE_PART)) {
+                    if (ObjectUtil.isNull(shippingTemplatesRegion)) {
+                        merchantOrderVo.getOrderInfoList().stream()
+                                //.filter(e -> m.getKey().equals(e.getTempId()))
+                                .forEach(info -> info.setFreightFee(BigDecimal.ZERO));
+                        continue;
+                    }
+                }
+                BigDecimal postageFee = BigDecimal.ZERO;
+                // 判断计费方式:件数、重量、体积
+                switch (shippingTemplate.getType()) {
+                    case ShippingTemplatesConstants.CHARGE_MODE_TYPE_NUMBER: // 件数
+                        // 判断件数是否超过首件
+                        Integer num = record.getInt("totalNum");
+                        if (num <= shippingTemplatesRegion.getFirst().intValue()) {
+                            storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice());
+                            postageFee = shippingTemplatesRegion.getFirstPrice();
+                        } else {// 超过首件的需要计算续件
+                            int renewalNum = num - shippingTemplatesRegion.getFirst().intValue();
+                            // 剩余件数/续件 = 需要计算的续件费用的次数
+                            // 更新运费计算公式 2024-4-15
+                            BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(new BigDecimal(String.valueOf(renewalNum)).divide(shippingTemplatesRegion.getRenewal(), 0, RoundingMode.UP));
+                            storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice);
+                            postageFee = shippingTemplatesRegion.getFirstPrice().add(renewalPrice);
+                        }
+                        List<PreSecondHandOrderInfoDetailVo> detailVoList = merchantOrderVo.getOrderInfoList().stream().filter(e -> e.getTempId().equals(tempId)).collect(Collectors.toList());
+                        if (detailVoList.size() == 1) {
+                            detailVoList.get(0).setFreightFee(postageFee);
+                        } else {
+                            Integer tempNum = num;
+                            for (int i = 0; i < detailVoList.size(); i++) {
+                                PreSecondHandOrderInfoDetailVo detail = detailVoList.get(i);
+                                if (detailVoList.size() == (i + 1)) {
+                                    detail.setFreightFee(postageFee);
+                                    break;
+                                }
+                                // 更新运费计算公式 2024-4-15
+                                BigDecimal multiply = postageFee.multiply(new BigDecimal(detail.getPayNum().toString())).divide(new BigDecimal(tempNum.toString()), 2, RoundingMode.UP);
+                                if (postageFee.compareTo(multiply) < 0) {
+                                    multiply = postageFee;
+                                }
+                                detail.setFreightFee(multiply);
+                                postageFee = postageFee.subtract(multiply);
+                                tempNum = tempNum - detail.getPayNum();
+                            }
+                        }
+                        break;
+                    case ShippingTemplatesConstants.CHARGE_MODE_TYPE_WEIGHT: // 重量
+                    case ShippingTemplatesConstants.CHARGE_MODE_TYPE_VOLIME: // 体积
+                        BigDecimal surplus = shippingTemplate.getType().equals(ShippingTemplatesConstants.CHARGE_MODE_TYPE_WEIGHT) ? record.getBigDecimal("weight") : record.getBigDecimal("volume");
+                        if (surplus.compareTo(shippingTemplatesRegion.getFirst()) <= 0) {
+                            storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice());
+                            postageFee = shippingTemplatesRegion.getFirstPrice();
+                        } else {// 超过首件的需要计算续件
+                            BigDecimal renewalNum = surplus.subtract(shippingTemplatesRegion.getFirst());
+                            // 剩余件数/续件 = 需要计算的续件费用的次数
+                            // 更新运费计算公式 2024-4-15
+                            BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(renewalNum.divide(shippingTemplatesRegion.getRenewal(), 0, RoundingMode.UP));
+                            storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice);
+                            postageFee = shippingTemplatesRegion.getFirstPrice().add(renewalPrice);
+                        }
+                        List<PreSecondHandOrderInfoDetailVo> infoDetailVoList = merchantOrderVo.getOrderInfoList().stream().filter(e -> e.getTempId().equals(tempId)).collect(Collectors.toList());
+                        if (infoDetailVoList.size() == 1) {
+                            infoDetailVoList.get(0).setFreightFee(postageFee);
+                        } else {
+                            BigDecimal tempSurplus = surplus;
+                            for (int i = 0; i < infoDetailVoList.size(); i++) {
+                                PreSecondHandOrderInfoDetailVo detail = infoDetailVoList.get(i);
+                                if (infoDetailVoList.size() == (i + 1)) {
+                                    detail.setFreightFee(postageFee);
+                                    break;
+                                }
+                                BigDecimal wv = shippingTemplate.getType().equals(ShippingTemplatesConstants.CHARGE_MODE_TYPE_WEIGHT) ? detail.getWeight() : detail.getVolume();
+                                // 更新运费计算公式 2024-4-15
+                                BigDecimal multiply = postageFee.multiply(wv.multiply(new BigDecimal(detail.getPayNum().toString()))).divide(tempSurplus, 2, RoundingMode.HALF_UP);
+                                if (postageFee.compareTo(multiply) < 0) {
+                                    multiply = postageFee;
+                                }
+                                detail.setFreightFee(multiply);
+                                postageFee = postageFee.subtract(multiply);
+                                tempSurplus = tempSurplus.subtract(wv.multiply(new BigDecimal(detail.getPayNum().toString())));
+                            }
+                        }
+                        break;
+                }
+            }
+            merchantOrderVo.setFreightFee(storePostage);
+            freightFee = freightFee.add(storePostage);
+        }
+          for(PreSellerOrderVo e:merchantOrderVoList ){
+                    if (merchantOrderVoList.stream().anyMatch(m -> (!m.getSellerId().equals(e.getSellerId())))) {
+                        throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "同一个订单不能购买不同卖家商品");
+                    }
+        }
+        orderInfoVo.setFreightFee(freightFee);
+    }
+
+    /**
+     * 校验预下单商品信息
+     *
+     * @param request 预下单请求参数
+     * @return OrderInfoVo
+     */
+    private PreSecondHandOrderInfoVo validatePreOrderRequest(PreSecondHandOrderRequest request, User user) {
+        PreSecondHandOrderInfoVo preOrderInfoVo = new PreSecondHandOrderInfoVo();
+        List<PreSellerOrderVo> sellerOrderVoList = CollUtil.newArrayList();
+        sellerOrderVoList = validatePreOrder(request, user);
+        preOrderInfoVo.setSellerOrderVoList(sellerOrderVoList);
+        SecondHandProd secondHandProd= prodService.getByIdException(request.getOrderDetails().get(0).getProductId());
+        UserAddress userAddress = userAddressService.getById(secondHandProd.getAddressId());
+        if(ObjectUtil.isNotNull(userAddress)) {
+            preOrderInfoVo.setAddressId(userAddress.getId());
+        }
+        preOrderInfoVo.setSellerId(secondHandProd.getUid());
+        return preOrderInfoVo;
+    }
+
+    /**
+     * 基础商品校验
+     */
+    private PreSellerOrderVo validatePreOrderBase(PreSecondHandOrderDetailRequest detailRequest) {
+        if (ObjectUtil.isNull(detailRequest.getProductId())) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "商品编号不能为空");
+        }
+        if (ObjectUtil.isNull(detailRequest.getProductNum()) || detailRequest.getProductNum() <= 0) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "购买数量必须大于0");
+        }
+        SecondHandProd product = prodService.getById(detailRequest.getProductId());
+        if (ObjectUtil.isNull(product) || product.getIsDel()==1) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "商品信息不存在,请刷新后重新选择");
+        }
+        if (product.getSaleStatus()==2) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "商品已下架,请刷新后重新选择");
+        }
+//        if (!product.getIsTakeTheir() && product.getDeliveryMethod().equals("2")) {
+//            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "此商品配送方式设置错误,请联系客服");
+//        }
+        User author = userService.getById(product.getUid());
+        User user = userService.getInfo();
+        // 构造PreMerchantOrderVo对象
+        PreSellerOrderVo merchantOrderVo = new PreSellerOrderVo();
+        merchantOrderVo.setSellerId(product.getUid());
+        merchantOrderVo.setSellerName(StrUtil.isEmpty(author.getRealName())?author.getNickname():author.getRealName());
+        merchantOrderVo.setSellerPhone(user.getPhone());
+        merchantOrderVo.setFreightFee(BigDecimal.ZERO);
+        merchantOrderVo.setTakeTheirSwitch(false);
+        PreSecondHandOrderInfoDetailVo detailVo = new PreSecondHandOrderInfoDetailVo();
+        detailVo.setProductId(product.getId());
+        detailVo.setProductType(0);
+        detailVo.setProductName(product.getTitle());
+        detailVo.setProductDesc(product.getContent());
+        detailVo.setPrice(product.getPrice());
+        detailVo.setPayPrice(product.getPrice());
+        detailVo.setPayNum(detailRequest.getProductNum());
+        detailVo.setVolume(BigDecimal.ZERO);
+        detailVo.setWeight(BigDecimal.ZERO);
+        detailVo.setImage(StrUtil.isNotBlank(product.getCover()) ?product.getCover() : product.getImage());
+        List<PreSecondHandOrderInfoDetailVo> infoList = CollUtil.newArrayList();
+        infoList.add(detailVo);
+        if (product.getSchool().equals(user.getSchool())) {   //同一所学校自提
+                merchantOrderVo.setShippingType(2);
+                merchantOrderVo.setTakeTheirSwitch(true);
+                detailVo.setDeliveryMethod("2");
+            } else {
+                detailVo.setDeliveryMethod("1");
+                merchantOrderVo.setShippingType(1);
+            }
+        merchantOrderVo.setOrderInfoList(infoList);
+        return merchantOrderVo;
+    }
+
+    private List<PreSellerOrderVo> validatePreOrder(PreSecondHandOrderRequest request, User user) {
+        List<PreSellerOrderVo> merchantOrderVoList = CollUtil.newArrayList();
+        request.getOrderDetails().forEach(e -> {
+            PreSellerOrderVo merchantOrderVo = validatePreOrderBase(e);
+            if (merchantOrderVoList.stream().anyMatch(m -> m.getSellerId().equals(merchantOrderVo.getSellerId()))) {
+                for (PreSellerOrderVo orderVo : merchantOrderVoList) {
+                    if (orderVo.getSellerId().equals(merchantOrderVo.getSellerId())) {
+                        orderVo.getOrderInfoList().addAll(merchantOrderVo.getOrderInfoList());
+                        break;
+                    }
+                }
+            } else {
+                merchantOrderVoList.add(merchantOrderVo);
+            }
+        });
+        for (PreSellerOrderVo merchantOrderVo : merchantOrderVoList) {
+            List<PreSecondHandOrderInfoDetailVo> orderInfoList = merchantOrderVo.getOrderInfoList();
+            boolean onlyMerchant = false;
+            boolean onlyVerification = false;
+            for (PreSecondHandOrderInfoDetailVo info : orderInfoList) {
+                if ("1".equals(info.getDeliveryMethod())) {
+                    onlyMerchant = true;
+                }
+                if ("2".equals(info.getDeliveryMethod())) {
+                    onlyVerification = true;
+                }
+            }
+            if (onlyMerchant && onlyVerification) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "部分商品配送方式不一致,请单独下单");
+            }
+            if (onlyVerification) {
+                merchantOrderVo.setShippingType(OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP);
+                SecondHandProd secondHandProd= prodService.getByIdException(orderInfoList.get(0).getProductId());
+                UserAddress userAddress = userAddressService.getById(secondHandProd.getAddressId());
+                if (ObjectUtil.isNull(userAddress)) {
+                    throw new CrmebException(CommonResultCode.VALIDATE_FAILED, StrUtil.format("{},卖家没有配置地址,请联系客服",merchantOrderVo.getSellerName()));
+                }
+                String userAddressStr = userAddress.getProvince() + userAddress.getCity() + userAddress.getDistrict() + userAddress.getStreet() + userAddress.getDetail();
+                merchantOrderVo.setSellerAddress(userAddressStr);
+                merchantOrderVo.setSellerPhone(userAddress.getPhone());
+                merchantOrderVo.setSellerName(userAddress.getRealName());
+            } else {
+                merchantOrderVo.setShippingType(1);
+            }
+        }
+        return merchantOrderVoList;
+    }
+}

+ 440 - 0
ydd_mer_java/crmeb-front/src/main/java/com/zbkj/front/service/impl/SecondHandFrontServiceImpl.java

@@ -0,0 +1,440 @@
+package com.zbkj.front.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.constants.*;
+import com.zbkj.common.exception.CrmebException;
+import com.zbkj.common.model.secondhand.SecondHandProd;
+import com.zbkj.common.model.secondhand.SecondHandCategory;
+import com.zbkj.common.model.secondhand.SecondHandRelation;
+import com.zbkj.common.model.system.GroupConfig;
+import com.zbkj.common.model.system.SystemUserLevel;
+import com.zbkj.common.model.user.User;
+import com.zbkj.common.model.user.UserAddress;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.*;
+import com.zbkj.common.response.*;
+import com.zbkj.common.response.secondhand.SecondHandProdTakeTheirResponse;
+import com.zbkj.common.result.CommonResultCode;
+import com.zbkj.common.result.CommunityResultCode;
+import com.zbkj.common.vo.PcHomeBannerVo;
+import com.zbkj.common.vo.PcHomeNavigationVo;
+import com.zbkj.front.service.SecondHandFrontService;
+import com.zbkj.service.service.*;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @ClassName CommunityServiceImpl
+ * @Description 社区服务实现类
+ * @Author HZW
+ * @Date 2023/3/9 14:39
+ * @Version 1.0
+ */
+@Service
+public class SecondHandFrontServiceImpl implements SecondHandFrontService {
+
+    @Autowired
+    private SystemConfigService systemConfigService;
+    @Autowired
+    private SecondHandCategoryService secondHandCategoryService;
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private SecondHandRelationService secondHandRelationService;
+    @Autowired
+    private SystemUserLevelService systemUserLevelService;
+//    @Autowired
+//    private CommunityAuthorConcernedService communityAuthorConcernedService;
+    @Autowired
+    private SecondHandProdConcernedService secondHandProdConcernedService;
+    @Autowired
+    private AsyncService asyncService;
+    @Autowired
+    private GroupConfigService groupConfigService;
+
+    @Autowired
+    private SecondHandProdService secondHandService;
+    @Autowired
+    private UserAddressService userAddressService;
+
+
+    @Override
+    public IndexInfoResponse getIndexInfo() {
+        IndexInfoResponse indexInfoResponse = new IndexInfoResponse();
+        indexInfoResponse.setBanner(getBanner());
+        indexInfoResponse.setNavigatList(getNavigation());
+        indexInfoResponse.setSchool(userService.getInfo().getSchool());
+        return indexInfoResponse;
+    }
+
+    /**
+     * 获取所有社区分类
+     */
+    @Override
+    public List<SecondHandCategory> getAllCategory() {
+        return secondHandCategoryService.findListByShow(Constants.COMMON_IS_FILED_ONE);
+    }
+
+    /**
+     * 社区笔记发现列表
+     * @param request 搜索参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondHandFrontPageResponse> findDiscoverNoteList(SecondHandFrontSearchRequest request) {
+        PageInfo<SecondHandProd> pageInfo = secondHandService.findH5List(request);
+        if (CollUtil.isEmpty(pageInfo.getList())) {
+            return CommonPage.copyPageInfo(pageInfo, new ArrayList<>());
+        }
+        Integer userId = userService.getUserId();
+        List<SecondHandFrontPageResponse> responseList = notesListToResponseList(pageInfo.getList(), userId);
+        return CommonPage.copyPageInfo(pageInfo, responseList);
+    }
+
+    /**
+     * 社区用户笔记详情
+     * @param noteId 文章ID
+     */
+    @Override
+    public SecondHandFrontDetailResponse getUserNoteDetail(Integer noteId) {
+        Integer userId = userService.getUserId();
+        SecondHandProd note = secondHandService.getByIdException(noteId);
+        if (!note.getAuditStatus().equals(SecondHandConstants.SECOND_HAND_AUDIT_SUCCESS) && !userId.equals(note.getUid())) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_NOTE_NOT_EXIST);
+        }
+        User author = userService.getById(note.getUid());
+        if (ObjectUtil.isNull(author) || author.getIsLogoff()) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_NOTE_AUTHOR_NOTE_EXIST);
+        }
+        SecondHandFrontDetailResponse response = new SecondHandFrontDetailResponse();
+        BeanUtils.copyProperties(note, response);
+        response.setAuthorId(author.getId());
+        response.setAuthorAvatar(author.getAvatar());
+        response.setAuthorName(author.getNickname());
+        if (author.getLevel() > 0) {
+            SystemUserLevel userLevel = systemUserLevelService.getByLevelId(author.getLevel());
+            response.setAuthorLevelIcon(userLevel.getIcon());
+        }
+        SecondHandCategory category = secondHandCategoryService.getById(note.getCategoryId());
+        response.setCategoryName(category.getName());
+
+        if (userId > 0) {
+            response.setUserIsLike(secondHandRelationService.isLikeByUid(note.getId(), userId));
+            if (userId.equals(note.getUid())) {
+                response.setIsConcerned(false);
+            } else {
+                response.setIsConcerned(secondHandProdConcernedService.isConcernedByUid(note.getUid(), userId));
+            }
+        }
+        return response;
+    }
+
+    /**
+     * 创建社区笔记
+     */
+    @Override
+    public void createNote(SecondHandSaveRequest request) {
+        secondHandService.create(request);
+    }
+
+    /**
+     * 编辑社区笔记
+     */
+    @Override
+    public void updateNote(SecondHandSaveRequest request) {
+        secondHandService.updateNote(request);
+    }
+
+
+
+
+    /**
+     * 社区之我的笔记列表
+     */
+    @Override
+    public PageInfo<SecondHandFrontPageResponse> findMyNoteList(PageParamRequest request) {
+        Integer userId = userService.getUserIdException();
+        PageInfo<SecondHandProd> pageInfo = secondHandService.findMyNoteList(userId, request);
+        if (CollUtil.isEmpty(pageInfo.getList())) {
+            return CommonPage.copyPageInfo(pageInfo, new ArrayList<>());
+        }
+        List<SecondHandFrontPageResponse> responseList = notesListToResponseList(pageInfo.getList(), userId);
+        return CommonPage.copyPageInfo(pageInfo, responseList);
+    }
+
+    @Override
+    public PageInfo<SecondHandFrontPageResponse> findRecommendList(SecondHandFrontSearchRequest request) {
+        request.setAuditStatus(SecondHandConstants.SECOND_HAND_AUDIT_SUCCESS);
+        request.setSaleStatus(0);
+        PageInfo<SecondHandProd> pageInfo =  secondHandService.findH5List(request);
+        List<SecondHandProd> notesList = pageInfo.getList();
+        if (CollUtil.isEmpty(notesList)) {
+            return CommonPage.copyPageInfo(pageInfo, new ArrayList<>());
+        }
+        Integer userId = userService.getUserId();
+        List<Integer> uidList = notesList.stream().map(SecondHandProd::getUid).collect(Collectors.toList());
+        Map<Integer, User> userMap = userService.getUidMapList(uidList);
+        List<SecondHandFrontPageResponse> responseList = notesList.stream().map(note -> {
+            SecondHandFrontPageResponse response = new SecondHandFrontPageResponse();
+            BeanUtils.copyProperties(note, response);
+            User author = userMap.get(note.getUid());
+            if (ObjectUtil.isNull(author) || author.getIsLogoff()) {
+                response.setAuthorId(0);
+                response.setAuthorAvatar("");
+                response.setAuthorName("");
+            } else {
+                response.setAuthorId(author.getId());
+                response.setAuthorAvatar(author.getAvatar());
+                response.setAuthorName(author.getNickname());
+                if (author.getLevel() > 0) {
+                    SystemUserLevel userLevel = systemUserLevelService.getByLevelId(author.getLevel());
+                    response.setAuthorLevelIcon(userLevel.getIcon());
+                }
+            }
+            if (ObjectUtil.isNotNull(userId) && userId > 0) {
+                response.setUserIsLike(secondHandRelationService.isLikeByUid(note.getId(), userId)); //我想要
+                response.setIsConcerned(secondHandProdConcernedService.isConcernedByUid(note.getUid(), userId));//我收藏
+            }
+            return response;
+        }).collect(Collectors.toList());
+        return CommonPage.copyPageInfo(pageInfo, responseList);
+    }
+
+    @Override
+    public PageInfo<SecondHandFrontPageResponse> findProdList(SecondHandFrontSearchRequest request) {
+        request.setSaleStatus(0);
+        PageInfo<SecondHandProd> pageInfo = secondHandService.findH5List(request);
+        List<SecondHandProd> notesList = pageInfo.getList();
+        if (CollUtil.isEmpty(notesList)) {
+            return CommonPage.copyPageInfo(pageInfo, new ArrayList<>());
+        }
+        Integer userId = userService.getUserId();
+        List<Integer> uidList = notesList.stream().map(SecondHandProd::getUid).collect(Collectors.toList());
+        Map<Integer, User> userMap = userService.getUidMapList(uidList);
+        List<SecondHandFrontPageResponse> responseList = notesList.stream().map(note -> {
+            SecondHandFrontPageResponse response = new SecondHandFrontPageResponse();
+            BeanUtils.copyProperties(note, response);
+            User author = userMap.get(note.getUid());
+            if (ObjectUtil.isNull(author) || author.getIsLogoff()) {
+                response.setAuthorId(0);
+                response.setAuthorAvatar("");
+                response.setAuthorName("");
+            } else {
+                response.setAuthorId(author.getId());
+                response.setAuthorAvatar(author.getAvatar());
+                response.setAuthorName(author.getNickname());
+                if (author.getLevel() > 0) {
+                    SystemUserLevel userLevel = systemUserLevelService.getByLevelId(author.getLevel());
+                    response.setAuthorLevelIcon(userLevel.getIcon());
+                }
+            }
+            if (ObjectUtil.isNotNull(userId) && userId > 0) {
+                response.setUserIsLike(secondHandRelationService.isLikeByUid(note.getId(), userId)); //我想要
+                response.setIsConcerned(secondHandProdConcernedService.isConcernedByUid(note.getUid(), userId));//我收藏
+            }
+            return response;
+        }).collect(Collectors.toList());
+        return CommonPage.copyPageInfo(pageInfo, responseList);
+    }
+
+    @Override
+    public void concernedProd(Integer prodId) {
+        Integer userId = userService.getUserIdException();
+        secondHandProdConcernedService.concernedProd(prodId,userId);
+    }
+
+
+    /**
+     * 社区笔记删除
+     * @param noteId 笔记ID
+     */
+    @Override
+    public void deleteNote(Integer noteId) {
+        Integer userId = userService.getUserIdException();
+        SecondHandProd communityNotes = secondHandService.getByIdException(noteId);
+        if (!userId.equals(communityNotes.getUid())) {
+            throw new CrmebException(CommonResultCode.FORBIDDEN.setMessage("不能操作非自己的资源"));
+        }
+        secondHandService.delete(noteId);
+    }
+
+    /**
+     * 社区笔记关注列表
+     * @param request 分页参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondHandFrontFollowResponse> findFollowNoteList(PageParamRequest request) {
+        Integer userId = userService.getUserIdException();
+//        if (userId <= 0) {
+//            return null;
+//        }
+        PageInfo<SecondHandProd> pageInfo = secondHandService.findFollowNoteList(request, userId);
+        if (CollUtil.isEmpty(pageInfo.getList())) {
+            return CommonPage.copyPageInfo(pageInfo, new ArrayList<>());
+        }
+        List<SecondHandProd> notesList = pageInfo.getList();
+        List<Integer> uidList = new ArrayList<>();
+        List<Integer> topicIdList = new ArrayList<>();
+        notesList.forEach(note -> {
+            uidList.add(note.getUid());
+
+        });
+        Map<Integer, User> userMap = userService.getUidMapList(uidList);
+        List<SecondHandFrontFollowResponse> responseList = notesList.stream().map(note -> {
+            SecondHandFrontFollowResponse response = new SecondHandFrontFollowResponse();
+            BeanUtils.copyProperties(note, response);
+            response.setAuthorId(note.getUid());
+            response.setAuthorName(userMap.get(note.getUid()).getNickname());
+            response.setAuthorAvatar(userMap.get(note.getUid()).getAvatar());
+            response.setUserIsLike(secondHandRelationService.isLikeByUid(note.getId(), userId));
+            if (userMap.get(note.getUid()).getLevel() > 0) {
+                SystemUserLevel userLevel = systemUserLevelService.getByLevelId(userMap.get(note.getUid()).getLevel());
+                response.setAuthorLevelIcon(userLevel.getIcon());
+            }
+            return response;
+        }).collect(Collectors.toList());
+        return CommonPage.copyPageInfo(pageInfo, responseList);
+    }
+
+    @Override
+    public void likeNote(Integer noteId) {
+        Integer userId = userService.getUserIdException();
+        SecondHandProd notes = secondHandService.getByIdException(noteId);
+        if (!notes.getAuditStatus().equals(SecondHandConstants.SECOND_HAND_AUDIT_SUCCESS)) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_NOTE_AUDIT_STATUS_EXCEPTION);
+        }
+        SecondHandRelation relation = secondHandRelationService.getOneByNoteIdAndUid(noteId, userId);
+        if (ObjectUtil.isNotNull(relation)) {
+            boolean remove = secondHandRelationService.removeById(relation);
+            if (!remove) {
+                throw new CrmebException(CommonResultCode.ERROR.setMessage("取消失败"));
+            }
+            asyncService.secondHandLikeOrClean(noteId, Constants.OPERATION_TYPE_SUBTRACT);
+            return;
+        }
+        relation = new SecondHandRelation();
+        relation.setSecondHandId(notes.getId());
+        relation.setType(CommunityConstants.COMMUNITY_NOTE_RELATION_LIKE);
+        relation.setUid(userId);
+        boolean save = secondHandRelationService.save(relation);
+        if (!save) {
+            throw new CrmebException(CommonResultCode.ERROR.setMessage("想要失败"));
+        }
+        asyncService.secondHandLikeOrClean(noteId, Constants.OPERATION_TYPE_ADD);
+    }
+
+    /**
+     * 社区之我的点赞列表
+     */
+    @Override
+    public PageInfo<SecondHandFrontPageResponse> findMyLikeNoteList(PageParamRequest request) {
+        Integer userId = userService.getUserIdException();
+        PageInfo<SecondHandRelation> pageInfo = secondHandRelationService.findLikePageByUid(userId, request);
+        List<SecondHandRelation> relationList = pageInfo.getList();
+        if (CollUtil.isEmpty(relationList)) {
+            return CommonPage.copyPageInfo(pageInfo, new ArrayList<>());
+        }
+        List<Integer> noteIdList = relationList.stream().map(SecondHandRelation::getSecondHandId).collect(Collectors.toList());
+        Map<Integer, SecondHandProd> notesMap = secondHandService.getMapByIdList(noteIdList);
+        List<SecondHandProd> notesList = new ArrayList<>();
+        relationList.forEach(r -> {
+            notesList.add(notesMap.get(r.getSecondHandId()));
+        });
+        List<SecondHandFrontPageResponse> responseList = notesListToResponseList(notesList, userId);
+        return CommonPage.copyPageInfo(pageInfo, responseList);
+    }
+    @Override
+    public SecondHandProdTakeTheirResponse getTakeTheir(Integer id) {
+        SecondHandProd merchant = secondHandService.getByIdException(id);
+        UserAddress userAddress = userAddressService.getById(merchant.getAddressId());
+        SecondHandProdTakeTheirResponse response = new SecondHandProdTakeTheirResponse();
+        response.setLatitude(merchant.getLatitude());
+        response.setLongitude(merchant.getLongitude() );
+        response.setPhone(userAddress.getPhone());
+        response.setName(userAddress.getRealName());
+        response.setProvince(userAddress.getProvince());
+        response.setCity(userAddress.getCity());
+        response.setDistrict(userAddress.getDistrict());
+        response.setAddressDetail(userAddress.getDetail());
+        return response;
+    }
+    private List<SecondHandFrontPageResponse> notesListToResponseList(List<SecondHandProd> notesList, Integer userId) {
+        List<Integer> uidList = notesList.stream().map(SecondHandProd::getUid).distinct().collect(Collectors.toList());
+        Map<Integer, User> userMap = userService.getUidMapList(uidList);
+        return notesList.stream().map(note -> {
+            SecondHandFrontPageResponse response = new SecondHandFrontPageResponse();
+            response.setId(note.getId());
+            response.setTitle(note.getTitle());
+            response.setType(note.getType());
+            response.setCover(note.getCover());
+            response.setAuthorId(note.getUid());
+            response.setAuthorName(userMap.get(note.getUid()).getNickname());
+            response.setAuthorAvatar(userMap.get(note.getUid()).getAvatar());
+            response.setLikeNum(note.getLikeNum());
+            response.setContent(note.getContent());
+            response.setCreateTime(note.getCreateTime());
+            response.setCategoryId(note.getCategoryId());
+            response.setIcon(note.getIcon());
+            response.setSchool(note.getSchool());
+            response.setImage(note.getImage());
+            response.setPrice(note.getPrice());
+            response.setSaleStatus(note.getSaleStatus());
+            if (userMap.get(note.getUid()).getLevel() > 0) {
+                SystemUserLevel userLevel = systemUserLevelService.getByLevelId(userMap.get(note.getUid()).getLevel());
+                response.setUserLevelIcon(userLevel.getIcon());
+            }
+            if (ObjectUtil.isNotNull(note.getAuditStatus())) {
+                response.setAuditStatus(note.getAuditStatus());
+            }
+            return response;
+        }).collect(Collectors.toList());
+    }
+    /**
+     * 获取Banner
+     * @return
+     */
+    private List<PcHomeBannerVo> getBanner(){
+        List<GroupConfig> configList = groupConfigService.findByTag(GroupConfigConstants.TAG_SECOND_TRAN_BANNER, Constants.SORT_ASC, null);
+        if (CollUtil.isEmpty(configList)) {
+            return new ArrayList<>();
+        }
+        Iterator<GroupConfig> iterator = configList.iterator();
+        List<PcHomeBannerVo> voList = new ArrayList<>();
+        while (iterator.hasNext()) {
+            GroupConfig config = iterator.next();
+            PcHomeBannerVo vo = new PcHomeBannerVo();
+            BeanUtils.copyProperties(config, vo);
+            voList.add(vo);
+        }
+        return voList;
+    }
+    /**
+     * 获取Banner
+     * @return
+     */
+    private List<PcHomeNavigationVo>  getNavigation(){
+        List<SecondHandCategory> navigationList= secondHandCategoryService.findListByShow(1);
+        List<PcHomeNavigationVo> voNavigationList=  CollectionUtil.newArrayList();
+        Iterator<SecondHandCategory> navigationIterator = navigationList.iterator();
+        while (navigationIterator.hasNext()) {
+            SecondHandCategory config = navigationIterator.next();
+            PcHomeNavigationVo vo = new PcHomeNavigationVo();
+            vo.setId(config.getId());
+            vo.setImageUrl(config.getIcon());
+            vo.setName(config.getName());
+            voNavigationList.add(vo);
+        }
+        return voNavigationList;
+    }
+}

+ 54 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/SecondHandOrderDetailDao.java

@@ -0,0 +1,54 @@
+package com.zbkj.service.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zbkj.common.model.order.OrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * <p>
+ * 订单详情表 Mapper 接口
+ * </p>
+ *
+ * @author HZW
+ * @since 2022-09-19
+ */
+public interface SecondHandOrderDetailDao extends BaseMapper<SecondHandOrderDetail> {
+
+    /**
+     * 订单商品评论列表
+     * @param userId 用户id
+     * @param isReply 是否评价,0-未评价,1-已评价
+     */
+    List<SecondHandOrderDetail> findReplyList(@Param("userId") Integer userId, @Param("isReply") Integer isReply);
+
+    /**
+     * 售后申请列表(可申请售后列表)
+     * @param uid 用户id
+     * @param keywords 订单号/商品名称
+     */
+    List<SecondHandOrderDetail> findAfterSaleApplyList(@Param("uid") Integer uid, @Param("keywords") String keywords);
+
+    /**
+     * 根据时间、商品id获取销售件数
+     * @param date 时间,格式'yyyy-MM-dd'
+     * @param proId 商品id
+     */
+    Integer getSalesNumByDateAndProductId(@Param("date") String date, @Param("proId")  Integer proId);
+
+    /**
+     * 根据时间、商品id获取销售额
+     * @param date 时间,格式'yyyy-MM-dd'
+     * @param proId 商品id
+     */
+    BigDecimal getSalesByDateAndProductId(@Param("date") String date, @Param("proId")  Integer proId);
+
+    /**
+     * 获取待评价数量
+     * @return 待评价数量
+     */
+    Integer getAwaitReplyCount(@Param("userId") Integer userId);
+}

+ 17 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandCategoryDao.java

@@ -0,0 +1,17 @@
+package com.zbkj.service.dao.secondhand;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zbkj.common.model.community.CommunityCategory;
+import com.zbkj.common.model.secondhand.SecondHandCategory;
+
+/**
+ * <p>
+ * 社区分类表 Mapper 接口
+ * </p>
+ *
+ * @author HZW
+ * @since 2023-03-07
+ */
+public interface SecondHandCategoryDao extends BaseMapper<SecondHandCategory> {
+
+}

+ 25 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandDao.java

@@ -0,0 +1,25 @@
+package com.zbkj.service.dao.secondhand;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zbkj.common.dto.CommunityNotePageDateDto;
+import com.zbkj.common.dto.SecondHandProdPageDateDto;
+import com.zbkj.common.model.secondhand.SecondHandProd;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 社区笔记表 Mapper 接口
+ * </p>
+ *
+ * @author HZW
+ * @since 2023-03-07
+ */
+public interface SecondHandDao extends BaseMapper<SecondHandProd> {
+
+    /**
+     * 社区笔记分页列表
+     */
+    List<SecondHandProdPageDateDto> findPageList(Map<String, Object> map);
+}

+ 49 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandOrderDao.java

@@ -0,0 +1,49 @@
+package com.zbkj.service.dao.secondhand;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zbkj.common.model.order.Order;
+import com.zbkj.common.model.secondhand.SecondHandOrder;
+import com.zbkj.common.response.IntegralOrderPageResponse;
+import com.zbkj.common.response.MerchantOrderPageResponse;
+import com.zbkj.common.response.PlatformOrderPageResponse;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 订单表 Mapper 接口
+ * </p>
+ *
+ * @author HZW
+ * @since 2022-09-19
+ */
+public interface SecondHandOrderDao extends BaseMapper<SecondHandOrder> {
+
+    /**
+     * 获取用户购买的商品数量
+     * @param uid 用户ID
+     * @param proId 商品ID
+     * @param marketingType 营销类型
+     */
+    Integer getProductNumCount(@Param(value = "uid") Integer uid, @Param(value = "proId") Integer proId, @Param(value = "marketingType") Integer marketingType);
+
+    /**
+     * 获取移动端订单列表
+     * @param searchMap 搜索参数
+     */
+    List<SecondHandOrder> findFrontList(Map<String, Object> searchMap);
+
+    List<PlatformOrderPageResponse> getPlatformAdminPage(Map<String, Object> map);
+
+    List<MerchantOrderPageResponse> getMerchantAdminPage(Map<String, Object> map);
+
+    Integer getIntegralOrderCount(Map<String, Object> map);
+
+    List<IntegralOrderPageResponse> findIntegralOrderPageByPlat(Map<String, Object> map);
+
+    Integer getMerchantAdminPageCount(Map<String, Object> map);
+
+    Integer getPlatformAdminPageCount(Map<String, Object> map);
+}

+ 17 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandProdConcernedDao.java

@@ -0,0 +1,17 @@
+package com.zbkj.service.dao.secondhand;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zbkj.common.model.community.CommunityAuthorConcerned;
+import com.zbkj.common.model.secondhand.SecondHandProdConcerned;
+
+/**
+ * <p>
+ * 社区作者关注表 Mapper 接口
+ * </p>
+ *
+ * @author HZW
+ * @since 2023-03-07
+ */
+public interface SecondHandProdConcernedDao extends BaseMapper<SecondHandProdConcerned> {
+
+}

+ 41 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandRefundOrderDao.java

@@ -0,0 +1,41 @@
+package com.zbkj.service.dao.secondhand;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zbkj.common.model.order.RefundOrder;
+import com.zbkj.common.model.secondhand.SecondHandRefundOrder;
+import com.zbkj.common.response.MerchantRefundOrderPageResponse;
+import com.zbkj.common.response.PlatformRefundOrderPageResponse;
+import com.zbkj.common.response.RefundOrderInfoResponse;
+import com.zbkj.common.response.RefundOrderResponse;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 退款单表 Mapper 接口
+ * </p>
+ *
+ * @author HZW
+ * @since 2022-09-19
+ */
+public interface SecondHandRefundOrderDao extends BaseMapper<SecondHandRefundOrder> {
+
+    /**
+     * 退款订单详情
+     * @param refundOrderNo 退款订单号
+     * @return RefundOrderInfoResponse
+     */
+    RefundOrderInfoResponse getRefundOrderDetailByRefundOrderNo(@Param("refundOrderNo") String refundOrderNo);
+
+    List<RefundOrderResponse> findSearchList(Map<String, Object> map);
+
+    List<SecondHandRefundOrder> findCanAutoRevokeOrderList(@Param("revokeTime") String revokeTime);
+
+    List<PlatformRefundOrderPageResponse> getPlatformAdminPage(Map<String, Object> map);
+
+    List<MerchantRefundOrderPageResponse> getMerchantAdminPage(Map<String, Object> map);
+
+    Integer getMerchantAdminPageCount(Map<String, Object> map);
+}

+ 17 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandRefundOrderInfoDao.java

@@ -0,0 +1,17 @@
+package com.zbkj.service.dao.secondhand;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zbkj.common.model.order.RefundOrderInfo;
+import com.zbkj.common.model.secondhand.SecondHandRefundOrderInfo;
+
+/**
+ * <p>
+ * 退款订单详情表 Mapper 接口
+ * </p>
+ *
+ * @author HZW
+ * @since 2022-09-19
+ */
+public interface SecondHandRefundOrderInfoDao extends BaseMapper<SecondHandRefundOrderInfo> {
+
+}

+ 17 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/secondhand/SecondHandRelationDao.java

@@ -0,0 +1,17 @@
+package com.zbkj.service.dao.secondhand;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zbkj.common.model.community.CommunityNotesRelation;
+import com.zbkj.common.model.secondhand.SecondHandRelation;
+
+/**
+ * <p>
+ * 社区笔记关系表 Mapper 接口
+ * </p>
+ *
+ * @author HZW
+ * @since 2023-03-07
+ */
+public interface SecondHandRelationDao extends BaseMapper<SecondHandRelation> {
+
+}

+ 6 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/AsyncService.java

@@ -70,6 +70,12 @@ public interface AsyncService {
      * @param operationType 操作类型:add-点赞,sub-取消
      */
     void communityNoteLikeOrClean(Integer noteId, String operationType);
+    /**
+     * 社区笔记点赞与取消
+     * @param noteId 笔记ID
+     * @param operationType 操作类型:add-点赞,sub-取消
+     */
+   void secondHandLikeOrClean(Integer noteId, String operationType);
 
     /**
      * 社区笔记评论点赞与取消

+ 0 - 1
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/OrderService.java

@@ -60,7 +60,6 @@ public interface OrderService extends IService<Order> {
      PageInfo<Order> getUserOrderList_v1_5(Integer userId, OrderFrontListRequest request);
     /**
      * 获取用户订单列表V1.5
-     * @param userId 用户id
      * @param request 搜索参数
      * @return PageInfo
      */

+ 6 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/PayCallbackService.java

@@ -28,6 +28,12 @@ public interface PayCallbackService {
      * @return String
      */
     String wechatExpPayCallback(String xmlInfo);
+    /**
+     * 快递微信支付回调
+     * @param xmlInfo 微信回调json
+     * @return String
+     */
+    String wechatSecondhandPayCallback(String xmlInfo);
 
     /**
      * 支付宝支付回调

+ 1 - 2
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/RefundOrderManagerService.java

@@ -78,7 +78,6 @@ public interface RefundOrderManagerService extends IService<RefundOrder> {
 
     /**
      * 获取平台端退款订单各状态数量
-     * @param dateLimit 时间参数
      * @return RefundOrderCountItemResponse
      */
     RefundOrderCountItemResponse getPlatformOrderStatusNum(RefundOrderSearchRequest request);
@@ -136,7 +135,7 @@ public interface RefundOrderManagerService extends IService<RefundOrder> {
      * 获取退款单详情
      * @param refundOrderNo 退款单号
      */
-    RefundOrder getByRefundOrderNo(String refundOrderNo);
+    RefundOrder     getByRefundOrderNo(String refundOrderNo);
 
     /**
      * 待退款订单数量

+ 69 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandCategoryService.java

@@ -0,0 +1,69 @@
+package com.zbkj.service.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.model.community.CommunityCategory;
+import com.zbkj.common.model.secondhand.SecondHandCategory;
+import com.zbkj.common.request.CommunityCategorySaveRequest;
+import com.zbkj.common.request.CommunityCategorySearchRequest;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+* CommunityCategory 接口
+* +----------------------------------------------------------------------
+* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+* +----------------------------------------------------------------------
+* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+* +----------------------------------------------------------------------
+* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+* +----------------------------------------------------------------------
+* | Author: CRMEB Team <admin@crmeb.com>
+* +----------------------------------------------------------------------
+*/
+public interface SecondHandCategoryService extends IService<SecondHandCategory> {
+
+    /**
+     * 社区分类分页列表
+     * @param request 请求参数
+     * @return 分页列表
+     */
+    PageInfo<SecondHandCategory> findPageList(CommunityCategorySearchRequest request);
+
+    /**
+     * 保存社区分类
+     * @param request 请求参数
+     */
+    void add(CommunityCategorySaveRequest request);
+
+    /**
+     * 编辑社区分类
+     * @param request 请求参数
+     */
+    void edit(CommunityCategorySaveRequest request);
+
+    /**
+     * 删除社区分类
+     * @param id 分类ID
+     */
+    void deleteById(Integer id);
+
+    /**
+     * 获取分类Map
+     * @param cateIdList 分类ID列表
+     * @return Map<id,name>
+     */
+    Map<Integer, String> getMapInIdList(List<Integer> cateIdList);
+
+    /**
+     * 社区分类显示开关
+     * @param id 分类ID
+     */
+    void showSwitch(Integer id);
+
+    /**
+     * 根据显示状态获取全部分类列表
+     */
+    List<SecondHandCategory> findListByShow(Integer isShow);
+}

+ 114 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandOrderService.java

@@ -0,0 +1,114 @@
+package com.zbkj.service.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.model.admin.SystemAdmin;
+import com.zbkj.common.model.order.Order;
+import com.zbkj.common.model.order.OrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandOrder;
+import com.zbkj.common.request.*;
+import com.zbkj.common.request.secondhand.SecondHandOrderSendRequest;
+import com.zbkj.common.response.*;
+import com.zbkj.common.vo.LogisticsResultVo;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+*  OrderService 接口
+*  +----------------------------------------------------------------------
+*  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+*  +----------------------------------------------------------------------
+*  | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+*  +----------------------------------------------------------------------
+*  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+*  +----------------------------------------------------------------------
+*  | Author: CRMEB Team <admin@crmeb.com>
+*  +----------------------------------------------------------------------
+*/
+public interface SecondHandOrderService extends IService<SecondHandOrder> {
+
+    /**
+     * 根据订单编号获取订单
+     * @param orderNo 订单编号
+     */
+    SecondHandOrder getByOrderNo(String orderNo);
+
+    /**
+     * 更新支付结果
+     * @param orderNo 订单编号
+     */
+    Boolean updatePaid(String orderNo);
+
+    /**
+     * 获取订单
+     * @param outTradeNo 商户系统内部的订单号
+     */
+    SecondHandOrder getByOutTradeNo(String outTradeNo);
+
+    /**
+     * 获取用户订单列表V1.4
+     * @param userId 用户id
+     * @param request 搜索参数
+     * @return PageInfo
+     */
+    PageInfo<SecondHandOrder> getUserOrderList_v1_4(Integer userId, OrderFrontListRequest request);
+
+    /**
+     * 获取用户订单列表V1.5
+     * @param request 搜索参数
+     * @return PageInfo
+     */
+    PageInfo<SecondHandOrder> getUserOrderList_v1_6(OrderFrontListRequest request);
+    /**
+     * 取消订单
+     * @param orderNo 订单编号
+     * @param isUser 是否用户取消
+     * @return Boolean
+     */
+    Boolean cancel(String orderNo, Boolean isUser);
+
+    /**
+     * 管理平台查询
+     * @param request
+     * @param systemAdmin
+     * @return
+     */
+    PageInfo<MerchantOrderPageResponse> getMerchantAdminPage(OrderSearchRequest request, SystemAdmin systemAdmin);
+
+    /**
+     * 订单详情(PC)
+     *
+     * @param orderNo 订单编号
+     * @return OrderAdminDetailResponse
+     */
+     OrderAdminDetailResponse adminDetail(String orderNo, SystemAdmin systemAdmin);
+
+    /**
+     * 获取订单数量(订单状态, 用户id)
+     * @param status 订单状态
+     * @param userId 用户ID
+     * @return 订单数量
+     */
+    Integer getCountByStatusAndUid(Integer status, Integer userId);
+    /**
+     * 订单收货
+     * @param orderNo 订单号
+     */
+    Boolean takeDelivery(String orderNo);
+
+    /**
+     *发货
+     * @param request
+     * @return
+     */
+    Boolean send(SecondHandOrderSendRequest request);
+
+    /**
+     * 订单退款申请
+     * @param request 申请参数
+     * @return Boolean
+     */
+    Boolean refundApply(OrderRefundApplyRequest request);
+
+}

+ 31 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandPayService.java

@@ -0,0 +1,31 @@
+package com.zbkj.service.service;
+
+import com.zbkj.common.request.OrderPayRequest;
+import com.zbkj.common.request.WechatPaymentQueryRequest;
+import com.zbkj.common.response.OrderPayResultResponse;
+
+/**
+ * ExpressPayService 接口
+ *
+ */
+public interface SecondHandPayService {
+    /**
+     * 订单支付
+     * @param orderPayRequest 订单支付参数
+     * @return OrderPayResultResponse
+     */
+    OrderPayResultResponse payment(OrderPayRequest orderPayRequest);
+
+    /**
+     * 查询支付结果
+     * @param orderNo
+     * @return
+     */
+    Boolean queryWechatPayResult(String orderNo);
+
+     /**
+     * 查询微信支付结果
+     */
+    Boolean queryWechatPaymentResult(WechatPaymentQueryRequest request);
+
+}

+ 65 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandProdConcernedService.java

@@ -0,0 +1,65 @@
+package com.zbkj.service.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.model.community.CommunityAuthorConcerned;
+import com.zbkj.common.model.secondhand.SecondHandProdConcerned;
+import com.zbkj.common.request.PageParamRequest;
+
+import java.util.List;
+
+/**
+* CommunityAuthorConcerned 接口
+* +----------------------------------------------------------------------
+* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+* +----------------------------------------------------------------------
+* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+* +----------------------------------------------------------------------
+* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+* +----------------------------------------------------------------------
+* | Author: CRMEB Team <admin@crmeb.com>
+* +----------------------------------------------------------------------
+*/
+public interface SecondHandProdConcernedService extends IService<SecondHandProdConcerned> {
+
+    /**
+     * 获取关注的作者ID列表
+     * @param userId 用户ID
+     */
+    List<Integer> findProdIdList(Integer userId);
+
+    /**
+     * 是否关注作者
+     * @param prodId 作者ID
+     * @param userId 用户ID
+     */
+    Boolean isConcernedByUid(Integer prodId, Integer userId);
+
+    /**
+     * 获取作者被关注数(粉丝数)
+     * @param prodId 作者ID
+     */
+    Integer getCountByProdId(Integer prodId);
+
+    /**
+     * 获取用户关注数
+     * @param userId 用户ID
+     */
+    Integer getCountByUserId(Integer userId);
+
+    /**
+     * 获取关注关系列表
+     * @param prodId 作者ID
+     * @param userId 用户ID
+     * @param request 分页参数
+     * @return PageInfo
+     */
+    PageInfo<SecondHandProdConcerned> findPage(Integer prodId, Integer userId, PageParamRequest request);
+
+    /**
+     * 社区关注/取关作者
+     * @param prodId 作者ID
+     * @param userId 用户ID
+     */
+    void concernedProd(Integer prodId, Integer userId);
+}

+ 174 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandProdService.java

@@ -0,0 +1,174 @@
+package com.zbkj.service.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.model.secondhand.SecondHandProd;
+import com.zbkj.common.request.*;
+import com.zbkj.common.response.CommunityNotePageDateResponse;
+import com.zbkj.common.response.SecondHandDetailResponse;
+import com.zbkj.common.response.SecondHandPageDataResponse;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+* CommunityNotes 接口
+* +----------------------------------------------------------------------
+* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+* +----------------------------------------------------------------------
+* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+* +----------------------------------------------------------------------
+* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+* +----------------------------------------------------------------------
+* | Author: CRMEB Team <admin@crmeb.com>
+* +----------------------------------------------------------------------
+*/
+public interface SecondHandProdService extends IService<SecondHandProd> {
+
+    /**
+     * 是否使用社区分类
+     * @param cateId 社区分类ID
+     */
+    Boolean isUseCategory(Integer cateId);
+
+
+    /**
+     * 社区笔记分页列表
+     * @param request 查询参数
+     * @return PageInfo
+     */
+    PageInfo<SecondHandPageDataResponse> findPageList(SecondHandProdSearchRequest request);
+
+    /**
+     * 社区笔记详情
+     * @param id 笔记ID
+     */
+    SecondHandDetailResponse detail(Integer id);
+
+    /**
+     * 社区笔记审核
+     */
+    void audit(CommonAuditRequest request);
+
+    /**
+     * 社区笔记强制下架
+     */
+    void forcedDown(CommonForcedDownRequest request);
+
+    /**
+     * 社区笔记删除
+     * @param id 笔记ID
+     */
+    void delete(Integer id);
+
+    /**
+     * 社区笔记分类批量修改
+     */
+    void categoryBatchUpdate(CommunityNoteCategoryBatchUpdateRequest request);
+
+    /**
+     * 社区笔记推荐星级编辑
+     */
+    void updateStar(CommonStarUpdateRequest request);
+
+
+    /**
+     * 移动端社区发现笔记分页列表
+     * @param request 搜索参数
+     * @return PageInfo
+     */
+    PageInfo<SecondHandProd> findH5List(SecondHandFrontSearchRequest request);
+
+
+    /**
+     * 获取话题关联的笔记数量
+     * @param topicId 话题ID
+     */
+    Integer getCountByTopic(Integer topicId);
+
+    /**
+     * 获取话题关联的笔记数量
+     * @param topicId 话题ID
+     */
+    Integer getFrontCountByTopic(Integer topicId);
+
+    /**
+     * 社区笔记作者列表
+     * @param authorId 作者ID
+     * @param request 分页参数
+     * @return PageInfo
+     */
+    PageInfo<SecondHandProd> findAuthorNoteList(Integer authorId, PageParamRequest request);
+
+    /**
+     * 获取笔记详情
+     * @param id 笔记ID
+     */
+    SecondHandProd getByIdException(Integer id);
+
+    /**
+     * 创建社区笔记
+     */
+    void create(SecondHandSaveRequest request);
+
+    /**
+     * 编辑社区笔记
+     */
+    void updateNote(SecondHandSaveRequest request);
+
+    /**
+     * 社区之我的笔记列表
+     */
+    PageInfo<SecondHandProd> findMyNoteList(Integer userId, PageParamRequest request);
+
+    /**
+     * 按时间倒序获取文章作者列表
+     */
+    PageInfo<Integer> findAuthorPageTimeDesc(Integer userId, PageParamRequest request);
+
+    /**
+     * 获取新笔记通过作者
+     * @param authorId 作者ID
+     * @param num 笔记数量
+     */
+    List<SecondHandProd> findNewNoteByAuthorId(Integer authorId, Integer num);
+
+    /**
+     * 社区笔记点赞数量
+     * @param noteId 笔记ID
+     * @param operationType 操作类型:add-点赞,sub-取消
+     */
+    void operationLike(Integer noteId, String operationType);
+
+    /**
+     * 操作社区笔记评论数量
+     * @param noteId 笔记ID
+     * @param num 评论数量
+     * @param operationType 操作类型
+     */
+    void operationReplyNum(Integer noteId, Integer num, String operationType);
+
+    /**
+     * 社区笔记发现推荐列表
+     * @param request 分页参数
+     */
+    PageInfo<SecondHandProd> findRecommendList(String keyWords, PageParamRequest request);
+
+    Map<Integer, SecondHandProd> getMapByIdList(List<Integer> noteIdList);
+
+    /**
+     * 删除用户所有笔记
+     * @param userId 用户ID
+     */
+    Boolean deleteByUid(Integer userId);
+
+    /**
+     * 关注列表
+     * @param request
+     * @param userId
+     * @return
+     */
+    PageInfo<SecondHandProd> findFollowNoteList(PageParamRequest request, Integer userId);
+
+    void updateStatusByOrderNo(String orderNo,Integer status);
+}

+ 27 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandRefundOrderInfoService.java

@@ -0,0 +1,27 @@
+package com.zbkj.service.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zbkj.common.model.order.RefundOrderInfo;
+import com.zbkj.common.model.secondhand.SecondHandRefundOrderInfo;
+
+/**
+*  RefundOrderInfoService 接口
+*  +----------------------------------------------------------------------
+*  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+*  +----------------------------------------------------------------------
+*  | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+*  +----------------------------------------------------------------------
+*  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+*  +----------------------------------------------------------------------
+*  | Author: CRMEB Team <admin@crmeb.com>
+*  +----------------------------------------------------------------------
+*/
+public interface SecondHandRefundOrderInfoService extends IService<SecondHandRefundOrderInfo> {
+
+    /**
+     * 根据退款单号获取详情
+     * @param refundOrderNo 退款单号
+     * @return RefundOrderInfo
+     */
+    SecondHandRefundOrderInfo getByRefundOrderNo(String refundOrderNo);
+}

+ 208 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandRefundOrderManagerService.java

@@ -0,0 +1,208 @@
+package com.zbkj.service.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.model.admin.SystemAdmin;
+import com.zbkj.common.model.order.Order;
+import com.zbkj.common.model.order.OrderDetail;
+import com.zbkj.common.model.order.RefundOrder;
+import com.zbkj.common.model.secondhand.SecondHandOrder;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandRefundOrder;
+import com.zbkj.common.request.*;
+import com.zbkj.common.response.*;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+*  RefundOrderService 接口
+*  +----------------------------------------------------------------------
+*  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+*  +----------------------------------------------------------------------
+*  | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+*  +----------------------------------------------------------------------
+*  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+*  +----------------------------------------------------------------------
+*  | Author: CRMEB Team <admin@crmeb.com>
+*  +----------------------------------------------------------------------
+*/
+public interface SecondHandRefundOrderManagerService extends IService<SecondHandRefundOrder> {
+
+    /**
+     * 商户端退款订单分页列表
+     * @param request 查询参数
+     * @return PageInfo
+     */
+    PageInfo<MerchantRefundOrderPageResponse> getMerchantAdminPage(RefundOrderSearchRequest request, SystemAdmin systemAdmin);
+
+    /**
+     * 获取商户端退款订单各状态数量
+     * @return RefundOrderCountItemResponse
+     */
+    RefundOrderCountItemResponse getMerchantOrderStatusNum(RefundOrderSearchRequest request, SystemAdmin systemAdmin);
+
+    /**
+     * 备注退款单
+     * @param request 备注参数
+     * @return Boolean
+     */
+    Boolean mark(RefundOrderRemarkRequest request, SystemAdmin systemAdmin);
+
+    SecondHandRefundOrder getInfoException(String refundOrderNo);
+
+    /**
+     * 移动端退款订单列表
+     * @param request 搜索参数
+     * @return List
+     */
+    PageInfo<RefundOrderResponse> getH5List(OrderAfterSalesSearchRequest request);
+
+    /**
+     * 退款订单详情(移动端)
+     * @param refundOrderNo 退款订单号
+     * @return RefundOrderInfoResponse
+     */
+    RefundOrderInfoResponse getRefundOrderDetailByRefundOrderNo(String refundOrderNo);
+
+    /**
+     * 商户端退款单详情响应对象
+     * @param refundOrderNo 退款单号
+     * @return 退款单详情
+     */
+    RefundOrderAdminDetailResponse getMerchantDetail(String refundOrderNo, SystemAdmin systemAdmin);
+
+    /**
+     * 平台端退款订单分页列表
+     * @param request 查询参数
+     * @return PageInfo
+     */
+    PageInfo<PlatformRefundOrderPageResponse> getPlatformAdminPage(RefundOrderSearchRequest request);
+
+    /**
+     * 获取平台端退款订单各状态数量
+     * @return RefundOrderCountItemResponse
+     */
+    RefundOrderCountItemResponse getPlatformOrderStatusNum(RefundOrderSearchRequest request);
+
+    /**
+     * 平台备注退款单
+     * @param request 备注参数
+     * @return Boolean
+     */
+    Boolean platformMark(RefundOrderRemarkRequest request);
+
+    /**
+     * 平台端退款订单详情
+     * @param refundOrderNo 退款单号
+     * @return 退款单详情
+     */
+    RefundOrderAdminDetailResponse getPlatformDetail(String refundOrderNo);
+
+    /**
+     * 获取某一天的所有数据
+     * @param merId 商户id,0为所有商户
+     * @param date 日期:年-月-日
+     * @return List
+     */
+    List<SecondHandRefundOrder> findByDate(Integer merId, String date);
+
+    /**
+     * 获取某一月的所有数据
+     * @param merId 商户id,0为所有商户
+     * @param month 日期:年-月
+     * @return List
+     */
+    List<SecondHandRefundOrder> findByMonth(Integer merId, String month);
+
+    /**
+     * 根据日期获取退款订单数量
+     * @param date 日期
+     * @return Integer
+     */
+    Integer getRefundOrderNumByDate(String date);
+
+    /**
+     * 根据日期获取退款订单金额
+     * @param date 日期
+     * @return Integer
+     */
+    BigDecimal getRefundOrderAmountByDate(String date);
+
+    /**
+     * 获取退款中(申请)订单数量
+     */
+    Integer getRefundingCount(Integer userId);
+
+    /**
+     * 获取退款单详情
+     * @param refundOrderNo 退款单号
+     */
+    SecondHandRefundOrder     getByRefundOrderNo(String refundOrderNo);
+
+    /**
+     * 待退款订单数量
+     * @return Integer
+     */
+    Integer getAwaitAuditNum(Integer merId);
+
+    /**
+     * 撤销退款单
+     * @param refundOrderNo 退款单号
+     */
+    Boolean revoke(String refundOrderNo);
+
+    /**
+     * 退款单审核
+     * @param request 审核参数
+     * @return 审核结果
+     */
+    Boolean audit(OrderRefundAuditRequest request, SystemAdmin systemAdmin);
+
+    /**
+     * 退款单收到退货
+     * @param refundOrderNo 退款单号
+     */
+    Boolean receiving(String refundOrderNo, SystemAdmin systemAdmin);
+
+    /**
+     * 平台强制退款
+     * @param refundOrderNo 退款单号
+     */
+    Boolean compulsoryRefund(String refundOrderNo, SystemAdmin systemAdmin);
+
+    /**
+     * 退款单-商家拒绝收货退款
+     * @param request 拒绝收货请求对象
+     */
+    Boolean receivingReject(RejectReceivingRequest request, SystemAdmin systemAdmin);
+
+    /**
+     * 自动撤销退款
+     */
+    void autoRevoke();
+
+    /**
+     * 查询支付宝退款定时任务
+     */
+    Boolean queryAliPayRefund(String refundOrderNo);
+
+    /**
+     * 订单退款是否包含用户退款
+     * @param orderNo 订单编号
+     */
+    Boolean isOrderContainUserRefund(String orderNo);
+
+    /**
+     * 商户直接退款
+     * @param order 订单
+     * @param orderDetailList 需要退款的订单详情列表
+     */
+    Boolean merchantDirectRefund(SecondHandOrder order, List<SecondHandOrderDetail> orderDetailList);
+
+    /**
+     * 根据第三方单号查询退款单
+     * @param outRefundNo 第三方单号
+     */
+    List<SecondHandRefundOrder> findByOutRefundNo(String outRefundNo);
+}

+ 207 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandRefundOrderService.java

@@ -0,0 +1,207 @@
+package com.zbkj.service.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.model.order.Order;
+import com.zbkj.common.model.order.OrderDetail;
+import com.zbkj.common.model.order.RefundOrder;
+import com.zbkj.common.model.secondhand.SecondHandOrder;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandRefundOrder;
+import com.zbkj.common.request.*;
+import com.zbkj.common.response.*;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+*  RefundOrderService 接口
+*  +----------------------------------------------------------------------
+*  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+*  +----------------------------------------------------------------------
+*  | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+*  +----------------------------------------------------------------------
+*  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+*  +----------------------------------------------------------------------
+*  | Author: CRMEB Team <admin@crmeb.com>
+*  +----------------------------------------------------------------------
+*/
+public interface SecondHandRefundOrderService extends IService<SecondHandRefundOrder> {
+
+    /**
+     * 商户端退款订单分页列表
+     * @param request 查询参数
+     * @return PageInfo
+     */
+    PageInfo<MerchantRefundOrderPageResponse> getMerchantAdminPage(RefundOrderSearchRequest request);
+
+    /**
+     * 获取商户端退款订单各状态数量
+     * @return RefundOrderCountItemResponse
+     */
+    RefundOrderCountItemResponse getMerchantOrderStatusNum(RefundOrderSearchRequest request);
+
+    /**
+     * 备注退款单
+     * @param request 备注参数
+     * @return Boolean
+     */
+    Boolean mark(RefundOrderRemarkRequest request);
+
+    SecondHandRefundOrder getInfoException(String refundOrderNo);
+
+    /**
+     * 移动端退款订单列表
+     * @param request 搜索参数
+     * @return List
+     */
+    PageInfo<RefundOrderResponse> getH5List(OrderAfterSalesSearchRequest request);
+
+    /**
+     * 退款订单详情(移动端)
+     * @param refundOrderNo 退款订单号
+     * @return RefundOrderInfoResponse
+     */
+    RefundOrderInfoResponse getRefundOrderDetailByRefundOrderNo(String refundOrderNo);
+
+    /**
+     * 商户端退款单详情响应对象
+     * @param refundOrderNo 退款单号
+     * @return 退款单详情
+     */
+    RefundOrderAdminDetailResponse getMerchantDetail(String refundOrderNo);
+
+    /**
+     * 平台端退款订单分页列表
+     * @param request 查询参数
+     * @return PageInfo
+     */
+    PageInfo<PlatformRefundOrderPageResponse> getPlatformAdminPage(RefundOrderSearchRequest request);
+
+    /**
+     * 获取平台端退款订单各状态数量
+     * @return RefundOrderCountItemResponse
+     */
+    RefundOrderCountItemResponse getPlatformOrderStatusNum(RefundOrderSearchRequest request);
+
+    /**
+     * 平台备注退款单
+     * @param request 备注参数
+     * @return Boolean
+     */
+    Boolean platformMark(RefundOrderRemarkRequest request);
+
+    /**
+     * 平台端退款订单详情
+     * @param refundOrderNo 退款单号
+     * @return 退款单详情
+     */
+    RefundOrderAdminDetailResponse getPlatformDetail(String refundOrderNo);
+
+    /**
+     * 获取某一天的所有数据
+     * @param merId 商户id,0为所有商户
+     * @param date 日期:年-月-日
+     * @return List
+     */
+    List<SecondHandRefundOrder> findByDate(Integer merId, String date);
+
+    /**
+     * 获取某一月的所有数据
+     * @param merId 商户id,0为所有商户
+     * @param month 日期:年-月
+     * @return List
+     */
+    List<SecondHandRefundOrder> findByMonth(Integer merId, String month);
+
+    /**
+     * 根据日期获取退款订单数量
+     * @param date 日期
+     * @return Integer
+     */
+    Integer getRefundOrderNumByDate(String date);
+
+    /**
+     * 根据日期获取退款订单金额
+     * @param date 日期
+     * @return Integer
+     */
+    BigDecimal getRefundOrderAmountByDate(String date);
+
+    /**
+     * 获取退款中(申请)订单数量
+     */
+    Integer getRefundingCount(Integer userId);
+
+    /**
+     * 获取退款单详情
+     * @param refundOrderNo 退款单号
+     */
+    SecondHandRefundOrder getByRefundOrderNo(String refundOrderNo);
+
+    /**
+     * 待退款订单数量
+     * @return Integer
+     */
+    Integer getAwaitAuditNum(Integer merId);
+
+    /**
+     * 撤销退款单
+     * @param refundOrderNo 退款单号
+     */
+    Boolean revoke(String refundOrderNo);
+
+    /**
+     * 退款单审核
+     * @param request 审核参数
+     * @return 审核结果
+     */
+    Boolean audit(OrderRefundAuditRequest request);
+
+    /**
+     * 退款单收到退货
+     * @param refundOrderNo 退款单号
+     */
+    Boolean receiving(String refundOrderNo);
+
+    /**
+     * 平台强制退款
+     * @param refundOrderNo 退款单号
+     */
+    Boolean compulsoryRefund(String refundOrderNo);
+
+    /**
+     * 退款单-商家拒绝收货退款
+     * @param request 拒绝收货请求对象
+     */
+    Boolean receivingReject(RejectReceivingRequest request);
+
+    /**
+     * 自动撤销退款
+     */
+    void autoRevoke();
+
+    /**
+     * 查询支付宝退款定时任务
+     */
+    Boolean queryAliPayRefund(String refundOrderNo);
+
+    /**
+     * 订单退款是否包含用户退款
+     * @param orderNo 订单编号
+     */
+    Boolean isOrderContainUserRefund(String orderNo);
+
+    /**
+     * 商户直接退款
+     * @param order 订单
+     * @param orderDetailList 需要退款的订单详情列表
+     */
+    Boolean merchantDirectRefund(SecondHandOrder order, List<SecondHandOrderDetail> orderDetailList);
+
+    /**
+     * 根据第三方单号查询退款单
+     * @param outRefundNo 第三方单号
+     */
+    List<SecondHandRefundOrder> findByOutRefundNo(String outRefundNo);
+}

+ 51 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/SecondHandRelationService.java

@@ -0,0 +1,51 @@
+package com.zbkj.service.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.model.community.CommunityNotesRelation;
+import com.zbkj.common.model.secondhand.SecondHandRelation;
+import com.zbkj.common.request.PageParamRequest;
+
+/**
+* CommunityNotesRelation 接口
+* +----------------------------------------------------------------------
+* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+* +----------------------------------------------------------------------
+* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+* +----------------------------------------------------------------------
+* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+* +----------------------------------------------------------------------
+* | Author: CRMEB Team <admin@crmeb.com>
+* +----------------------------------------------------------------------
+*/
+public interface SecondHandRelationService extends IService<SecondHandRelation> {
+
+    /**
+     * 用户是否点赞
+     * @param noteId 笔记ID
+     * @param userId 用户ID
+     * @return 是否点赞
+     */
+    Boolean isLikeByUid(Integer noteId, Integer userId);
+
+    /**
+     * 获取点赞详情
+     * @param noteId 笔记ID
+     * @param userId 用户ID
+     */
+    SecondHandRelation getOneByNoteIdAndUid(Integer noteId, Integer userId);
+
+    /**
+     * 删除社区笔记关联关系
+     */
+    Boolean deleteByNoteId(Integer noteId);
+
+    /**
+     * 获取用户点赞分页列表
+     * @param userId 用户ID
+     * @param request 分页参数
+     */
+    PageInfo<SecondHandRelation> findLikePageByUid(Integer userId, PageParamRequest request);
+
+
+}

+ 15 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/AsyncServiceImpl.java

@@ -134,6 +134,9 @@ public class AsyncServiceImpl implements AsyncService {
     @Lazy
     @Autowired
     private GroupBuyUserService groupBuyUserService;
+    @Lazy
+    @Autowired
+    private SecondHandProdService secondHandProdService;
 
     /**
      * 商品详情统计
@@ -418,6 +421,18 @@ public class AsyncServiceImpl implements AsyncService {
     }
 
     /**
+     * 社区笔记点赞与取消
+     *
+     * @param noteId        笔记ID
+     * @param operationType 操作类型:add-点赞,sub-取消
+     */
+    @Async
+    @Override
+    public void secondHandLikeOrClean(Integer noteId, String operationType) {
+        secondHandProdService.operationLike(noteId, operationType);
+    }
+
+    /**
      * 社区笔记评论点赞与取消
      *
      * @param replyId       评论ID

+ 10 - 8
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/CommunityNotesServiceImpl.java

@@ -329,7 +329,7 @@ public class CommunityNotesServiceImpl extends ServiceImpl<CommunityNotesDao, Co
     private PageInfo<CommunityNotes> findFrontSearchList(CommunityNoteFrontSearchRequest request) {
         Page<CommunityNotes> page = PageHelper.startPage(request.getPage(), request.getLimit());
         LambdaQueryWrapper<CommunityNotes> lqw = Wrappers.lambdaQuery();
-        lqw.select(CommunityNotes::getId, CommunityNotes::getTitle, CommunityNotes::getCover, CommunityNotes::getUid,
+        lqw.select(CommunityNotes::getId, CommunityNotes::getTitle, CommunityNotes::getCover, CommunityNotes::getUid,CommunityNotes::getReplyNum,CommunityNotes::getSchool,
                 CommunityNotes::getType, CommunityNotes::getLikeNum, CommunityNotes::getAuditStatus,CommunityNotes::getCategoryId,CommunityNotes::getContent,CommunityNotes::getCreateTime);
         if (ObjectUtil.isNotNull(request.getCategoryId())) {
             lqw.eq(CommunityNotes::getCategoryId, request.getCategoryId());
@@ -347,12 +347,12 @@ public class CommunityNotesServiceImpl extends ServiceImpl<CommunityNotesDao, Co
         if (ObjectUtil.isNotNull(request.getTopicId())) {
             lqw.apply("FIND_IN_SET({0}, topic_ids)", request.getTopicId());
         }
-        if (ObjectUtil.isNotNull(request.getSecondType())) {
+        if (ObjectUtil.isNotNull(request.getSecondType()) && request.getSecondType()>0) {
              if(request.getSecondType()==1){// 有评论
-                 lqw.lt(CommunityNotes::getReplyNum,0);
+                 lqw.gt(CommunityNotes::getReplyNum,0);
              }
             if(request.getSecondType()==2){// 有点赞
-                lqw.lt(CommunityNotes::getLikeNum,0);
+                lqw.gt(CommunityNotes::getLikeNum,0);
             }
             if(request.getSecondType()==3){// 有图
                 lqw.isNotNull(CommunityNotes::getImage).or().isNotNull(CommunityNotes::getVideo);
@@ -498,10 +498,11 @@ public class CommunityNotesServiceImpl extends ServiceImpl<CommunityNotesDao, Co
     @Override
     public void create(CommunityNoteSaveRequest request) {
         validatorNoteParam(request);
-        Integer userId = userService.getUserIdException();
+        User user=userService.getInfo();
+        //Integer userId = userService.getUserIdException();
         CommunityNotes note = new CommunityNotes();
         BeanUtils.copyProperties(request, note, "id");
-        note.setUid(userId);
+        note.setUid(user.getId());
         note.setCover(systemAttachmentService.clearPrefix(request.getCover()));
         if (CommunityConstants.COMMUNITY_NOTE_TYPE_IMAGE_CONTENT.equals(request.getType())) {
             note.setImage(systemAttachmentService.clearPrefix(request.getImage()));
@@ -509,6 +510,7 @@ public class CommunityNotesServiceImpl extends ServiceImpl<CommunityNotesDao, Co
         if (CommunityConstants.COMMUNITY_NOTE_TYPE_SHORT_VIDEO.equals(request.getType())) {
             note.setVideo(systemAttachmentService.clearPrefix(request.getVideo()));
         }
+        note.setSchool(user.getSchool());
 
         List<CommunityNotesProduct> notesProductList = new ArrayList<>();
         if (StrUtil.isNotBlank(request.getProIds())) {
@@ -516,7 +518,7 @@ public class CommunityNotesServiceImpl extends ServiceImpl<CommunityNotesDao, Co
             proIdList.forEach(pid -> {
                 CommunityNotesProduct notesProduct = new CommunityNotesProduct();
                 notesProduct.setProductId(pid);
-                notesProduct.setIsPay(orderDetailService.isPurchased(pid, userId) ? 1 : 0);
+                notesProduct.setIsPay(orderDetailService.isPurchased(pid, user.getId()) ? 1 : 0);
                 notesProductList.add(notesProduct);
             });
         }
@@ -552,7 +554,7 @@ public class CommunityNotesServiceImpl extends ServiceImpl<CommunityNotesDao, Co
         }
         if (note.getAuditStatus().equals(CommunityConstants.COMMUNITY_NOTE_AUDIT_SUCCESS)) {
             // 异步掉用添加用户经验
-            asyncService.noteUpExp(userId, note.getId());
+            asyncService.noteUpExp(user.getId(), note.getId());
         }
     }
 

+ 3 - 1
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/MerchantServiceImpl.java

@@ -906,6 +906,7 @@ public class MerchantServiceImpl extends ServiceImpl<MerchantDao, Merchant> impl
      */
     @Override
     public PageInfo<MerchantSearchResponse> findSearchList_v1(MerchantMoveSearchRequest request, PageParamRequest pageParamRequest) {
+        PageHelper.clearPage();;
         Page<Merchant> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
         Map<String,Object> params=new HashMap<String,Object>();
         if (StrUtil.isNotBlank(request.getCategoryIds())) {
@@ -1172,7 +1173,7 @@ public class MerchantServiceImpl extends ServiceImpl<MerchantDao, Merchant> impl
         if (ObjectUtil.isNotNull(request.getCateId())) {
             params.put("productType",request.getCateId());
         }
-        params.put("limit",recomdProdsNum);
+        params.put("frontLimit",recomdProdsNum);
         List<MerchantVo> merchantList = dao.selectMerchantList(params);
        // List<MerchantVo>  merchantList= dao.selectMerchantList(siteSearchRequest.getLatitude(),siteSearchRequest.getLongitude(),siteSearchRequest.getCateId(),null,recomdProdsNum);
         //redisUtil.addSet(StrUtil.format(RedisConstants.FRONT_USER_TOKEN_SET_KEY, user.getId()), userTokenKey);
@@ -1190,6 +1191,7 @@ public class MerchantServiceImpl extends ServiceImpl<MerchantDao, Merchant> impl
                 if(ObjectUtil.isNotNull(mer.getDistance()))
                     response.setDeliverTime(DistanceCalculator.distanceToTimeInMinutes(mer.getDistance(), DistanceCalculator.AVERAGE_SPEED));//时间
            // }
+            PageHelper.clearPage();
             //推荐的商品
             response.setProList(productService.getRecommendedProductsByMerId(mer.getId(), 4));
             //店铺可使用的优惠券

+ 155 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/PayCallbackServiceImpl.java

@@ -17,6 +17,9 @@ import com.zbkj.common.model.member.PaidMemberOrder;
 import com.zbkj.common.model.order.Order;
 import com.zbkj.common.model.order.RechargeOrder;
 import com.zbkj.common.model.order.RefundOrder;
+import com.zbkj.common.model.secondhand.SecondHandOrder;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandProd;
 import com.zbkj.common.model.user.User;
 import com.zbkj.common.model.wechat.WechatPayInfo;
 import com.zbkj.common.utils.CrmebDateUtil;
@@ -68,6 +71,12 @@ public class PayCallbackServiceImpl implements PayCallbackService {
     @Autowired
     private ExpressOrderService expressOrderService;
     @Autowired
+    private SecondHandOrderService secondHandOrderService;
+    @Autowired
+    private SecondHandProdService secondHandProdService;
+    @Autowired
+    private SecondHandOrderDetailService secondHandOrderDetailService;
+    @Autowired
     private UserService userService;
     @Autowired
     private RedisUtil redisUtil;
@@ -491,6 +500,152 @@ public class PayCallbackServiceImpl implements PayCallbackService {
         return sb.toString();
     }
 
+    @Override
+    public String wechatSecondhandPayCallback(String xmlInfo) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("<xml>");
+        if (StrUtil.isBlank(xmlInfo)) {
+            sb.append("<return_code><![CDATA[FAIL]]></return_code>");
+            sb.append("<return_msg><![CDATA[xmlInfo is blank]]></return_msg>");
+            sb.append("</xml>");
+            logger.error("wechat callback error : " + sb);
+            return sb.toString();
+        }
+
+        try {
+            HashMap<String, Object> map = WxPayUtil.processResponseXml(xmlInfo);
+            // 通信是否成功
+            String returnCode = (String) map.get("return_code");
+            if (!returnCode.equals(Constants.SUCCESS)) {
+                sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
+                sb.append("<return_msg><![CDATA[OK]]></return_msg>");
+                sb.append("</xml>");
+                logger.error("wechat callback error : wx pay return code is fail returnMsg : " + map.get("return_msg"));
+                return sb.toString();
+            }
+            // 交易是否成功
+            String resultCode = (String) map.get("result_code");
+            if (!resultCode.equals(Constants.SUCCESS)) {
+                sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
+                sb.append("<return_msg><![CDATA[OK]]></return_msg>");
+                sb.append("</xml>");
+                logger.error("wechat callback error : wx pay result code is fail");
+                return sb.toString();
+            }
+
+            //解析xml
+            WechatPayCallbackVo callbackVo = CrmebUtil.mapToObj(map, WechatPayCallbackVo.class);
+            AttachVo attachVo = JSONObject.toJavaObject(JSONObject.parseObject(callbackVo.getAttach()), AttachVo.class);
+
+            //判断openid
+            User user = userService.getById(attachVo.getUserId());
+            if (ObjectUtil.isNull(user)) {
+                //用户信息错误
+                throw new CrmebException("用户信息错误!");
+            }
+
+            //根据类型判断是订单或者充值
+            if (!PayConstants.PAY_SERVICE_TYPE_ORDER.equals(attachVo.getType())) {
+                logger.error("wechat pay err : 未知的支付类型==》" + callbackVo.getOutTradeNo());
+                throw new CrmebException("未知的支付类型!");
+            }
+            // 订单
+            if (PayConstants.PAY_SERVICE_TYPE_ORDER.equals(attachVo.getType())) {
+                SecondHandOrder order = secondHandOrderService.getByOutTradeNo(callbackVo.getOutTradeNo());
+                if (ObjectUtil.isNull(order) || !order.getUid().equals(attachVo.getUserId())) {
+                    logger.error("wechat pay error : 订单信息不存在==》" + callbackVo.getOutTradeNo());
+                    throw new CrmebException("wechat pay error : 订单信息不存在==》" + callbackVo.getOutTradeNo());
+                }
+                if (order.getPaid()) {
+                    sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
+                    sb.append("<return_msg><![CDATA[OK]]></return_msg>");
+                    sb.append("</xml>");
+                    return sb.toString();
+                }
+
+                String signKey = "";
+                String payChannel = order.getPayChannel();
+                if (payChannel.equals(PayConstants.PAY_CHANNEL_H5) || payChannel.equals(PayConstants.PAY_CHANNEL_WECHAT_NATIVE)) {
+                    String source = systemConfigService.getValueByKey(SysConfigConstants.WECHAT_PAY_SOURCE_H5_PC);
+                    if (StrUtil.isNotBlank(source) && source.equals(PayConstants.WECHAT_PAY_SOURCE_MINI)) {
+                        payChannel = PayConstants.PAY_CHANNEL_WECHAT_MINI;
+                    } else {
+                        payChannel = PayConstants.PAY_CHANNEL_WECHAT_PUBLIC;
+                    }
+                }
+                switch (payChannel) {
+                    case PayConstants.PAY_CHANNEL_WECHAT_PUBLIC:
+                        signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_PUBLIC_KEY);
+                        break;
+                    case PayConstants.PAY_CHANNEL_WECHAT_MINI:
+                    case PayConstants.PAY_CHANNEL_WECHAT_MINI_VIDEO:
+                        signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_MINI_KEY);
+                        break;
+                    case PayConstants.PAY_CHANNEL_WECHAT_APP_IOS:
+                    case PayConstants.PAY_CHANNEL_WECHAT_APP_ANDROID:
+                        signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_APP_KEY);
+                        break;
+                }
+                Map<String, String> stringMap = WxPayUtil.xmlToMap(xmlInfo);
+                String sign = WxPayUtil.getSign(stringMap, signKey);
+                if (!sign.equals(stringMap.get(PayConstants.FIELD_SIGN))) {
+                    logger.error("wechat pay error : 微信订单回调验签失败 ==> {}", xmlInfo);
+                    throw new CrmebException(StrUtil.format("wechat pay error : 微信订单回调验签失败 ==> {}", xmlInfo));
+                }
+
+                WechatPayInfo wechatPayInfo = wechatPayInfoService.getByNo(order.getOutTradeNo());
+                if (ObjectUtil.isNull(wechatPayInfo)) {
+                    logger.error("wechat pay error : 微信订单信息不存在==》" + callbackVo.getOutTradeNo());
+                    throw new CrmebException("wechat pay error : 微信订单信息不存在==》" + callbackVo.getOutTradeNo());
+                }
+                wechatPayInfo.setIsSubscribe(callbackVo.getIsSubscribe());
+                wechatPayInfo.setBankType(callbackVo.getBankType());
+                wechatPayInfo.setCashFee(callbackVo.getCashFee());
+                wechatPayInfo.setCouponFee(callbackVo.getCouponFee());
+                wechatPayInfo.setTransactionId(callbackVo.getTransactionId());
+                wechatPayInfo.setTimeEnd(callbackVo.getTimeEnd());
+                List<SecondHandOrderDetail> orderDetailList= secondHandOrderDetailService.getByOrderNo(order.getOrderNo());
+                // 添加支付成功redis队列
+                Boolean execute = transactionTemplate.execute(e -> {
+                    order.setPaid(true);
+                    order.setPayTime(CrmebDateUtil.nowDateTime());
+                    order.setStatus(OrderConstants.ORDER_STATUS_WAIT_SHIPPING);
+                    secondHandOrderService.updateById(order);
+                    wechatPayInfoService.updateById(wechatPayInfo);
+                    if(orderDetailList!=null && orderDetailList.size()>0) {
+                        SecondHandProd   secondHandProd = secondHandProdService.getById(orderDetailList.get(0).getProductId());
+                        if(ObjectUtil.isNotNull(secondHandProd)){
+                            if(order.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP)) {
+                                secondHandProd.setSaleStatus(1);//已售
+                            }
+                            else {
+                                secondHandProd.setSaleStatus(2);//已售,待发货
+                            }
+                            secondHandProdService.updateById(secondHandProd);
+                        }
+                    }
+                    return Boolean.TRUE;
+                });
+                if (!execute) {
+                    logger.error("wechat pay error : 订单更新失败==》" + callbackVo.getOutTradeNo());
+                    sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
+                    sb.append("<return_msg><![CDATA[OK]]></return_msg>");
+                    sb.append("</xml>");
+                    return sb.toString();
+                }
+                redisUtil.lPush(TaskConstants.ORDER_TASK_PAY_SUCCESS_AFTER, order.getOrderNo());
+            }
+            sb.append("<return_code><![CDATA[SUCCESS]]></return_code>");
+            sb.append("<return_msg><![CDATA[OK]]></return_msg>");
+        } catch (Exception e) {
+            sb.append("<return_code><![CDATA[FAIL]]></return_code>");
+            sb.append("<return_msg><![CDATA[").append(e.getMessage()).append("]]></return_msg>");
+            logger.error("wechat pay error : 业务异常==》" + e.getMessage());
+        }
+        sb.append("</xml>");
+        return sb.toString();
+    }
+
     /**
      * 支付宝支付回调
      */

+ 216 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandCategoryServiceImpl.java

@@ -0,0 +1,216 @@
+package com.zbkj.service.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.URLUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.constants.Constants;
+import com.zbkj.common.exception.CrmebException;
+import com.zbkj.common.model.community.CommunityCategory;
+import com.zbkj.common.model.secondhand.SecondHandCategory;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.CommunityCategorySaveRequest;
+import com.zbkj.common.request.CommunityCategorySearchRequest;
+import com.zbkj.common.result.CommonResultCode;
+import com.zbkj.common.result.CommunityResultCode;
+import com.zbkj.service.dao.community.CommunityCategoryDao;
+import com.zbkj.service.dao.secondhand.SecondHandCategoryDao;
+import com.zbkj.service.service.CommunityCategoryService;
+import com.zbkj.service.service.CommunityNotesService;
+import com.zbkj.service.service.SecondHandCategoryService;
+import com.zbkj.service.service.SystemAttachmentService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * CommunityCategory 接口实现
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Service
+public class SecondHandCategoryServiceImpl extends ServiceImpl<SecondHandCategoryDao, SecondHandCategory> implements SecondHandCategoryService {
+
+    @Resource
+    private SecondHandCategoryDao dao;
+
+    @Autowired
+    private CommunityNotesService notesService;
+
+    @Autowired
+    private SystemAttachmentService systemAttachmentService;
+
+    /**
+     * 社区分类分页列表
+     *
+     * @param request 请求参数
+     * @return 分页列表
+     */
+    @Override
+    public PageInfo<SecondHandCategory> findPageList(CommunityCategorySearchRequest request) {
+        Page<SecondHandCategory> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        LambdaQueryWrapper<SecondHandCategory> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandCategory::getId, SecondHandCategory::getName, SecondHandCategory::getSort,
+                SecondHandCategory::getIsShow, SecondHandCategory::getCreateTime,SecondHandCategory::getIcon);
+        if (StrUtil.isNotBlank(request.getName())) {
+            lqw.like(SecondHandCategory::getName, URLUtil.decode(request.getName()));
+        }
+        if (ObjectUtil.isNotNull(request.getIsShow())) {
+            lqw.eq(SecondHandCategory::getIsShow, request.getIsShow());
+        }
+        lqw.eq(SecondHandCategory::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        lqw.orderByDesc(SecondHandCategory::getSort, SecondHandCategory::getId);
+        List<SecondHandCategory> list = dao.selectList(lqw);
+//        list.stream().forEach(communityCategory->{
+//            communityCategory.setIcon(systemAttachmentService.clearPrefix(communityCategory.getIcon()));
+//        });
+        return CommonPage.copyPageInfo(page, list);
+    }
+
+    /**
+     * 保存社区分类
+     *
+     * @param request 请求参数
+     */
+    @Override
+    public void add(CommunityCategorySaveRequest request) {
+        if (isExistName(request.getName(), 0)) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_CATEGORY_EXIST);
+        }
+        SecondHandCategory category = new SecondHandCategory();
+        BeanUtils.copyProperties(request, category, "id");
+        category.setIcon(systemAttachmentService.clearPrefix(request.getIcon()));
+        boolean save = save(category);
+        if (!save) {
+            throw new CrmebException("添加二手交易分类失败");
+        }
+    }
+
+    /**
+     * 编辑社区分类
+     *
+     * @param request 请求参数
+     */
+    @Override
+    public void edit(CommunityCategorySaveRequest request) {
+        if (ObjectUtil.isNull(request.getId())) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_CATEGORY_ID_NULL);
+        }
+        SecondHandCategory category = getByIdExpetion(request.getId());
+
+        if (!category.getName().equals(request.getName()) && isExistName(request.getName(), request.getId())) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_CATEGORY_EXIST);
+        }
+        BeanUtils.copyProperties(request, category);
+        category.setIcon(systemAttachmentService.clearPrefix(request.getIcon()));
+        boolean update = updateById(category);
+        if (!update) {
+            throw new CrmebException(CommonResultCode.ERROR.setMessage("编辑二手交易分类失败"));
+        }
+    }
+
+    /**
+     * 删除社区分类
+     * @param id 分类ID
+     */
+    @Override
+    public void deleteById(Integer id) {
+        SecondHandCategory category = getByIdExpetion(id);
+
+        if (notesService.isUseCategory(id)) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_CATEGORY_USING);
+        }
+        category.setIsDel(Constants.COMMON_IS_FILED_ONE);
+        boolean update = updateById(category);
+        if (!update) {
+            throw new CrmebException(CommonResultCode.ERROR.setMessage("二手交易分类失败"));
+        }
+    }
+
+    /**
+     * 获取分类Map
+     * @param cateIdList 分类ID列表
+     * @return Map<id,name>
+     */
+    @Override
+    public Map<Integer, String> getMapInIdList(List<Integer> cateIdList) {
+        LambdaQueryWrapper<SecondHandCategory> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandCategory::getId, SecondHandCategory::getName);
+        lqw.in(SecondHandCategory::getId, cateIdList);
+        lqw.eq(SecondHandCategory::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        List<SecondHandCategory> list = dao.selectList(lqw);
+        Map<Integer, String> map = CollUtil.newHashMap();
+        list.forEach(e -> {
+            map.put(e.getId(), e.getName());
+        });
+        return map;
+    }
+
+    /**
+     * 社区分类显示开关
+     * @param id 分类ID
+     */
+    @Override
+    public void showSwitch(Integer id) {
+        SecondHandCategory category = getByIdExpetion(id);
+        category.setIsShow(category.getIsShow().equals(Constants.COMMON_IS_FILED_ONE) ? Constants.COMMON_IS_FILED_ZERO : Constants.COMMON_IS_FILED_ONE);
+        boolean update = updateById(category);
+        if (!update) {
+            throw new CrmebException("编辑二手交易分显示状态失败");
+        }
+    }
+
+    /**
+     * 根据显示状态获取全部分类列表
+     */
+    @Override
+    public List<SecondHandCategory> findListByShow(Integer isShow) {
+        LambdaQueryWrapper<SecondHandCategory> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandCategory::getId, SecondHandCategory::getName,SecondHandCategory::getIcon);
+        if (ObjectUtil.isNotNull(isShow)) {
+            lqw.eq(SecondHandCategory::getIsShow, isShow);
+        }
+        lqw.eq(SecondHandCategory::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        lqw.orderByDesc(SecondHandCategory::getSort, SecondHandCategory::getId);
+        return dao.selectList(lqw);
+    }
+
+    private boolean isExistName(String name, Integer id) {
+        LambdaQueryWrapper<SecondHandCategory> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandCategory::getId);
+        lqw.eq(SecondHandCategory::getName, name);
+        lqw.eq(SecondHandCategory::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        if (ObjectUtil.isNotNull(id) && id > 0) {
+            lqw.ne(SecondHandCategory::getId, id);
+        }
+        lqw.last("limit 1");
+        SecondHandCategory communityCategory = dao.selectOne(lqw);
+        return ObjectUtil.isNotNull(communityCategory);
+    }
+
+    private SecondHandCategory getByIdExpetion(Integer id) {
+        SecondHandCategory category = getById(id);
+        if (ObjectUtil.isNull(category) || category.getIsDel().equals(Constants.COMMON_IS_FILED_ONE)) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_CATEGORY_NOT_EXIST);
+        }
+        return category;
+    }
+}
+

+ 115 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandOrderDetailService.java

@@ -0,0 +1,115 @@
+package com.zbkj.service.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.model.order.OrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import com.zbkj.common.request.CommonSearchRequest;
+import com.zbkj.common.request.PageParamRequest;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+/**
+*  OrderDetailService 接口
+*  +----------------------------------------------------------------------
+*  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+*  +----------------------------------------------------------------------
+*  | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+*  +----------------------------------------------------------------------
+*  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+*  +----------------------------------------------------------------------
+*  | Author: CRMEB Team <admin@crmeb.com>
+*  +----------------------------------------------------------------------
+*/
+public interface SecondHandOrderDetailService extends IService<SecondHandOrderDetail> {
+
+    /**
+     * 根据主订单号获取
+     * @param orderNo 订单编号
+     * @return List
+     */
+    List<SecondHandOrderDetail> getByOrderNo(String orderNo);
+
+    /**
+     * 订单商品评论列表
+     * @param userId 用户id
+     * @param isReply 是否评价
+     * @param pageRequest 分页参数
+     * @return PageInfo
+     */
+    PageInfo<SecondHandOrderDetail> getReplyList(Integer userId, Boolean isReply, PageParamRequest pageRequest);
+
+    /**
+     * 订单收货
+     * @param orderNo 订单号
+     */
+    Boolean takeDelivery(String orderNo);
+
+    /**
+     * 售后申请列表(可申请售后列表)
+     * @param request 分页参数
+     * @return PageInfo
+     */
+    PageInfo<SecondHandOrderDetail> findAfterSaleApplyList(Integer uid, CommonSearchRequest request);
+
+    /**
+     * 根据时间、商品id获取销售件数
+     * @param date 时间,格式'yyyy-MM-dd'
+     * @param proId 商品id
+     * @return Integer
+     */
+    Integer getSalesNumByDateAndProductId(String date, Integer proId);
+
+    /**
+     * 根据时间、商品id获取销售额
+     * @param date 时间,格式'yyyy-MM-dd'
+     * @param proId 商品id
+     * @return BigDecimal
+     */
+    BigDecimal getSalesByDateAndProductId(String date, Integer proId);
+
+    /**
+     * 订单发货获取订单详情列表
+     * @param orderNo 订单号
+     * @return 订单详情列表
+     */
+    List<SecondHandOrderDetail> getShipmentByOrderNo(String orderNo);
+
+    /**
+     * 获取待评价数量
+     * @return 待评价数量
+     */
+    Integer getAwaitReplyCount(Integer userId);
+
+    /**
+     * 是否已购买(已收货后才算已购)
+     */
+    Boolean isPurchased(Integer proId, Integer userId);
+
+    /**
+     * 获取已购商品列表
+     * @param pageParamRequest 分页参数
+     * @return PageInfo
+     */
+    PageInfo<SecondHandOrderDetail> findPurchasedList(Integer userId, PageParamRequest pageParamRequest);
+
+    /**
+     * 通过订单号获取订单商品详情Map
+     * @param orderNoList 订单号列表
+     */
+    Map<String, List<SecondHandOrderDetail>> getMapByOrderNoList(List<String> orderNoList);
+
+    Integer getByGroupBuyActivityId(Integer groupBuyActivityId, Integer productId, Integer uid);
+
+    Integer getOrderRefundNum(String orderNo);
+
+    /**
+     * 根据产品id获取订单信息
+     * @param sellerId
+     * @param productId
+     * @return
+     */
+    List<SecondHandOrderDetail> findList(Integer sellerId,Integer productId);
+}

+ 257 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandOrderDetailServiceImpl.java

@@ -0,0 +1,257 @@
+package com.zbkj.service.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.URLUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.constants.OrderConstants;
+import com.zbkj.common.model.order.Order;
+import com.zbkj.common.model.order.OrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandOrder;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.CommonSearchRequest;
+import com.zbkj.common.request.PageParamRequest;
+import com.zbkj.service.dao.OrderDetailDao;
+import com.zbkj.service.dao.SecondHandOrderDetailDao;
+import com.zbkj.service.service.OrderDetailService;
+import com.zbkj.service.service.OrderService;
+import com.zbkj.service.service.SecondHandOrderService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+*  OrderDetailServiceImpl 接口实现
+*  +----------------------------------------------------------------------
+*  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+*  +----------------------------------------------------------------------
+*  | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+*  +----------------------------------------------------------------------
+*  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+*  +----------------------------------------------------------------------
+*  | Author: CRMEB Team <admin@crmeb.com>
+*  +----------------------------------------------------------------------
+*/
+@Service
+public class SecondHandOrderDetailServiceImpl extends ServiceImpl<SecondHandOrderDetailDao, SecondHandOrderDetail> implements SecondHandOrderDetailService {
+
+    @Resource
+    private SecondHandOrderDetailDao dao;
+    @Autowired
+    private SecondHandOrderService orderService;
+
+    /**
+     * 根据主订单号获取
+     * @param orderNo 订单编号
+     * @return List
+     */
+    @Override
+    public List<SecondHandOrderDetail> getByOrderNo(String orderNo) {
+        LambdaQueryWrapper<SecondHandOrderDetail> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandOrderDetail::getOrderNo, orderNo);
+        return dao.selectList(lqw);
+    }
+
+    /**
+     * 订单商品评论列表
+     * @param userId 用户id
+     * @param isReply 是否评价
+     * @param pageRequest 分页参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondHandOrderDetail> getReplyList(Integer userId, Boolean isReply, PageParamRequest pageRequest) {
+        Page<SecondHandOrderDetail> page = PageHelper.startPage(pageRequest.getPage(), pageRequest.getLimit());
+        List<SecondHandOrderDetail> orderDetailList = dao.findReplyList(userId, isReply ? 1 : 0);
+        return CommonPage.copyPageInfo(page, orderDetailList);
+    }
+
+    /**
+     * 订单收货
+     * @param orderNo 订单号
+     */
+    @Override
+    public Boolean takeDelivery(String orderNo) {
+        LambdaUpdateWrapper<SecondHandOrderDetail> wrapper = Wrappers.lambdaUpdate();
+        wrapper.set(SecondHandOrderDetail::getIsReceipt, true);
+        wrapper.eq(SecondHandOrderDetail::getOrderNo, orderNo);
+        return update(wrapper);
+    }
+
+    /**
+     * 售后申请列表(可申请售后列表)
+     * @param request 分页参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondHandOrderDetail> findAfterSaleApplyList(Integer uid, CommonSearchRequest request) {
+        Page<SecondHandOrderDetail> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        String keywords = StrUtil.isNotBlank(request.getKeywords()) ? URLUtil.decode(request.getKeywords()) : "";
+        List<SecondHandOrderDetail> orderDetailList = dao.findAfterSaleApplyList(uid, keywords);
+        return CommonPage.copyPageInfo(page, orderDetailList);
+    }
+
+    /**
+     * 根据时间、商品id获取销售件数
+     * @param date 时间,格式'yyyy-MM-dd'
+     * @param proId 商品id
+     * @return Integer
+     */
+    @Override
+    public Integer getSalesNumByDateAndProductId(String date, Integer proId) {
+        return dao.getSalesNumByDateAndProductId(date, proId);
+    }
+
+    /**
+     * 根据时间、商品id获取销售额
+     * @param date 时间,格式'yyyy-MM-dd'
+     * @param proId 商品id
+     * @return BigDecimal
+     */
+    @Override
+    public BigDecimal getSalesByDateAndProductId(String date, Integer proId) {
+        return dao.getSalesByDateAndProductId(date, proId);
+    }
+
+    /**
+     * 订单发货获取订单详情列表
+     * @param orderNo 订单号
+     * @return 订单详情列表
+     */
+    @Override
+    public List<SecondHandOrderDetail> getShipmentByOrderNo(String orderNo) {
+        LambdaQueryWrapper<SecondHandOrderDetail> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandOrderDetail::getId, SecondHandOrderDetail::getProductName, SecondHandOrderDetail::getImage,
+                SecondHandOrderDetail::getPayNum, SecondHandOrderDetail::getDeliveryNum, SecondHandOrderDetail::getRefundNum, SecondHandOrderDetail::getPrice,
+                SecondHandOrderDetail::getPayPrice, SecondHandOrderDetail::getRefundPrice, SecondHandOrderDetail::getApplyRefundNum);
+        lqw.eq(SecondHandOrderDetail::getOrderNo, orderNo);
+        return dao.selectList(lqw);
+    }
+
+    /**
+     * 获取待评价数量
+     * @return 待评价数量
+     */
+    @Override
+    public Integer getAwaitReplyCount(Integer userId) {
+        return dao.getAwaitReplyCount(userId);
+    }
+
+    /**
+     * 是否已购买(已收货后才算已购)
+     */
+    @Override
+    public Boolean isPurchased(Integer proId, Integer userId) {
+        LambdaQueryWrapper<SecondHandOrderDetail> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandOrderDetail::getId);
+        lqw.eq(SecondHandOrderDetail::getProductId, proId);
+        lqw.eq(SecondHandOrderDetail::getUid, userId);
+        lqw.eq(SecondHandOrderDetail::getIsReceipt, 1);
+        lqw.last("limit 1");
+        SecondHandOrderDetail orderDetail = dao.selectOne(lqw);
+        return ObjectUtil.isNotNull(orderDetail) ? Boolean.TRUE : Boolean.FALSE;
+    }
+
+    /**
+     * 获取已购商品列表
+     * @param pageParamRequest 分页参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondHandOrderDetail> findPurchasedList(Integer userId, PageParamRequest pageParamRequest) {
+        Page<SecondHandOrderDetail> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
+        LambdaQueryWrapper<SecondHandOrderDetail> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandOrderDetail::getId, SecondHandOrderDetail::getProductId);
+        lqw.eq(SecondHandOrderDetail::getUid, userId);
+        //lqw.gt(SecondHandOrderDetail::getMerId, 0);
+        lqw.eq(SecondHandOrderDetail::getIsReceipt, 1);
+        lqw.in(SecondHandOrderDetail::getProductType, 0,2,5,6);
+        lqw.groupBy(SecondHandOrderDetail::getProductId);
+        lqw.orderByDesc(SecondHandOrderDetail::getId);
+        List<SecondHandOrderDetail> detailList = dao.selectList(lqw);
+        return CommonPage.copyPageInfo(page, detailList);
+    }
+    @Override
+    public List<SecondHandOrderDetail> findList(Integer sellerId,Integer productId) {
+        LambdaQueryWrapper<SecondHandOrderDetail> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandOrderDetail::getSellerId, sellerId);
+        lqw.eq(SecondHandOrderDetail::getProductId, productId);
+        lqw.in(SecondHandOrderDetail::getProductType, 0,2,5,6);
+        lqw.groupBy(SecondHandOrderDetail::getProductId);
+        lqw.orderByDesc(SecondHandOrderDetail::getId);
+        return dao.selectList(lqw);
+    }
+    /**
+     * 通过订单号获取订单商品详情Map
+     * @param orderNoList 订单号列表
+     */
+    @Override
+    public Map<String, List<SecondHandOrderDetail>> getMapByOrderNoList(List<String> orderNoList) {
+        if (CollUtil.isEmpty(orderNoList)) {
+            return new HashMap<>();
+        }
+        LambdaQueryWrapper<SecondHandOrderDetail> lqw = Wrappers.lambdaQuery();
+        lqw.in(SecondHandOrderDetail::getOrderNo, orderNoList);
+        List<SecondHandOrderDetail> detailList = dao.selectList(lqw);
+        if (CollUtil.isEmpty(detailList)) {
+            return new HashMap<>();
+        }
+        return detailList.stream().collect(Collectors.groupingBy(SecondHandOrderDetail::getOrderNo));
+    }
+
+    /**
+     * @param groupBuyActivityId
+     * @return
+     */
+    @Override
+    public Integer getByGroupBuyActivityId(Integer groupBuyActivityId, Integer productId, Integer uid) {
+        Integer waitPayNum = 0;
+        LambdaQueryWrapper<SecondHandOrderDetail> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandOrderDetail::getProductId, productId);
+        lqw.eq(SecondHandOrderDetail::getUid, uid);
+//        lqw.eq(OrderDetail::getAttrValueId, skuId);
+//        lqw.last("limit 1");
+        List<SecondHandOrderDetail> orderDetailList = dao.selectList(lqw);
+        if(!orderDetailList.isEmpty()){
+            for (SecondHandOrderDetail orderDetail : orderDetailList) {
+                SecondHandOrder o = orderService.getByOrderNo(orderDetail.getOrderNo());
+                // 待支付的订单 !o.getPaid() ||
+                if(o.getStatus().equals(OrderConstants.ORDER_STATUS_WAIT_PAY)){
+                    waitPayNum += orderDetail.getPayNum();
+                }
+            }
+            return waitPayNum;
+        }
+
+
+
+        return waitPayNum;
+    }
+
+    @Override
+    public Integer getOrderRefundNum(String orderNo) {
+        LambdaQueryWrapper<SecondHandOrderDetail> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandOrderDetail::getRefundNum);
+        lqw.eq(SecondHandOrderDetail::getOrderNo, orderNo);
+        List<SecondHandOrderDetail> orderDetailList = dao.selectList(lqw);
+        if (CollUtil.isEmpty(orderDetailList)) {
+            return 0;
+        }
+        return orderDetailList.stream().mapToInt(SecondHandOrderDetail::getRefundNum).sum();
+    }
+}
+

+ 512 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandOrderServiceImpl.java

@@ -0,0 +1,512 @@
+package com.zbkj.service.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.URLUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.config.CrmebConfig;
+import com.zbkj.common.constants.*;
+import com.zbkj.common.exception.CrmebException;
+import com.zbkj.common.model.admin.SystemAdmin;
+import com.zbkj.common.model.express.Express;
+import com.zbkj.common.model.merchant.Merchant;
+import com.zbkj.common.model.order.*;
+import com.zbkj.common.model.secondhand.SecondHandOrder;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandProd;
+import com.zbkj.common.model.system.SystemNotification;
+import com.zbkj.common.model.user.User;
+import com.zbkj.common.model.user.UserToken;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.*;
+import com.zbkj.common.request.secondhand.SecondHandOrderSendRequest;
+import com.zbkj.common.response.*;
+import com.zbkj.common.response.onepass.ElectrResponse;
+import com.zbkj.common.result.CommonResultCode;
+import com.zbkj.common.result.OrderResultCode;
+import com.zbkj.common.utils.CrmebDateUtil;
+import com.zbkj.common.utils.CrmebUtil;
+import com.zbkj.common.utils.RedisUtil;
+import com.zbkj.common.utils.ValidateFormUtil;
+import com.zbkj.common.vo.DateLimitUtilVo;
+import com.zbkj.common.vo.LogisticsResultVo;
+import com.zbkj.common.vo.MyRecord;
+import com.zbkj.service.dao.OrderDao;
+import com.zbkj.service.dao.secondhand.SecondHandOrderDao;
+import com.zbkj.service.service.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * OrderServiceImpl 接口实现
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Service
+public class SecondHandOrderServiceImpl extends ServiceImpl<SecondHandOrderDao, SecondHandOrder> implements SecondHandOrderService {
+    private static final Logger logger = LoggerFactory.getLogger(SecondHandOrderServiceImpl.class);
+    @Resource
+    private SecondHandOrderDao dao;
+
+    @Autowired
+    private MerchantOrderService merchantOrderService;
+    @Autowired
+    private UserService userService;
+    @Autowired
+    private SecondHandOrderDetailService orderDetailService;
+    @Autowired
+    private SecondHandProdService secondHandProdService;
+    @Autowired
+    private RefundOrderService refundOrderService;
+    @Autowired
+    private CrmebConfig crmebConfig;
+
+    @Autowired
+    private TransactionTemplate transactionTemplate;
+
+    @Autowired
+    private OrderInvoiceService orderInvoiceService;
+
+    /**
+     * 根据订单编号获取订单
+     *
+     * @param orderNo 订单编号
+     */
+    @Override
+    public SecondHandOrder getByOrderNo(String orderNo) {
+        PageHelper.clearPage();
+        LambdaQueryWrapper<SecondHandOrder> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandOrder::getOrderNo, orderNo);
+        lqw.last(" limit 1");
+        SecondHandOrder order = dao.selectOne(lqw);
+        if (ObjectUtil.isNull(order)) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST);
+        }
+        return order;
+    }
+
+    @Override
+    public Boolean updatePaid(String orderNo) {
+        LambdaUpdateWrapper<SecondHandOrder> lqw = new LambdaUpdateWrapper<>();
+        lqw.set(SecondHandOrder::getPaid, true);
+        lqw.set(SecondHandOrder::getPayTime, DateUtil.date());
+        lqw.set(SecondHandOrder::getStatus, OrderConstants.ORDER_STATUS_WAIT_SHIPPING);
+        lqw.eq(SecondHandOrder::getOrderNo, orderNo);
+        lqw.eq(SecondHandOrder::getPaid, false);
+        return update(lqw);
+    }
+
+    /**
+     * 获取订单
+     *
+     * @param outTradeNo 商户系统内部的订单号
+     */
+    @Override
+    public SecondHandOrder getByOutTradeNo(String outTradeNo) {
+        LambdaQueryWrapper<SecondHandOrder> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandOrder::getOutTradeNo, outTradeNo);
+        lqw.last(" limit 1");
+        SecondHandOrder order = dao.selectOne(lqw);
+        if (ObjectUtil.isNull(order)) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST);
+        }
+        return order;
+    }
+
+    /**
+     * 获取用户订单列表V1.4
+     *
+     * @param userId  用户id
+     * @param request 搜索参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondHandOrder> getUserOrderList_v1_4(Integer userId, OrderFrontListRequest request) {
+        Page<SecondHandOrder> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        if (StrUtil.isBlank(request.getKeywords())) {
+            LambdaQueryWrapper<SecondHandOrder> lqw = Wrappers.lambdaQuery();
+            lqw.eq(SecondHandOrder::getUid, userId);
+            if (request.getStatus() >= 0) {
+                if (request.getStatus() == 1) {
+                    lqw.in(SecondHandOrder::getStatus, OrderConstants.ORDER_STATUS_WAIT_SHIPPING, OrderConstants.ORDER_STATUS_PART_SHIPPING);
+                } else if(request.getStatus() == 3) {
+                    lqw.eq(SecondHandOrder::getStatus, 3);
+                } else {
+                    lqw.eq(SecondHandOrder::getStatus, request.getStatus());
+//                    lqw.eq(Order::getGroupBuyRecordStatus, 0);
+                }
+                lqw.lt(SecondHandOrder::getRefundStatus, OrderConstants.ORDER_REFUND_STATUS_REFUND);
+            }
+            lqw.eq(SecondHandOrder::getIsUserDel, false);
+            lqw.eq(SecondHandOrder::getIsDel, false);
+
+            lqw.orderByDesc(SecondHandOrder::getId);
+            List<SecondHandOrder> orderList = dao.selectList(lqw);
+            return CommonPage.copyPageInfo(page, orderList);
+        }
+        Map<String, Object> searchMap = new HashMap<>();
+        String keywords = URLUtil.decode(request.getKeywords());
+        searchMap.put("keywords", keywords);
+        searchMap.put("status", request.getStatus());
+        searchMap.put("userId", userId);
+        List<SecondHandOrder> orderList = dao.findFrontList(searchMap);
+        return CommonPage.copyPageInfo(page, orderList);
+    }
+
+
+    /**
+     * 获取用户订单列表V1.6
+     *
+     * @param request 搜索参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondHandOrder> getUserOrderList_v1_6(OrderFrontListRequest request) {
+        Page<SecondHandOrder> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        if (StrUtil.isBlank(request.getKeywords())) {
+            LambdaQueryWrapper<SecondHandOrder> lqw = Wrappers.lambdaQuery();
+            if (request.getStatus() >= 0) {
+                if (request.getStatus() == 1) {
+                    lqw.in(SecondHandOrder::getStatus, OrderConstants.ORDER_STATUS_WAIT_SHIPPING);
+                } else if(request.getStatus() == 3) {
+                    lqw.eq(SecondHandOrder::getStatus, 3);
+                } else {
+                    lqw.eq(SecondHandOrder::getStatus, request.getStatus());
+                }
+                lqw.in(SecondHandOrder::getStatus, OrderConstants.ORDER_STATUS_WAIT_SHIPPING);
+                lqw.lt(SecondHandOrder::getRefundStatus, OrderConstants.ORDER_REFUND_STATUS_REFUND);
+            }
+            lqw.eq(SecondHandOrder::getIsUserDel, false);
+            lqw.eq(SecondHandOrder::getIsDel, false);
+            lqw.orderByDesc(SecondHandOrder::getId);
+            List<SecondHandOrder> orderList = dao.selectList(lqw);
+            return CommonPage.copyPageInfo(page, orderList);
+        }
+        Map<String, Object> searchMap = new HashMap<>();
+        String keywords = URLUtil.decode(request.getKeywords());
+        searchMap.put("keywords", keywords);
+        searchMap.put("status", request.getStatus());
+        List<SecondHandOrder> orderList = dao.findFrontList(searchMap);
+        return CommonPage.copyPageInfo(page, orderList);
+    }
+    /**
+     * 取消订单
+     *
+     * @param orderNo 订单编号
+     * @param isUser  是否用户取消
+     * @return Boolean
+     */
+    @Override
+    public Boolean cancel(String orderNo, Boolean isUser) {
+        LambdaUpdateWrapper<SecondHandOrder> wrapper = Wrappers.lambdaUpdate();
+        wrapper.set(SecondHandOrder::getCancelStatus, isUser ? OrderConstants.ORDER_CANCEL_STATUS_USER : OrderConstants.ORDER_CANCEL_STATUS_SYSTEM);
+        wrapper.set(SecondHandOrder::getStatus, OrderConstants.ORDER_STATUS_CANCEL);
+        wrapper.eq(SecondHandOrder::getOrderNo, orderNo);
+        wrapper.eq(SecondHandOrder::getPaid, false);
+        wrapper.eq(SecondHandOrder::getStatus, OrderConstants.ORDER_STATUS_WAIT_PAY);
+        return update(wrapper);
+    }
+
+    /**
+     * 商户端后台分页列表
+     *
+     * @param request 查询参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<MerchantOrderPageResponse> getMerchantAdminPage(OrderSearchRequest request, SystemAdmin systemAdmin) {
+        Page<SecondHandOrder> startPage = PageHelper.startPage(request.getPage(), request.getLimit());
+        Map<String, Object> map = CollUtil.newHashMap();
+        map.put("status", request.getStatus());
+        if (StrUtil.isNotBlank(request.getContent())) {
+            ValidateFormUtil.validatorUserCommonSearch(request);
+            String keywords = URLUtil.decode(request.getContent());
+            switch (request.getSearchType()) {
+                case UserConstants.USER_SEARCH_TYPE_ALL:
+                    map.put("keywords", keywords);
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_UID:
+                    map.put("uid", Integer.valueOf(request.getContent()));
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_NICKNAME:
+                    map.put("nickname", keywords);
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_PHONE:
+                    map.put("phone", request.getContent());
+                    break;
+            }
+        }
+        //时间范围
+        if (StrUtil.isNotBlank(request.getDateLimit())) {
+            DateLimitUtilVo dateLimit = CrmebDateUtil.getDateLimit(request.getDateLimit());
+            //判断时间
+            int compareDateResult = CrmebDateUtil.compareDate(dateLimit.getEndTime(), dateLimit.getStartTime(), DateConstants.DATE_FORMAT);
+            if (compareDateResult == -1) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "开始时间不能大于结束时间!");
+            }
+            if (StrUtil.isNotBlank(dateLimit.getStartTime())) {
+                map.put("startTime", dateLimit.getStartTime());
+                map.put("endTime", dateLimit.getEndTime());
+            }
+        }
+        map.put("merId", systemAdmin.getMerId());
+        if (StrUtil.isNotBlank(request.getOrderNo())) {
+            map.put("orderNo", URLUtil.decode(request.getOrderNo()));
+        }
+        if (ObjectUtil.isNotNull(request.getType())) {
+            map.put("type", request.getType());
+        }
+        List<MerchantOrderPageResponse> responseList = dao.getMerchantAdminPage(map);
+        if (CollUtil.isEmpty(responseList)) {
+            return CommonPage.copyPageInfo(startPage, CollUtil.newArrayList());
+        }
+        responseList.forEach(response -> {
+            if (response.getRefundStatus() > 0) {
+                response.setUserRefundSign(refundOrderService.isOrderContainUserRefund(response.getOrderNo()));
+                if (response.getRefundStatus().equals(2)) {
+                    response.setRefundNum(orderDetailService.getOrderRefundNum(response.getOrderNo()));
+                }
+            }
+            List<OrderInfoFrontDataResponse> infoResponseList = CollUtil.newArrayList();
+            List<SecondHandOrderDetail> orderDetailList = orderDetailService.getByOrderNo(response.getOrderNo());
+            orderDetailList.forEach(od -> {
+                OrderInfoFrontDataResponse orderInfoResponse = new OrderInfoFrontDataResponse();
+                BeanUtils.copyProperties(od, orderInfoResponse);
+                infoResponseList.add(orderInfoResponse);
+            });
+            response.setInfoResponseList(infoResponseList);
+        });
+        return CommonPage.copyPageInfo(startPage, responseList);
+    }
+
+
+
+    /**
+     * 订单详情(PC)
+     *
+     * @param orderNo 订单编号
+     * @return OrderAdminDetailResponse
+     */
+    @Override
+    public OrderAdminDetailResponse adminDetail(String orderNo, SystemAdmin systemAdmin) {
+        SecondHandOrder order = getByOrderNo(orderNo);
+        if (order.getIsSellerDel()) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST);
+        }
+        OrderAdminDetailResponse orderAdminDetailResponse = new OrderAdminDetailResponse();
+        MerchantOrder merchantOrder = merchantOrderService.getOneByOrderNo(orderNo);
+        BeanUtils.copyProperties(merchantOrder, orderAdminDetailResponse);
+        BeanUtils.copyProperties(order, orderAdminDetailResponse);
+        List<SecondHandOrderDetail> orderDetailList = orderDetailService.getByOrderNo(orderNo);
+        List<OrderInfoFrontDataResponse> orderInfoList = orderDetailList.stream().map(e -> {
+            OrderInfoFrontDataResponse dataResponse = new OrderInfoFrontDataResponse();
+            BeanUtils.copyProperties(e, dataResponse);
+            return dataResponse;
+        }).collect(Collectors.toList());
+        orderAdminDetailResponse.setOrderDetailList(orderInfoList);
+
+        if (order.getRefundStatus() > 0) {
+            orderAdminDetailResponse.setUserRefundSign(refundOrderService.isOrderContainUserRefund(order.getOrderNo()));
+        }
+        // 用户信息
+        User user = userService.getById(order.getUid());
+        orderAdminDetailResponse.setNickname(user.getNickname());
+        orderAdminDetailResponse.setPhone(user.getPhone());
+        orderAdminDetailResponse.setIsLogoff(user.getIsLogoff());
+        orderAdminDetailResponse.setAvatar(user.getAvatar());
+        orderAdminDetailResponse.setUserLevel(user.getLevel());
+        orderAdminDetailResponse.setIsPaidMember(user.getIsPaidMember());
+//        if (merchantOrder.getClerkId() > 0) {
+//            SystemAdmin clerkAdmin = systemAdminService.getById(merchantOrder.getClerkId());
+//            // 这里做一个溶于判断 当管理员中不存在的情况下 那么查询用户id 要么管理员核销,要么移动端商户管理员核销
+//            if (ObjectUtil.isNull(clerkAdmin)) {
+//                clerkAdmin = userService.getSystemAdminByMerchantEmployee();
+//            }
+//            orderAdminDetailResponse.setClerkName(clerkAdmin.getRealName());
+//        }
+        if (crmebConfig.getPhoneMaskSwitch()) {
+            orderAdminDetailResponse.setPhone(CrmebUtil.maskMobile(orderAdminDetailResponse.getPhone()));
+            if (StrUtil.isNotBlank(orderAdminDetailResponse.getUserPhone())) {
+                orderAdminDetailResponse.setUserPhone(CrmebUtil.maskMobile(orderAdminDetailResponse.getUserPhone()));
+            }
+        }
+        return orderAdminDetailResponse;
+    }
+
+    /**
+     * 获取订单数量(订单状态, 用户id)
+     *
+     * @param status 订单状态(0:待支付,1:待发货,2:部分发货, 3:待核销,4:待收货,5:已收货,6:已完成,9:已取消)
+     * @param userId 用户ID
+     * @return 订单数量
+     */
+    @Override
+    public Integer getCountByStatusAndUid(Integer status, Integer userId) {
+        if (status < 0) {
+            return 0;
+        }
+        LambdaQueryWrapper<SecondHandOrder> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandOrder::getUid, userId);
+        lqw.eq(SecondHandOrder::getIsDel, false);
+        if (OrderConstants.ORDER_STATUS_WAIT_SHIPPING.equals(status)) {
+            lqw.in(SecondHandOrder::getStatus, OrderConstants.ORDER_STATUS_WAIT_SHIPPING, OrderConstants.ORDER_STATUS_PART_SHIPPING);
+
+        } else if (OrderConstants.ORDER_STATUS_AWAIT_VERIFICATION.equals(status)) {
+            lqw.eq(SecondHandOrder::getStatus, OrderConstants.ORDER_STATUS_AWAIT_VERIFICATION);
+        } else  {
+            lqw.eq(SecondHandOrder::getStatus, status);
+        }
+        lqw.eq(SecondHandOrder::getIsUserDel, false);
+        lqw.eq(SecondHandOrder::getIsSellerDel, false);
+        lqw.eq(SecondHandOrder::getIsDel, false);
+        lqw.ne(SecondHandOrder::getRefundStatus, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND);
+        return dao.selectCount(lqw);
+    }
+
+    /**
+     * 订单收货
+     *
+     * @param orderNo 订单号
+     */
+    @Override
+    public Boolean takeDelivery(String orderNo) {
+        SecondHandOrder order =getByOrderNo(orderNo);
+        LambdaUpdateWrapper<SecondHandOrder> wrapper = Wrappers.lambdaUpdate();
+        wrapper.set(SecondHandOrder::getStatus, OrderConstants.ORDER_STATUS_COMPLETE);
+        wrapper.set(SecondHandOrder::getReceivingTime, DateUtil.date());
+        wrapper.eq(SecondHandOrder::getOrderNo, orderNo);
+        if(order.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP)){
+            wrapper.eq(SecondHandOrder::getStatus, OrderConstants.ORDER_STATUS_WAIT_SHIPPING);
+        }else {
+            wrapper.eq(SecondHandOrder::getStatus, OrderConstants.ORDER_STATUS_WAIT_RECEIPT);
+        }
+        return update(wrapper);
+    }
+
+    @Override
+    public Boolean send(SecondHandOrderSendRequest request) {
+        validateOrderSend(request);
+        Integer userId=userService.getUserId();
+        SecondHandOrder order = getByOrderNo(request.getOrderNo());
+        if (!order.getSellerId().equals(userId)) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST);
+        }
+        if (order.getIsUserDel() || order.getIsSellerDel()) {
+            throw new CrmebException(OrderResultCode.ORDER_DELETE);
+        }
+        if (!(order.getStatus().equals(OrderConstants.ORDER_STATUS_WAIT_SHIPPING)
+                || order.getStatus().equals(OrderConstants.ORDER_STATUS_PART_SHIPPING))) {
+            throw new CrmebException(OrderResultCode.ORDER_STATUS_ABNORMAL.setMessage("订单不处于待发货状态"));
+        }
+        if (order.getRefundStatus().equals(OrderConstants.ORDER_REFUND_STATUS_ALL)) {
+            throw new CrmebException(OrderResultCode.ORDER_REFUND_ED);
+        }
+        if (!(order.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_EXPRESS))) {
+            throw new CrmebException(OrderResultCode.ORDER_SHIPPING_TYPE_PICK_UP);
+        }
+        if (order.getRefundStatus().equals(OrderConstants.ORDER_REFUND_STATUS_APPLY)) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "请先处理售后,再进行发货操作");
+        }
+        return sendExpress(request, order);
+    }
+
+    @Override
+    public Boolean refundApply(OrderRefundApplyRequest request) {
+        return null;
+    }
+
+    /**
+     * 快递发货
+     *
+     * @param request       发货参数
+     * @param order         订单信息
+     */
+    private Boolean sendExpress(SecondHandOrderSendRequest request, SecondHandOrder order) {
+        //快递公司信息
+        if (ObjectUtil.isNull(request.getExpressCompy())) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "未找到快递公司");
+        }
+        // 筛选需要发货的订单详情
+        List<SecondHandOrderDetail> orderDetailList = orderDetailService.getByOrderNo(order.getOrderNo());
+        List<OrderInvoiceDetail> orderInvoiceDetailList = new ArrayList<>();
+        orderDetailList.forEach(od -> {
+            if (od.getPayNum() > od.getDeliveryNum()) {
+                OrderInvoiceDetail invoiceDetail = new OrderInvoiceDetail();
+                BeanUtils.copyProperties(od, invoiceDetail);
+                invoiceDetail.setNum(od.getPayNum() - od.getDeliveryNum());
+                invoiceDetail.setCreateTime(DateUtil.date());
+                invoiceDetail.setUpdateTime(DateUtil.date());
+                orderInvoiceDetailList.add(invoiceDetail);
+                od.setDeliveryNum(od.getPayNum());
+            }
+        });
+        if (CollUtil.isEmpty(orderInvoiceDetailList)) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "订单没有需要发货的商品");
+        }
+        // 生成发货单
+        OrderInvoice invoice = new OrderInvoice();
+        invoice.setMerId(order.getSellerId());
+        invoice.setOrderNo(order.getOrderNo());
+        invoice.setTrackingNumber(request.getExpressNumber());
+        invoice.setUid(order.getUid());
+        invoice.setExpressRecordType("1");//快递发送
+        invoice.setExpressName(request.getExpressCompy());
+        invoice.setDeliveryMark(request.getDeliveryMark());
+        invoice.setTotalNum(orderInvoiceDetailList.stream().mapToInt(OrderInvoiceDetail::getNum).sum());
+        order.setStatus(OrderConstants.ORDER_STATUS_WAIT_RECEIPT);
+        SecondHandProd secondHandProd=secondHandProdService.getById(orderDetailList.get(0).getProductId());
+        secondHandProd.setSaleStatus(3);//待收货
+        Boolean execute = transactionTemplate.execute(i -> {
+            updateById(order);
+            secondHandProdService.updateById(secondHandProd);
+            orderInvoiceService.save(invoice);
+            return Boolean.TRUE;
+        });
+
+        if (!execute) throw new CrmebException("快递发货失败!");
+        return execute;
+    }
+    /**
+     * 校验快递发货参数
+     *
+     * @param request 发货参数
+     */
+    private void validateOrderSend(SecondHandOrderSendRequest request) {
+        if (request.getDeliveryType().equals(OrderConstants.ORDER_DELIVERY_TYPE_EXPRESS)) {
+            if (StrUtil.isBlank(request.getExpressNumber()))
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "请填写快递单号");
+            if (StrUtil.isBlank(request.getExpressCompy()))
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "请选择快递公司");
+        }
+
+    }
+}
+

+ 505 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandPayServiceImpl.java

@@ -0,0 +1,505 @@
+package com.zbkj.service.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.zbkj.common.config.CrmebConfig;
+import com.zbkj.common.constants.*;
+import com.zbkj.common.exception.CrmebException;
+import com.zbkj.common.model.express.ExpressOrder;
+import com.zbkj.common.model.secondhand.SecondHandOrder;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandProd;
+import com.zbkj.common.model.user.User;
+import com.zbkj.common.model.user.UserBalanceRecord;
+import com.zbkj.common.model.user.UserToken;
+import com.zbkj.common.model.wechat.WechatPayInfo;
+import com.zbkj.common.request.OrderPayRequest;
+import com.zbkj.common.request.WechatPaymentQueryRequest;
+import com.zbkj.common.response.OrderPayResultResponse;
+import com.zbkj.common.result.CommonResultCode;
+import com.zbkj.common.result.OrderResultCode;
+import com.zbkj.common.result.UserResultCode;
+import com.zbkj.common.utils.*;
+import com.zbkj.common.vo.*;
+import com.zbkj.service.ExpressOrderService;
+import com.zbkj.service.service.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * PayServiceImpl 接口实现
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Service
+public class SecondHandPayServiceImpl implements SecondHandPayService {
+
+    private static final Logger logger = LoggerFactory.getLogger(SecondHandPayServiceImpl.class);
+
+    @Autowired
+    private SystemConfigService systemConfigService;
+
+    @Autowired
+    private UserService userService;
+    @Autowired
+    private TransactionTemplate transactionTemplate;
+    @Autowired
+    private UserTokenService userTokenService;
+    @Autowired
+    private WechatService wechatService;
+    @Autowired
+    private WechatPayInfoService wechatPayInfoService;
+
+    @Autowired
+    private UserBalanceRecordService userBalanceRecordService;
+
+    @Autowired
+    private CrmebConfig crmebConfig;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    @Autowired
+    private SecondHandOrderService orderService;
+    @Autowired
+    private SecondHandProdService secondHandProdService;
+    @Autowired
+    private SecondHandOrderDetailService secondHandOrderDetailService;
+    /**
+     * 订单支付
+     *
+     * @param orderPayRequest 订单支付参数
+     * @return OrderPayResultResponse
+     */
+    @Override
+    public OrderPayResultResponse payment(OrderPayRequest orderPayRequest) {
+        SecondHandOrder order = orderService.getByOrderNo(orderPayRequest.getOrderNo());
+        if (order.getCancelStatus() > OrderConstants.ORDER_CANCEL_STATUS_NORMAL) {
+            throw new CrmebException(OrderResultCode.ORDER_CANCEL);
+        }
+        if (order.getPaid()) {
+            throw new CrmebException(OrderResultCode.ORDER_PAID);
+        }
+        if (order.getStatus() > OrderConstants.ORDER_STATUS_WAIT_PAY) {
+            throw new CrmebException(OrderResultCode.ORDER_STATUS_ABNORMAL);
+        }
+        User user = userService.getInfo();
+        // 根据支付类型进行校验,更换支付类型
+        order.setPayType(orderPayRequest.getPayType());
+        order.setPayChannel(orderPayRequest.getPayChannel());
+        // 获取过期时间 增加redis缓存的判断 2025-02-12
+        DateTime cancelTime;
+        if (redisUtil.exists(redisUtil.get(StrUtil.format(RedisConstants.ORDER_EXPIRE_TIME, order.getOrderNo())))) {
+            String expireTime = redisUtil.get(StrUtil.format(RedisConstants.ORDER_EXPIRE_TIME, order.getOrderNo()));
+            cancelTime = DateUtil.parseDateTime(expireTime);
+        } else {
+            cancelTime = DateUtil.offset(order.getCreateTime(), DateField.MINUTE, crmebConfig.getOrderCancelTime());
+        }
+        long between = DateUtil.between(cancelTime, DateUtil.date(), DateUnit.SECOND, false);
+        if (between > 0) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "订单已过期");
+        }
+
+        // 余额支付
+        if (orderPayRequest.getPayType().equals(PayConstants.PAY_TYPE_YUE)) {
+            if (user.getNowMoney().compareTo(order.getPayPrice()) < 0) {
+                throw new CrmebException(UserResultCode.USER_BALANCE_INSUFFICIENT);
+            }
+        }
+
+        OrderPayResultResponse response = new OrderPayResultResponse();
+        response.setOrderNo(order.getOrderNo());
+        response.setPayType(order.getPayType());
+        response.setPayChannel(order.getPayChannel());
+        if (order.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "支付金额不能低于等于0元");
+        }
+
+        // 余额支付
+        if (order.getPayType().equals(PayConstants.PAY_TYPE_YUE) || order.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
+            Boolean yueBoolean = yuePay(order, user);
+            response.setStatus(yueBoolean);
+            return response;
+        }
+        // 微信支付,调用微信预下单,返回拉起微信支付需要的信息
+        if (order.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) {
+            WxPayJsResultVo vo = wechatPayment(order);
+            orderService.updateById(order);
+            response.setStatus(true);
+            response.setJsConfig(vo);
+            return response;
+        }
+        response.setStatus(false);
+        return response;
+    }
+
+    /**
+     * 查询支付结果
+     *
+     * @param orderNo 订单编号
+     */
+    @Override
+    public Boolean queryWechatPayResult(String orderNo) {
+        SecondHandOrder order = orderService.getByOrderNo(orderNo);
+        if (ObjectUtil.isNull(order)) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST);
+        }
+        if (order.getCancelStatus() > OrderConstants.ORDER_CANCEL_STATUS_NORMAL) {
+            throw new CrmebException(OrderResultCode.ORDER_CANCEL);
+        }
+        if (!order.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT)) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "不是微信支付类型订单");
+        }
+        if (order.getPaid()) {
+            return Boolean.TRUE;
+        }
+        WechatPayInfo wechatPayInfo = wechatPayInfoService.getByNo(order.getOutTradeNo());
+        if (ObjectUtil.isNull(wechatPayInfo)) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "未找到对应微信订单");
+        }
+        Map<String, String> payVo = getWechatQueryPayVo(order.getOutTradeNo(), order.getPayChannel());
+        MyRecord myRecord = wechatService.payOrderQuery(payVo);
+        if (myRecord.getInt("payStatus") < 1) {
+            return Boolean.FALSE;
+        }
+        List<SecondHandOrderDetail> orderDetailList= secondHandOrderDetailService.getByOrderNo(order.getOrderNo());
+        wechatPayInfo.setIsSubscribe(myRecord.getStr("is_subscribe"));
+        wechatPayInfo.setTradeState(myRecord.getStr("trade_state"));
+        wechatPayInfo.setBankType(myRecord.getStr("bank_type"));
+        wechatPayInfo.setCashFee(myRecord.getInt("cash_fee"));
+        wechatPayInfo.setCouponFee(myRecord.getInt("coupon_fee"));
+        wechatPayInfo.setTransactionId(myRecord.getStr("transaction_id"));
+        wechatPayInfo.setTimeEnd(myRecord.getStr("time_end"));
+        wechatPayInfo.setTradeStateDesc(myRecord.getStr("trade_state_desc"));
+        Boolean updatePaid = transactionTemplate.execute(e -> {
+            orderService.updatePaid(orderNo);
+            wechatPayInfoService.updateById(wechatPayInfo);
+            if(orderDetailList!=null && orderDetailList.size()>0) {
+                SecondHandProd secondHandProd = secondHandProdService.getById(orderDetailList.get(0).getProductId());
+                if(ObjectUtil.isNotNull(secondHandProd)){
+                    if(order.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP)) {
+                        secondHandProd.setSaleStatus(1);//已售
+                    }
+                    else {
+                        secondHandProd.setSaleStatus(2);//已售,待发货
+                    }
+                    secondHandProdService.updateById(secondHandProd);
+                }
+            }
+            return Boolean.TRUE;
+        });
+        if (!updatePaid) {
+            throw new CrmebException("支付成功更新订单失败");
+        }
+        // 添加支付成功task
+        redisUtil.lPush(TaskConstants.ORDER_TASK_PAY_SUCCESS_AFTER, orderNo);
+        return Boolean.TRUE;
+    }
+
+
+    /**
+     * 查询微信支付结果
+     */
+    @Override
+    public Boolean queryWechatPaymentResult(WechatPaymentQueryRequest request) {
+        if (request.getOrderType().equals(PayConstants.PAY_SERVICE_TYPE_ORDER)) {
+            return queryWechatPayResult(request.getOrderNo());
+        }
+        throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "不是微信支付类型订单");
+    }
+    private Map<String, String> getWechatQueryPayVo(String outTradeNo, String payChannel) {
+        // 获取appid、mch_id
+        // 微信签名key
+        String appId = "";
+        String mchId = "";
+        String signKey = "";
+        String tempPayChannel = payChannel;
+        if (tempPayChannel.equals(PayConstants.PAY_CHANNEL_H5) || tempPayChannel.equals(PayConstants.PAY_CHANNEL_WECHAT_NATIVE)) {
+            String source = systemConfigService.getValueByKey(SysConfigConstants.WECHAT_PAY_SOURCE_H5_PC);
+            if (StrUtil.isNotBlank(source) && source.equals(PayConstants.WECHAT_PAY_SOURCE_MINI)) {
+                tempPayChannel = PayConstants.PAY_CHANNEL_WECHAT_MINI;
+            } else {
+                tempPayChannel = PayConstants.PAY_CHANNEL_WECHAT_PUBLIC;
+            }
+        }
+        switch (tempPayChannel) {
+            case PayConstants.PAY_CHANNEL_WECHAT_PUBLIC:
+                appId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PUBLIC_APPID);
+                mchId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_PUBLIC_MCHID);
+                signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_PUBLIC_KEY);
+                break;
+            case PayConstants.PAY_CHANNEL_WECHAT_MINI:
+            case PayConstants.PAY_CHANNEL_WECHAT_MINI_VIDEO:
+                appId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_MINI_APPID);
+                mchId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_MINI_MCHID);
+                signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_MINI_KEY);
+                break;
+            case PayConstants.PAY_CHANNEL_WECHAT_APP_IOS:
+            case PayConstants.PAY_CHANNEL_WECHAT_APP_ANDROID:
+                appId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_APP_APPID);
+                mchId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_APP_MCHID);
+                signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_APP_KEY);
+                break;
+        }
+
+        // 生成查询订单对象
+        Map<String, String> map = CollUtil.newHashMap();
+        map.put("appid", appId);
+        map.put("mch_id", mchId);
+        map.put("out_trade_no", outTradeNo);
+        map.put("nonce_str", WxPayUtil.getNonceStr());
+        map.put("sign_type", PayConstants.WX_PAY_SIGN_TYPE_MD5);
+        map.put("sign", WxPayUtil.getSign(map, signKey));
+        return map;
+    }
+
+    /**
+     * 微信支付
+     *
+     * @param order 订单
+     * @return WxPayJsResultVo
+     */
+    private WxPayJsResultVo wechatPayment(SecondHandOrder order) {
+        // 预下单
+        Map<String, String> unifiedorder = unifiedorder(order);
+        WxPayJsResultVo vo = new WxPayJsResultVo();
+        vo.setAppId(unifiedorder.get("appId"));
+        vo.setNonceStr(unifiedorder.get("nonceStr"));
+        vo.setPackages(unifiedorder.get("package"));
+        vo.setSignType(unifiedorder.get("signType"));
+        vo.setTimeStamp(unifiedorder.get("timeStamp"));
+        vo.setPaySign(unifiedorder.get("paySign"));
+        if (order.getPayChannel().equals(PayConstants.PAY_CHANNEL_H5)) {
+            vo.setMwebUrl(unifiedorder.get("mweb_url"));
+        }
+        if (order.getPayChannel().equals(PayConstants.PAY_CHANNEL_WECHAT_APP_IOS) ||
+                order.getPayChannel().equals(PayConstants.PAY_CHANNEL_WECHAT_APP_ANDROID)) {// App
+            vo.setPartnerid(unifiedorder.get("partnerid"));
+        }
+        if (order.getPayChannel().equals(PayConstants.PAY_CHANNEL_WECHAT_NATIVE)) {
+            vo.setMwebUrl(unifiedorder.get("code_url"));
+        }
+        // 更新商户订单号
+        order.setOutTradeNo(unifiedorder.get("outTradeNo"));
+        return vo;
+    }
+
+    /**
+     * 余额支付
+     *
+     * @param order 订单
+     * @return Boolean Boolean
+     */
+    private Boolean yuePay(SecondHandOrder order, User user) {
+        // 用户余额扣除
+        Boolean execute = transactionTemplate.execute(e -> {
+            Boolean update = Boolean.TRUE;
+            // 订单修改
+            order.setPaid(true);
+            order.setPayTime(DateUtil.date());
+            order.setStatus(OrderConstants.ORDER_STATUS_WAIT_SHIPPING);
+            order.setPayType(PayConstants.PAY_TYPE_YUE);
+            order.setPayChannel(PayConstants.PAY_CHANNEL_YUE);
+            orderService.updateById(order);
+            // 这里只扣除金额,账单记录在task中处理
+            if (order.getPayPrice().compareTo(BigDecimal.ZERO) > 0) {
+                update = userService.updateNowMoney(order.getUid(), order.getPayPrice(), Constants.OPERATION_TYPE_SUBTRACT);
+                if (!update) {
+                    logger.error("余额支付,扣除用户余额失败,orderNo = {}", order.getOrderNo());
+                    e.setRollbackOnly();
+                    return update;
+                }
+                // 用户余额记录
+                UserBalanceRecord userBalanceRecord = new UserBalanceRecord();
+                userBalanceRecord.setUid(user.getId());
+                userBalanceRecord.setLinkId(order.getOrderNo());
+                userBalanceRecord.setLinkType(BalanceRecordConstants.BALANCE_RECORD_LINK_TYPE_ORDER);
+                userBalanceRecord.setType(BalanceRecordConstants.BALANCE_RECORD_TYPE_SUB);
+                userBalanceRecord.setAmount(order.getPayPrice());
+                userBalanceRecord.setBalance(user.getNowMoney().subtract(order.getPayPrice()));
+                userBalanceRecord.setRemark(StrUtil.format(BalanceRecordConstants.BALANCE_RECORD_REMARK_ORDER, order.getPayPrice()));
+                userBalanceRecordService.save(userBalanceRecord);
+            }
+            return update;
+        });
+        if (!execute) throw new CrmebException("余额支付订单失败");
+        return true;
+    }
+
+    /**
+     * 预下单
+     *
+     * @param order 订单
+     * @return 预下单返回对象
+     */
+    private Map<String, String> unifiedorder(SecondHandOrder order) {
+        // 获取用户openId
+        // 根据订单支付类型来判断获取公众号openId还是小程序openId
+        UserToken userToken = new UserToken();
+        userToken.setToken("");
+        if (order.getPayChannel().equals(PayConstants.PAY_CHANNEL_WECHAT_PUBLIC)) {// 公众号
+            userToken = userTokenService.getTokenByUserId(order.getUid(), UserConstants.USER_TOKEN_TYPE_WECHAT);
+        }
+        if (order.getPayChannel().equals(PayConstants.PAY_CHANNEL_WECHAT_MINI)
+                || order.getPayChannel().equals(PayConstants.PAY_CHANNEL_WECHAT_MINI_VIDEO)) {// 小程序
+            userToken = userTokenService.getTokenByUserId(order.getUid(), UserConstants.USER_TOKEN_TYPE_ROUTINE);
+        }
+
+        // 获取appid、mch_id、微信签名key
+        String appId = "";
+        String mchId = "";
+        String signKey = "";
+        // 从config表中获取H5/PC支付使用的是公众号还是小程序的
+        String payChannel = order.getPayChannel();
+        if (payChannel.equals(PayConstants.PAY_CHANNEL_H5) || payChannel.equals(PayConstants.PAY_CHANNEL_WECHAT_NATIVE)) {
+            String source = systemConfigService.getValueByKey(SysConfigConstants.WECHAT_PAY_SOURCE_H5_PC);
+            if (StrUtil.isNotBlank(source) && source.equals(PayConstants.WECHAT_PAY_SOURCE_MINI)) {
+                payChannel = PayConstants.PAY_CHANNEL_WECHAT_MINI;
+            } else {
+                payChannel = PayConstants.PAY_CHANNEL_WECHAT_PUBLIC;
+            }
+        }
+        switch (payChannel) {
+            case PayConstants.PAY_CHANNEL_WECHAT_PUBLIC:
+                appId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PUBLIC_APPID);
+                mchId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_PUBLIC_MCHID);
+                signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_PUBLIC_KEY);
+                break;
+            case PayConstants.PAY_CHANNEL_WECHAT_MINI:
+            case PayConstants.PAY_CHANNEL_WECHAT_MINI_VIDEO:
+                appId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_MINI_APPID);
+                mchId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_MINI_MCHID);
+                signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_MINI_KEY);
+                break;
+            case PayConstants.PAY_CHANNEL_WECHAT_APP_IOS:
+            case PayConstants.PAY_CHANNEL_WECHAT_APP_ANDROID:
+                appId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_APP_APPID);
+                mchId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_APP_MCHID);
+                signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_APP_KEY);
+                break;
+        }
+        // 获取微信预下单对象
+        CreateOrderRequestVo unifiedorderVo = getUnifiedorderVo(order, userToken.getToken(), appId, mchId, signKey);
+
+        // 预下单(统一下单)
+        CreateOrderResponseVo responseVo = wechatService.payUnifiedorder(unifiedorderVo);
+        // 组装前端预下单参数
+        Map<String, String> map = new HashMap<>();
+        map.put("appId", unifiedorderVo.getAppid());
+        map.put("nonceStr", unifiedorderVo.getAppid());
+        map.put("package", "prepay_id=".concat(responseVo.getPrepayId()));
+        map.put("signType", unifiedorderVo.getSign_type());
+        Long currentTimestamp = WxPayUtil.getCurrentTimestamp();
+        map.put("timeStamp", Long.toString(currentTimestamp));
+        String paySign = WxPayUtil.getSign(map, signKey);
+        map.put("paySign", paySign);
+        map.put("prepayId", responseVo.getPrepayId());
+        map.put("prepayTime", CrmebDateUtil.nowDateTimeStr());
+        map.put("outTradeNo", unifiedorderVo.getOut_trade_no());
+        if (order.getPayChannel().equals(PayConstants.PAY_CHANNEL_H5)) {
+            map.put("mweb_url", responseVo.getMWebUrl());
+        }
+        if (order.getPayChannel().equals(PayConstants.PAY_CHANNEL_WECHAT_APP_IOS) ||
+                order.getPayChannel().equals(PayConstants.PAY_CHANNEL_WECHAT_APP_ANDROID)) {// App
+            map.put("partnerid", mchId);
+            map.put("package", responseVo.getPrepayId());
+            Map<String, Object> appMap = new HashMap<>();
+            appMap.put("appid", unifiedorderVo.getAppid());
+            appMap.put("partnerid", mchId);
+            appMap.put("prepayid", responseVo.getPrepayId());
+            appMap.put("package", "Sign=WXPay");
+            appMap.put("noncestr", unifiedorderVo.getAppid());
+            appMap.put("timestamp", currentTimestamp);
+            String sign = WxPayUtil.getSignObject(appMap, signKey);
+            map.put("paySign", sign);
+        }
+        if (order.getPayChannel().equals(PayConstants.PAY_CHANNEL_WECHAT_NATIVE)) {
+            map.put("code_url", responseVo.getCodeUrl());
+        }
+        return map;
+    }
+
+    /**
+     * 获取微信预下单对象
+     *
+     * @return 微信预下单对象
+     */
+    private CreateOrderRequestVo getUnifiedorderVo(SecondHandOrder order, String openid, String appId, String mchId, String signKey) {
+        // 获取域名
+        String domain = systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_KEY_SITE_URL);
+        String apiDomain = systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_KEY_API_URL);
+
+        AttachVo attachVo = new AttachVo(PayConstants.PAY_SERVICE_TYPE_ORDER, order.getUid());
+
+        CreateOrderRequestVo vo = new CreateOrderRequestVo();
+        vo.setAppid(appId);
+        vo.setMch_id(mchId);
+        vo.setNonce_str(WxPayUtil.getNonceStr());
+        vo.setSign_type(PayConstants.WX_PAY_SIGN_TYPE_MD5);
+        String siteName = systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_KEY_SITE_NAME);
+        // 因商品名称在微信侧超长更换为网站名称
+        vo.setBody(siteName);
+        vo.setAttach(JSONObject.toJSONString(attachVo));
+        vo.setOut_trade_no(CrmebUtil.getOrderNo(OrderConstants.ORDER_PREFIX_WECHAT));
+        // 订单中使用的是BigDecimal,这里要转为Integer类型
+        vo.setTotal_fee(order.getPayPrice().multiply(BigDecimal.TEN).multiply(BigDecimal.TEN).intValue());
+        vo.setSpbill_create_ip(RequestUtil.getClientIp());
+        vo.setNotify_url(apiDomain + PayConstants.WX_SECONDHAND_PAY_NOTIFY_API_URI);
+        switch (order.getPayChannel()) {
+            case PayConstants.PAY_CHANNEL_H5:
+                vo.setTrade_type(PayConstants.WX_PAY_TRADE_TYPE_H5);
+                vo.setOpenid(null);
+                break;
+            case PayConstants.PAY_CHANNEL_WECHAT_APP_IOS:
+            case PayConstants.PAY_CHANNEL_WECHAT_APP_ANDROID:
+                vo.setTrade_type(PayConstants.WX_PAY_TRADE_TYPE_APP);
+                vo.setOpenid(null);
+                break;
+            case PayConstants.PAY_CHANNEL_WECHAT_NATIVE:
+                vo.setTrade_type(PayConstants.WX_PAY_TRADE_TYPE_NATIVE);
+                vo.setProduct_id(order.getOrderNo());
+                vo.setOpenid(null);
+                break;
+            default:
+                vo.setTrade_type(PayConstants.WX_PAY_TRADE_TYPE_JS);
+                vo.setOpenid(openid);
+        }
+        CreateOrderH5SceneInfoVo createOrderH5SceneInfoVo = new CreateOrderH5SceneInfoVo(
+                new CreateOrderH5SceneInfoDetailVo(
+                        domain,
+                        systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_KEY_SITE_NAME)
+                )
+        );
+        vo.setScene_info(JSONObject.toJSONString(createOrderH5SceneInfoVo));
+
+        vo.setTime_start(DateUtil.date().toString(DateConstants.DATE_TIME_FORMAT_NUM));
+        DateTime cancelTime = DateUtil.offset(order.getCreateTime(), DateField.MINUTE, crmebConfig.getOrderCancelTime());
+        String cancelStr = cancelTime.toString(DateConstants.DATE_TIME_FORMAT_NUM);
+        vo.setTime_expire(cancelStr);
+        String sign = WxPayUtil.getSign(vo, signKey);
+        vo.setSign(sign);
+        return vo;
+    }
+}
+

+ 156 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandProdConcernedServiceImpl.java

@@ -0,0 +1,156 @@
+package com.zbkj.service.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.exception.CrmebException;
+import com.zbkj.common.model.community.CommunityAuthorConcerned;
+import com.zbkj.common.model.secondhand.SecondHandProd;
+import com.zbkj.common.model.secondhand.SecondHandProdConcerned;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.PageParamRequest;
+import com.zbkj.common.result.CommonResultCode;
+import com.zbkj.service.dao.community.CommunityAuthorConcernedDao;
+import com.zbkj.service.dao.secondhand.SecondHandProdConcernedDao;
+import com.zbkj.service.service.CommunityAuthorConcernedService;
+import com.zbkj.service.service.SecondHandProdConcernedService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+* CommunityAuthorConcerned 接口实现
+* +----------------------------------------------------------------------
+* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+* +----------------------------------------------------------------------
+* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+* +----------------------------------------------------------------------
+* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+* +----------------------------------------------------------------------
+* | Author: CRMEB Team <admin@crmeb.com>
+* +----------------------------------------------------------------------
+*/
+@Service
+public class SecondHandProdConcernedServiceImpl extends ServiceImpl<SecondHandProdConcernedDao, SecondHandProdConcerned> implements SecondHandProdConcernedService {
+
+    @Resource
+    private SecondHandProdConcernedDao dao;
+
+    /**
+     * 获取关注的作者ID列表
+     * @param userId 用户ID
+     */
+    @Override
+    public List<Integer> findProdIdList(Integer userId) {
+        LambdaQueryWrapper<SecondHandProdConcerned> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandProdConcerned::getSecondHandId);
+        lqw.eq(SecondHandProdConcerned::getUid, userId);
+        List<SecondHandProdConcerned> list = dao.selectList(lqw);
+        if (CollUtil.isEmpty(list)) {
+            return new ArrayList<>();
+        }
+        return list.stream().map(SecondHandProdConcerned::getSecondHandId).collect(Collectors.toList());
+    }
+
+    /**
+     * 是否关注作者
+     * @param prodId 作者ID
+     * @param userId 用户ID
+     */
+    @Override
+    public Boolean isConcernedByUid(Integer prodId, Integer userId) {
+        LambdaQueryWrapper<SecondHandProdConcerned> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandProdConcerned::getId);
+        lqw.eq(SecondHandProdConcerned::getSecondHandId, prodId);
+        lqw.eq(SecondHandProdConcerned::getUid, userId);
+        SecondHandProdConcerned concerned = dao.selectOne(lqw);
+        return ObjectUtil.isNotNull(concerned) ? Boolean.TRUE : Boolean.FALSE;
+    }
+
+    /**
+     * 获取作者被关注数(粉丝数)
+     * @param prodId 作者ID
+     */
+    @Override
+    public Integer getCountByProdId(Integer prodId) {
+        LambdaQueryWrapper<SecondHandProdConcerned> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandProdConcerned::getId);
+        lqw.eq(SecondHandProdConcerned::getSecondHandId, prodId);
+        return dao.selectCount(lqw);
+    }
+
+    /**
+     * 获取用户关注数
+     * @param userId 用户ID
+     */
+    @Override
+    public Integer getCountByUserId(Integer userId) {
+        LambdaQueryWrapper<SecondHandProdConcerned> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandProdConcerned::getId);
+        lqw.eq(SecondHandProdConcerned::getUid, userId);
+        return dao.selectCount(lqw);
+    }
+
+    /**
+     * 获取关注关系列表
+     * @param prodId 作者ID
+     * @param userId 用户ID
+     * @param request 分页参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondHandProdConcerned> findPage(Integer prodId, Integer userId, PageParamRequest request) {
+        Page<SecondHandProdConcerned> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        LambdaQueryWrapper<SecondHandProdConcerned> lqw = Wrappers.lambdaQuery();
+        if (prodId > 0) {
+            lqw.eq(SecondHandProdConcerned::getSecondHandId, prodId);
+        }
+        if (userId > 0) {
+            lqw.eq(SecondHandProdConcerned::getUid, userId);
+        }
+        lqw.orderByDesc(SecondHandProdConcerned::getId);
+        List<SecondHandProdConcerned> list = dao.selectList(lqw);
+        return CommonPage.copyPageInfo(page, list);
+    }
+
+    /**
+     * 社区关注/取关作者
+     * @param prodId 作者ID
+     * @param userId 用户ID
+     */
+    @Override
+    public void concernedProd(Integer prodId, Integer userId) {
+        SecondHandProdConcerned concerned = getDetail(prodId, userId);
+        if (ObjectUtil.isNotNull(concerned)) {
+            boolean remove = removeById(concerned);
+            if (!remove) {
+                throw new CrmebException(CommonResultCode.ERROR.setMessage("取关失败"));
+            }
+            return;
+        }
+        concerned = new SecondHandProdConcerned();
+        concerned.setSecondHandId(prodId);
+        concerned.setUid(userId);
+        boolean save = save(concerned);
+        if (!save) {
+            throw new CrmebException(CommonResultCode.ERROR.setMessage("关注失败"));
+        }
+    }
+
+    private SecondHandProdConcerned getDetail(Integer prodId, Integer userId) {
+        LambdaQueryWrapper<SecondHandProdConcerned> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandProdConcerned::getSecondHandId, prodId);
+        lqw.eq(SecondHandProdConcerned::getUid, userId);
+        lqw.last(" limit 1");
+        return dao.selectOne(lqw);
+    }
+}
+

+ 715 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandProdServiceImpl.java

@@ -0,0 +1,715 @@
+package com.zbkj.service.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.URLUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.constants.CommunityConstants;
+import com.zbkj.common.constants.SecondHandConstants;
+import com.zbkj.common.constants.Constants;
+import com.zbkj.common.constants.UserConstants;
+import com.zbkj.common.dto.SecondHandProdPageDateDto;
+import com.zbkj.common.exception.CrmebException;
+import com.zbkj.common.model.community.CommunityNotes;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandProd;
+import com.zbkj.common.model.secondhand.SecondHandCategory;
+import com.zbkj.common.model.user.User;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.*;
+import com.zbkj.common.response.SecondHandDetailResponse;
+import com.zbkj.common.response.SecondHandPageDataResponse;
+import com.zbkj.common.result.CommonResultCode;
+import com.zbkj.common.result.CommunityResultCode;
+import com.zbkj.common.utils.CrmebUtil;
+import com.zbkj.common.utils.ValidateFormUtil;
+import com.zbkj.service.dao.secondhand.SecondHandDao;
+import com.zbkj.service.service.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+* CommunityNotes 接口实现
+* +----------------------------------------------------------------------
+* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+* +----------------------------------------------------------------------
+* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+* +----------------------------------------------------------------------
+* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+* +----------------------------------------------------------------------
+* | Author: CRMEB Team <admin@crmeb.com>
+* +----------------------------------------------------------------------
+*/
+@Slf4j
+@Service
+public class SecondHandProdServiceImpl extends ServiceImpl<SecondHandDao, SecondHandProd> implements SecondHandProdService {
+
+    @Resource
+    private SecondHandDao dao;
+
+    @Autowired
+    private SecondHandCategoryService categoryService;
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private TransactionTemplate transactionTemplate;
+    @Autowired
+    private SecondHandProdConcernedService secondHandProdConcernedService;
+
+    @Autowired
+    private SecondHandOrderDetailService orderDetailService;
+    @Autowired
+    private SystemAttachmentService systemAttachmentService;
+    @Autowired
+    private SystemConfigService systemConfigService;
+    @Autowired
+    private AsyncService asyncService;
+
+
+
+    /**
+     * 是否使用社区分类
+     * @param cateId 社区分类ID
+     */
+    @Override
+    public Boolean isUseCategory(Integer cateId) {
+        LambdaQueryWrapper<SecondHandProd> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandProd::getId);
+        lqw.eq(SecondHandProd::getCategoryId, cateId);
+        lqw.eq(SecondHandProd::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        lqw.last("limit 1");
+        SecondHandProd communityNotes = dao.selectOne(lqw);
+        return ObjectUtil.isNotNull(communityNotes);
+    }
+
+    /**
+     * 社区笔记分页列表
+     * @param request 查询参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondHandPageDataResponse> findPageList(SecondHandProdSearchRequest request) {
+        Map<String, Object> map = CollUtil.newHashMap();
+        if (StrUtil.isNotBlank(request.getTitle())) {
+            map.put("title", URLUtil.decode(request.getTitle()));
+        }
+        if (ObjectUtil.isNotNull(request.getType())) {
+            map.put("type", request.getType());
+        }
+        if (ObjectUtil.isNotNull(request.getCategoryId())) {
+            map.put("categoryId", request.getCategoryId());
+        }
+        if (ObjectUtil.isNotNull(request.getContent())) {
+            map.put("content", request.getContent());
+        }
+        if (ObjectUtil.isNotNull(request.getSaleStatus())) {
+            map.put("saleStatus", request.getSaleStatus());
+        }
+        if (ObjectUtil.isNotNull(request.getTopicId())) {
+            map.put("topicId", request.getTopicId());
+        }
+        if (ObjectUtil.isNotNull(request.getAuditStatus())) {
+            map.put("auditStatus", request.getAuditStatus());
+        }
+        if (StrUtil.isNotBlank(request.getContent())) {
+            ValidateFormUtil.validatorUserCommonSearch(request);
+            String keywords = URLUtil.decode(request.getContent());
+            switch (request.getSearchType()) {
+                case UserConstants.USER_SEARCH_TYPE_ALL:
+                    map.put("keywords", keywords);
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_UID:
+                    map.put("uid", Integer.valueOf(request.getContent()));
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_NICKNAME:
+                    map.put("nickname", keywords);
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_PHONE:
+                    map.put("phone", request.getContent());
+                    break;
+            }
+        }
+        Page<SecondHandProdPageDateDto> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        List<SecondHandProdPageDateDto> dtoList = dao.findPageList(map);
+        if (CollUtil.isEmpty(dtoList)) {
+            return CommonPage.copyPageInfo(page, new ArrayList<>());
+        }
+        List<Integer> cateIdList = CollUtil.newArrayList();
+        List<Integer> topicIdList = CollUtil.newArrayList();
+        dtoList.forEach(e -> {
+            cateIdList.add(e.getCategoryId());
+            if (StrUtil.isNotBlank(e.getTopicIds())) {
+                topicIdList.addAll(CrmebUtil.stringToArray(e.getTopicIds()));
+            }
+        });
+        Map<Integer, String> categoryMap = categoryService.getMapInIdList(cateIdList);
+        List<SecondHandPageDataResponse> responseList = dtoList.stream().map(dto -> {
+            SecondHandPageDataResponse response = new SecondHandPageDataResponse();
+            BeanUtils.copyProperties(dto, response);
+            response.setCategoryName(categoryMap.get(dto.getCategoryId()));
+            return response;
+        }).collect(Collectors.toList());
+        return CommonPage.copyPageInfo(page, responseList);
+    }
+
+    /**
+     * 详情
+     * @param id 笔记ID
+     */
+    @Override
+    public SecondHandDetailResponse detail(Integer id) {
+        SecondHandProd note = getByIdException(id);
+        SecondHandDetailResponse response = new SecondHandDetailResponse();
+        BeanUtils.copyProperties(note, response);
+        User user = userService.getById(note.getUid());
+        response.setAuthorId(note.getUid());
+        response.setAuthorName(user.getNickname());
+        return response;
+    }
+
+    /**
+     * 审核
+     */
+    @Override
+    public void audit(CommonAuditRequest request) {
+        if (request.getAuditStatus().equals(CommunityConstants.COMMUNITY_NOTE_AUDIT_ERROR) && StrUtil.isBlank(request.getRefusalReason())) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED.setMessage("请填写审核拒绝原因"));
+        }
+        SecondHandProd notes = getByIdException(request.getId());
+        if (!notes.getAuditStatus().equals(SecondHandConstants.SECOND_HAND_AUDIT_AWAIT)) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_NOTE_AUDIT_STATUS_EXCEPTION);
+        }
+        notes.setAuditStatus(request.getAuditStatus());
+        if (request.getAuditStatus().equals(SecondHandConstants.SECOND_HAND_AUDIT_ERROR) && StrUtil.isNotBlank(request.getRefusalReason())) {
+            notes.setRefusal(request.getRefusalReason());
+        }
+        notes.setOperateTime(DateUtil.date());
+        boolean update = updateById(notes);
+        if (!update) {
+            throw new CrmebException("商品发布 审核失败");
+        }
+        if (notes.getAuditStatus().equals(SecondHandConstants.SECOND_HAND_AUDIT_SUCCESS)) {
+            asyncService.noteUpExp(notes.getUid(), notes.getId());
+        }
+    }
+
+    /**
+     * 强制下架
+     */
+    @Override
+    public void forcedDown(CommonForcedDownRequest request) {
+        SecondHandProd notes = getByIdException(request.getId());
+        if (!notes.getAuditStatus().equals(SecondHandConstants.SECOND_HAND_AUDIT_SUCCESS)) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_NOTE_AUDIT_STATUS_EXCEPTION);
+        }
+        notes.setAuditStatus(SecondHandConstants.SECOND_HAND_AUDIT_CLOSE);
+        notes.setOperateTime(DateUtil.date());
+        notes.setRefusal(request.getReason());
+        boolean update = updateById(notes);
+        if (!update) {
+            throw new CrmebException("商品强制下架失败");
+        }
+    }
+
+    /**
+     * 删除
+     * @param id 笔记ID
+     */
+    @Override
+    public void delete(Integer id) {
+        SecondHandProd notes = getByIdException(id);
+        notes.setIsDel(Constants.COMMON_IS_FILED_ONE);
+        Boolean execute = transactionTemplate.execute(e -> {
+            updateById(notes);
+            //notesProductService.deleteByNoteId(id);
+            //replyService.deleteByNoteId(id);
+            //communityNotesRelationService.deleteByNoteId(id);
+            return Boolean.TRUE;
+        });
+        if (!execute) {
+            throw new CrmebException("商品删除失败");
+        }
+    }
+
+    /**
+     * 分类批量修改
+     */
+    @Override
+    public void categoryBatchUpdate(CommunityNoteCategoryBatchUpdateRequest request) {
+        LambdaUpdateWrapper<SecondHandProd> wrapper = Wrappers.lambdaUpdate();
+        wrapper.set(SecondHandProd::getCategoryId, request.getCategoryId());
+        wrapper.in(SecondHandProd::getId, request.getNoteIdList());
+        update(wrapper);
+    }
+
+    /**
+     * 社区笔记推荐星级编辑
+     */
+    @Override
+    public void updateStar(CommonStarUpdateRequest request) {
+        SecondHandProd notes = getByIdException(request.getId());
+        if (!notes.getAuditStatus().equals(SecondHandConstants.SECOND_HAND_AUDIT_SUCCESS)) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_NOTE_AUDIT_STATUS_EXCEPTION);
+        }
+        if (notes.getStar().equals(request.getStar())) {
+            return;
+        }
+        notes.setStar(request.getStar());
+        boolean update = updateById(notes);
+        if (!update) {
+            throw new CrmebException("推荐星级编辑失败");
+        }
+    }
+
+
+    private PageInfo<SecondHandProd> findFrontSearchList(SecondHandFrontSearchRequest request) {
+        Page<SecondHandProd> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        LambdaQueryWrapper<SecondHandProd> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandProd::getId, SecondHandProd::getTitle, SecondHandProd::getVideo, SecondHandProd::getCover, SecondHandProd::getUid, SecondHandProd::getSchool, SecondHandProd::getPrice,SecondHandProd::getSaleStatus,
+                SecondHandProd::getType, SecondHandProd::getAuditStatus, SecondHandProd::getCategoryId, SecondHandProd::getContent, SecondHandProd::getCreateTime, SecondHandProd::getImage,SecondHandProd::getLikeNum);
+        if (ObjectUtil.isNotNull(request.getCategoryId())) {
+            lqw.eq(SecondHandProd::getCategoryId, request.getCategoryId());
+        }
+        if (ObjectUtil.isNotNull(request.getSaleStatus())) {
+            lqw.eq(SecondHandProd::getSaleStatus, request.getSaleStatus());
+        }
+        if (ObjectUtil.isNotNull(request.getKeywords())) {
+            lqw.like(SecondHandProd::getContent, request.getKeywords());
+        }
+        if (StrUtil.isNotBlank(request.getTitle())) {
+            lqw.like(SecondHandProd::getTitle, request.getTitle());
+        }
+        if (ObjectUtil.isNotNull(request.getUid())) {
+            lqw.eq(SecondHandProd::getUid, request.getUid());
+        }
+        if (ObjectUtil.isNotNull(request.getAuditStatus())) {
+            lqw.eq(SecondHandProd::getAuditStatus, request.getAuditStatus());
+        }
+        if (StrUtil.isNotBlank(request.getRange())) {
+            if(request.getRange().equals("school")) {
+                User user = userService.getInfo();
+                lqw.like(SecondHandProd::getSchool, user.getSchool());
+            }
+            if(request.getRange().equals("city")) {
+                lqw.like(SecondHandProd::getCity, request.getCity());
+            }
+        }
+        lqw.eq(SecondHandProd::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        switch (request.getCollation()) {
+            case "star":
+                lqw.orderByDesc(SecondHandProd::getStar, SecondHandProd::getId);
+                break;
+            case "hot":
+                lqw.orderByDesc(SecondHandProd::getLikeNum, SecondHandProd::getId);
+                break;
+            default:
+                lqw.orderByDesc(SecondHandProd::getId);
+        }
+        List<SecondHandProd> list = dao.selectList(lqw);
+        list.stream().forEach(communityNote->{
+            SecondHandCategory communityCategory=  categoryService.getById(communityNote.getCategoryId());
+            if(ObjectUtil.isNotNull(communityCategory)) {
+                communityNote.setIcon(communityCategory.getIcon());
+            }
+        });
+        return CommonPage.copyPageInfo(page, list);
+    }
+
+    /**
+     * 移动端社区发现笔记分页列表
+     * @param searchRequest 搜索参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondHandProd> findH5List(SecondHandFrontSearchRequest searchRequest) {
+        if (ObjectUtil.isNotNull(searchRequest.getCategoryId())&& searchRequest.getCategoryId()>0) {
+            searchRequest.setCategoryId(searchRequest.getCategoryId());
+        }
+        if (StrUtil.isNotBlank(searchRequest.getTitle())) {
+            searchRequest.setTitle(URLUtil.decode(searchRequest.getTitle()));
+        }
+        searchRequest.setAuditStatus(SecondHandConstants.SECOND_HAND_AUDIT_SUCCESS);
+        searchRequest.setCollation("star");
+        searchRequest.setPage(searchRequest.getPage());
+        searchRequest.setLimit(searchRequest.getLimit());
+        return findFrontSearchList(searchRequest);
+    }
+
+    /**
+     * 获取话题关联的笔记数量
+     * @param topicId 话题ID
+     */
+    @Override
+    public Integer getCountByTopic(Integer topicId) {
+        LambdaQueryWrapper<SecondHandProd> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandProd::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        lqw.apply("FIND_IN_SET({0}, topic_ids)", topicId);
+        return dao.selectCount(lqw);
+    }
+
+    /**
+     * 获取话题关联的笔记数量
+     * @param topicId 话题ID
+     */
+    @Override
+    public Integer getFrontCountByTopic(Integer topicId) {
+        LambdaQueryWrapper<SecondHandProd> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandProd::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        lqw.eq(SecondHandProd::getAuditStatus, CommunityConstants.COMMUNITY_NOTE_AUDIT_SUCCESS);
+        lqw.apply("FIND_IN_SET({0}, topic_ids)", topicId);
+        return dao.selectCount(lqw);
+    }
+
+    /**
+     * 社区笔记作者列表
+     * @param authorId 作者ID
+     * @param request 分页参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<SecondHandProd> findAuthorNoteList(Integer authorId, PageParamRequest request) {
+        SecondHandFrontSearchRequest searchRequest = new SecondHandFrontSearchRequest();
+        searchRequest.setUid(authorId);
+        searchRequest.setAuditStatus(CommunityConstants.COMMUNITY_NOTE_AUDIT_SUCCESS);
+        searchRequest.setPage(request.getPage());
+        searchRequest.setLimit(request.getLimit());
+        return findFrontSearchList(searchRequest);
+    }
+
+    @Override
+    public SecondHandProd getByIdException(Integer id) {
+        SecondHandProd notes = getById(id);
+        if (ObjectUtil.isNull(notes) || notes.getIsDel().equals(Constants.COMMON_IS_FILED_ONE)) {
+            throw new CrmebException(CommunityResultCode.COMMUNITY_NOTE_NOT_EXIST);
+        }
+        return notes;
+    }
+
+
+    /**
+     * 创建社区笔记
+     */
+    @Override
+    public void create(SecondHandSaveRequest request) {
+        validatorNoteParam(request);
+        User user=userService.getInfo();
+        //Integer userId = userService.getUserIdException();
+        SecondHandProd note = new SecondHandProd();
+        BeanUtils.copyProperties(request, note, "id");
+        note.setUid(user.getId());
+        note.setCover(systemAttachmentService.clearPrefix(request.getCover()));
+        if (SecondHandConstants.SECOND_HAND_TYPE_IMAGE_CONTENT.equals(request.getType())) {
+            note.setImage(systemAttachmentService.clearPrefix(request.getImage()));
+        }
+        if (SecondHandConstants.SECOND_HAND_TYPE_SHORT_VIDEO.equals(request.getType())) {
+            note.setVideo(systemAttachmentService.clearPrefix(request.getVideo()));
+        }
+        note.setSchool(user.getSchool());
+        note.setAuditStatus(SecondHandConstants.SECOND_HAND_AUDIT_SUCCESS);
+        if (SecondHandConstants.SECOND_HAND_TYPE_IMAGE_CONTENT.equals(request.getType())) {
+            String textAuditSwitch = systemConfigService.getValueByKeyException(SecondHandConstants.SECOND_HAND_IMAGE_TEXT_AUDIT_SWITCH);
+            if (Constants.COMMON_SWITCH_OPEN.equals(textAuditSwitch)) {
+                note.setAuditStatus(SecondHandConstants.SECOND_HAND_AUDIT_AWAIT);
+            }
+        }
+        if (SecondHandConstants.SECOND_HAND_TYPE_SHORT_VIDEO.equals(request.getType())) {
+            String videoAuditSwitch = systemConfigService.getValueByKeyException(SecondHandConstants.SECOND_HAND_SHORT_VIDEO_AUDIT_SWITCH);
+            if (Constants.COMMON_SWITCH_OPEN.equals(videoAuditSwitch)) {
+                note.setAuditStatus(SecondHandConstants.SECOND_HAND_AUDIT_AWAIT);
+            }
+        }
+
+        Boolean execute = transactionTemplate.execute(e -> {
+            int insert = dao.insert(note);
+            if (insert < 1) {
+                e.setRollbackOnly();
+                log.error("添加商品失败,request = {}", request);
+                return Boolean.FALSE;
+            }
+            return Boolean.TRUE;
+        });
+        if (!execute) {
+            throw new CrmebException("创建商品失败");
+        }
+        if (note.getAuditStatus().equals(SecondHandConstants.SECOND_HAND_AUDIT_SUCCESS)) {
+            // 异步掉用添加用户经验
+            asyncService.noteUpExp(user.getId(), note.getId());
+        }
+    }
+
+    /**
+     * 编辑社区笔记
+     */
+    @Override
+    public void updateNote(SecondHandSaveRequest request) {
+        if (ObjectUtil.isNull(request.getId())) {
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED.setMessage("请先发布商品"));
+        }
+        validatorNoteParam(request);
+        Integer userId = userService.getUserIdException();
+        SecondHandProd note = getByIdException(request.getId());
+        if (!note.getUid().equals(userId)) {
+            throw new CrmebException("不能操作别人的数据");
+        }
+        note.setTitle(StrUtil.isNotBlank(request.getTitle()) ? request.getTitle() : "");
+        note.setCover(systemAttachmentService.clearPrefix(request.getCover()));
+        if (SecondHandConstants.SECOND_HAND_TYPE_IMAGE_CONTENT.equals(request.getType())) {
+            note.setImage(systemAttachmentService.clearPrefix(request.getImage()));
+        }
+        if (SecondHandConstants.SECOND_HAND_TYPE_SHORT_VIDEO.equals(request.getType())) {
+            note.setVideo(systemAttachmentService.clearPrefix(request.getVideo()));
+        }
+        note.setContent(StrUtil.isNotBlank(request.getContent()) ? request.getContent() : "");
+        note.setTitle(StrUtil.isNotBlank(request.getTitle()) ? request.getTitle() : "");
+        note.setCategoryId(request.getCategoryId());
+        note.setType(request.getType());
+        note.setSaleStatus(request.getSaleStatus());
+        note.setPrice(request.getPrice());
+        note.setAddressId(request.getAddressId());
+
+        if (note.getAuditStatus().equals(SecondHandConstants.SECOND_HAND_AUDIT_CLOSE)) {
+            note.setAuditStatus(SecondHandConstants.SECOND_HAND_AUDIT_AWAIT);
+        } else if (SecondHandConstants.SECOND_HAND_TYPE_IMAGE_CONTENT.equals(request.getType())) {
+            String textAuditSwitch = systemConfigService.getValueByKeyException(SecondHandConstants.SECOND_HAND_IMAGE_TEXT_AUDIT_SWITCH);
+            if (Constants.COMMON_SWITCH_OPEN.equals(textAuditSwitch)) {
+                note.setAuditStatus(SecondHandConstants.SECOND_HAND_AUDIT_AWAIT);
+            }
+        } else if (SecondHandConstants.SECOND_HAND_TYPE_SHORT_VIDEO.equals(request.getType())) {
+            String videoAuditSwitch = systemConfigService.getValueByKeyException(SecondHandConstants.SECOND_HAND_SHORT_VIDEO_AUDIT_SWITCH);
+            if (Constants.COMMON_SWITCH_OPEN.equals(videoAuditSwitch)) {
+                note.setAuditStatus(SecondHandConstants.SECOND_HAND_AUDIT_AWAIT);
+            }
+        } else {
+            note.setAuditStatus(SecondHandConstants.SECOND_HAND_AUDIT_SUCCESS);
+        }
+        Boolean execute = transactionTemplate.execute(e -> {
+            boolean update = updateById(note);
+            if (!update) {
+                e.setRollbackOnly();
+                log.error("编辑商品失败,request = {}", request);
+                return Boolean.FALSE;
+            }
+            return Boolean.TRUE;
+        });
+        if (!execute) {
+            throw new CrmebException("编辑商品失败");
+        }
+    }
+
+    /**
+     * 社区之我的笔记列表
+     */
+    @Override
+    public PageInfo<SecondHandProd> findMyNoteList(Integer userId, PageParamRequest request) {
+        SecondHandFrontSearchRequest searchRequest = new SecondHandFrontSearchRequest();
+        searchRequest.setUid(userId);
+        searchRequest.setPage(request.getPage());
+        searchRequest.setLimit(request.getLimit());
+        return findFrontSearchList(searchRequest);
+    }
+
+    /**
+     * 按时间倒序获取文章作者列表
+     */
+    @Override
+    public PageInfo<Integer> findAuthorPageTimeDesc(Integer userId, PageParamRequest request) {
+        List<Integer> authorConcernedList = secondHandProdConcernedService.findProdIdList(userId);
+        authorConcernedList.add(userId);
+        Page<CommunityNotes> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        LambdaQueryWrapper<SecondHandProd> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandProd::getUid);
+        lqw.notIn(SecondHandProd::getUid, authorConcernedList);
+        lqw.eq(SecondHandProd::getAuditStatus, CommunityConstants.COMMUNITY_NOTE_AUDIT_SUCCESS);
+        lqw.eq(SecondHandProd::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        lqw.groupBy(SecondHandProd::getUid);
+        lqw.orderByDesc(SecondHandProd::getCreateTime);
+        List<SecondHandProd> list = dao.selectList(lqw);
+        if (CollUtil.isEmpty(list)) {
+            return CommonPage.copyPageInfo(page, new ArrayList<>());
+        }
+        List<Integer> authorIdList = list.stream().map(SecondHandProd::getUid).collect(Collectors.toList());
+        return CommonPage.copyPageInfo(page, authorIdList);
+    }
+
+    /**
+     * 获取新笔记通过作者
+     * @param authorId 作者ID
+     * @param num 笔记数量
+     */
+    @Override
+    public List<SecondHandProd> findNewNoteByAuthorId(Integer authorId, Integer num) {
+        LambdaQueryWrapper<SecondHandProd> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandProd::getId, SecondHandProd::getCover, SecondHandProd::getType);
+        lqw.eq(SecondHandProd::getUid, authorId);
+        lqw.eq(SecondHandProd::getAuditStatus, CommunityConstants.COMMUNITY_NOTE_AUDIT_SUCCESS);
+        lqw.eq(SecondHandProd::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        lqw.orderByDesc(SecondHandProd::getId);
+        lqw.last(" limit " + num);
+        return dao.selectList(lqw);
+    }
+
+    /**
+     * 社区笔记点赞数量
+     * @param noteId 笔记ID
+     * @param operationType 操作类型:add-点赞,sub-取消
+     */
+    @Override
+    public void operationLike(Integer noteId, String operationType) {
+        LambdaUpdateWrapper<SecondHandProd> wrapper = Wrappers.lambdaUpdate();
+        if (operationType.equals(Constants.OPERATION_TYPE_ADD)) {
+            wrapper.setSql("like_num = like_num + 1");
+        } else {
+            wrapper.setSql("like_num = like_num - 1");
+        }
+        wrapper.eq(SecondHandProd::getId, noteId);
+        update(wrapper);
+    }
+
+    /**
+     * 操作社区笔记评论数量
+     * @param noteId 笔记ID
+     * @param num 评论数量
+     * @param operationType 操作类型
+     */
+    @Override
+    public void operationReplyNum(Integer noteId, Integer num, String operationType) {
+        LambdaUpdateWrapper<SecondHandProd> wrapper = Wrappers.lambdaUpdate();
+        if (operationType.equals(Constants.OPERATION_TYPE_ADD)) {
+            wrapper.setSql(StrUtil.format("reply_num = reply_num + {}", num));
+        } else {
+            wrapper.setSql(StrUtil.format("reply_num = reply_num - {}", num));
+        }
+        wrapper.eq(SecondHandProd::getId, noteId);
+        update(wrapper);
+    }
+
+    /**
+     * 社区笔记发现推荐列表
+     * @param request 分页参数
+     */
+    @Override
+    public PageInfo<SecondHandProd> findRecommendList(String keywords, PageParamRequest request) {
+        Page<SecondHandProd> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        LambdaQueryWrapper<SecondHandProd> lqw = Wrappers.lambdaQuery();
+        //User user=userService.getInfo();
+        if (StrUtil.isNotBlank(keywords)) {
+            lqw.and(i -> i.like(SecondHandProd::getContent,  URLUtil.decode(keywords)));
+        }
+        //lqw.like(SecondHand::getSchool, user.getSchool());
+        lqw.eq(SecondHandProd::getAuditStatus, CommunityConstants.COMMUNITY_NOTE_AUDIT_SUCCESS);
+        lqw.eq(SecondHandProd::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        lqw.orderByDesc(SecondHandProd::getLikeNum, SecondHandProd::getSchool);
+        List<SecondHandProd> list = dao.selectList(lqw);
+        if (CollUtil.isNotEmpty(list)) {
+            Collections.shuffle(list);
+        }
+        return CommonPage.copyPageInfo(page, list);
+    }
+
+    @Override
+    public Map<Integer, SecondHandProd> getMapByIdList(List<Integer> noteIdList) {
+        LambdaQueryWrapper<SecondHandProd> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandProd::getId, SecondHandProd::getTitle, SecondHandProd::getCover, SecondHandProd::getUid,SecondHandProd::getPrice,
+                SecondHandProd::getType, SecondHandProd::getLikeNum, SecondHandProd::getContent, SecondHandProd::getCreateTime, SecondHandProd::getCategoryId);
+        lqw.in(SecondHandProd::getId, noteIdList);
+        List<SecondHandProd> list = dao.selectList(lqw);
+        Map<Integer, SecondHandProd> map = new HashMap<>();
+        list.forEach(e -> {
+            SecondHandCategory communityCategory=  categoryService.getById(e.getCategoryId());
+            if(ObjectUtil.isNotNull(communityCategory)) {
+                e.setIcon(communityCategory.getIcon());
+            }
+            map.put(e.getId(), e);
+        });
+        return map;
+    }
+
+    /**
+     * 删除用户所有笔记
+     * @param userId 用户ID
+     */
+    @Override
+    public Boolean deleteByUid(Integer userId) {
+        LambdaUpdateWrapper<SecondHandProd> wrapper = Wrappers.lambdaUpdate();
+        wrapper.set(SecondHandProd::getIsDel, Constants.COMMON_IS_FILED_ONE);
+        wrapper.eq(SecondHandProd::getUid, userId);
+        wrapper.eq(SecondHandProd::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        return update(wrapper);
+    }
+
+    @Override
+    public PageInfo<SecondHandProd> findFollowNoteList(PageParamRequest request, Integer userId) {
+        List<Integer> authorIdList = secondHandProdConcernedService.findProdIdList(userId);
+        Page<SecondHandProd> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        if (CollUtil.isEmpty(authorIdList)) {
+            return CommonPage.copyPageInfo(page, new ArrayList<>());
+        }
+        LambdaQueryWrapper<SecondHandProd> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandProd::getId, SecondHandProd::getTitle, SecondHandProd::getCover, SecondHandProd::getContent,
+                SecondHandProd::getVideo, SecondHandProd::getTopicIds, SecondHandProd::getUid, SecondHandProd::getType,SecondHandProd::getPrice,
+                SecondHandProd::getCreateTime, SecondHandProd::getLikeNum, SecondHandProd::getImage, SecondHandProd::getReplyNum);
+        lqw.in(SecondHandProd::getUid, authorIdList);
+        lqw.eq(SecondHandProd::getAuditStatus, CommunityConstants.COMMUNITY_NOTE_AUDIT_SUCCESS);
+        lqw.eq(SecondHandProd::getIsDel, Constants.COMMON_IS_FILED_ZERO);
+        lqw.orderByDesc(SecondHandProd::getId);
+        List<SecondHandProd> list = dao.selectList(lqw);
+        return CommonPage.copyPageInfo(page, list);
+    }
+
+    @Override
+    public void updateStatusByOrderNo(String orderNo, Integer status) {
+        List<SecondHandOrderDetail> orderDetailList=orderDetailService.getByOrderNo(orderNo);
+        if(CollUtil.isNotEmpty(orderDetailList)){
+            SecondHandOrderDetail secondHandOrderDetail=orderDetailList.get(0);
+            SecondHandProd secondHandProd=getByIdException(secondHandOrderDetail.getProductId());
+            secondHandProd.setSaleStatus(status);
+            updateById(secondHandProd);
+        }
+    }
+
+    /**
+     * 校验笔记参数
+     */
+    private void validatorNoteParam(SecondHandSaveRequest request) {
+        if (CommunityConstants.COMMUNITY_NOTE_TYPE_IMAGE_CONTENT.equals(request.getType())) {
+            if (StrUtil.isBlank(request.getImage())) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED.setMessage("请先上传图片"));
+            }
+            String[] split = request.getImage().split(",");
+            if (split.length > 9) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED.setMessage("最多只能上传9张图片"));
+            }
+            if (StrUtil.isNotBlank(request.getContent()) && request.getContent().length() > 600) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED.setMessage("正文不能超过600个字符"));
+            }
+
+        }
+        if (CommunityConstants.COMMUNITY_NOTE_TYPE_SHORT_VIDEO.equals(request.getType())) {
+            if (StrUtil.isBlank(request.getVideo())) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED.setMessage("请先上传视频"));
+            }
+            if (StrUtil.isNotBlank(request.getContent()) && request.getContent().length() > 200) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED.setMessage("视频正文不能超过200个字符"));
+            }
+
+        }
+    }
+}
+

+ 47 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandRefundOrderInfoServiceImpl.java

@@ -0,0 +1,47 @@
+package com.zbkj.service.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zbkj.common.model.order.RefundOrderInfo;
+import com.zbkj.common.model.secondhand.SecondHandRefundOrderInfo;
+import com.zbkj.service.dao.RefundOrderInfoDao;
+import com.zbkj.service.dao.secondhand.SecondHandRefundOrderInfoDao;
+import com.zbkj.service.service.RefundOrderInfoService;
+import com.zbkj.service.service.SecondHandRefundOrderInfoService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+*  RefundOrderInfoServiceImpl 接口实现
+*  +----------------------------------------------------------------------
+*  | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+*  +----------------------------------------------------------------------
+*  | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+*  +----------------------------------------------------------------------
+*  | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+*  +----------------------------------------------------------------------
+*  | Author: CRMEB Team <admin@crmeb.com>
+*  +----------------------------------------------------------------------
+*/
+@Service
+public class SecondHandRefundOrderInfoServiceImpl extends ServiceImpl<SecondHandRefundOrderInfoDao, SecondHandRefundOrderInfo> implements SecondHandRefundOrderInfoService {
+
+    @Resource
+    private SecondHandRefundOrderInfoDao dao;
+
+    /**
+     * 根据退款单号获取详情
+     * @param refundOrderNo 退款单号
+     * @return RefundOrderInfo
+     */
+    @Override
+    public SecondHandRefundOrderInfo getByRefundOrderNo(String refundOrderNo) {
+        LambdaQueryWrapper<SecondHandRefundOrderInfo> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandRefundOrderInfo::getRefundOrderNo, refundOrderNo);
+        lqw.last(" limit 1");
+        return dao.selectOne(lqw);
+    }
+}
+

+ 1381 - 0
ydd_mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/SecondHandRefundOrderManagerServiceImpl.java

@@ -0,0 +1,1381 @@
+package com.zbkj.service.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.URLUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.constants.*;
+import com.zbkj.common.exception.CrmebException;
+import com.zbkj.common.model.admin.SystemAdmin;
+import com.zbkj.common.model.merchant.MerchantAddress;
+import com.zbkj.common.model.order.*;
+import com.zbkj.common.model.secondhand.SecondHandOrder;
+import com.zbkj.common.model.secondhand.SecondHandOrderDetail;
+import com.zbkj.common.model.secondhand.SecondHandRefundOrder;
+import com.zbkj.common.model.secondhand.SecondHandRefundOrderInfo;
+import com.zbkj.common.model.user.User;
+import com.zbkj.common.model.user.UserBalanceRecord;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.*;
+import com.zbkj.common.response.*;
+import com.zbkj.common.result.CommonResultCode;
+import com.zbkj.common.result.OrderResultCode;
+import com.zbkj.common.utils.*;
+import com.zbkj.common.vo.DateLimitUtilVo;
+import com.zbkj.common.vo.RefundOrderDetailOrderInfoVo;
+import com.zbkj.common.vo.WxRefundVo;
+import com.zbkj.service.dao.RefundOrderDao;
+import com.zbkj.service.dao.secondhand.SecondHandRefundOrderDao;
+import com.zbkj.service.service.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * RefundOrderServiceImpl 接口实现 最深度的退款订单 service
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Service
+public class SecondHandRefundOrderManagerServiceImpl extends ServiceImpl<SecondHandRefundOrderDao, SecondHandRefundOrder> implements SecondHandRefundOrderManagerService {
+    private static final Logger logger = LoggerFactory.getLogger(SecondHandRefundOrderManagerServiceImpl.class);
+    @Resource
+    private SecondHandRefundOrderDao dao;
+
+    @Autowired
+    private SecondHandOrderService orderService;
+    @Autowired
+    private SecondHandOrderDetailService orderDetailService;
+    @Autowired
+    private SecondHandRefundOrderInfoService refundOrderInfoService;
+    @Autowired
+    private TransactionTemplate transactionTemplate;
+    @Autowired
+    private WechatService wechatService;
+    @Autowired
+    private SystemConfigService systemConfigService;
+    @Autowired
+    private AliPayService aliPayService;
+    @Autowired
+    private UserService userService;
+    @Autowired
+    private RedisUtil redisUtil;
+    @Autowired
+    private UserBalanceRecordService userBalanceRecordService;
+    @Autowired
+    private MerchantAddressService merchantAddressService;
+    @Autowired
+    private RefundOrderStatusService refundOrderStatusService;
+    @Autowired
+    private MerchantOrderService merchantOrderService;
+    @Autowired
+    private AsyncService asyncService;
+
+    /**
+     * 商户端退款订单分页列表
+     *
+     * @param request          查询参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<MerchantRefundOrderPageResponse> getMerchantAdminPage(RefundOrderSearchRequest request, SystemAdmin systemAdmin) {
+        Page<RefundOrder> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        Map<String, Object> map = CollUtil.newHashMap();
+        if (StrUtil.isNotBlank(request.getContent())) {
+            ValidateFormUtil.validatorUserCommonSearch(request);
+            String keywords = URLUtil.decode(request.getContent());
+            switch (request.getSearchType()) {
+                case UserConstants.USER_SEARCH_TYPE_ALL:
+                    map.put("keywords", keywords);
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_UID:
+                    map.put("uid", Integer.valueOf(request.getContent()));
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_NICKNAME:
+                    map.put("nickname", keywords);
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_PHONE:
+                    map.put("phone", request.getContent());
+                    break;
+            }
+        }
+        //时间范围
+        if (StrUtil.isNotBlank(request.getDateLimit())) {
+            DateLimitUtilVo dateLimit = CrmebDateUtil.getDateLimit(request.getDateLimit());
+            //判断时间
+            int compareDateResult = CrmebDateUtil.compareDate(dateLimit.getEndTime(), dateLimit.getStartTime(), DateConstants.DATE_FORMAT);
+            if (compareDateResult == -1) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "开始时间不能大于结束时间!");
+            }
+            if (StrUtil.isNotBlank(dateLimit.getStartTime())) {
+                map.put("startTime", dateLimit.getStartTime());
+                map.put("endTime", dateLimit.getEndTime());
+            }
+        }
+        map.put("merId",  systemAdmin.getMerId());
+        if (StrUtil.isNotBlank(request.getRefundOrderNo())) {
+            map.put("refundOrderNo", request.getRefundOrderNo());
+        }
+        if (StrUtil.isNotBlank(request.getOrderNo())) {
+            map.put("orderNo", request.getOrderNo());
+        }
+        if (StrUtil.isNotBlank(request.getTrackingNumber())) {
+            map.put("trackingNumber", request.getTrackingNumber());
+        }
+        if (ObjectUtil.isNotNull(request.getRefundStatus()) && request.getRefundStatus() != 9) {
+            map.put("refundStatus", request.getRefundStatus());
+        }
+        List<MerchantRefundOrderPageResponse> responseList = dao.getMerchantAdminPage(map);
+        if (CollUtil.isEmpty(responseList)) {
+            return CommonPage.copyPageInfo(page, CollUtil.newArrayList());
+        }
+        responseList.forEach(response -> {
+            // TODO 移动端商户管理需要区分
+            RefundOrderInfo refundOrderInfo=new RefundOrderInfo();
+            SecondHandRefundOrderInfo secondHandRefundOrderInfo = refundOrderInfoService.getByRefundOrderNo(response.getRefundOrderNo());
+            BeanUtils.copyProperties(secondHandRefundOrderInfo,refundOrderInfo);
+            response.setRefundOrderInfo(refundOrderInfo);
+        });
+        return CommonPage.copyPageInfo(page, responseList);
+    }
+
+    /**
+     * 获取商户端退款订单各状态数量
+     *
+     * @return RefundOrderCountItemResponse
+     */
+    @Override
+    public RefundOrderCountItemResponse getMerchantOrderStatusNum(RefundOrderSearchRequest request, SystemAdmin systemAdmin) {
+        return getOrderStatusNum(request, systemAdmin.getMerId());
+    }
+
+    /**
+     * 备注退款单
+     *
+     * @param request 备注参数
+     * @return Boolean
+     */
+    @Override
+    public Boolean mark(RefundOrderRemarkRequest request, SystemAdmin systemAdmin) {
+        SecondHandRefundOrder refundOrder = getInfoException(request.getRefundOrderNo());
+        if (!refundOrder.getMerId().equals(systemAdmin.getMerId())) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_NOT_EXIST);
+        }
+        refundOrder.setMerRemark(request.getRemark());
+        return updateById(refundOrder);
+    }
+
+    /**
+     * 微信退款
+     * @param order 订单
+     * @param refundOrderNo 退款单号
+     * @param refundPrice 退款金额
+     * @param totalPrice 订单支付总金额
+     */
+    private void wxRefund(SecondHandOrder order, String refundOrderNo, BigDecimal refundPrice, BigDecimal totalPrice) {
+        String appId = "";
+        String mchId = "";
+        String signKey = "";
+        String path = "";
+        String payChannel = order.getPayChannel();
+        if (payChannel.equals(PayConstants.PAY_CHANNEL_H5) || payChannel.equals(PayConstants.PAY_CHANNEL_WECHAT_NATIVE)) {
+            String source = systemConfigService.getValueByKey(SysConfigConstants.WECHAT_PAY_SOURCE_H5_PC);
+            if (StrUtil.isNotBlank(source) && source.equals(PayConstants.WECHAT_PAY_SOURCE_MINI)) {
+                payChannel = PayConstants.PAY_CHANNEL_WECHAT_MINI;
+            } else {
+                payChannel = PayConstants.PAY_CHANNEL_WECHAT_PUBLIC;
+            }
+        }
+        switch (payChannel) {
+            case PayConstants.PAY_CHANNEL_WECHAT_PUBLIC:
+                appId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PUBLIC_APPID);
+                mchId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_PUBLIC_MCHID);
+                signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_PUBLIC_KEY);
+                path = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_PUBLIC_CERTIFICATE_PATH);
+                break;
+            case PayConstants.PAY_CHANNEL_WECHAT_MINI:
+            case PayConstants.PAY_CHANNEL_WECHAT_MINI_VIDEO:
+                appId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_MINI_APPID);
+                mchId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_MINI_MCHID);
+                signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_MINI_KEY);
+                path = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_MINI_CERTIFICATE_PATH);
+                break;
+            case PayConstants.PAY_CHANNEL_WECHAT_APP_IOS:
+            case PayConstants.PAY_CHANNEL_WECHAT_APP_ANDROID:
+                appId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_APP_APPID);
+                mchId = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_APP_MCHID);
+                signKey = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_APP_KEY);
+                path = systemConfigService.getValueByKeyException(WeChatConstants.WECHAT_PAY_APP_CERTIFICATE_PATH);
+                break;
+        }
+        String apiDomain = systemConfigService.getValueByKeyException(SysConfigConstants.CONFIG_KEY_API_URL);
+
+        //统一下单数据
+        WxRefundVo wxRefundVo = new WxRefundVo();
+        wxRefundVo.setAppid(appId);
+        wxRefundVo.setMch_id(mchId);
+        wxRefundVo.setNonce_str(WxPayUtil.getNonceStr());
+        wxRefundVo.setOut_trade_no(order.getOutTradeNo());
+        wxRefundVo.setOut_refund_no(refundOrderNo);
+        wxRefundVo.setTotal_fee(totalPrice.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN).intValue());
+        wxRefundVo.setRefund_fee(refundPrice.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN).intValue());
+        wxRefundVo.setNotify_url(apiDomain + PayConstants.WX_PAY_REFUND_NOTIFY_API_URI);
+        String sign = WxPayUtil.getSign(wxRefundVo, signKey);
+        wxRefundVo.setSign(sign);
+        wechatService.payRefund(wxRefundVo, path);
+    }
+
+    /**
+     * 设置订单状态
+     *
+     * @param order       订单
+     */
+    private void settingOrderStatus(SecondHandOrder order) {
+        List<SecondHandOrderDetail> orderDetailList = orderDetailService.getByOrderNo(order.getOrderNo());
+        if (order.getStatus().equals(OrderConstants.ORDER_STATUS_PART_SHIPPING)) {
+            long counted = orderDetailList.stream().filter(e -> e.getPayNum() > (e.getDeliveryNum() + e.getRefundNum())).count();
+            if (counted <= 0) {
+                order.setStatus(OrderConstants.ORDER_STATUS_WAIT_RECEIPT);
+                if (order.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT) && order.getPayChannel().equals(PayConstants.PAY_CHANNEL_WECHAT_MINI)) {
+                    String shippingSwitch = systemConfigService.getValueByKey(WeChatConstants.CONFIG_WECHAT_ROUTINE_SHIPPING_SWITCH);
+                    if (StrUtil.isNotBlank(shippingSwitch) && shippingSwitch.equals("1")) {
+                        asyncService.wechatSendUploadShipping(order.getOrderNo());
+                    }
+                }
+            }
+        }
+
+        long count = orderDetailList.stream().filter(e -> e.getRefundNum().equals(0)).count();
+        if (count == orderDetailList.size()) {
+            order.setRefundStatus(OrderConstants.ORDER_REFUND_STATUS_NORMAL);
+            return;
+        }
+        SecondHandOrderDetail orderDetail = orderDetailList.stream().filter(e -> e.getApplyRefundNum() > 0).findAny().orElse(null);
+        if (ObjectUtil.isNotNull(orderDetail)) {
+            order.setRefundStatus(OrderConstants.ORDER_REFUND_STATUS_APPLY);
+            return;
+        }
+        long refundCount = orderDetailList.stream().filter(e -> e.getRefundNum().equals(e.getPayNum())).count();
+        if (refundCount == orderDetailList.size()) {
+            order.setRefundStatus(OrderConstants.ORDER_REFUND_STATUS_ALL);
+            return;
+        }
+        order.setRefundStatus(OrderConstants.ORDER_REFUND_STATUS_PORTION);
+    }
+
+    @Override
+    public SecondHandRefundOrder getInfoException(String refundOrderNo) {
+        LambdaQueryWrapper<SecondHandRefundOrder> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandRefundOrder::getRefundOrderNo, refundOrderNo);
+        lqw.last(" limit 1");
+        SecondHandRefundOrder refundOrder = dao.selectOne(lqw);
+        if (ObjectUtil.isNull(refundOrder)) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_NOT_EXIST);
+        }
+        return refundOrder;
+    }
+
+    /**
+     * 退款订单列表
+     * @param request 搜索参数
+     * @return List
+     */
+    @Override
+    public PageInfo<RefundOrderResponse> getH5List(OrderAfterSalesSearchRequest request) {
+        Integer userId = userService.getUserId();
+        Map<String, Object> map = CollUtil.newHashMap();
+        map.put("userId", userId);
+        if (request.getType().equals(0)) {
+            map.put("refundStatusStr", "0,2,4,5");
+        }
+        if (StrUtil.isNotBlank(request.getKeywords())) {
+            map.put("keywords", URLUtil.decode(request.getKeywords()));
+        }
+        Page<Object> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        List<RefundOrderResponse> list = dao.findSearchList(map);
+        return CommonPage.copyPageInfo(page, list);
+    }
+
+    /**
+     * 退款订单详情(移动端)
+     * @param refundOrderNo 退款订单号
+     * @return RefundOrderInfoResponse
+     */
+    @Override
+    public RefundOrderInfoResponse getRefundOrderDetailByRefundOrderNo(String refundOrderNo) {
+        RefundOrderInfoResponse response = dao.getRefundOrderDetailByRefundOrderNo(refundOrderNo);
+        response.setStatusList(refundOrderStatusService.findListByRefundOrderNo(refundOrderNo));
+        return response;
+    }
+
+    /**
+     * 商户端退款单详情响应对象
+     * @param refundOrderNo 退款单号
+     * @return 退款单详情
+     */
+    @Override
+    public RefundOrderAdminDetailResponse getMerchantDetail(String refundOrderNo, SystemAdmin systemAdmin) {
+
+        SecondHandRefundOrder refundOrder = getInfoException(refundOrderNo);
+        if (!systemAdmin.getMerId().equals(refundOrder.getMerId())) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_NOT_EXIST);
+        }
+        SecondHandRefundOrderInfo refundOrderInfo = refundOrderInfoService.getByRefundOrderNo(refundOrderNo);
+
+        RefundOrderAdminDetailResponse response = new RefundOrderAdminDetailResponse();
+        response.setRefundOrderNo(refundOrder.getRefundOrderNo());
+        response.setAfterSalesType(refundOrder.getAfterSalesType());
+        response.setRefundStatus(refundOrder.getRefundStatus());
+        response.setRefundPrice(refundOrder.getRefundPrice());
+        response.setPayPrice(refundOrderInfo.getPayPrice());
+        response.setPromoterType(refundOrder.getPromoterType());
+
+        response.setProductName(refundOrderInfo.getProductName());
+        response.setImage(refundOrderInfo.getImage());
+        response.setSku(refundOrderInfo.getSku());
+        response.setPrice(refundOrderInfo.getPrice());
+        response.setRefundTime(refundOrder.getRefundTime());
+        response.setPayNum(refundOrderInfo.getPayNum());
+        response.setRefundFreightFee(refundOrder.getRefundFreightFee());
+        response.setApplyRefundNum(refundOrder.getTotalNum());
+        response.setReturnGoodsType(refundOrder.getReturnGoodsType());
+        response.setRefundReasonWap(refundOrder.getRefundReasonWap());
+        response.setRefundReasonWapImg(refundOrder.getRefundReasonWapImg());
+        response.setRefundReasonWapExplain(refundOrder.getRefundReasonWapExplain());
+        response.setReceiver(refundOrder.getReceiver());
+        response.setReceiverPhone(refundOrder.getReceiverPhone());
+        response.setReceiverAddressDetail(refundOrder.getReceiverAddressDetail());
+        response.setExpressName(refundOrder.getExpressName());
+        response.setTrackingNumber(refundOrder.getTrackingNumber());
+        response.setTelephone(refundOrder.getTelephone());
+        response.setIsUserRevoke(refundOrder.getIsUserRevoke());
+        response.setRefundReason(refundOrder.getRefundReason());
+        response.setMerRemark(refundOrder.getMerRemark());
+
+        response.setStatusList(refundOrderStatusService.findListByRefundOrderNo(refundOrderNo));
+
+        RefundOrderDetailOrderInfoVo orderInfoVo = getRefundOrderDetailOrderInfo(refundOrder.getOrderNo());
+        response.setOrderInfoVo(orderInfoVo);
+        return response;
+    }
+
+    /**
+     * 获取退款单详情订单信息部分
+     *
+     * @param orderNo 订单编号
+     */
+    private RefundOrderDetailOrderInfoVo getRefundOrderDetailOrderInfo(String orderNo) {
+        SecondHandOrder order = orderService.getByOrderNo(orderNo);
+        RefundOrderDetailOrderInfoVo orderInfoVo = new RefundOrderDetailOrderInfoVo();
+        orderInfoVo.setOrderNo(orderNo);
+        orderInfoVo.setUid(order.getUid());
+        User user = userService.getById(order.getUid());
+        orderInfoVo.setNickname(user.getNickname());
+        orderInfoVo.setPhone(user.getPhone());
+        orderInfoVo.setStatus(order.getStatus());
+        orderInfoVo.setTotalNum(order.getTotalNum());
+        orderInfoVo.setPaid(order.getPaid());
+        orderInfoVo.setPayType(order.getPayType());
+        orderInfoVo.setPayTime(order.getPayTime());
+        orderInfoVo.setCreateTime(order.getCreateTime());
+        if (order.getStatus() <= OrderConstants.ORDER_STATUS_WAIT_SHIPPING || order.getStatus().equals(OrderConstants.ORDER_STATUS_AWAIT_VERIFICATION)) {// 未发货
+            orderInfoVo.setDeliveryNum(0);
+        } else {
+            orderInfoVo.setDeliveryNum(order.getTotalNum());
+//            if (!merchantOrder.getIsSplitDelivery()) {
+//                orderInfoVo.setDeliveryNum(merchantOrder.getTotalNum());
+//            } else {
+//                List<SecondHandOrderDetail> orderDetailList = orderDetailService.getShipmentByOrderNo(orderNo);
+//                int deliveryNum = orderDetailList.stream().mapToInt(SecondHandOrderDetail::getDeliveryNum).sum();
+//                orderInfoVo.setDeliveryNum(deliveryNum);
+//            }
+        }
+
+        orderInfoVo.setProTotalPrice(order.getProTotalPrice());
+        orderInfoVo.setPayPrice(order.getPayPrice());
+        orderInfoVo.setPayPostage(order.getPayPostage());
+        orderInfoVo.setUserRemark(order.getUserRemark());
+        orderInfoVo.setMerchantRemark(order.getUserRemark());
+        orderInfoVo.setShippingType(order.getShippingType());
+        orderInfoVo.setRealName(order.getRealName());
+        orderInfoVo.setUserPhone(order.getUserPhone());
+        orderInfoVo.setUserAddress(order.getUserAddress());
+        orderInfoVo.setRefundStatus(order.getRefundStatus());
+        orderInfoVo.setType(order.getType());
+        return orderInfoVo;
+    }
+
+    /**
+     * 平台端退款订单分页列表
+     * @param request 查询参数
+     * @return PageInfo
+     */
+    @Override
+    public PageInfo<PlatformRefundOrderPageResponse> getPlatformAdminPage(RefundOrderSearchRequest request) {
+        Page<RefundOrder> page = PageHelper.startPage(request.getPage(), request.getLimit());
+        Map<String, Object> map = CollUtil.newHashMap();
+        if (StrUtil.isNotBlank(request.getContent())) {
+            ValidateFormUtil.validatorUserCommonSearch(request);
+            String keywords = URLUtil.decode(request.getContent());
+            switch (request.getSearchType()) {
+                case UserConstants.USER_SEARCH_TYPE_ALL:
+                    map.put("keywords", keywords);
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_UID:
+                    map.put("uid", Integer.valueOf(request.getContent()));
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_NICKNAME:
+                    map.put("nickname", keywords);
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_PHONE:
+                    map.put("phone", request.getContent());
+                    break;
+            }
+        }
+        //时间范围
+        if (StrUtil.isNotBlank(request.getDateLimit())) {
+            DateLimitUtilVo dateLimit = CrmebDateUtil.getDateLimit(request.getDateLimit());
+            //判断时间
+            int compareDateResult = CrmebDateUtil.compareDate(dateLimit.getEndTime(), dateLimit.getStartTime(), DateConstants.DATE_FORMAT);
+            if (compareDateResult == -1) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "开始时间不能大于结束时间!");
+            }
+            if (StrUtil.isNotBlank(dateLimit.getStartTime())) {
+                map.put("startTime", dateLimit.getStartTime());
+                map.put("endTime", dateLimit.getEndTime());
+            }
+        }
+        if (ObjectUtil.isNotNull(request.getMerId()) && request.getMerId() > 0) {
+            map.put("merId", request.getMerId());
+        }
+        if (StrUtil.isNotBlank(request.getRefundOrderNo())) {
+            map.put("refundOrderNo", request.getRefundOrderNo());
+        }
+        if (StrUtil.isNotBlank(request.getOrderNo())) {
+            map.put("orderNo", request.getOrderNo());
+        }
+        if (StrUtil.isNotBlank(request.getTrackingNumber())) {
+            map.put("trackingNumber", request.getTrackingNumber());
+        }
+        if (ObjectUtil.isNotNull(request.getRefundStatus()) && request.getRefundStatus() != 9) {
+            map.put("refundStatus", request.getRefundStatus());
+        }
+        List<PlatformRefundOrderPageResponse> responseList = dao.getPlatformAdminPage(map);
+        return CommonPage.copyPageInfo(page, responseList);
+    }
+
+    /**
+     * 获取平台端退款订单各状态数量
+     * @return RefundOrderCountItemResponse
+     */
+    @Override
+    public RefundOrderCountItemResponse getPlatformOrderStatusNum(RefundOrderSearchRequest request) {
+        return getOrderStatusNum(request, ObjectUtil.isNull(request.getMerId()) ? 0 : request.getMerId());
+    }
+
+    /**
+     * 平台备注退款单
+     * @param request 备注参数
+     * @return Boolean
+     */
+    @Override
+    public Boolean platformMark(RefundOrderRemarkRequest request) {
+        SecondHandRefundOrder refundOrder = getInfoException(request.getRefundOrderNo());
+        refundOrder.setPlatformRemark(request.getRemark());
+        return updateById(refundOrder);
+    }
+
+    /**fan
+     * 平台端退款订单详情
+     * @param refundOrderNo 退款单号
+     * @return 退款单详情
+     */
+    @Override
+    public RefundOrderAdminDetailResponse getPlatformDetail(String refundOrderNo) {
+        SecondHandRefundOrder refundOrder = getInfoException(refundOrderNo);
+        SecondHandRefundOrderInfo refundOrderInfo = refundOrderInfoService.getByRefundOrderNo(refundOrderNo);
+
+        RefundOrderAdminDetailResponse response = new RefundOrderAdminDetailResponse();
+        response.setRefundOrderNo(refundOrder.getRefundOrderNo());
+        response.setAfterSalesType(refundOrder.getAfterSalesType());
+        response.setRefundStatus(refundOrder.getRefundStatus());
+        response.setRefundPrice(refundOrder.getRefundPrice());
+        response.setPayPrice(refundOrderInfo.getPayPrice());
+        response.setPromoterType(refundOrder.getPromoterType());
+
+        response.setProductName(refundOrderInfo.getProductName());
+        response.setImage(refundOrderInfo.getImage());
+        response.setSku(refundOrderInfo.getSku());
+        response.setPrice(refundOrderInfo.getPrice());
+        response.setRefundTime(refundOrder.getRefundTime());
+        response.setPayNum(refundOrderInfo.getPayNum());
+
+        response.setRefundFreightFee(refundOrder.getRefundFreightFee());
+        response.setApplyRefundNum(refundOrder.getTotalNum());
+
+        response.setReturnGoodsType(refundOrder.getReturnGoodsType());
+        response.setRefundReasonWap(refundOrder.getRefundReasonWap());
+        response.setRefundReasonWapImg(refundOrder.getRefundReasonWapImg());
+        response.setRefundReasonWapExplain(refundOrder.getRefundReasonWapExplain());
+        response.setReceiver(refundOrder.getReceiver());
+        response.setReceiverPhone(refundOrder.getReceiverPhone());
+        response.setReceiverAddressDetail(refundOrder.getReceiverAddressDetail());
+        response.setExpressName(refundOrder.getExpressName());
+        response.setTrackingNumber(refundOrder.getTrackingNumber());
+        response.setTelephone(refundOrder.getTelephone());
+        response.setIsUserRevoke(refundOrder.getIsUserRevoke());
+        response.setRefundReason(refundOrder.getRefundReason());
+
+        response.setMerRemark(refundOrder.getMerRemark());
+        response.setPlatformRemark(refundOrder.getPlatformRemark());
+
+        response.setStatusList(refundOrderStatusService.findListByRefundOrderNo(refundOrderNo));
+
+        RefundOrderDetailOrderInfoVo orderInfoVo = getRefundOrderDetailOrderInfo(refundOrder.getOrderNo());
+        response.setOrderInfoVo(orderInfoVo);
+        return response;
+    }
+
+    /**
+     * 获取某一天的所有数据
+     * @param merId 商户id,0为所有商户
+     * @param date 日期:年-月-日
+     * @return List
+     */
+    @Override
+    public List<SecondHandRefundOrder> findByDate(Integer merId, String date) {
+        LambdaQueryWrapper<SecondHandRefundOrder> lqw = Wrappers.lambdaQuery();
+        if (merId > 0) {
+            lqw.eq(SecondHandRefundOrder::getMerId, merId);
+        }
+        lqw.eq(SecondHandRefundOrder::getRefundStatus, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND);
+        lqw.apply("date_format(refund_time, '%Y-%m-%d') = {0}", date);
+        return dao.selectList(lqw);
+    }
+
+    /**
+     * 获取某一月的所有数据
+     * @param merId 商户id,0为所有商户
+     * @param month 日期:年-月
+     * @return List
+     */
+    @Override
+    public List<SecondHandRefundOrder> findByMonth(Integer merId, String month) {
+        LambdaQueryWrapper<SecondHandRefundOrder> lqw = Wrappers.lambdaQuery();
+        if (merId > 0) {
+            lqw.eq(SecondHandRefundOrder::getMerId, merId);
+        }
+        lqw.eq(SecondHandRefundOrder::getRefundStatus, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND);
+        lqw.apply("date_format(refund_time, '%Y-%m') = {0}", month);
+        return dao.selectList(lqw);
+    }
+
+    /**
+     * 根据日期获取退款订单数量
+     * @param date 日期
+     * @return Integer
+     */
+    @Override
+    public Integer getRefundOrderNumByDate(String date) {
+        LambdaQueryWrapper<SecondHandRefundOrder> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandRefundOrder::getId);
+        lqw.eq(SecondHandRefundOrder::getRefundStatus, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND);
+        lqw.apply("date_format(update_time, '%Y-%m-%d') = {0}", date);
+        return dao.selectCount(lqw);
+    }
+
+    /**
+     * 根据日期获取退款订单金额
+     * @param date 日期
+     * @return Integer
+     */
+    @Override
+    public BigDecimal getRefundOrderAmountByDate(String date) {
+        LambdaQueryWrapper<SecondHandRefundOrder> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandRefundOrder::getRefundPrice);
+        lqw.eq(SecondHandRefundOrder::getRefundStatus, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND);
+        lqw.apply("date_format(update_time, '%Y-%m-%d') = {0}", date);
+        List<SecondHandRefundOrder> orderList = dao.selectList(lqw);
+        if (CollUtil.isEmpty(orderList)) {
+            return BigDecimal.ZERO;
+        }
+        return orderList.stream().map(SecondHandRefundOrder::getRefundPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
+    }
+
+    /**
+     * 获取退款中(申请)订单数量
+     */
+    @Override
+    public Integer getRefundingCount(Integer userId) {
+        LambdaQueryWrapper<SecondHandRefundOrder> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandRefundOrder::getUid, userId);
+        List<Integer> statusList = new ArrayList<>();
+        statusList.add(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_APPLY);
+        statusList.add(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUNDING);
+        statusList.add(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_RETURN_GOODS);
+        statusList.add(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_AWAIT_RECEIVING);
+        lqw.in(SecondHandRefundOrder::getRefundStatus, statusList);
+        return dao.selectCount(lqw);
+    }
+
+    /**
+     * 获取退款单详情
+     * @param refundOrderNo 退款单号
+     */
+    @Override
+    public SecondHandRefundOrder getByRefundOrderNo(String refundOrderNo) {
+        LambdaQueryWrapper<SecondHandRefundOrder> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandRefundOrder::getRefundOrderNo, refundOrderNo);
+        lqw.last(" limit 1");
+        return dao.selectOne(lqw);
+    }
+
+    /**
+     * 待退款订单数量
+     * @return Integer
+     */
+    @Override
+    public Integer getAwaitAuditNum(Integer merId) {
+        LambdaQueryWrapper<SecondHandRefundOrder> lqw = Wrappers.lambdaQuery();
+        lqw.select(SecondHandRefundOrder::getId);
+        lqw.eq(SecondHandRefundOrder::getRefundStatus, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_APPLY);
+        if (merId > 0) {
+            lqw.eq(SecondHandRefundOrder::getMerId, merId);
+        }
+        return dao.selectCount(lqw);
+    }
+
+    /**
+     * 撤销退款单
+     * @param refundOrderNo 退款单号
+     */
+    @Override
+    public Boolean revoke(String refundOrderNo) {
+        SecondHandRefundOrder refundOrder = getByRefundOrderNo(refundOrderNo);
+        if (ObjectUtil.isNull(refundOrder)) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_NOT_EXIST);
+        }
+        if (!(refundOrder.getRefundStatus() == 0 || refundOrder.getRefundStatus() == 4 || refundOrder.getRefundStatus() == 5)) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_STATUS_ABNORMAL);
+        }
+        SecondHandOrder order = orderService.getByOrderNo(refundOrder.getOrderNo());
+        if (ObjectUtil.isNull(order)) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST.setMessage("退款单关联的订单不存在"));
+        }
+        refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REVOKE);
+        refundOrder.setIsUserRevoke(true);
+        SecondHandRefundOrderInfo refundOrderInfo = refundOrderInfoService.getByRefundOrderNo(refundOrder.getRefundOrderNo());
+        SecondHandOrderDetail orderDetail = orderDetailService.getById(refundOrderInfo.getOrderDetailId());
+        orderDetail.setApplyRefundNum(orderDetail.getApplyRefundNum() - refundOrderInfo.getApplyRefundNum());
+        Boolean execute = transactionTemplate.execute(e -> {
+            updateById(refundOrder);
+            orderDetailService.updateById(orderDetail);
+            refundOrderStatusService.add(refundOrderNo, RefundOrderConstants.REFUND_ORDER_LOG_REVOKE, "用户撤销退款");
+            return Boolean.TRUE;
+        });
+        if (execute) {
+            // 设置订单退款状态
+            settingOrderStatus(order);
+            orderService.updateById(order);
+        }
+        return execute;
+    }
+
+    /**
+     * 退款单审核
+     * @param request 审核参数
+     * @return 审核结果
+     */
+    @Override
+    public Boolean audit(OrderRefundAuditRequest request, SystemAdmin systemAdmin) {
+        validatedAuditRequest(request);
+
+        SecondHandRefundOrder refundOrder = getInfoException(request.getRefundOrderNo());
+        if (!refundOrder.getRefundStatus().equals(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_APPLY)) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_STATUS_ABNORMAL);
+        }
+        if (!refundOrder.getMerId().equals(systemAdmin.getMerId())) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_NOT_EXIST);
+        }
+        SecondHandOrder order = orderService.getByOrderNo(refundOrder.getOrderNo());
+        if (ObjectUtil.isNull(order)) {
+            throw new CrmebException(OrderResultCode.ORDER_NOT_EXIST.setMessage("退款单关联的订单不存在"));
+        }
+        if (request.getAuditType().equals(RefundOrderConstants.REFUND_ORDER_AUDIT_REFUSE)) {
+            refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REJECT);
+            refundOrder.setRefundReason(request.getReason());
+            SecondHandRefundOrderInfo refundOrderInfo = refundOrderInfoService.getByRefundOrderNo(refundOrder.getRefundOrderNo());
+            SecondHandOrderDetail orderDetail = orderDetailService.getById(refundOrderInfo.getOrderDetailId());
+            orderDetail.setApplyRefundNum(orderDetail.getApplyRefundNum() - refundOrderInfo.getApplyRefundNum());
+            Boolean execute = transactionTemplate.execute(e -> {
+                updateById(refundOrder);
+                orderDetailService.updateById(orderDetail);
+                refundOrderStatusService.add(refundOrder.getRefundOrderNo(), RefundOrderConstants.REFUND_ORDER_LOG_AUDIT, "售后单商家审核拒绝");
+                return Boolean.TRUE;
+            });
+            if (execute) {
+                // 设置订单退款状态
+                settingOrderStatus(order);
+                orderService.updateById(order);
+            }
+            return execute;
+        }
+        if (refundOrder.getAfterSalesType().equals(RefundOrderConstants.REFUND_ORDER_AFTER_SALES_TYPE_PRICE_PRODUCT)) {
+            if (refundOrder.getReturnGoodsType().equals(1)) {
+                if (ObjectUtil.isNull(request.getMerAddressId())) {
+                    throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "请选择商家退货地址");
+                }
+                MerchantAddress merchantAddress = merchantAddressService.getByIdException(request.getMerAddressId());
+                refundOrder.setReceiver(merchantAddress.getReceiverName());
+                refundOrder.setReceiverPhone(merchantAddress.getReceiverPhone());
+                refundOrder.setReceiverAddressDetail(merchantAddress.getDetail());
+            }
+            refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_RETURN_GOODS);
+
+            return transactionTemplate.execute(e -> {
+                updateById(refundOrder);
+                refundOrderStatusService.add(refundOrder.getRefundOrderNo(), RefundOrderConstants.REFUND_ORDER_LOG_AUDIT, "售后单商家审核通过");
+                return Boolean.TRUE;
+            });
+        }
+        Boolean refundResult = refundPrice(refundOrder, order);
+        if (refundResult) {
+            refundOrderStatusService.add(refundOrder.getRefundOrderNo(), RefundOrderConstants.REFUND_ORDER_LOG_AUDIT, "售后单商家审核通过");
+        }
+        return refundResult;
+    }
+
+    /**
+     * 退款单收到退货
+     * @param refundOrderNo 退款单号
+     */
+    @Override
+    public Boolean receiving(String refundOrderNo, SystemAdmin systemAdmin) {
+        SecondHandRefundOrder refundOrder = getInfoException(refundOrderNo);
+        if (refundOrder.getRefundStatus().equals(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REJECT)
+            || refundOrder.getRefundStatus().equals(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUNDING)
+            || refundOrder.getRefundStatus().equals(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND)
+            || refundOrder.getRefundStatus().equals(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REVOKE)) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_STATUS_ABNORMAL);
+        }
+        if (!refundOrder.getMerId().equals(systemAdmin.getMerId())) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_NOT_EXIST);
+        }
+
+        SecondHandOrder order = orderService.getByOrderNo(refundOrder.getOrderNo());
+        Boolean refundResult = refundPrice(refundOrder, order);
+        if (refundResult) {
+            refundOrderStatusService.add(refundOrder.getRefundOrderNo(), RefundOrderConstants.REFUND_ORDER_LOG_RECEIVING, "售后单商家确认收货");
+        }
+        return refundResult;
+    }
+
+    /**
+     * 平台强制退款
+     * @param refundOrderNo 退款单号
+     */
+    @Override
+    public Boolean compulsoryRefund(String refundOrderNo, SystemAdmin systemAdmin) {
+        SecondHandRefundOrder refundOrder = getInfoException(refundOrderNo);
+        if (!refundOrder.getRefundStatus().equals(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_APPLY)
+                && !refundOrder.getRefundStatus().equals(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_AWAIT_RECEIVING)) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_STATUS_ABNORMAL);
+        }
+        SecondHandOrder order = orderService.getByOrderNo(refundOrder.getOrderNo());
+        refundOrder.setIsCompulsoryRefund(true);
+        refundOrder.setCompulsoryAdminId(systemAdmin.getId());
+        Boolean refundResult = refundPrice(refundOrder, order);
+        if (refundResult) {
+            refundOrderStatusService.add(refundOrder.getRefundOrderNo(), RefundOrderConstants.REFUND_ORDER_LOG_COMPULSORY, "平台强制退款");
+        }
+        return refundResult;
+    }
+
+    /**
+     * 退款单-商家拒绝收货退款
+     * @param request 拒绝收货请求对象
+     */
+    @Override
+    public Boolean receivingReject(RejectReceivingRequest request, SystemAdmin systemAdmin) {
+        SecondHandRefundOrder refundOrder = getInfoException(request.getRefundOrderNo());
+        if (!refundOrder.getMerId().equals(systemAdmin.getMerId())) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_NOT_EXIST);
+        }
+        if (!refundOrder.getRefundStatus().equals(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_AWAIT_RECEIVING)) {
+            throw new CrmebException(OrderResultCode.REFUND_ORDER_STATUS_ABNORMAL);
+        }
+        refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REJECT);
+        refundOrder.setRefundReason(request.getReason());
+        SecondHandRefundOrderInfo refundOrderInfo = refundOrderInfoService.getByRefundOrderNo(refundOrder.getRefundOrderNo());
+        SecondHandOrder order = orderService.getByOrderNo(refundOrder.getOrderNo());
+        SecondHandOrderDetail orderDetail = orderDetailService.getById(refundOrderInfo.getOrderDetailId());
+        orderDetail.setApplyRefundNum(orderDetail.getApplyRefundNum() - refundOrderInfo.getApplyRefundNum());
+        Boolean execute = transactionTemplate.execute(e -> {
+            updateById(refundOrder);
+            orderDetailService.updateById(orderDetail);
+            refundOrderStatusService.add(refundOrder.getRefundOrderNo(), RefundOrderConstants.REFUND_ORDER_LOG_REJECTION_GOODS, "售后单商家拒绝收货");
+            return Boolean.TRUE;
+        });
+        if (execute) {
+            // 设置订单退款状态
+            settingOrderStatus(order);
+            orderService.updateById(order);
+        }
+        return execute;
+    }
+
+    /**
+     * 自动撤销退款
+     */
+    @Override
+    public void autoRevoke() {
+        List<SecondHandRefundOrder> refundOrderList = findCanAutoRevokeOrderList();
+        if (CollUtil.isEmpty(refundOrderList)) {
+            return;
+        }
+        for (SecondHandRefundOrder refundOrder : refundOrderList) {
+            SecondHandOrder order = orderService.getByOrderNo(refundOrder.getOrderNo());
+            if (ObjectUtil.isNull(order)) {
+                continue;
+            }
+            refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REVOKE);
+            refundOrder.setIsUserRevoke(false);
+            SecondHandRefundOrderInfo refundOrderInfo = refundOrderInfoService.getByRefundOrderNo(refundOrder.getRefundOrderNo());
+            SecondHandOrderDetail orderDetail = orderDetailService.getById(refundOrderInfo.getOrderDetailId());
+            orderDetail.setApplyRefundNum(orderDetail.getApplyRefundNum() - refundOrderInfo.getApplyRefundNum());
+            updateById(refundOrder);
+            orderDetailService.updateById(orderDetail);
+            refundOrderStatusService.add(refundOrder.getRefundOrderNo(), RefundOrderConstants.REFUND_ORDER_LOG_REVOKE, "系统自动撤销退款单");
+            settingOrderStatus(order);
+            orderService.updateById(order);
+        }
+    }
+
+    /**
+     * 查询支付宝退款定时任务
+     */
+    @Override
+    public Boolean queryAliPayRefund(String refundOrderNo) {
+        SecondHandRefundOrder refundOrder = getByRefundOrderNo(refundOrderNo);
+        if (ObjectUtil.isNull(refundOrder)) {
+            logger.error("查询支付宝退款 : 订单信息不存在==》{}", refundOrderNo);
+            return false;
+        }
+        if (refundOrder.getRefundStatus().equals(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND)) {
+            return true;
+        }
+        if (!refundOrder.getRefundStatus().equals(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUNDING)) {
+            logger.error("查询支付宝退款 : 退款单状态异常==> {}", refundOrderNo);
+            return false;
+        }
+        SecondHandOrder order = orderService.getByOrderNo(refundOrder.getOrderNo());
+        Boolean queryResultBoolean = aliPayService.queryRefund(order.getPlatOrderNo(), refundOrder.getOutRefundNo());
+        if (!queryResultBoolean) {
+            logger.error("查询支付宝退款 : 支付宝查询失败==> {}", refundOrderNo);
+            return false;
+        }
+        refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND);
+        boolean update = updateById(refundOrder);
+        if (!update) {
+            logger.error("查询支付宝退款 : 支付宝退款订单更新失败==> {}", refundOrderNo);
+            return false;
+        }
+        // 退款task
+        return redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER, refundOrderNo);
+    }
+
+    /**
+     * 订单退款是否包含用户退款
+     * @param orderNo 订单编号
+     */
+    @Override
+    public Boolean isOrderContainUserRefund(String orderNo) {
+        LambdaQueryWrapper<SecondHandRefundOrder> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandRefundOrder::getOrderNo, orderNo);
+        lqw.notIn(SecondHandRefundOrder::getRefundStatus, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REJECT, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REVOKE);
+        lqw.eq(SecondHandRefundOrder::getPromoterType, "user");
+        Integer count = dao.selectCount(lqw);
+        return count > 0;
+    }
+
+    /**
+     * 商户直接退款
+     * @param order 订单
+     * @param orderDetailList 需要退款的订单详情列表
+     */
+    @Override
+    public Boolean merchantDirectRefund(SecondHandOrder order, List<SecondHandOrderDetail> orderDetailList) {
+        // 生成退款单
+        String outRefundNo = CrmebUtil.getOrderNo(OrderConstants.ORDER_PREFIX_REFUND);
+        List<SecondHandRefundOrder> refundOrderList = new ArrayList<>();
+        List<SecondHandRefundOrderInfo> refundOrderInfoList = new ArrayList<>();
+        BigDecimal totalRefundPrice = BigDecimal.ZERO;
+        for (SecondHandOrderDetail orderDetail : orderDetailList) {
+            SecondHandRefundOrder refundOrder = new SecondHandRefundOrder();
+            refundOrder.setRefundOrderNo(CrmebUtil.getOrderNo(OrderConstants.ORDER_PREFIX_REFUND));
+            refundOrder.setOrderNo(order.getOrderNo());
+            refundOrder.setMerId(order.getSellerId());
+            refundOrder.setUid(order.getUid());
+            refundOrder.setRealName(order.getRealName());
+            refundOrder.setUserPhone(order.getUserPhone());
+            refundOrder.setUserAddress(order.getUserAddress());
+            refundOrder.setTotalNum(orderDetail.getApplyRefundNum());
+            refundOrder.setRefundReasonWap("");
+            refundOrder.setRefundReasonWapImg("");
+            refundOrder.setRefundReasonWapExplain("");
+            refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_APPLY);
+            refundOrder.setAfterSalesType(1);
+            refundOrder.setReturnGoodsType(0);
+            refundOrder.setPromoterType("merchant");
+
+            SecondHandRefundOrderInfo refundOrderInfo = new SecondHandRefundOrderInfo();
+            refundOrderInfo.setRefundOrderNo(refundOrder.getRefundOrderNo());
+            refundOrderInfo.setMerId(orderDetail.getSellerId());
+            refundOrderInfo.setOrderDetailId(orderDetail.getId());
+            refundOrderInfo.setProductId(orderDetail.getProductId());
+            refundOrderInfo.setProductName(orderDetail.getProductName());
+            refundOrderInfo.setImage(orderDetail.getImage());
+            refundOrderInfo.setPrice(orderDetail.getPrice());
+            refundOrderInfo.setPayNum(orderDetail.getPayNum());
+            refundOrderInfo.setProductType(orderDetail.getProductType());
+            refundOrderInfo.setPayPrice(orderDetail.getPayPrice());
+            refundOrderInfo.setApplyRefundNum(orderDetail.getApplyRefundNum());
+
+            BigDecimal refundPrice;
+            if (orderDetail.getPayNum().equals(refundOrderInfo.getApplyRefundNum())) {
+                // sku整退
+                refundPrice = orderDetail.getPayPrice();
+                orderDetail.setRefundPrice(refundPrice);
+                refundOrderInfo.setRefundPrice(refundPrice);
+                if (orderDetail.getFreightFee().compareTo(BigDecimal.ZERO) > 0) {
+                    refundOrderInfo.setRefundFreightFee(orderDetail.getFreightFee());
+                    orderDetail.setRefundFreightFee(orderDetail.getFreightFee());
+                }
+                refundOrderInfo.setMerchantRefundPrice(refundPrice);
+            } else if (orderDetail.getPayNum() == (orderDetail.getRefundNum() + refundOrderInfo.getApplyRefundNum())) { // sku分退
+                refundPrice = orderDetail.getPayPrice().subtract(orderDetail.getRefundPrice());
+                // sku最后一部分退款
+                orderDetail.setRefundPrice(orderDetail.getPayPrice());
+                refundOrderInfo.setRefundPrice(refundPrice);
+                refundOrderInfo.setMerchantRefundPrice(refundPrice);
+
+                if (orderDetail.getFreightFee().compareTo(BigDecimal.ZERO) > 0) {
+                    refundOrderInfo.setRefundFreightFee(orderDetail.getFreightFee().subtract(orderDetail.getRefundFreightFee()));
+                    orderDetail.setRefundFreightFee(orderDetail.getFreightFee());
+                }
+            } else {
+                // sku非最后一部分退款
+                BigDecimal ratio = new BigDecimal(refundOrderInfo.getApplyRefundNum()).divide(new BigDecimal(orderDetail.getPayNum()), 10, BigDecimal.ROUND_HALF_UP);
+                refundPrice = orderDetail.getPayPrice().multiply(ratio).setScale(2, BigDecimal.ROUND_HALF_UP);
+                orderDetail.setRefundPrice(orderDetail.getRefundPrice().add(refundPrice));
+                refundOrderInfo.setRefundPrice(refundPrice);
+                refundOrderInfo.setMerchantRefundPrice(refundPrice);
+                if (orderDetail.getFreightFee().compareTo(BigDecimal.ZERO) > 0) {
+                    refundOrderInfo.setRefundFreightFee(orderDetail.getFreightFee().multiply(ratio).setScale(2, BigDecimal.ROUND_HALF_UP));
+                    orderDetail.setRefundFreightFee(orderDetail.getRefundFreightFee().add(refundOrderInfo.getRefundFreightFee()));
+                }
+            }
+
+            refundOrder.setRefundPrice(refundPrice);
+            refundOrder.setMerchantRefundPrice(refundOrderInfo.getMerchantRefundPrice());
+
+            refundOrder.setRefundPayType(order.getPayType());
+            refundOrder.setRefundFreightFee(refundOrderInfo.getRefundFreightFee());
+
+            orderDetail.setApplyRefundNum(orderDetail.getApplyRefundNum() - refundOrderInfo.getApplyRefundNum());
+            orderDetail.setRefundNum(orderDetail.getRefundNum() + refundOrderInfo.getApplyRefundNum());
+
+            refundOrder.setOutRefundNo(outRefundNo);
+            refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUNDING);
+
+            refundOrderList.add(refundOrder);
+            refundOrderInfoList.add(refundOrderInfo);
+            totalRefundPrice = totalRefundPrice.add(refundPrice);
+        }
+
+        //退款
+        if (order.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT) && totalRefundPrice.compareTo(BigDecimal.ZERO) > 0) {
+            try {
+                SecondHandOrder platOrder = orderService.getByOrderNo(order.getPlatOrderNo());
+                wxRefund(order, outRefundNo, totalRefundPrice, platOrder.getPayPrice());
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CrmebException("商家主动退款,微信申请退款失败!" + e.getMessage());
+            }
+        }
+        Boolean aliPayIsRefund = false;
+        if (order.getPayType().equals(PayConstants.PAY_TYPE_ALI_PAY) && totalRefundPrice.compareTo(BigDecimal.ZERO) > 0) {
+            try {
+                aliPayIsRefund = aliPayService.refund(order.getPlatOrderNo(), outRefundNo, "商家主动退款", totalRefundPrice);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CrmebException("商家主动退款,支付宝申请退款失败!" + e.getMessage());
+            }
+        }
+
+        User user = userService.getById(order.getUid());
+        refundOrderList.forEach(refundOrder -> {
+            refundOrder.setRefundTime(DateUtil.date());
+        });
+        Boolean finalAliPayIsRefund = aliPayIsRefund;
+        BigDecimal finalTotalRefundPrice = totalRefundPrice;
+        Boolean execute = transactionTemplate.execute(e -> {
+            orderDetailService.updateBatchById(orderDetailList);
+
+            if (order.getPayType().equals(PayConstants.PAY_TYPE_YUE)) {
+                refundOrderList.forEach(refundOrder -> {
+                    refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND);
+                });
+                for (SecondHandRefundOrder refundOrder : refundOrderList) {
+                    if (refundOrder.getRefundPrice().compareTo(BigDecimal.ZERO) > 0) {
+                        // 更新用户金额
+                        userService.updateNowMoney(order.getUid(), refundOrder.getRefundPrice(), Constants.OPERATION_TYPE_ADD);
+                        // 用户余额记录
+                        UserBalanceRecord userBalanceRecord = new UserBalanceRecord();
+                        userBalanceRecord.setUid(user.getId());
+                        userBalanceRecord.setLinkId(refundOrder.getRefundOrderNo());
+                        userBalanceRecord.setLinkType(BalanceRecordConstants.BALANCE_RECORD_LINK_TYPE_ORDER);
+                        userBalanceRecord.setType(BalanceRecordConstants.BALANCE_RECORD_TYPE_ADD);
+                        userBalanceRecord.setAmount(refundOrder.getRefundPrice());
+                        userBalanceRecord.setBalance(user.getNowMoney().add(refundOrder.getRefundPrice()));
+                        userBalanceRecord.setRemark(StrUtil.format(BalanceRecordConstants.BALANCE_RECORD_REMARK_ORDER_REFUND, refundOrder.getRefundPrice()));
+                        userBalanceRecordService.save(userBalanceRecord);
+                    }
+                }
+            }
+            if (order.getPayType().equals(PayConstants.PAY_TYPE_ALI_PAY) && finalTotalRefundPrice.compareTo(BigDecimal.ZERO) > 0 && finalAliPayIsRefund) {
+                refundOrderList.forEach(refundOrder -> {
+                    refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND);
+                });
+            }
+            saveBatch(refundOrderList);
+            refundOrderInfoService.saveBatch(refundOrderInfoList);
+            return Boolean.TRUE;
+        });
+        if (execute) {
+            settingOrderStatus(order);
+            orderService.updateById(order);
+            // 积分、佣金、优惠券等放入后置task中处理
+            if (order.getPayType().equals(PayConstants.PAY_TYPE_YUE)) {
+                refundOrderList.forEach(refundOrder -> {
+                    redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER, refundOrder.getRefundOrderNo());
+                });
+            }
+            if (order.getPayType().equals(PayConstants.PAY_TYPE_ALI_PAY) && totalRefundPrice.compareTo(BigDecimal.ZERO) > 0) {
+                if (aliPayIsRefund) {
+                    refundOrderList.forEach(refundOrder -> {
+                        redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER, refundOrder.getRefundOrderNo());
+                    });
+                } else {
+                    refundOrderList.forEach(refundOrder -> {
+                        redisUtil.lPush(TaskConstants.TASK_REFUND_ORDER_ALIPAY_QUERY_KEY, refundOrder.getRefundOrderNo());
+                    });
+                }
+            }
+        }
+        return execute;
+    }
+
+    /**
+     * 根据第三方单号查询退款单
+     * @param outRefundNo 第三方单号
+     */
+    @Override
+    public List<SecondHandRefundOrder> findByOutRefundNo(String outRefundNo) {
+        LambdaQueryWrapper<SecondHandRefundOrder> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SecondHandRefundOrder::getOutRefundNo, outRefundNo);
+        return dao.selectList(lqw);
+    }
+
+    private List<SecondHandRefundOrder> findCanAutoRevokeOrderList() {
+        DateTime date = DateUtil.date();
+        DateTime dateTime = DateUtil.offsetDay(date, -7);
+        return dao.findCanAutoRevokeOrderList(dateTime.toString());
+    }
+
+    /**
+     * 退款
+     * @param refundOrder 退款单
+     */
+    private Boolean refundPrice(SecondHandRefundOrder refundOrder, SecondHandOrder order) {
+        SecondHandRefundOrderInfo refundOrderInfo = refundOrderInfoService.getByRefundOrderNo(refundOrder.getRefundOrderNo());
+        SecondHandOrderDetail orderDetail = orderDetailService.getById(refundOrderInfo.getOrderDetailId());
+        BigDecimal refundPrice;
+        if (orderDetail.getPayNum().equals(refundOrderInfo.getApplyRefundNum())) {
+            // sku整退
+            refundPrice = orderDetail.getPayPrice();
+            orderDetail.setRefundPrice(refundPrice);
+            refundOrderInfo.setRefundPrice(refundPrice);
+
+            refundOrderInfo.setMerchantRefundPrice(refundPrice);
+            if (orderDetail.getFreightFee().compareTo(BigDecimal.ZERO) > 0) {
+                refundOrderInfo.setRefundFreightFee(orderDetail.getFreightFee());
+                orderDetail.setRefundFreightFee(orderDetail.getFreightFee());
+            }
+        } else if (orderDetail.getPayNum() == (orderDetail.getRefundNum() + refundOrderInfo.getApplyRefundNum())) { // sku分退
+            refundPrice = orderDetail.getPayPrice().subtract(orderDetail.getRefundPrice());
+            // sku最后一部分退款
+            orderDetail.setRefundPrice(orderDetail.getPayPrice());
+            refundOrderInfo.setRefundPrice(refundPrice);
+            refundOrderInfo.setMerchantRefundPrice(refundPrice);
+
+            if (orderDetail.getFreightFee().compareTo(BigDecimal.ZERO) > 0) {
+                refundOrderInfo.setRefundFreightFee(orderDetail.getFreightFee().subtract(orderDetail.getRefundFreightFee()));
+                orderDetail.setRefundFreightFee(orderDetail.getFreightFee());
+            }
+        } else {
+            // sku非最后一部分退款
+            BigDecimal ratio = new BigDecimal(refundOrderInfo.getApplyRefundNum()).divide(new BigDecimal(orderDetail.getPayNum()), 10, BigDecimal.ROUND_HALF_UP);
+            refundPrice = orderDetail.getPayPrice().multiply(ratio).setScale(2, BigDecimal.ROUND_HALF_UP);
+            orderDetail.setRefundPrice(orderDetail.getRefundPrice().add(refundPrice));
+            refundOrderInfo.setRefundPrice(refundPrice);
+            refundOrderInfo.setMerchantRefundPrice(refundPrice);
+
+
+            if (orderDetail.getFreightFee().compareTo(BigDecimal.ZERO) > 0) {
+                refundOrderInfo.setRefundFreightFee(orderDetail.getFreightFee().multiply(ratio).setScale(2, BigDecimal.ROUND_HALF_UP));
+                orderDetail.setRefundFreightFee(orderDetail.getRefundFreightFee().add(refundOrderInfo.getRefundFreightFee()));
+            }
+        }
+
+        refundOrder.setRefundPrice(refundPrice);
+        refundOrder.setMerchantRefundPrice(refundOrderInfo.getMerchantRefundPrice());
+
+        refundOrder.setRefundPayType(order.getPayType());
+        refundOrder.setRefundFreightFee(refundOrderInfo.getRefundFreightFee());
+        //退款
+        if (order.getPayType().equals(PayConstants.PAY_TYPE_WE_CHAT) && refundPrice.compareTo(BigDecimal.ZERO) > 0) {
+            try {
+                SecondHandOrder platOrder = orderService.getByOrderNo(order.getPlatOrderNo());
+                wxRefund(order, refundOrder.getOutRefundNo(), refundPrice, platOrder.getPayPrice());
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CrmebException("微信申请退款失败!" + e.getMessage());
+            }
+        }
+        Boolean aliPayIsRefund = false;
+        if (order.getPayType().equals(PayConstants.PAY_TYPE_ALI_PAY) && refundPrice.compareTo(BigDecimal.ZERO) > 0) {
+            try {
+                aliPayIsRefund = aliPayService.refund(order.getPlatOrderNo(), refundOrder.getOutRefundNo(), refundOrder.getRefundReasonWapExplain(), refundPrice);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new CrmebException("支付宝申请退款失败!" + e.getMessage());
+            }
+        }
+
+        orderDetail.setApplyRefundNum(orderDetail.getApplyRefundNum() - refundOrderInfo.getApplyRefundNum());
+        orderDetail.setRefundNum(orderDetail.getRefundNum() + refundOrderInfo.getApplyRefundNum());
+
+        User user = userService.getById(order.getUid());
+        refundOrder.setRefundTime(DateUtil.date());
+        Boolean finalAliPayIsRefund = aliPayIsRefund;
+        Boolean execute = transactionTemplate.execute(e -> {
+            orderDetailService.updateById(orderDetail);
+            refundOrderInfoService.updateById(refundOrderInfo);
+            refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUNDING);
+            if (order.getPayType().equals(PayConstants.PAY_TYPE_YUE)) {
+                refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND);
+                if (refundOrder.getRefundPrice().compareTo(BigDecimal.ZERO) > 0) {
+                    // 更新用户金额
+                    userService.updateNowMoney(order.getUid(), refundOrder.getRefundPrice(), Constants.OPERATION_TYPE_ADD);
+                    // 用户余额记录
+                    UserBalanceRecord userBalanceRecord = new UserBalanceRecord();
+                    userBalanceRecord.setUid(user.getId());
+                    userBalanceRecord.setLinkId(refundOrder.getRefundOrderNo());
+                    userBalanceRecord.setLinkType(BalanceRecordConstants.BALANCE_RECORD_LINK_TYPE_ORDER);
+                    userBalanceRecord.setType(BalanceRecordConstants.BALANCE_RECORD_TYPE_ADD);
+                    userBalanceRecord.setAmount(refundOrder.getRefundPrice());
+                    userBalanceRecord.setBalance(user.getNowMoney().add(refundOrder.getRefundPrice()));
+                    userBalanceRecord.setRemark(StrUtil.format(BalanceRecordConstants.BALANCE_RECORD_REMARK_ORDER_REFUND, refundOrder.getRefundPrice()));
+                    userBalanceRecordService.save(userBalanceRecord);
+                }
+            }
+            if (order.getPayType().equals(PayConstants.PAY_TYPE_ALI_PAY) && refundPrice.compareTo(BigDecimal.ZERO) > 0 && finalAliPayIsRefund) {
+                refundOrder.setRefundStatus(OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND);
+            }
+            updateById(refundOrder);
+            return Boolean.TRUE;
+        });
+        if (execute) {
+            settingOrderStatus(order);
+            orderService.updateById(order);
+            // 积分、佣金、优惠券等放入后置task中处理
+            if (order.getPayType().equals(PayConstants.PAY_TYPE_YUE)) {
+                redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER, refundOrder.getRefundOrderNo());
+            }
+            if (order.getPayType().equals(PayConstants.PAY_TYPE_ALI_PAY) && refundPrice.compareTo(BigDecimal.ZERO) > 0) {
+                if (aliPayIsRefund) {
+                    redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AFTER_REFUND_BY_USER, refundOrder.getRefundOrderNo());
+                } else {
+                    redisUtil.lPush(TaskConstants.TASK_REFUND_ORDER_ALIPAY_QUERY_KEY, refundOrder.getRefundOrderNo());
+                }
+            }
+        }
+        return execute;
+    }
+
+    /**
+     * 校验审核参数
+     */
+    private void validatedAuditRequest(OrderRefundAuditRequest request) {
+        if (request.getAuditType().equals("refuse")) {
+            if (StrUtil.isEmpty(request.getReason())) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "请填写拒绝退款原因");
+            }
+        }
+    }
+
+    /**
+     * 获取退款订单各状态数量
+     *
+     * @param merId     商户id,平台为0
+     * @return RefundOrderCountItemResponse
+     */
+    private RefundOrderCountItemResponse getOrderStatusNum(RefundOrderSearchRequest request, Integer merId) {
+        RefundOrderCountItemResponse response = new RefundOrderCountItemResponse();
+        // 全部订单
+        response.setAll(getCount(request, 9, merId));
+        // 待审核
+        response.setAwait(getCount(request, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_APPLY, merId));
+        // 审核拒绝
+        response.setReject(getCount(request, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REJECT, merId));
+        // 退款中
+        response.setRefunding(getCount(request, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUNDING, merId));
+        // 已退款
+        response.setRefunded(getCount(request, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REFUND, merId));
+        response.setAwaitReturning(getCount(request, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_RETURN_GOODS, merId));
+        response.setAwaitReceiving(getCount(request, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_AWAIT_RECEIVING, merId));
+        response.setRevoke(getCount(request, OrderConstants.MERCHANT_REFUND_ORDER_STATUS_REVOKE, merId));
+        return response;
+    }
+
+    /**
+     * 获取订单总数
+     *
+     * @param dateLimit 时间端
+     * @param status    String 状态
+     * @return Integer
+     */
+    private Integer getCount(String dateLimit, Integer status, Integer merId) {
+        //总数只计算时间
+        QueryWrapper<SecondHandRefundOrder> queryWrapper = new QueryWrapper<>();
+        if (merId > 0) {
+            queryWrapper.eq("mer_id", merId);
+        }
+        if (StrUtil.isNotBlank(dateLimit)) {
+            getRequestTimeWhere(queryWrapper, dateLimit);
+        }
+        getStatusWhere(queryWrapper, status);
+        return dao.selectCount(queryWrapper);
+    }
+
+    /**
+     * 获取订单总数
+     *
+     * @param status    String 状态
+     * @return Integer
+     */
+    private Integer getCount(RefundOrderSearchRequest request, Integer status, Integer merId) {
+        Map<String, Object> map = CollUtil.newHashMap();
+        if (StrUtil.isNotBlank(request.getContent())) {
+            ValidateFormUtil.validatorUserCommonSearch(request);
+            String keywords = URLUtil.decode(request.getContent());
+            switch (request.getSearchType()) {
+                case UserConstants.USER_SEARCH_TYPE_ALL:
+                    map.put("keywords", keywords);
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_UID:
+                    map.put("uid", Integer.valueOf(request.getContent()));
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_NICKNAME:
+                    map.put("nickname", keywords);
+                    break;
+                case UserConstants.USER_SEARCH_TYPE_PHONE:
+                    map.put("phone", request.getContent());
+                    break;
+            }
+        }
+        //时间范围
+        if (StrUtil.isNotBlank(request.getDateLimit())) {
+            DateLimitUtilVo dateLimit = CrmebDateUtil.getDateLimit(request.getDateLimit());
+            //判断时间
+            int compareDateResult = CrmebDateUtil.compareDate(dateLimit.getEndTime(), dateLimit.getStartTime(), DateConstants.DATE_FORMAT);
+            if (compareDateResult == -1) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "开始时间不能大于结束时间!");
+            }
+            if (StrUtil.isNotBlank(dateLimit.getStartTime())) {
+                map.put("startTime", dateLimit.getStartTime());
+                map.put("endTime", dateLimit.getEndTime());
+            }
+        }
+        if (merId > 0) {
+            map.put("merId",  merId);
+        }
+        if (StrUtil.isNotBlank(request.getRefundOrderNo())) {
+            map.put("refundOrderNo", request.getRefundOrderNo());
+        }
+        if (StrUtil.isNotBlank(request.getOrderNo())) {
+            map.put("orderNo", request.getOrderNo());
+        }
+        if (StrUtil.isNotBlank(request.getTrackingNumber())) {
+            map.put("trackingNumber", request.getTrackingNumber());
+        }
+        if (ObjectUtil.isNotNull(status) && status != 9) {
+            map.put("refundStatus", status);
+        }
+        return dao.getMerchantAdminPageCount(map);
+    }
+
+    /**
+     * 获取request的where条件
+     *
+     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
+     * @param dateLimit    时间区间参数
+     */
+    private void getRequestTimeWhere(QueryWrapper<SecondHandRefundOrder> queryWrapper, String dateLimit) {
+        DateLimitUtilVo dateLimitUtilVo = CrmebDateUtil.getDateLimit(dateLimit);
+        queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime());
+    }
+
+    /**
+     * 根据订单状态获取where条件
+     *
+     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
+     * @param status       Integer 类型 9-全部
+     */
+    private void getStatusWhere(QueryWrapper<SecondHandRefundOrder> queryWrapper, Integer status) {
+        if (ObjectUtil.isNull(status)) {
+            return;
+        }
+        if (status == 9) {
+            return;
+        }
+        queryWrapper.eq("refund_status", status);
+    }
+}
+

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů