From ba97d65f344fb6d7f4e80a7f8e831bd6c84613fa Mon Sep 17 00:00:00 2001 From: b2894lxlx <517289602@qq.com> Date: Mon, 11 Aug 2025 19:20:54 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=96=B0=E5=A2=9E=E7=A4=BC=E5=93=81?= =?UTF-8?q?=E5=8D=A1=E6=A8=A1=E5=9D=97=202=E3=80=81=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E4=BC=98=E6=83=A0=E5=88=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../ShopCouponApplyCateController.java | 124 ++ .../ShopCouponApplyItemController.java | 125 ++ .../shop/controller/ShopCouponController.java | 93 +- .../shop/controller/ShopGiftController.java | 259 ++++ .../ShopGoodsCategoryController.java | 1 - .../controller/ShopUserCouponController.java | 94 +- .../com/gxwebsoft/shop/entity/ShopCoupon.java | 26 +- .../shop/entity/ShopCouponApplyCate.java | 50 + .../shop/entity/ShopCouponApplyItem.java | 50 + .../com/gxwebsoft/shop/entity/ShopGift.java | 75 + .../gxwebsoft/shop/entity/ShopUserCoupon.java | 16 + .../mapper/ShopCouponApplyCateMapper.java | 37 + .../mapper/ShopCouponApplyItemMapper.java | 37 + .../gxwebsoft/shop/mapper/ShopGiftMapper.java | 37 + .../mapper/xml/ShopCouponApplyCateMapper.xml | 54 + .../mapper/xml/ShopCouponApplyItemMapper.xml | 54 + .../shop/mapper/xml/ShopGiftMapper.xml | 72 + .../shop/param/ShopCouponApplyCateParam.java | 46 + .../shop/param/ShopCouponApplyItemParam.java | 46 + .../gxwebsoft/shop/param/ShopGiftParam.java | 67 + .../service/ShopCouponApplyCateService.java | 43 + .../service/ShopCouponApplyItemService.java | 43 + .../shop/service/ShopGiftService.java | 43 + .../service/ShopOrderUpdate10550Service.java | 21 + .../shop/service/ShopUserCouponService.java | 1 + .../impl/ShopCouponApplyCateServiceImpl.java | 56 + .../impl/ShopCouponApplyItemServiceImpl.java | 56 + .../service/impl/ShopCouponServiceImpl.java | 24 + .../service/impl/ShopGiftServiceImpl.java | 71 + .../service/impl/ShopOrderServiceImpl.java | 1207 ++++++++--------- .../impl/ShopOrderUpdate10550ServiceImpl.java | 90 ++ .../impl/ShopUserCouponServiceImpl.java | 10 + .../gxwebsoft/generator/ShopGenerator.java | 7 +- 34 files changed, 2396 insertions(+), 641 deletions(-) create mode 100644 src/main/java/com/gxwebsoft/shop/controller/ShopCouponApplyCateController.java create mode 100644 src/main/java/com/gxwebsoft/shop/controller/ShopCouponApplyItemController.java create mode 100644 src/main/java/com/gxwebsoft/shop/controller/ShopGiftController.java create mode 100644 src/main/java/com/gxwebsoft/shop/entity/ShopCouponApplyCate.java create mode 100644 src/main/java/com/gxwebsoft/shop/entity/ShopCouponApplyItem.java create mode 100644 src/main/java/com/gxwebsoft/shop/entity/ShopGift.java create mode 100644 src/main/java/com/gxwebsoft/shop/mapper/ShopCouponApplyCateMapper.java create mode 100644 src/main/java/com/gxwebsoft/shop/mapper/ShopCouponApplyItemMapper.java create mode 100644 src/main/java/com/gxwebsoft/shop/mapper/ShopGiftMapper.java create mode 100644 src/main/java/com/gxwebsoft/shop/mapper/xml/ShopCouponApplyCateMapper.xml create mode 100644 src/main/java/com/gxwebsoft/shop/mapper/xml/ShopCouponApplyItemMapper.xml create mode 100644 src/main/java/com/gxwebsoft/shop/mapper/xml/ShopGiftMapper.xml create mode 100644 src/main/java/com/gxwebsoft/shop/param/ShopCouponApplyCateParam.java create mode 100644 src/main/java/com/gxwebsoft/shop/param/ShopCouponApplyItemParam.java create mode 100644 src/main/java/com/gxwebsoft/shop/param/ShopGiftParam.java create mode 100644 src/main/java/com/gxwebsoft/shop/service/ShopCouponApplyCateService.java create mode 100644 src/main/java/com/gxwebsoft/shop/service/ShopCouponApplyItemService.java create mode 100644 src/main/java/com/gxwebsoft/shop/service/ShopGiftService.java create mode 100644 src/main/java/com/gxwebsoft/shop/service/ShopOrderUpdate10550Service.java create mode 100644 src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponApplyCateServiceImpl.java create mode 100644 src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponApplyItemServiceImpl.java create mode 100644 src/main/java/com/gxwebsoft/shop/service/impl/ShopGiftServiceImpl.java create mode 100644 src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderUpdate10550ServiceImpl.java diff --git a/pom.xml b/pom.xml index 94680d7..3c2e497 100644 --- a/pom.xml +++ b/pom.xml @@ -370,7 +370,7 @@ - org.projectlombok + org.project-lombok lombok diff --git a/src/main/java/com/gxwebsoft/shop/controller/ShopCouponApplyCateController.java b/src/main/java/com/gxwebsoft/shop/controller/ShopCouponApplyCateController.java new file mode 100644 index 0000000..ada1a79 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/controller/ShopCouponApplyCateController.java @@ -0,0 +1,124 @@ +package com.gxwebsoft.shop.controller; + +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.shop.service.ShopCouponApplyCateService; +import com.gxwebsoft.shop.entity.ShopCouponApplyCate; +import com.gxwebsoft.shop.param.ShopCouponApplyCateParam; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.BatchParam; +import com.gxwebsoft.common.core.annotation.OperationLog; +import com.gxwebsoft.common.system.entity.User; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 优惠券可用分类控制器 + * + * @author 科技小王子 + * @since 2025-08-11 12:47:49 + */ +@Tag(name = "优惠券可用分类管理") +@RestController +@RequestMapping("/api/shop/shop-coupon-apply-cate") +public class ShopCouponApplyCateController extends BaseController { + @Resource + private ShopCouponApplyCateService shopCouponApplyCateService; + + @PreAuthorize("hasAuthority('shop:shopCouponApplyCate:list')") + @Operation(summary = "分页查询优惠券可用分类") + @GetMapping("/page") + public ApiResult> page(ShopCouponApplyCateParam param) { + // 使用关联查询 + return success(shopCouponApplyCateService.pageRel(param)); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyCate:list')") + @Operation(summary = "查询全部优惠券可用分类") + @GetMapping() + public ApiResult> list(ShopCouponApplyCateParam param) { + // 使用关联查询 + return success(shopCouponApplyCateService.listRel(param)); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyCate:list')") + @Operation(summary = "根据id查询优惠券可用分类") + @GetMapping("/{id}") + public ApiResult get(@PathVariable("id") Integer id) { + // 使用关联查询 + return success(shopCouponApplyCateService.getByIdRel(id)); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyCate:save')") + @OperationLog + @Operation(summary = "添加优惠券可用分类") + @PostMapping() + public ApiResult save(@RequestBody ShopCouponApplyCate shopCouponApplyCate) { + if (shopCouponApplyCateService.save(shopCouponApplyCate)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyCate:update')") + @OperationLog + @Operation(summary = "修改优惠券可用分类") + @PutMapping() + public ApiResult update(@RequestBody ShopCouponApplyCate shopCouponApplyCate) { + if (shopCouponApplyCateService.updateById(shopCouponApplyCate)) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyCate:remove')") + @OperationLog + @Operation(summary = "删除优惠券可用分类") + @DeleteMapping("/{id}") + public ApiResult remove(@PathVariable("id") Integer id) { + if (shopCouponApplyCateService.removeById(id)) { + return success("删除成功"); + } + return fail("删除失败"); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyCate:save')") + @OperationLog + @Operation(summary = "批量添加优惠券可用分类") + @PostMapping("/batch") + public ApiResult saveBatch(@RequestBody List list) { + if (shopCouponApplyCateService.saveBatch(list)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyCate:update')") + @OperationLog + @Operation(summary = "批量修改优惠券可用分类") + @PutMapping("/batch") + public ApiResult removeBatch(@RequestBody BatchParam batchParam) { + if (batchParam.update(shopCouponApplyCateService, "id")) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyCate:remove')") + @OperationLog + @Operation(summary = "批量删除优惠券可用分类") + @DeleteMapping("/batch") + public ApiResult removeBatch(@RequestBody List ids) { + if (shopCouponApplyCateService.removeByIds(ids)) { + return success("删除成功"); + } + return fail("删除失败"); + } + +} diff --git a/src/main/java/com/gxwebsoft/shop/controller/ShopCouponApplyItemController.java b/src/main/java/com/gxwebsoft/shop/controller/ShopCouponApplyItemController.java new file mode 100644 index 0000000..02091c9 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/controller/ShopCouponApplyItemController.java @@ -0,0 +1,125 @@ +package com.gxwebsoft.shop.controller; + +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.shop.service.ShopCouponApplyItemService; +import com.gxwebsoft.shop.entity.ShopCouponApplyItem; +import com.gxwebsoft.shop.param.ShopCouponApplyItemParam; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.BatchParam; +import com.gxwebsoft.common.core.annotation.OperationLog; +import com.gxwebsoft.common.system.entity.User; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 优惠券可用分类控制器 + * + * @author 科技小王子 + * @since 2025-08-11 12:47:49 + */ +@Tag(name = "优惠券可用分类管理") +@RestController +@RequestMapping("/api/shop/shop-coupon-apply-item") +public class ShopCouponApplyItemController extends BaseController { + @Resource + private ShopCouponApplyItemService shopCouponApplyItemService; + + @PreAuthorize("hasAuthority('shop:shopCouponApplyItem:list')") + @Operation(summary = "分页查询优惠券可用分类") + @GetMapping("/page") + public ApiResult> page(ShopCouponApplyItemParam param) { + // 使用关联查询 + return success(shopCouponApplyItemService.pageRel(param)); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyItem:list')") + @Operation(summary = "查询全部优惠券可用分类") + @GetMapping() + public ApiResult> list(ShopCouponApplyItemParam param) { + // 使用关联查询 + return success(shopCouponApplyItemService.listRel(param)); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyItem:list')") + @Operation(summary = "根据id查询优惠券可用分类") + @GetMapping("/{id}") + public ApiResult get(@PathVariable("id") Integer id) { + // 使用关联查询 + return success(shopCouponApplyItemService.getByIdRel(id)); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyItem:save')") + @OperationLog + @Operation(summary = "添加优惠券可用分类") + @PostMapping() + public ApiResult save(@RequestBody ShopCouponApplyItem shopCouponApplyItem) { + + if (shopCouponApplyItemService.save(shopCouponApplyItem)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyItem:update')") + @OperationLog + @Operation(summary = "修改优惠券可用分类") + @PutMapping() + public ApiResult update(@RequestBody ShopCouponApplyItem shopCouponApplyItem) { + if (shopCouponApplyItemService.updateById(shopCouponApplyItem)) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyItem:remove')") + @OperationLog + @Operation(summary = "删除优惠券可用分类") + @DeleteMapping("/{id}") + public ApiResult remove(@PathVariable("id") Integer id) { + if (shopCouponApplyItemService.removeById(id)) { + return success("删除成功"); + } + return fail("删除失败"); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyItem:save')") + @OperationLog + @Operation(summary = "批量添加优惠券可用分类") + @PostMapping("/batch") + public ApiResult saveBatch(@RequestBody List list) { + if (shopCouponApplyItemService.saveBatch(list)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyItem:update')") + @OperationLog + @Operation(summary = "批量修改优惠券可用分类") + @PutMapping("/batch") + public ApiResult removeBatch(@RequestBody BatchParam batchParam) { + if (batchParam.update(shopCouponApplyItemService, "id")) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('shop:shopCouponApplyItem:remove')") + @OperationLog + @Operation(summary = "批量删除优惠券可用分类") + @DeleteMapping("/batch") + public ApiResult removeBatch(@RequestBody List ids) { + if (shopCouponApplyItemService.removeByIds(ids)) { + return success("删除成功"); + } + return fail("删除失败"); + } + +} diff --git a/src/main/java/com/gxwebsoft/shop/controller/ShopCouponController.java b/src/main/java/com/gxwebsoft/shop/controller/ShopCouponController.java index ae60c1d..d5a5990 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/ShopCouponController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/ShopCouponController.java @@ -1,6 +1,14 @@ package com.gxwebsoft.shop.controller; +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.shop.entity.ShopCouponApplyCate; +import com.gxwebsoft.shop.entity.ShopCouponApplyItem; +import com.gxwebsoft.shop.entity.ShopUserCoupon; +import com.gxwebsoft.shop.service.ShopCouponApplyCateService; +import com.gxwebsoft.shop.service.ShopCouponApplyItemService; import com.gxwebsoft.shop.service.ShopCouponService; import com.gxwebsoft.shop.entity.ShopCoupon; import com.gxwebsoft.shop.param.ShopCouponParam; @@ -10,12 +18,14 @@ import com.gxwebsoft.common.core.web.PageParam; import com.gxwebsoft.common.core.web.BatchParam; import com.gxwebsoft.common.core.annotation.OperationLog; import com.gxwebsoft.common.system.entity.User; +import com.gxwebsoft.shop.service.ShopUserCouponService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.util.ArrayList; import java.util.List; /** @@ -30,6 +40,57 @@ import java.util.List; public class ShopCouponController extends BaseController { @Resource private ShopCouponService shopCouponService; + @Resource + private ShopUserCouponService userCouponService; + @Resource + private ShopCouponService couponService; + @Resource + private ShopCouponApplyItemService couponApplyItemService; + @Resource + private ShopCouponApplyCateService couponApplyCateService; + + @Operation(summary = "可领取优惠券列表") + @PostMapping("/list") + public ApiResult> page() { + Integer uid = getLoginUserId(); + // 用户已经领取的优惠券 + List userCouponList = userCouponService.userList(uid); + List hasTakeCouponIdList = new ArrayList<>(); + for (ShopUserCoupon userCoupon : userCouponList) { + hasTakeCouponIdList.add(userCoupon.getCouponId()); + } + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); +// if (!hasTakeCouponIdList.isEmpty()) queryWrapper.notIn(Coupon::getCouponId, hasTakeCouponIdList); + queryWrapper.eq(ShopCoupon::getStatus, 0); + queryWrapper.apply("(expire_type = 0 OR (expire_type = 1 AND end_time > '" + + DateUtil.date() + "'))"); + queryWrapper.orderByAsc(ShopCoupon::getSortNumber); + List couponList = couponService.list(queryWrapper); + for (ShopCoupon coupon : couponList) { + coupon.setCouponApplyItemList(couponApplyItemService.list( + new LambdaQueryWrapper().eq(ShopCouponApplyItem::getCouponId, coupon.getId()) + )); + coupon.setCouponApplyCateList(couponApplyCateService.list( + new LambdaQueryWrapper().eq(ShopCouponApplyCate::getCouponId, coupon.getId()) + )); + boolean hasTake = hasTakeCouponIdList.contains(coupon.getId()); + coupon.setHasTake(hasTake); + if (hasTake) { + int userUseNum = 0; + List userCouponList1 = userCouponService.list( + new LambdaQueryWrapper() + .eq(ShopUserCoupon::getCouponId, coupon.getId()) + ); + coupon.setUserTakeNum(userCouponList1.size()); + for (ShopUserCoupon userCoupon : userCouponList1) { + if (userCoupon.getIsUse().equals(1)) userUseNum++; + } + coupon.setUserUseNum(userUseNum); + } + } + return success(couponList); + } + @PreAuthorize("hasAuthority('shop:shopCoupon:list')") @Operation(summary = "分页查询优惠券") @@ -63,9 +124,22 @@ public class ShopCouponController extends BaseController { // 记录当前登录用户id User loginUser = getLoginUser(); if (loginUser != null) { - shopCoupon.setUserId(loginUser.getUserId()); + shopCoupon.setUserId(loginUser.getUserId()); } if (shopCouponService.save(shopCoupon)) { + if (shopCoupon.getCouponApplyCateList() != null && !shopCoupon.getCouponApplyCateList().isEmpty()) { + for (ShopCouponApplyCate couponApplyCate : shopCoupon.getCouponApplyCateList()) { + couponApplyCate.setCouponId(shopCoupon.getId()); + } + couponApplyCateService.saveBatch(shopCoupon.getCouponApplyCateList()); + } + + if (shopCoupon.getCouponApplyItemList() != null && !shopCoupon.getCouponApplyItemList().isEmpty()) { + for (ShopCouponApplyItem couponApplyItem : shopCoupon.getCouponApplyItemList()) { + couponApplyItem.setCouponId(shopCoupon.getId()); + } + couponApplyItemService.saveBatch(shopCoupon.getCouponApplyItemList()); + } return success("添加成功"); } return fail("添加失败"); @@ -77,6 +151,21 @@ public class ShopCouponController extends BaseController { @PutMapping() public ApiResult update(@RequestBody ShopCoupon shopCoupon) { if (shopCouponService.updateById(shopCoupon)) { + couponApplyCateService.removeByCouponId(shopCoupon.getId()); + if (shopCoupon.getCouponApplyCateList() != null && !shopCoupon.getCouponApplyCateList().isEmpty()) { + for (ShopCouponApplyCate couponApplyCate : shopCoupon.getCouponApplyCateList()) { + couponApplyCate.setCouponId(shopCoupon.getId()); + } + couponApplyCateService.saveBatch(shopCoupon.getCouponApplyCateList()); + } + + couponApplyItemService.removeByCouponId(shopCoupon.getId()); + if (shopCoupon.getCouponApplyItemList() != null && !shopCoupon.getCouponApplyItemList().isEmpty()) { + for (ShopCouponApplyItem couponApplyItem : shopCoupon.getCouponApplyItemList()) { + couponApplyItem.setCouponId(shopCoupon.getId()); + } + couponApplyItemService.saveBatch(shopCoupon.getCouponApplyItemList()); + } return success("修改成功"); } return fail("修改失败"); @@ -88,6 +177,8 @@ public class ShopCouponController extends BaseController { @DeleteMapping("/{id}") public ApiResult remove(@PathVariable("id") Integer id) { if (shopCouponService.removeById(id)) { + couponApplyCateService.removeByCouponId(id); + couponApplyItemService.removeByCouponId(id); return success("删除成功"); } return fail("删除失败"); diff --git a/src/main/java/com/gxwebsoft/shop/controller/ShopGiftController.java b/src/main/java/com/gxwebsoft/shop/controller/ShopGiftController.java new file mode 100644 index 0000000..3e5f4e8 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/controller/ShopGiftController.java @@ -0,0 +1,259 @@ +package com.gxwebsoft.shop.controller; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.RandomUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.gxwebsoft.common.core.config.ConfigProperties; +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.common.system.entity.FileRecord; +import com.gxwebsoft.shop.entity.ShopGoods; +import com.gxwebsoft.shop.service.ShopGiftService; +import com.gxwebsoft.shop.entity.ShopGift; +import com.gxwebsoft.shop.param.ShopGiftParam; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.BatchParam; +import com.gxwebsoft.common.core.annotation.OperationLog; +import com.gxwebsoft.common.system.entity.User; +import com.gxwebsoft.shop.service.ShopGoodsService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.apache.poi.xssf.streaming.SXSSFRow; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.FileOutputStream; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 礼品卡控制器 + * + * @author 科技小王子 + * @since 2025-08-11 18:07:32 + */ +@Tag(name = "礼品卡管理") +@RestController +@RequestMapping("/api/shop/shop-gift") +public class ShopGiftController extends BaseController { + @Resource + private ShopGiftService shopGiftService; + @Value("${config.upload-path}") + private String uploadPath; + @Value("${config.api-url}") + private String apiUrl; + @Resource + private ShopGoodsService shopGoodsService; + + @Operation(summary = "根据code查询礼品卡") + @GetMapping("/by-code/{code}") + public ApiResult get(@PathVariable("code") String code) { + // 使用关联查询 + return success(shopGiftService.getByCode(code)); + } + + @Operation(summary = "礼品卡核销") + @PostMapping("/set-take") + public ApiResult setTake(@RequestBody ShopGift shopGift) { + if (getLoginUser() == null) return fail("请登录"); + if (shopGift.getCode() == null) { + return fail("非法请求"); + } + ShopGift shopGift1 = shopGiftService.getByCode(shopGift.getCode()); + if (shopGift1 == null) return fail("礼品卡不存在"); + if (shopGift1.getTakeTime() != null) { + return fail("礼品卡已使用"); + } + shopGift1.setTakeTime(LocalDateTime.now()); + shopGift1.setOperatorUserId(getLoginUserId()); + shopGiftService.updateById(shopGift1); + return success(); + } + + @PreAuthorize("hasAuthority('shop:shopGift:list')") + @Operation(summary = "分页查询礼品卡") + @GetMapping("/page") + public ApiResult> page(ShopGiftParam param) { + // 使用关联查询 + return success(shopGiftService.pageRel(param)); + } + + @PreAuthorize("hasAuthority('shop:shopGift:list')") + @Operation(summary = "查询全部礼品卡") + @GetMapping() + public ApiResult> list(ShopGiftParam param) { + // 使用关联查询 + return success(shopGiftService.listRel(param)); + } + + @PreAuthorize("hasAuthority('shop:shopGift:list')") + @Operation(summary = "根据id查询礼品卡") + @GetMapping("/{id}") + public ApiResult get(@PathVariable("id") Integer id) { + // 使用关联查询 + return success(shopGiftService.getByIdRel(id)); + } + + @PreAuthorize("hasAuthority('shop:shopGift:save')") + @OperationLog + @Operation(summary = "添加礼品卡") + @PostMapping() + public ApiResult save(@RequestBody ShopGift shopGift) { + // 记录当前登录用户id + User loginUser = getLoginUser(); + if (loginUser != null) { + shopGift.setUserId(loginUser.getUserId()); + } + if (shopGiftService.save(shopGift)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('shop:shopGift:update')") + @OperationLog + @Operation(summary = "修改礼品卡") + @PutMapping() + public ApiResult update(@RequestBody ShopGift shopGift) { + if (shopGiftService.updateById(shopGift)) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('shop:shopGift:save')") + @OperationLog + @Operation(summary = "批量生成礼品卡") + @PostMapping("/make") + public ApiResult make(@RequestBody ShopGift shopGiftData) { + if (shopGiftData.getNum() == null || shopGiftData.getNum() <= 0) { + return fail("请输入正确的数量"); + } + if (shopGiftData.getGoodsId() == null || shopGiftData.getGoodsId() <= 0) { + return fail("请选择商品"); + } + List giftList = new ArrayList<>(); + for (int i = 0; i < shopGiftData.getNum(); i++) { + ShopGift shopGift = new ShopGift(); + shopGift.setName(shopGiftData.getName()); + shopGift.setCode(RandomUtil.randomString(8)); + shopGift.setGoodsId(shopGiftData.getGoodsId()); + giftList.add(shopGift); + } + if (shopGiftService.saveBatch(giftList)) { + return success("生成成功"); + } + return fail("生成失败"); + } + + @PreAuthorize("hasAuthority('shop:shopGift:remove')") + @OperationLog + @Operation(summary = "删除礼品卡") + @DeleteMapping("/{id}") + public ApiResult remove(@PathVariable("id") Integer id) { + if (shopGiftService.removeById(id)) { + return success("删除成功"); + } + return fail("删除失败"); + } + + @PreAuthorize("hasAuthority('shop:shopGift:save')") + @OperationLog + @Operation(summary = "批量添加礼品卡") + @PostMapping("/batch") + public ApiResult saveBatch(@RequestBody List list) { + if (shopGiftService.saveBatch(list)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('shop:shopGift:update')") + @OperationLog + @Operation(summary = "批量修改礼品卡") + @PutMapping("/batch") + public ApiResult removeBatch(@RequestBody BatchParam batchParam) { + if (batchParam.update(shopGiftService, "id")) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('shop:shopGift:remove')") + @OperationLog + @Operation(summary = "批量删除礼品卡") + @DeleteMapping("/batch") + public ApiResult removeBatch(@RequestBody List ids) { + if (shopGiftService.removeByIds(ids)) { + return success("删除成功"); + } + return fail("删除失败"); + } + + @PreAuthorize("hasAuthority('shop:shopGift:list')") + @Operation(summary = "导出礼品卡") + @PostMapping("/export") + public ApiResult export(@RequestBody(required = false) List ids) throws IOException { + String filename = "file/excel/礼品卡.xlsx"; + if (!FileUtil.exist(uploadPath + "file/excel")) { + FileUtil.mkdir(uploadPath + "file/excel"); + } + List list; + if (ids != null && !ids.isEmpty()) { + list = shopGiftService.listByIds(ids); + } else { + list = shopGiftService.list(); + } + if (!list.isEmpty()) { + Set goodsIds = list.stream().map(ShopGift::getGoodsId).collect(Collectors.toSet()); + List goodsList = shopGoodsService.listByIds(goodsIds); + for (ShopGift shopGift : list) { + ShopGoods shopGoods = goodsList.stream().filter(sG -> sG.getGoodsId().equals(shopGift.getGoodsId())).findFirst().orElse(null); + if (shopGoods != null) { + shopGift.setGoods(shopGoods); + } + } + } + String path = uploadPath + filename; + SXSSFWorkbook workbook = new SXSSFWorkbook(); + //创建工作表单 + SXSSFSheet sheet = workbook.createSheet(); + String[] headers = {"名称", "秘钥", "领取时间", "商品"}; + + SXSSFRow row0 = sheet.createRow(0); + for (int i = 0; i < headers.length; i++) { + row0.createCell(i).setCellValue(headers[i]); + } + if (!list.isEmpty()) { + for (ShopGift shopGift : list) { + SXSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1); + row.createCell(0).setCellValue(shopGift.getName()); + row.createCell(1).setCellValue(shopGift.getCode()); + row.createCell(2).setCellValue(shopGift.getTakeTime()); + row.createCell(3).setCellValue(shopGift.getGoods() != null ? shopGift.getGoods().getName() : ""); + } + } + FileOutputStream output = new FileOutputStream(path); + workbook.write(output); + output.flush(); + + FileRecord result = new FileRecord(); + result.setCreateUserId(getLoginUserId()); + result.setName("礼品卡"); + result.setPath(filename); + result.setUrl(apiUrl + "/" + filename); + return success(result); + } + +} diff --git a/src/main/java/com/gxwebsoft/shop/controller/ShopGoodsCategoryController.java b/src/main/java/com/gxwebsoft/shop/controller/ShopGoodsCategoryController.java index 1e11433..49077a7 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/ShopGoodsCategoryController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/ShopGoodsCategoryController.java @@ -39,7 +39,6 @@ public class ShopGoodsCategoryController extends BaseController { return success(shopGoodsCategoryService.pageRel(param)); } - @PreAuthorize("hasAuthority('shop:shopGoodsCategory:list')") @Operation(summary = "查询全部商品分类") @GetMapping() public ApiResult> list(ShopGoodsCategoryParam param) { diff --git a/src/main/java/com/gxwebsoft/shop/controller/ShopUserCouponController.java b/src/main/java/com/gxwebsoft/shop/controller/ShopUserCouponController.java index 73ab99f..37bb118 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/ShopUserCouponController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/ShopUserCouponController.java @@ -1,6 +1,16 @@ package com.gxwebsoft.shop.controller; +import cn.hutool.core.date.DateUnit; +import cn.hutool.core.date.LocalDateTimeUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.shop.entity.ShopCoupon; +import com.gxwebsoft.shop.entity.ShopCouponApplyCate; +import com.gxwebsoft.shop.entity.ShopCouponApplyItem; +import com.gxwebsoft.shop.service.ShopCouponApplyCateService; +import com.gxwebsoft.shop.service.ShopCouponApplyItemService; +import com.gxwebsoft.shop.service.ShopCouponService; import com.gxwebsoft.shop.service.ShopUserCouponService; import com.gxwebsoft.shop.entity.ShopUserCoupon; import com.gxwebsoft.shop.param.ShopUserCouponParam; @@ -16,6 +26,12 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Calendar; +import java.util.Date; import java.util.List; /** @@ -30,6 +46,82 @@ import java.util.List; public class ShopUserCouponController extends BaseController { @Resource private ShopUserCouponService shopUserCouponService; + @Resource + private ShopCouponService couponService; + @Resource + private ShopCouponApplyCateService couponApplyCateService; + @Resource + private ShopCouponApplyItemService couponApplyItemService; + + @Operation(summary = "用户优惠券列表") + @PostMapping("/list") + public ApiResult> list(@RequestBody ShopUserCoupon userCouponParam) throws ParseException { + MPJLambdaWrapper queryWrapper = new MPJLambdaWrapper() + .selectAll(ShopUserCoupon.class) + .selectAs(ShopCoupon::getName, ShopCoupon::getName) + .eq(ShopUserCoupon::getUserId, getLoginUserId()) + .leftJoin(ShopCoupon.class, ShopCoupon::getId, ShopUserCoupon::getCouponId); + if (userCouponParam.getIsExpire() != null) + queryWrapper.eq(ShopUserCoupon::getIsExpire, userCouponParam.getIsExpire()); + if (userCouponParam.getIsUse() != null) queryWrapper.eq(ShopUserCoupon::getIsUse, userCouponParam.getIsUse()); + List userCouponList = shopUserCouponService.list(queryWrapper); + for (ShopUserCoupon userCoupon : userCouponList) { + if (userCoupon.getEndTime().isBefore(LocalDateTime.now())) { + userCoupon.setIsExpire(1); + shopUserCouponService.updateById(userCoupon); + } + ShopCoupon coupon = couponService.getById(userCoupon.getCouponId()); + coupon.setCouponApplyCateList(couponApplyCateService.list( + new LambdaQueryWrapper() + .eq(ShopCouponApplyCate::getCouponId, userCoupon.getCouponId()) + )); + coupon.setCouponApplyItemList(couponApplyItemService.list( + new LambdaQueryWrapper() + .eq(ShopCouponApplyItem::getCouponId, userCoupon.getCouponId()) + )); + userCoupon.setCouponItem(coupon); + } + return success(userCouponList); + } + + @Operation(summary = "领取优惠券") + @PostMapping("/take") + public ApiResult take(@RequestBody ShopUserCoupon userCoupon) { + ShopCoupon coupon = couponService.getByIdRel(userCoupon.getCouponId()); + if (coupon.getTotalCount() != -1 && coupon.getReceiveNum() >= coupon.getTotalCount()) return fail("已经被领完了"); + List userCouponList = shopUserCouponService.list( + new LambdaQueryWrapper() + .eq(ShopUserCoupon::getCouponId, userCoupon.getCouponId()) + .eq(ShopUserCoupon::getUserId, getLoginUserId()) + ); + int userNotUsedNum = 0; + for (ShopUserCoupon userCouponItem : userCouponList) { + if (userCouponItem.getIsUse().equals(0)) userNotUsedNum++; + } + if (userNotUsedNum > 0) return fail("您还有未使用的优惠券,无法领取"); + if (coupon.getLimitPerUser() > -1) { + if (userCouponList.size() >= coupon.getLimitPerUser()) + return fail("每用户最多领取" + coupon.getLimitPerUser() + "张优惠券"); + } + userCoupon.setType(coupon.getType()); + userCoupon.setReducePrice(coupon.getReducePrice()); + userCoupon.setDiscount(coupon.getDiscount()); + userCoupon.setMinPrice(coupon.getMinPrice()); + Integer expireType = coupon.getExpireType(); + userCoupon.setExpireType(expireType); + if (expireType == 10) { + userCoupon.setStartTime(LocalDateTime.now()); + userCoupon.setEndTime(LocalDateTimeUtil.offset(userCoupon.getStartTime(), coupon.getExpireDay(), ChronoUnit.DAYS)); + } else { + userCoupon.setStartTime(coupon.getStartTime()); + userCoupon.setEndTime(coupon.getEndTime()); + } + userCoupon.setUserId(getLoginUserId()); + shopUserCouponService.save(userCoupon); + coupon.setReceiveNum(coupon.getReceiveNum() + 1); + couponService.updateById(coupon); + return success("领取成功"); + } @PreAuthorize("hasAuthority('shop:shopUserCoupon:list')") @Operation(summary = "分页查询用户优惠券") @@ -63,7 +155,7 @@ public class ShopUserCouponController extends BaseController { // 记录当前登录用户id User loginUser = getLoginUser(); if (loginUser != null) { - shopUserCoupon.setUserId(loginUser.getUserId()); + shopUserCoupon.setUserId(loginUser.getUserId()); } if (shopUserCouponService.save(shopUserCoupon)) { return success("添加成功"); diff --git a/src/main/java/com/gxwebsoft/shop/entity/ShopCoupon.java b/src/main/java/com/gxwebsoft/shop/entity/ShopCoupon.java index c7b6ec6..f9f2c5c 100644 --- a/src/main/java/com/gxwebsoft/shop/entity/ShopCoupon.java +++ b/src/main/java/com/gxwebsoft/shop/entity/ShopCoupon.java @@ -3,11 +3,14 @@ package com.gxwebsoft.shop.entity; import java.math.BigDecimal; import com.baomidou.mybatisplus.annotation.IdType; import java.time.LocalDate; + +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import java.time.LocalDateTime; import com.baomidou.mybatisplus.annotation.TableLogic; import java.io.Serializable; import java.util.Date; +import java.util.List; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -54,10 +57,10 @@ public class ShopCoupon implements Serializable { private Integer expireDay; @Schema(description = "有效期开始时间") - private LocalDate startTime; + private LocalDateTime startTime; @Schema(description = "有效期结束时间") - private LocalDate endTime; + private LocalDateTime endTime; @Schema(description = "适用范围(10全部商品 20指定商品 30指定分类)") private Integer applyRange; @@ -85,7 +88,7 @@ public class ShopCoupon implements Serializable { private Integer tenantId; @Schema(description = "创建时间") - private Data createTime; + private Date createTime; @Schema(description = "修改时间") private Date updateTime; @@ -102,4 +105,21 @@ public class ShopCoupon implements Serializable { @Schema(description = "是否启用(0禁用 1启用)") private Boolean enabled; + @TableField(exist = false) + private List couponApplyItemList; + + @TableField(exist = false) + private List couponApplyCateList; + + @TableField(exist = false) + private Boolean hasTake; + + @TableField(exist = false) + private Integer userTakeNum; + + @TableField(exist = false) + private Integer userUseNum; + + @TableField(exist = false) + private Integer receiveNum; } diff --git a/src/main/java/com/gxwebsoft/shop/entity/ShopCouponApplyCate.java b/src/main/java/com/gxwebsoft/shop/entity/ShopCouponApplyCate.java new file mode 100644 index 0000000..77cc89b --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/entity/ShopCouponApplyCate.java @@ -0,0 +1,50 @@ +package com.gxwebsoft.shop.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.TableLogic; +import java.io.Serializable; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 优惠券可用分类 + * + * @author 科技小王子 + * @since 2025-08-11 12:47:49 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Schema(name = "ShopCouponApplyCate对象", description = "优惠券可用分类") +public class ShopCouponApplyCate implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + private Integer couponId; + + private Integer cateId; + + @Schema(description = "分类等级") + private Integer cateLevel; + + @Schema(description = "状态, 0正常, 1冻结") + private Integer status; + + @Schema(description = "是否删除, 0否, 1是") + @TableLogic + private Integer deleted; + + @Schema(description = "租户id") + private Integer tenantId; + + @Schema(description = "注册时间") + private LocalDateTime createTime; + + @Schema(description = "修改时间") + private LocalDateTime updateTime; + +} diff --git a/src/main/java/com/gxwebsoft/shop/entity/ShopCouponApplyItem.java b/src/main/java/com/gxwebsoft/shop/entity/ShopCouponApplyItem.java new file mode 100644 index 0000000..c770a7d --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/entity/ShopCouponApplyItem.java @@ -0,0 +1,50 @@ +package com.gxwebsoft.shop.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.TableLogic; +import java.io.Serializable; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 优惠券可用分类 + * + * @author 科技小王子 + * @since 2025-08-11 12:47:49 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Schema(name = "ShopCouponApplyItem对象", description = "优惠券可用分类") +public class ShopCouponApplyItem implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + private Integer couponId; + + private Integer type; + + @Schema(description = "0服务1需求2闲置") + private Integer pk; + + @Schema(description = "状态, 0正常, 1冻结") + private Integer status; + + @Schema(description = "是否删除, 0否, 1是") + @TableLogic + private Integer deleted; + + @Schema(description = "租户id") + private Integer tenantId; + + @Schema(description = "注册时间") + private LocalDateTime createTime; + + @Schema(description = "修改时间") + private LocalDateTime updateTime; + +} diff --git a/src/main/java/com/gxwebsoft/shop/entity/ShopGift.java b/src/main/java/com/gxwebsoft/shop/entity/ShopGift.java new file mode 100644 index 0000000..9694eca --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/entity/ShopGift.java @@ -0,0 +1,75 @@ +package com.gxwebsoft.shop.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.TableLogic; +import java.io.Serializable; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 礼品卡 + * + * @author 科技小王子 + * @since 2025-08-11 18:07:31 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Schema(name = "ShopGift对象", description = "礼品卡") +public class ShopGift implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + private String name; + + @Schema(description = "秘钥") + private String code; + + @Schema(description = "商品ID") + private Integer goodsId; + + @Schema(description = "领取时间") + private LocalDateTime takeTime; + + @Schema(description = "操作人") + private Integer operatorUserId; + + @Schema(description = "是否展示") + private Boolean isShow; + + @Schema(description = "状态, 0上架 1待上架 2待审核 3审核不通过") + private Integer status; + + @Schema(description = "备注") + private String comments; + + @Schema(description = "排序号") + private Integer sortNumber; + + @Schema(description = "用户ID") + private Integer userId; + + @Schema(description = "是否删除, 0否, 1是") + @TableLogic + private Integer deleted; + + @Schema(description = "租户id") + private Integer tenantId; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "修改时间") + private LocalDateTime updateTime; + + @TableField(exist = false) + private Integer num; + + @TableField(exist = false) + private ShopGoods goods; +} diff --git a/src/main/java/com/gxwebsoft/shop/entity/ShopUserCoupon.java b/src/main/java/com/gxwebsoft/shop/entity/ShopUserCoupon.java index 25fcc2f..00da1cd 100644 --- a/src/main/java/com/gxwebsoft/shop/entity/ShopUserCoupon.java +++ b/src/main/java/com/gxwebsoft/shop/entity/ShopUserCoupon.java @@ -2,6 +2,7 @@ package com.gxwebsoft.shop.entity; import java.math.BigDecimal; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import java.time.LocalDateTime; import com.baomidou.mybatisplus.annotation.TableLogic; @@ -53,9 +54,18 @@ public class ShopUserCoupon implements Serializable { @Schema(description = "适用范围(10全部商品 20指定商品 30指定分类)") private Integer applyRange; + @Schema(description = "到期类型(10领取后生效 20固定时间)") + private Integer expireType; + + @Schema(description = "领取后生效-有效天数") + private Integer expireDay; + @Schema(description = "适用范围配置(json格式)") private String applyRangeConfig; + @Schema(description = "是否过期(0未过期 1已过期)") + private Integer isExpire; + @Schema(description = "有效期开始时间") private LocalDateTime startTime; @@ -71,6 +81,9 @@ public class ShopUserCoupon implements Serializable { @Schema(description = "使用订单ID") private Long orderId; + @Schema(description = "是否已使用") + private Integer isUse; + @Schema(description = "使用订单号") private String orderNo; @@ -93,4 +106,7 @@ public class ShopUserCoupon implements Serializable { @Schema(description = "修改时间") private LocalDateTime updateTime; + @TableField(exist = false) + private ShopCoupon couponItem; + } diff --git a/src/main/java/com/gxwebsoft/shop/mapper/ShopCouponApplyCateMapper.java b/src/main/java/com/gxwebsoft/shop/mapper/ShopCouponApplyCateMapper.java new file mode 100644 index 0000000..6d86d1d --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/mapper/ShopCouponApplyCateMapper.java @@ -0,0 +1,37 @@ +package com.gxwebsoft.shop.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.gxwebsoft.shop.entity.ShopCouponApplyCate; +import com.gxwebsoft.shop.param.ShopCouponApplyCateParam; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 优惠券可用分类Mapper + * + * @author 科技小王子 + * @since 2025-08-11 12:47:49 + */ +public interface ShopCouponApplyCateMapper extends BaseMapper { + + /** + * 分页查询 + * + * @param page 分页对象 + * @param param 查询参数 + * @return List + */ + List selectPageRel(@Param("page") IPage page, + @Param("param") ShopCouponApplyCateParam param); + + /** + * 查询全部 + * + * @param param 查询参数 + * @return List + */ + List selectListRel(@Param("param") ShopCouponApplyCateParam param); + +} diff --git a/src/main/java/com/gxwebsoft/shop/mapper/ShopCouponApplyItemMapper.java b/src/main/java/com/gxwebsoft/shop/mapper/ShopCouponApplyItemMapper.java new file mode 100644 index 0000000..077989a --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/mapper/ShopCouponApplyItemMapper.java @@ -0,0 +1,37 @@ +package com.gxwebsoft.shop.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.gxwebsoft.shop.entity.ShopCouponApplyItem; +import com.gxwebsoft.shop.param.ShopCouponApplyItemParam; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 优惠券可用分类Mapper + * + * @author 科技小王子 + * @since 2025-08-11 12:47:49 + */ +public interface ShopCouponApplyItemMapper extends BaseMapper { + + /** + * 分页查询 + * + * @param page 分页对象 + * @param param 查询参数 + * @return List + */ + List selectPageRel(@Param("page") IPage page, + @Param("param") ShopCouponApplyItemParam param); + + /** + * 查询全部 + * + * @param param 查询参数 + * @return List + */ + List selectListRel(@Param("param") ShopCouponApplyItemParam param); + +} diff --git a/src/main/java/com/gxwebsoft/shop/mapper/ShopGiftMapper.java b/src/main/java/com/gxwebsoft/shop/mapper/ShopGiftMapper.java new file mode 100644 index 0000000..bf0a45d --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/mapper/ShopGiftMapper.java @@ -0,0 +1,37 @@ +package com.gxwebsoft.shop.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.gxwebsoft.shop.entity.ShopGift; +import com.gxwebsoft.shop.param.ShopGiftParam; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 礼品卡Mapper + * + * @author 科技小王子 + * @since 2025-08-11 18:07:31 + */ +public interface ShopGiftMapper extends BaseMapper { + + /** + * 分页查询 + * + * @param page 分页对象 + * @param param 查询参数 + * @return List + */ + List selectPageRel(@Param("page") IPage page, + @Param("param") ShopGiftParam param); + + /** + * 查询全部 + * + * @param param 查询参数 + * @return List + */ + List selectListRel(@Param("param") ShopGiftParam param); + +} diff --git a/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopCouponApplyCateMapper.xml b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopCouponApplyCateMapper.xml new file mode 100644 index 0000000..ef13b35 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopCouponApplyCateMapper.xml @@ -0,0 +1,54 @@ + + + + + + + SELECT a.* + FROM shop_coupon_apply_cate a + + + AND a.id = #{param.id} + + + AND a.coupon_id = #{param.couponId} + + + AND a.cate_id = #{param.cateId} + + + AND a.cate_level = #{param.cateLevel} + + + AND a.status = #{param.status} + + + AND a.deleted = #{param.deleted} + + + AND a.deleted = 0 + + + AND a.create_time >= #{param.createTimeStart} + + + AND a.create_time <= #{param.createTimeEnd} + + + AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') + ) + + + + + + + + + + + diff --git a/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopCouponApplyItemMapper.xml b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopCouponApplyItemMapper.xml new file mode 100644 index 0000000..5933bd7 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopCouponApplyItemMapper.xml @@ -0,0 +1,54 @@ + + + + + + + SELECT a.* + FROM shop_coupon_apply_item a + + + AND a.id = #{param.id} + + + AND a.coupon_id = #{param.couponId} + + + AND a.type = #{param.type} + + + AND a.pk = #{param.pk} + + + AND a.status = #{param.status} + + + AND a.deleted = #{param.deleted} + + + AND a.deleted = 0 + + + AND a.create_time >= #{param.createTimeStart} + + + AND a.create_time <= #{param.createTimeEnd} + + + AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') + ) + + + + + + + + + + + diff --git a/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopGiftMapper.xml b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopGiftMapper.xml new file mode 100644 index 0000000..547ea97 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/mapper/xml/ShopGiftMapper.xml @@ -0,0 +1,72 @@ + + + + + + + SELECT a.* + FROM shop_gift a + + + AND a.id = #{param.id} + + + AND a.name LIKE CONCAT('%', #{param.name}, '%') + + + AND a.code LIKE CONCAT('%', #{param.code}, '%') + + + AND a.goods_id = #{param.goodsId} + + + AND a.take_time LIKE CONCAT('%', #{param.takeTime}, '%') + + + AND a.operator_user_id = #{param.operatorUserId} + + + AND a.is_show = #{param.isShow} + + + AND a.status = #{param.status} + + + AND a.comments LIKE CONCAT('%', #{param.comments}, '%') + + + AND a.sort_number = #{param.sortNumber} + + + AND a.user_id = #{param.userId} + + + AND a.deleted = #{param.deleted} + + + AND a.deleted = 0 + + + AND a.create_time >= #{param.createTimeStart} + + + AND a.create_time <= #{param.createTimeEnd} + + + AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') + ) + + + + + + + + + + + diff --git a/src/main/java/com/gxwebsoft/shop/param/ShopCouponApplyCateParam.java b/src/main/java/com/gxwebsoft/shop/param/ShopCouponApplyCateParam.java new file mode 100644 index 0000000..b80698a --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/param/ShopCouponApplyCateParam.java @@ -0,0 +1,46 @@ +package com.gxwebsoft.shop.param; + +import java.math.BigDecimal; +import com.gxwebsoft.common.core.annotation.QueryField; +import com.gxwebsoft.common.core.annotation.QueryType; +import com.gxwebsoft.common.core.web.BaseParam; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 优惠券可用分类查询参数 + * + * @author 科技小王子 + * @since 2025-08-11 12:47:48 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(name = "ShopCouponApplyCateParam对象", description = "优惠券可用分类查询参数") +public class ShopCouponApplyCateParam extends BaseParam { + private static final long serialVersionUID = 1L; + + @QueryField(type = QueryType.EQ) + private Integer id; + + @QueryField(type = QueryType.EQ) + private Integer couponId; + + @QueryField(type = QueryType.EQ) + private Integer cateId; + + @Schema(description = "分类等级") + @QueryField(type = QueryType.EQ) + private Boolean cateLevel; + + @Schema(description = "状态, 0正常, 1冻结") + @QueryField(type = QueryType.EQ) + private Integer status; + + @Schema(description = "是否删除, 0否, 1是") + @QueryField(type = QueryType.EQ) + private Integer deleted; + +} diff --git a/src/main/java/com/gxwebsoft/shop/param/ShopCouponApplyItemParam.java b/src/main/java/com/gxwebsoft/shop/param/ShopCouponApplyItemParam.java new file mode 100644 index 0000000..38c4820 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/param/ShopCouponApplyItemParam.java @@ -0,0 +1,46 @@ +package com.gxwebsoft.shop.param; + +import java.math.BigDecimal; +import com.gxwebsoft.common.core.annotation.QueryField; +import com.gxwebsoft.common.core.annotation.QueryType; +import com.gxwebsoft.common.core.web.BaseParam; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 优惠券可用分类查询参数 + * + * @author 科技小王子 + * @since 2025-08-11 12:47:49 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(name = "ShopCouponApplyItemParam对象", description = "优惠券可用分类查询参数") +public class ShopCouponApplyItemParam extends BaseParam { + private static final long serialVersionUID = 1L; + + @QueryField(type = QueryType.EQ) + private Integer id; + + @QueryField(type = QueryType.EQ) + private Integer couponId; + + @QueryField(type = QueryType.EQ) + private Boolean type; + + @Schema(description = "0服务1需求2闲置") + @QueryField(type = QueryType.EQ) + private Integer pk; + + @Schema(description = "状态, 0正常, 1冻结") + @QueryField(type = QueryType.EQ) + private Integer status; + + @Schema(description = "是否删除, 0否, 1是") + @QueryField(type = QueryType.EQ) + private Integer deleted; + +} diff --git a/src/main/java/com/gxwebsoft/shop/param/ShopGiftParam.java b/src/main/java/com/gxwebsoft/shop/param/ShopGiftParam.java new file mode 100644 index 0000000..e57869e --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/param/ShopGiftParam.java @@ -0,0 +1,67 @@ +package com.gxwebsoft.shop.param; + +import java.math.BigDecimal; +import com.gxwebsoft.common.core.annotation.QueryField; +import com.gxwebsoft.common.core.annotation.QueryType; +import com.gxwebsoft.common.core.web.BaseParam; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 礼品卡查询参数 + * + * @author 科技小王子 + * @since 2025-08-11 18:07:31 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(name = "ShopGiftParam对象", description = "礼品卡查询参数") +public class ShopGiftParam extends BaseParam { + private static final long serialVersionUID = 1L; + + @QueryField(type = QueryType.EQ) + private Integer id; + + private String name; + + @Schema(description = "秘钥") + private String code; + + @Schema(description = "商品ID") + @QueryField(type = QueryType.EQ) + private Integer goodsId; + + @Schema(description = "领取时间") + private String takeTime; + + @Schema(description = "操作人") + @QueryField(type = QueryType.EQ) + private Integer operatorUserId; + + @Schema(description = "是否展示") + @QueryField(type = QueryType.EQ) + private Boolean isShow; + + @Schema(description = "状态, 0上架 1待上架 2待审核 3审核不通过") + @QueryField(type = QueryType.EQ) + private Integer status; + + @Schema(description = "备注") + private String comments; + + @Schema(description = "排序号") + @QueryField(type = QueryType.EQ) + private Integer sortNumber; + + @Schema(description = "用户ID") + @QueryField(type = QueryType.EQ) + private Integer userId; + + @Schema(description = "是否删除, 0否, 1是") + @QueryField(type = QueryType.EQ) + private Integer deleted; + +} diff --git a/src/main/java/com/gxwebsoft/shop/service/ShopCouponApplyCateService.java b/src/main/java/com/gxwebsoft/shop/service/ShopCouponApplyCateService.java new file mode 100644 index 0000000..f247bf7 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/service/ShopCouponApplyCateService.java @@ -0,0 +1,43 @@ +package com.gxwebsoft.shop.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.shop.entity.ShopCouponApplyCate; +import com.gxwebsoft.shop.param.ShopCouponApplyCateParam; + +import java.util.List; + +/** + * 优惠券可用分类Service + * + * @author 科技小王子 + * @since 2025-08-11 12:47:49 + */ +public interface ShopCouponApplyCateService extends IService { + + /** + * 分页关联查询 + * + * @param param 查询参数 + * @return PageResult + */ + PageResult pageRel(ShopCouponApplyCateParam param); + + /** + * 关联查询全部 + * + * @param param 查询参数 + * @return List + */ + List listRel(ShopCouponApplyCateParam param); + + /** + * 根据id查询 + * + * @param id + * @return ShopCouponApplyCate + */ + ShopCouponApplyCate getByIdRel(Integer id); + + void removeByCouponId(Integer couponId); +} diff --git a/src/main/java/com/gxwebsoft/shop/service/ShopCouponApplyItemService.java b/src/main/java/com/gxwebsoft/shop/service/ShopCouponApplyItemService.java new file mode 100644 index 0000000..bcca01d --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/service/ShopCouponApplyItemService.java @@ -0,0 +1,43 @@ +package com.gxwebsoft.shop.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.shop.entity.ShopCouponApplyItem; +import com.gxwebsoft.shop.param.ShopCouponApplyItemParam; + +import java.util.List; + +/** + * 优惠券可用分类Service + * + * @author 科技小王子 + * @since 2025-08-11 12:47:49 + */ +public interface ShopCouponApplyItemService extends IService { + + /** + * 分页关联查询 + * + * @param param 查询参数 + * @return PageResult + */ + PageResult pageRel(ShopCouponApplyItemParam param); + + /** + * 关联查询全部 + * + * @param param 查询参数 + * @return List + */ + List listRel(ShopCouponApplyItemParam param); + + /** + * 根据id查询 + * + * @param id + * @return ShopCouponApplyItem + */ + ShopCouponApplyItem getByIdRel(Integer id); + + void removeByCouponId(Integer couponId); +} diff --git a/src/main/java/com/gxwebsoft/shop/service/ShopGiftService.java b/src/main/java/com/gxwebsoft/shop/service/ShopGiftService.java new file mode 100644 index 0000000..5ff156d --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/service/ShopGiftService.java @@ -0,0 +1,43 @@ +package com.gxwebsoft.shop.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.shop.entity.ShopGift; +import com.gxwebsoft.shop.param.ShopGiftParam; + +import java.util.List; + +/** + * 礼品卡Service + * + * @author 科技小王子 + * @since 2025-08-11 18:07:31 + */ +public interface ShopGiftService extends IService { + + /** + * 分页关联查询 + * + * @param param 查询参数 + * @return PageResult + */ + PageResult pageRel(ShopGiftParam param); + + /** + * 关联查询全部 + * + * @param param 查询参数 + * @return List + */ + List listRel(ShopGiftParam param); + + /** + * 根据id查询 + * + * @param id + * @return ShopGift + */ + ShopGift getByIdRel(Integer id); + + ShopGift getByCode(String code); +} diff --git a/src/main/java/com/gxwebsoft/shop/service/ShopOrderUpdate10550Service.java b/src/main/java/com/gxwebsoft/shop/service/ShopOrderUpdate10550Service.java new file mode 100644 index 0000000..2399a6d --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/service/ShopOrderUpdate10550Service.java @@ -0,0 +1,21 @@ +package com.gxwebsoft.shop.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.shop.entity.ShopOrder; +import com.gxwebsoft.shop.entity.ShopOrderDelivery; +import com.gxwebsoft.shop.param.ShopOrderDeliveryParam; + +import java.util.List; + +/** + * 发货单Service + * + * @author 科技小王子 + * @since 2025-01-11 10:45:12 + */ +public interface ShopOrderUpdate10550Service { + + + void update(ShopOrder shopOrder); +} diff --git a/src/main/java/com/gxwebsoft/shop/service/ShopUserCouponService.java b/src/main/java/com/gxwebsoft/shop/service/ShopUserCouponService.java index 31b7b0d..62e19fb 100644 --- a/src/main/java/com/gxwebsoft/shop/service/ShopUserCouponService.java +++ b/src/main/java/com/gxwebsoft/shop/service/ShopUserCouponService.java @@ -39,4 +39,5 @@ public interface ShopUserCouponService extends IService { */ ShopUserCoupon getByIdRel(Integer id); + List userList(Integer userId); } diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponApplyCateServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponApplyCateServiceImpl.java new file mode 100644 index 0000000..c613194 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponApplyCateServiceImpl.java @@ -0,0 +1,56 @@ +package com.gxwebsoft.shop.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.gxwebsoft.shop.mapper.ShopCouponApplyCateMapper; +import com.gxwebsoft.shop.service.ShopCouponApplyCateService; +import com.gxwebsoft.shop.entity.ShopCouponApplyCate; +import com.gxwebsoft.shop.param.ShopCouponApplyCateParam; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.PageResult; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 优惠券可用分类Service实现 + * + * @author 科技小王子 + * @since 2025-08-11 12:47:49 + */ +@Service +public class ShopCouponApplyCateServiceImpl extends ServiceImpl implements ShopCouponApplyCateService { + + @Override + public PageResult pageRel(ShopCouponApplyCateParam param) { + PageParam page = new PageParam<>(param); + page.setDefaultOrder("sort_number asc, create_time desc"); + List list = baseMapper.selectPageRel(page, param); + return new PageResult<>(list, page.getTotal()); + } + + @Override + public List listRel(ShopCouponApplyCateParam param) { + List list = baseMapper.selectListRel(param); + // 排序 + PageParam page = new PageParam<>(); + page.setDefaultOrder("sort_number asc, create_time desc"); + return page.sortRecords(list); + } + + @Override + public ShopCouponApplyCate getByIdRel(Integer id) { + ShopCouponApplyCateParam param = new ShopCouponApplyCateParam(); + param.setId(id); + return param.getOne(baseMapper.selectListRel(param)); + } + + @Override + public void removeByCouponId(Integer couponId) { + remove( + new LambdaQueryWrapper() + .eq(ShopCouponApplyCate::getCouponId, couponId) + ); + } + +} diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponApplyItemServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponApplyItemServiceImpl.java new file mode 100644 index 0000000..6baa5ea --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponApplyItemServiceImpl.java @@ -0,0 +1,56 @@ +package com.gxwebsoft.shop.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.gxwebsoft.shop.mapper.ShopCouponApplyItemMapper; +import com.gxwebsoft.shop.service.ShopCouponApplyItemService; +import com.gxwebsoft.shop.entity.ShopCouponApplyItem; +import com.gxwebsoft.shop.param.ShopCouponApplyItemParam; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.PageResult; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 优惠券可用分类Service实现 + * + * @author 科技小王子 + * @since 2025-08-11 12:47:49 + */ +@Service +public class ShopCouponApplyItemServiceImpl extends ServiceImpl implements ShopCouponApplyItemService { + + @Override + public PageResult pageRel(ShopCouponApplyItemParam param) { + PageParam page = new PageParam<>(param); + page.setDefaultOrder("sort_number asc, create_time desc"); + List list = baseMapper.selectPageRel(page, param); + return new PageResult<>(list, page.getTotal()); + } + + @Override + public List listRel(ShopCouponApplyItemParam param) { + List list = baseMapper.selectListRel(param); + // 排序 + PageParam page = new PageParam<>(); + page.setDefaultOrder("sort_number asc, create_time desc"); + return page.sortRecords(list); + } + + @Override + public ShopCouponApplyItem getByIdRel(Integer id) { + ShopCouponApplyItemParam param = new ShopCouponApplyItemParam(); + param.setId(id); + return param.getOne(baseMapper.selectListRel(param)); + } + + @Override + public void removeByCouponId(Integer couponId) { + remove( + new LambdaQueryWrapper() + .eq(ShopCouponApplyItem::getCouponId, couponId) + ); + } + +} diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponServiceImpl.java index 5a9aedd..9369a0e 100644 --- a/src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponServiceImpl.java +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopCouponServiceImpl.java @@ -1,7 +1,12 @@ package com.gxwebsoft.shop.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.gxwebsoft.shop.entity.ShopCouponApplyCate; +import com.gxwebsoft.shop.entity.ShopCouponApplyItem; import com.gxwebsoft.shop.mapper.ShopCouponMapper; +import com.gxwebsoft.shop.service.ShopCouponApplyCateService; +import com.gxwebsoft.shop.service.ShopCouponApplyItemService; import com.gxwebsoft.shop.service.ShopCouponService; import com.gxwebsoft.shop.entity.ShopCoupon; import com.gxwebsoft.shop.param.ShopCouponParam; @@ -9,6 +14,7 @@ import com.gxwebsoft.common.core.web.PageParam; import com.gxwebsoft.common.core.web.PageResult; import org.springframework.stereotype.Service; +import javax.annotation.Resource; import java.util.List; /** @@ -19,12 +25,30 @@ import java.util.List; */ @Service public class ShopCouponServiceImpl extends ServiceImpl implements ShopCouponService { + @Resource + private ShopCouponApplyItemService couponApplyItemService; + @Resource + private ShopCouponApplyCateService couponApplyCateService; @Override public PageResult pageRel(ShopCouponParam param) { PageParam page = new PageParam<>(param); page.setDefaultOrder("sort_number asc, create_time desc"); List list = baseMapper.selectPageRel(page, param); + for (ShopCoupon coupon : list) { + coupon.setCouponApplyCateList( + couponApplyCateService.list( + new LambdaQueryWrapper() + .eq(ShopCouponApplyCate::getCouponId, coupon.getId()) + ) + ); + coupon.setCouponApplyItemList( + couponApplyItemService.list( + new LambdaQueryWrapper() + .eq(ShopCouponApplyItem::getCouponId, coupon.getId()) + ) + ); + } return new PageResult<>(list, page.getTotal()); } diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopGiftServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopGiftServiceImpl.java new file mode 100644 index 0000000..55a067e --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopGiftServiceImpl.java @@ -0,0 +1,71 @@ +package com.gxwebsoft.shop.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.gxwebsoft.shop.entity.ShopGoods; +import com.gxwebsoft.shop.mapper.ShopGiftMapper; +import com.gxwebsoft.shop.service.ShopGiftService; +import com.gxwebsoft.shop.entity.ShopGift; +import com.gxwebsoft.shop.param.ShopGiftParam; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.shop.service.ShopGoodsService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 礼品卡Service实现 + * + * @author 科技小王子 + * @since 2025-08-11 18:07:31 + */ +@Service +public class ShopGiftServiceImpl extends ServiceImpl implements ShopGiftService { + @Resource + private ShopGoodsService shopGoodsService; + + @Override + public PageResult pageRel(ShopGiftParam param) { + PageParam page = new PageParam<>(param); + page.setDefaultOrder("sort_number asc, create_time desc"); + List list = baseMapper.selectPageRel(page, param); + if (!list.isEmpty()) { + Set goodsIds = list.stream().map(ShopGift::getGoodsId).collect(Collectors.toSet()); + List goodsList = shopGoodsService.listByIds(goodsIds); + for (ShopGift shopGift : list) { + ShopGoods shopGoods = goodsList.stream().filter(sG -> sG.getGoodsId().equals(shopGift.getGoodsId())).findFirst().orElse(null); + if (shopGoods != null) { + shopGift.setGoods(shopGoods); + } + } + } + return new PageResult<>(list, page.getTotal()); + } + + @Override + public List listRel(ShopGiftParam param) { + List list = baseMapper.selectListRel(param); + // 排序 + PageParam page = new PageParam<>(); + page.setDefaultOrder("sort_number asc, create_time desc"); + return page.sortRecords(list); + } + + @Override + public ShopGift getByIdRel(Integer id) { + ShopGiftParam param = new ShopGiftParam(); + param.setId(id); + return param.getOne(baseMapper.selectListRel(param)); + } + + @Override + public ShopGift getByCode(String code) { + ShopGiftParam param = new ShopGiftParam(); + param.setCode(code); + return param.getOne(baseMapper.selectListRel(param)); + } + +} diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java index 42d478e..4e564b4 100644 --- a/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java @@ -1,51 +1,51 @@ - package com.gxwebsoft.shop.service.impl; - - import cn.hutool.core.date.DateUtil; - import cn.hutool.core.util.StrUtil; - import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; - import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; - import com.gxwebsoft.common.core.config.ConfigProperties; - import com.gxwebsoft.common.core.config.CertificateProperties; - import com.gxwebsoft.common.core.utils.*; - import com.gxwebsoft.common.core.service.PaymentCacheService; - import com.gxwebsoft.common.core.web.ApiResult; - import com.gxwebsoft.common.system.entity.Payment; - import com.gxwebsoft.common.system.entity.User; - import com.gxwebsoft.shop.entity.*; - import com.gxwebsoft.shop.service.*; - import lombok.extern.slf4j.Slf4j; - import com.gxwebsoft.common.system.service.PaymentService; - import com.gxwebsoft.common.system.service.SettingService; - import com.gxwebsoft.shop.mapper.ShopOrderMapper; - import com.gxwebsoft.shop.param.ShopOrderParam; - import com.gxwebsoft.common.core.web.PageParam; - import com.gxwebsoft.common.core.web.PageResult; - import com.wechat.pay.java.core.Config; - import com.wechat.pay.java.core.RSAConfig; - import com.wechat.pay.java.core.RSAPublicKeyConfig; - import com.wechat.pay.java.core.exception.ServiceException; - import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension; - import com.wechat.pay.java.service.payments.jsapi.model.*; - import com.wechat.pay.java.service.payments.model.Transaction; - import org.springframework.beans.factory.annotation.Value; - import org.springframework.stereotype.Service; - import org.springframework.util.CollectionUtils; - - import javax.annotation.Resource; - import java.math.BigDecimal; - import java.sql.Date; - import java.util.*; - import java.util.stream.Collectors; - - /** - * 订单Service实现 - * - * @author 科技小王子 - * @since 2025-01-11 10:45:12 - */ - @Slf4j - @Service - public class ShopOrderServiceImpl extends ServiceImpl implements ShopOrderService { +package com.gxwebsoft.shop.service.impl; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.gxwebsoft.common.core.config.ConfigProperties; +import com.gxwebsoft.common.core.config.CertificateProperties; +import com.gxwebsoft.common.core.utils.*; +import com.gxwebsoft.common.core.service.PaymentCacheService; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.system.entity.Payment; +import com.gxwebsoft.common.system.entity.User; +import com.gxwebsoft.shop.entity.*; +import com.gxwebsoft.shop.service.*; +import lombok.extern.slf4j.Slf4j; +import com.gxwebsoft.common.system.service.PaymentService; +import com.gxwebsoft.common.system.service.SettingService; +import com.gxwebsoft.shop.mapper.ShopOrderMapper; +import com.gxwebsoft.shop.param.ShopOrderParam; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.PageResult; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAConfig; +import com.wechat.pay.java.core.RSAPublicKeyConfig; +import com.wechat.pay.java.core.exception.ServiceException; +import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension; +import com.wechat.pay.java.service.payments.jsapi.model.*; +import com.wechat.pay.java.service.payments.model.Transaction; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.sql.Date; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 订单Service实现 + * + * @author 科技小王子 + * @since 2025-01-11 10:45:12 + */ +@Slf4j +@Service +public class ShopOrderServiceImpl extends ServiceImpl implements ShopOrderService { @Value("${spring.profiles.active}") String active; @Resource @@ -73,149 +73,146 @@ @Resource private WechatPayCertificateDiagnostic certificateDiagnostic; @Resource - private RequestUtil requestUtil; - @Resource - private ShopDealerOrderService shopDealerOrderService; - @Resource - private ShopDealerCapitalService shopDealerCapitalService; + private ShopOrderUpdate10550Service shopOrderUpdate10550Service; + @Override public PageResult pageRel(ShopOrderParam param) { - PageParam page = new PageParam<>(param); - page.setDefaultOrder("sort_number asc, create_time desc"); - List list = baseMapper.selectPageRel(page, param); - - // 整理订单数据 - if (!CollectionUtils.isEmpty(list)) { - final Set orderIds = list.stream().map(ShopOrder::getOrderId).collect(Collectors.toSet()); - final List goodsList = shopOrderGoodsService.list(new LambdaQueryWrapper().in(ShopOrderGoods::getOrderId, orderIds)); - final Map> collect = goodsList.stream().collect(Collectors.groupingBy(ShopOrderGoods::getOrderId)); - list.forEach(d -> { - d.setOrderGoods(collect.get(d.getOrderId())); - - // 确保 realName 字段有值,优先使用关联查询的结果,如果为空则使用订单表中的 realName - if (StrUtil.isBlank(d.getRealName())) { - log.debug("订单 {} 的 realName 为空,尝试从其他字段获取", d.getOrderId()); - // 可以根据业务需求添加其他逻辑,比如从 nickname 或其他字段获取 - } - }); - } - return new PageResult<>(list, page.getTotal()); + PageParam page = new PageParam<>(param); + page.setDefaultOrder("sort_number asc, create_time desc"); + List list = baseMapper.selectPageRel(page, param); + + // 整理订单数据 + if (!CollectionUtils.isEmpty(list)) { + final Set orderIds = list.stream().map(ShopOrder::getOrderId).collect(Collectors.toSet()); + final List goodsList = shopOrderGoodsService.list(new LambdaQueryWrapper().in(ShopOrderGoods::getOrderId, orderIds)); + final Map> collect = goodsList.stream().collect(Collectors.groupingBy(ShopOrderGoods::getOrderId)); + list.forEach(d -> { + d.setOrderGoods(collect.get(d.getOrderId())); + + // 确保 realName 字段有值,优先使用关联查询的结果,如果为空则使用订单表中的 realName + if (StrUtil.isBlank(d.getRealName())) { + log.debug("订单 {} 的 realName 为空,尝试从其他字段获取", d.getOrderId()); + // 可以根据业务需求添加其他逻辑,比如从 nickname 或其他字段获取 + } + }); + } + return new PageResult<>(list, page.getTotal()); } @Override public List listRel(ShopOrderParam param) { - List list = baseMapper.selectListRel(param); - // 排序 - PageParam page = new PageParam<>(); - page.setDefaultOrder("sort_number asc, create_time desc"); - return page.sortRecords(list); + List list = baseMapper.selectListRel(param); + // 排序 + PageParam page = new PageParam<>(); + page.setDefaultOrder("sort_number asc, create_time desc"); + return page.sortRecords(list); } @Override public ShopOrder getByIdRel(Integer orderId) { - ShopOrderParam param = new ShopOrderParam(); - param.setOrderId(orderId); - return param.getOne(baseMapper.selectListRel(param)); + ShopOrderParam param = new ShopOrderParam(); + param.setOrderId(orderId); + return param.getOne(baseMapper.selectListRel(param)); } @Override public HashMap createWxOrder(ShopOrder order) { - try { - // 后台微信支付配置信息 - final Payment payment = getPayment(order); - System.out.println("=== 开始创建微信支付订单 ==="); - System.out.println("订单号: " + order.getOrderNo()); - System.out.println("租户ID: " + order.getTenantId()); - System.out.println("支付配置: " + (payment != null ? "已获取" : "未获取")); + try { + // 后台微信支付配置信息 + final Payment payment = getPayment(order); + System.out.println("=== 开始创建微信支付订单 ==="); + System.out.println("订单号: " + order.getOrderNo()); + System.out.println("租户ID: " + order.getTenantId()); + System.out.println("支付配置: " + (payment != null ? "已获取" : "未获取")); + + // 返回的订单数据 + final HashMap orderInfo = new HashMap<>(); + // 构建service + System.out.println("开始构建微信支付服务..."); + JsapiServiceExtension service = getWxService(order); + System.out.println("微信支付服务构建完成"); + + // 订单金额 + BigDecimal decimal = order.getTotalPrice(); + final BigDecimal multiply = decimal.multiply(new BigDecimal(100)); + Integer money = multiply.intValue(); + + PrepayRequest request = new PrepayRequest(); + Amount amount = new Amount(); + amount.setTotal(money); + amount.setCurrency("CNY"); + request.setAmount(amount); + request.setAppid(payment.getAppId()); + request.setMchid(payment.getMchId()); + // 微信支付description字段限制127字节,需要截断处理 + String description = com.gxwebsoft.common.core.utils.WechatPayUtils.processDescription(order.getComments()); + request.setDescription(description); + request.setOutTradeNo(order.getOrderNo()); + request.setAttach(order.getTenantId().toString()); + final Payer payer = new Payer(); + payer.setOpenid(order.getOpenid()); + request.setPayer(payer); + request.setNotifyUrl(config.getServerUrl() + "/system/wx-pay/notify/" + order.getTenantId()); // 默认回调地址 + // 测试环境 + if (active.equals("dev")) { + amount.setTotal(1); + request.setAmount(amount); + request.setNotifyUrl("http://jimei-api.natapp1.cc/api/shop/wx-pay/notify/" + order.getTenantId()); // 默认回调地址 + } + // 后台配置的回调地址 + if (StrUtil.isNotBlank(payment.getNotifyUrl())) { + request.setNotifyUrl(payment.getNotifyUrl().concat("/").concat(order.getTenantId().toString())); + System.out.println("后台配置的回调地址 = " + request.getNotifyUrl()); + } + System.out.println("=== 发起微信支付请求 ==="); + System.out.println("请求参数: " + request); + + PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request); + + System.out.println("=== 微信支付响应成功 ==="); + System.out.println("预支付ID: " + response.getPackageVal()); + + orderInfo.put("provider", "wxpay"); + orderInfo.put("timeStamp", response.getTimeStamp()); + orderInfo.put("nonceStr", response.getNonceStr()); + orderInfo.put("package", response.getPackageVal()); + orderInfo.put("signType", "RSA"); + orderInfo.put("paySign", response.getPaySign()); + orderInfo.put("orderNo", order.getOrderNo()); + return orderInfo; + } catch (Exception e) { + System.err.println("=== 创建微信支付订单失败 ==="); + System.err.println("错误信息: " + e.getMessage()); + System.err.println("错误类型: " + e.getClass().getName()); + + // 特殊处理签名验证失败的情况 + if (e.getMessage() != null && e.getMessage().contains("signature is incorrect")) { + System.err.println("🔍 签名验证失败诊断:"); + System.err.println("1. 检查商户证书序列号是否正确"); + System.err.println("2. 检查APIv3密钥是否正确"); + System.err.println("3. 检查私钥文件是否正确"); + System.err.println("4. 检查微信支付平台证书是否过期"); + System.err.println("5. 建议使用自动证书配置避免证书管理问题"); + System.err.println("当前支付配置:"); + try { + final Payment paymentInfo = getPayment(order); + System.err.println(" - 商户号: " + paymentInfo.getMchId()); + System.err.println(" - 序列号: " + paymentInfo.getMerchantSerialNumber()); + System.err.println(" - 环境: " + active); + } catch (Exception ex) { + System.err.println(" - 无法获取支付配置信息: " + ex.getMessage()); + } + } - // 返回的订单数据 - final HashMap orderInfo = new HashMap<>(); - // 构建service - System.out.println("开始构建微信支付服务..."); - JsapiServiceExtension service = getWxService(order); - System.out.println("微信支付服务构建完成"); - - // 订单金额 - BigDecimal decimal = order.getTotalPrice(); - final BigDecimal multiply = decimal.multiply(new BigDecimal(100)); - Integer money = multiply.intValue(); - - PrepayRequest request = new PrepayRequest(); - Amount amount = new Amount(); - amount.setTotal(money); - amount.setCurrency("CNY"); - request.setAmount(amount); - request.setAppid(payment.getAppId()); - request.setMchid(payment.getMchId()); - // 微信支付description字段限制127字节,需要截断处理 - String description = com.gxwebsoft.common.core.utils.WechatPayUtils.processDescription(order.getComments()); - request.setDescription(description); - request.setOutTradeNo(order.getOrderNo()); - request.setAttach(order.getTenantId().toString()); - final Payer payer = new Payer(); - payer.setOpenid(order.getOpenid()); - request.setPayer(payer); - request.setNotifyUrl(config.getServerUrl() + "/system/wx-pay/notify/" + order.getTenantId()); // 默认回调地址 - // 测试环境 - if (active.equals("dev")) { - amount.setTotal(1); - request.setAmount(amount); - request.setNotifyUrl("http://jimei-api.natapp1.cc/api/shop/wx-pay/notify/" + order.getTenantId()); // 默认回调地址 - } - // 后台配置的回调地址 - if (StrUtil.isNotBlank(payment.getNotifyUrl())) { - request.setNotifyUrl(payment.getNotifyUrl().concat("/").concat(order.getTenantId().toString())); - System.out.println("后台配置的回调地址 = " + request.getNotifyUrl()); - } - System.out.println("=== 发起微信支付请求 ==="); - System.out.println("请求参数: " + request); - - PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request); - - System.out.println("=== 微信支付响应成功 ==="); - System.out.println("预支付ID: " + response.getPackageVal()); - - orderInfo.put("provider", "wxpay"); - orderInfo.put("timeStamp", response.getTimeStamp()); - orderInfo.put("nonceStr", response.getNonceStr()); - orderInfo.put("package", response.getPackageVal()); - orderInfo.put("signType", "RSA"); - orderInfo.put("paySign", response.getPaySign()); - orderInfo.put("orderNo", order.getOrderNo()); - return orderInfo; - } catch (Exception e) { - System.err.println("=== 创建微信支付订单失败 ==="); - System.err.println("错误信息: " + e.getMessage()); - System.err.println("错误类型: " + e.getClass().getName()); - - // 特殊处理签名验证失败的情况 - if (e.getMessage() != null && e.getMessage().contains("signature is incorrect")) { - System.err.println("🔍 签名验证失败诊断:"); - System.err.println("1. 检查商户证书序列号是否正确"); - System.err.println("2. 检查APIv3密钥是否正确"); - System.err.println("3. 检查私钥文件是否正确"); - System.err.println("4. 检查微信支付平台证书是否过期"); - System.err.println("5. 建议使用自动证书配置避免证书管理问题"); - System.err.println("当前支付配置:"); - try { - final Payment paymentInfo = getPayment(order); - System.err.println(" - 商户号: " + paymentInfo.getMchId()); - System.err.println(" - 序列号: " + paymentInfo.getMerchantSerialNumber()); - System.err.println(" - 环境: " + active); - } catch (Exception ex) { - System.err.println(" - 无法获取支付配置信息: " + ex.getMessage()); - } + e.printStackTrace(); + throw new RuntimeException("创建支付订单失败:" + e.getMessage(), e); } - - e.printStackTrace(); - throw new RuntimeException("创建支付订单失败:" + e.getMessage(), e); - } } @Override public ShopOrder getByOutTradeNo(String outTradeNo) { - return baseMapper.getByOutTradeNo(outTradeNo); + return baseMapper.getByOutTradeNo(outTradeNo); } /** @@ -225,88 +222,36 @@ */ @Override public Boolean queryOrderByOutTradeNo(ShopOrder shopOrder) { - // 后台微信支付配置信息 - final Payment payment = getPayment(shopOrder); - QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest(); - queryRequest.setMchid(payment.getMchId()); - queryRequest.setOutTradeNo(shopOrder.getOrderNo()); - // 构建service - JsapiServiceExtension service = getWxService(shopOrder); - try { - Transaction result = service.queryOrderByOutTradeNo(queryRequest); - if (result.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)) { - shopOrder.setPayStatus(true); - shopOrder.setPayTime(DateUtil.date()); - shopOrder.setTransactionId(result.getTransactionId()); - updateById(shopOrder); - return true; + // 后台微信支付配置信息 + final Payment payment = getPayment(shopOrder); + QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest(); + queryRequest.setMchid(payment.getMchId()); + queryRequest.setOutTradeNo(shopOrder.getOrderNo()); + // 构建service + JsapiServiceExtension service = getWxService(shopOrder); + try { + Transaction result = service.queryOrderByOutTradeNo(queryRequest); + if (result.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)) { + shopOrder.setPayStatus(true); + shopOrder.setPayTime(DateUtil.date()); + shopOrder.setTransactionId(result.getTransactionId()); + updateById(shopOrder); + return true; + } + } catch (ServiceException e) { + // API返回失败, 例如ORDER_NOT_EXISTS + System.out.printf("code=[%s], message=[%s]\n", e.getErrorCode(), e.getErrorMessage()); + System.out.printf("reponse body=[%s]\n", e.getResponseBody()); } - } catch (ServiceException e) { - // API返回失败, 例如ORDER_NOT_EXISTS - System.out.printf("code=[%s], message=[%s]\n", e.getErrorCode(), e.getErrorMessage()); - System.out.printf("reponse body=[%s]\n", e.getResponseBody()); - } - return false; + return false; } @Override public void updateByOutTradeNo(ShopOrder order) { - baseMapper.updateByOutTradeNo(order); - if (order.getTenantId().equals(10550)) { - requestUtil.setTenantId(order.getTenantId().toString()); - ApiResult partnerConditionReq = requestUtil.pageDictData(1460); - if (partnerConditionReq.getCode().equals(0) && partnerConditionReq.getData() != null) { - LinkedHashMap dictDataMap = (LinkedHashMap) partnerConditionReq.getData(); - List dictDataList = (List) dictDataMap.get("list"); - String dictDataCode = (String) dictDataList.get(0).get("dictDataCode"); - BigDecimal partnerCondition = new BigDecimal(dictDataCode); - - User user = requestUtil.getByUserIdWithoutLogin(order.getUserId()); - if (user != null) { - user.setExpendMoney(user.getExpendMoney().add(order.getPayPrice())); - if (user.getExpendMoney().compareTo(partnerCondition) >= 0) { - user.setGradeId(3); - } - requestUtil.updateWithoutLogin(user); - - // 上级 - User parent = requestUtil.getParent(order.getUserId()); - if (parent != null) { - - List shopOrderGoodsList = shopOrderGoodsService.getListByOrderId(order.getOrderId()); - List goodsIds = shopOrderGoodsList.stream().map(ShopOrderGoods::getGoodsId).toList(); - List shopGoodsList = shopGoodsService.listByIds(goodsIds); - BigDecimal commission = BigDecimal.ZERO; - for (ShopOrderGoods shopOrderGoods : shopOrderGoodsList) { - ShopGoods shopGoods = shopGoodsList.stream().filter(sG -> sG.getGoodsId().equals(shopOrderGoods.getGoodsId())).findFirst().orElse(null); - if (shopGoods != null) { - commission = commission.add(shopGoods.getCommission().multiply(BigDecimal.valueOf(shopOrderGoods.getTotalNum()))); - } - } - parent.setBalance(parent.getBalance().add(commission)); - requestUtil.updateWithoutLogin(user); - - // 分销订单 - ShopDealerOrder shopDealerOrder = new ShopDealerOrder(); - shopDealerOrder.setUserId(parent.getUserId()); - shopDealerOrder.setOrderId(order.getOrderId()); - shopDealerOrder.setOrderPrice(order.getTotalPrice()); - shopDealerOrder.setFirstUserId(order.getUserId()); - shopDealerOrder.setFirstMoney(commission); - shopDealerOrder.setIsSettled(1); - shopDealerOrder.setSettleTime(DateUtil.currentSeconds()); - shopDealerOrderService.save(shopDealerOrder); - - // 分销资明细 - ShopDealerCapital shopDealerCapital = new ShopDealerCapital(); - shopDealerCapital.setUserId(parent.getUserId()); - shopDealerCapital.setOrderId(order.getOrderId()); - shopDealerCapital.setFlowType(10); - shopDealerCapitalService.save(shopDealerCapital); - } - } + baseMapper.updateByOutTradeNo(order); + if (order.getTenantId().equals(10550)) { + shopOrderUpdate10550Service.update(order); } - } } /** @@ -317,420 +262,420 @@ * @return */ public Payment getPayment(ShopOrder order) { - // 先清除可能的错误缓存 + // 先清除可能的错误缓存 // paymentCacheService.removePaymentConfig(order.getPayType().toString(), order.getTenantId()); - Payment payment = paymentCacheService.getPaymentConfig(order.getPayType(), order.getTenantId()); + Payment payment = paymentCacheService.getPaymentConfig(order.getPayType(), order.getTenantId()); - // 添加详细的支付配置检查 - System.out.println("=== 支付配置检查 ==="); - System.out.println("订单支付类型: " + order.getPayType()); - System.out.println("租户ID: " + order.getTenantId()); + // 添加详细的支付配置检查 + System.out.println("=== 支付配置检查 ==="); + System.out.println("订单支付类型: " + order.getPayType()); + System.out.println("租户ID: " + order.getTenantId()); - if (payment == null) { - throw new RuntimeException("未找到支付配置,支付类型: " + order.getPayType() + ", 租户ID: " + order.getTenantId()); - } + if (payment == null) { + throw new RuntimeException("未找到支付配置,支付类型: " + order.getPayType() + ", 租户ID: " + order.getTenantId()); + } - System.out.println("支付配置ID: " + payment.getId()); - System.out.println("支付方式名称: " + payment.getName()); - System.out.println("支付类型: " + payment.getType()); - System.out.println("支付代码: " + payment.getCode()); - System.out.println("应用ID: " + payment.getAppId()); - System.out.println("商户号: " + payment.getMchId()); - System.out.println("API密钥: " + (payment.getApiKey() != null ? "已配置(长度:" + payment.getApiKey().length() + ")" : "未配置")); - System.out.println("商户证书序列号: " + payment.getMerchantSerialNumber()); - System.out.println("状态: " + payment.getStatus()); + System.out.println("支付配置ID: " + payment.getId()); + System.out.println("支付方式名称: " + payment.getName()); + System.out.println("支付类型: " + payment.getType()); + System.out.println("支付代码: " + payment.getCode()); + System.out.println("应用ID: " + payment.getAppId()); + System.out.println("商户号: " + payment.getMchId()); + System.out.println("API密钥: " + (payment.getApiKey() != null ? "已配置(长度:" + payment.getApiKey().length() + ")" : "未配置")); + System.out.println("商户证书序列号: " + payment.getMerchantSerialNumber()); + System.out.println("状态: " + payment.getStatus()); - return payment; + return payment; } /** * 构建微信支付 + * * @param order * @return */ public JsapiServiceExtension getWxService(ShopOrder order) { - try { - final Payment payment = getPayment(order); - String privateKey; - String apiclientCert = null; - String pubKey = null; - - // 运行配置诊断 - System.out.println("=== 运行微信支付配置诊断 ==="); - wechatPayDiagnostic.diagnosePaymentConfig(payment, null, active); - - // 运行证书诊断 - System.out.println("=== 运行证书诊断 ==="); - WechatPayCertificateDiagnostic.DiagnosticResult diagnosticResult = - certificateDiagnostic.diagnoseCertificateConfig(payment, order.getTenantId(), active); - System.out.println(diagnosticResult.getFullReport()); - - // 开发环境配置 - 使用自动证书配置 - if (active.equals("dev")) { - // 构建包含租户号的证书路径: dev/wechat/{tenantId}/ - String tenantCertPath = "dev/wechat/" + order.getTenantId(); - String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile(); - - System.out.println("开发环境证书路径 - 租户ID: " + order.getTenantId()); - System.out.println("开发环境证书路径 - 私钥: " + privateKeyPath); - System.out.println("=== 支付配置详细信息 ==="); - System.out.println("商户号: " + payment.getMchId()); - System.out.println("序列号: " + payment.getMerchantSerialNumber()); - System.out.println("API密钥: " + (payment.getApiKey() != null ? "已配置(长度:" + payment.getApiKey().length() + ")" : "未配置")); - System.out.println("应用ID: " + payment.getAppId()); - System.out.println("支付类型: " + payment.getType()); - System.out.println("支付代码: " + payment.getCode()); - - privateKey = certificateLoader.loadCertificatePath(privateKeyPath); - - System.out.println("私钥完整路径: " + privateKey); - System.out.println("证书加载完成 - 私钥文件: " + privateKey); - System.out.println("使用自动证书配置,无需手动加载微信支付平台证书"); - - // 更新诊断信息,包含私钥路径 - wechatPayDiagnostic.diagnosePaymentConfig(payment, privateKey, active); - } else { - // 生产环境配置 - 从容器证书目录加载 - final String certRootPath = certConfig.getCertRootPath(); // /www/wwwroot/file.ws - final String certBasePath = certRootPath + "/file"; // 实际文件存储路径 - - System.out.println("生产环境证书路径 - 租户ID: " + order.getTenantId()); - System.out.println("生产环境证书根路径: " + certRootPath); - System.out.println("生产环境证书基础路径: " + certBasePath); - System.out.println("私钥文件名: " + payment.getApiclientKey()); - System.out.println("证书文件名: " + payment.getApiclientCert()); - - // 构建完整的证书文件路径 - // 处理数据库路径可能以/开头的情况,避免双斜杠 - String privateKeyRelativePath = payment.getApiclientKey(); - String apiclientCertRelativePath = payment.getApiclientCert(); - - // 如果数据库路径以/开头,直接拼接;否则添加/ - String privateKeyFullPath = privateKeyRelativePath.startsWith("/") - ? certBasePath + privateKeyRelativePath - : certBasePath + "/" + privateKeyRelativePath; - String apiclientCertFullPath = apiclientCertRelativePath.startsWith("/") - ? certBasePath + apiclientCertRelativePath - : certBasePath + "/" + apiclientCertRelativePath; - - System.out.println("私钥完整路径: " + privateKeyFullPath); - System.out.println("证书完整路径: " + apiclientCertFullPath); - - privateKey = certificateLoader.loadCertificatePath(privateKeyFullPath); - apiclientCert = certificateLoader.loadCertificatePath(apiclientCertFullPath); - - if (payment.getPubKey() != null && !payment.getPubKey().isEmpty()) { - String pubKeyRelativePath = payment.getPubKey(); - String pubKeyFullPath = pubKeyRelativePath.startsWith("/") - ? certBasePath + pubKeyRelativePath - : certBasePath + "/" + pubKeyRelativePath; - System.out.println("公钥完整路径: " + pubKeyFullPath); - pubKey = certificateLoader.loadCertificatePath(pubKeyFullPath); - } - } - - // 构建微信支付配置 - Config config = null; - if (active.equals("dev")) { - // 开发环境使用自动证书配置 - // 检查数据库配置是否完整 - if (payment.getMchId() == null || payment.getMchId().trim().isEmpty()) { - throw new RuntimeException("数据库中商户号(mchId)未配置"); - } - if (payment.getMerchantSerialNumber() == null || payment.getMerchantSerialNumber().trim().isEmpty()) { - throw new RuntimeException("数据库中商户证书序列号(merchantSerialNumber)未配置"); - } - if (payment.getApiKey() == null || payment.getApiKey().trim().isEmpty()) { - throw new RuntimeException("数据库中API密钥(apiKey)未配置"); - } - - System.out.println("=== 使用数据库支付配置 ==="); - System.out.println("商户号: " + payment.getMchId()); - System.out.println("序列号: " + payment.getMerchantSerialNumber()); - System.out.println("API密钥: 已配置(长度:" + payment.getApiKey().length() + ")"); - - // 临时使用RSA配置替代自动证书配置,避免404错误 - System.out.println("=== 注意:使用RSA配置替代自动证书配置 ==="); - System.out.println("原因:商户平台可能未开启API安全功能或未申请微信支付公钥"); - - // 首先检查是否配置了公钥,如果有则优先使用公钥模式 - if (payment.getPubKey() != null && !payment.getPubKey().isEmpty() && - payment.getPubKeyId() != null && !payment.getPubKeyId().isEmpty()) { - - try { - // 开发环境固定使用 wechatpay_public_key.pem - String tenantCertPath = "dev/wechat/" + order.getTenantId(); - String pubKeyPath = tenantCertPath + "/wechatpay_public_key.pem"; - - System.out.println("开发环境公钥文件路径: " + pubKeyPath); - - // 检查公钥文件是否存在 - if (certificateLoader.certificateExists(pubKeyPath)) { - System.out.println("=== 检测到公钥配置,使用RSA公钥模式 ==="); - System.out.println("公钥文件: " + payment.getPubKey()); - System.out.println("公钥ID: " + payment.getPubKeyId()); - - String pubKeyFile = certificateLoader.loadCertificatePath(pubKeyPath); - System.out.println("✅ 开发环境公钥文件加载成功: " + pubKeyFile); - - config = new RSAPublicKeyConfig.Builder() - .merchantId(payment.getMchId()) - .privateKeyFromPath(privateKey) - .publicKeyFromPath(pubKeyFile) - .publicKeyId(payment.getPubKeyId()) - .merchantSerialNumber(payment.getMerchantSerialNumber()) - .apiV3Key(payment.getApiKey()) - .build(); - System.out.println("✅ 开发环境RSA公钥配置成功"); + try { + final Payment payment = getPayment(order); + String privateKey; + String apiclientCert = null; + String pubKey = null; + + // 运行配置诊断 + System.out.println("=== 运行微信支付配置诊断 ==="); + wechatPayDiagnostic.diagnosePaymentConfig(payment, null, active); + + // 运行证书诊断 + System.out.println("=== 运行证书诊断 ==="); + WechatPayCertificateDiagnostic.DiagnosticResult diagnosticResult = + certificateDiagnostic.diagnoseCertificateConfig(payment, order.getTenantId(), active); + System.out.println(diagnosticResult.getFullReport()); + + // 开发环境配置 - 使用自动证书配置 + if (active.equals("dev")) { + // 构建包含租户号的证书路径: dev/wechat/{tenantId}/ + String tenantCertPath = "dev/wechat/" + order.getTenantId(); + String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile(); + + System.out.println("开发环境证书路径 - 租户ID: " + order.getTenantId()); + System.out.println("开发环境证书路径 - 私钥: " + privateKeyPath); + System.out.println("=== 支付配置详细信息 ==="); + System.out.println("商户号: " + payment.getMchId()); + System.out.println("序列号: " + payment.getMerchantSerialNumber()); + System.out.println("API密钥: " + (payment.getApiKey() != null ? "已配置(长度:" + payment.getApiKey().length() + ")" : "未配置")); + System.out.println("应用ID: " + payment.getAppId()); + System.out.println("支付类型: " + payment.getType()); + System.out.println("支付代码: " + payment.getCode()); + + privateKey = certificateLoader.loadCertificatePath(privateKeyPath); + + System.out.println("私钥完整路径: " + privateKey); + System.out.println("证书加载完成 - 私钥文件: " + privateKey); + System.out.println("使用自动证书配置,无需手动加载微信支付平台证书"); + + // 更新诊断信息,包含私钥路径 + wechatPayDiagnostic.diagnosePaymentConfig(payment, privateKey, active); } else { - System.out.println("⚠️ 开发环境公钥文件不存在,跳过公钥模式: " + pubKeyPath); - // 跳过公钥配置,继续后续的自动证书配置 + // 生产环境配置 - 从容器证书目录加载 + final String certRootPath = certConfig.getCertRootPath(); // /www/wwwroot/file.ws + final String certBasePath = certRootPath + "/file"; // 实际文件存储路径 + + System.out.println("生产环境证书路径 - 租户ID: " + order.getTenantId()); + System.out.println("生产环境证书根路径: " + certRootPath); + System.out.println("生产环境证书基础路径: " + certBasePath); + System.out.println("私钥文件名: " + payment.getApiclientKey()); + System.out.println("证书文件名: " + payment.getApiclientCert()); + + // 构建完整的证书文件路径 + // 处理数据库路径可能以/开头的情况,避免双斜杠 + String privateKeyRelativePath = payment.getApiclientKey(); + String apiclientCertRelativePath = payment.getApiclientCert(); + + // 如果数据库路径以/开头,直接拼接;否则添加/ + String privateKeyFullPath = privateKeyRelativePath.startsWith("/") + ? certBasePath + privateKeyRelativePath + : certBasePath + "/" + privateKeyRelativePath; + String apiclientCertFullPath = apiclientCertRelativePath.startsWith("/") + ? certBasePath + apiclientCertRelativePath + : certBasePath + "/" + apiclientCertRelativePath; + + System.out.println("私钥完整路径: " + privateKeyFullPath); + System.out.println("证书完整路径: " + apiclientCertFullPath); + + privateKey = certificateLoader.loadCertificatePath(privateKeyFullPath); + apiclientCert = certificateLoader.loadCertificatePath(apiclientCertFullPath); + + if (payment.getPubKey() != null && !payment.getPubKey().isEmpty()) { + String pubKeyRelativePath = payment.getPubKey(); + String pubKeyFullPath = pubKeyRelativePath.startsWith("/") + ? certBasePath + pubKeyRelativePath + : certBasePath + "/" + pubKeyRelativePath; + System.out.println("公钥完整路径: " + pubKeyFullPath); + pubKey = certificateLoader.loadCertificatePath(pubKeyFullPath); + } } - } catch (Exception e) { - System.err.println("❌ 开发环境公钥配置检查失败: " + e.getMessage()); - // 跳过公钥配置,继续后续的自动证书配置 - } - } - // 如果没有公钥配置或公钥文件不存在,尝试自动证书配置 - if (config == null) { - // 没有公钥配置,尝试自动证书配置 - try { - System.out.println("=== 尝试创建自动证书配置 ==="); - System.out.println("商户号: " + payment.getMchId()); - System.out.println("私钥路径: " + privateKey); - System.out.println("序列号: " + payment.getMerchantSerialNumber()); - System.out.println("API密钥长度: " + (payment.getApiKey() != null ? payment.getApiKey().length() : 0)); - - config = wechatCertAutoConfig.createAutoConfig( - payment.getMchId(), - privateKey, - payment.getMerchantSerialNumber(), - payment.getApiKey() - ); - System.out.println("✅ 开发环境自动证书配置成功"); - } catch (Exception e) { - System.err.println("❌ 自动证书配置失败: " + e.getMessage()); - System.err.println("错误类型: " + e.getClass().getName()); - e.printStackTrace(); - - // 检查是否是证书相关的错误 - if (e.getMessage() != null && ( - e.getMessage().contains("certificate") || - e.getMessage().contains("X509Certificate") || - e.getMessage().contains("getSerialNumber") || - e.getMessage().contains("404") || - e.getMessage().contains("API安全"))) { - - System.err.println("🔍 证书问题诊断:"); - System.err.println("1. 检查商户平台是否已开启API安全功能"); - System.err.println("2. 检查是否已申请使用微信支付公钥"); - System.err.println("3. 检查网络连接是否正常"); - System.err.println("4. 检查商户证书序列号是否正确"); - System.err.println("5. 参考文档:https://pay.weixin.qq.com/doc/v3/merchant/4012153196"); - - // 开发环境回退到基础RSA配置 - System.err.println("⚠️ 开发环境回退到基础RSA配置..."); - try { - // 方案1:尝试使用RSA证书配置(需要商户证书文件) - String tenantCertPath = "dev/wechat/" + order.getTenantId(); - String apiclientCertPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getApiclientCertFile(); - - if (certificateLoader.certificateExists(apiclientCertPath)) { - String apiclientCertFile = certificateLoader.loadCertificatePath(apiclientCertPath); - System.out.println("方案1: 使用RSA证书配置作为回退方案"); - System.out.println("商户证书路径: " + apiclientCertFile); + // 构建微信支付配置 + Config config = null; + if (active.equals("dev")) { + // 开发环境使用自动证书配置 + // 检查数据库配置是否完整 + if (payment.getMchId() == null || payment.getMchId().trim().isEmpty()) { + throw new RuntimeException("数据库中商户号(mchId)未配置"); + } + if (payment.getMerchantSerialNumber() == null || payment.getMerchantSerialNumber().trim().isEmpty()) { + throw new RuntimeException("数据库中商户证书序列号(merchantSerialNumber)未配置"); + } + if (payment.getApiKey() == null || payment.getApiKey().trim().isEmpty()) { + throw new RuntimeException("数据库中API密钥(apiKey)未配置"); + } - try { - config = new RSAConfig.Builder() - .merchantId(payment.getMchId()) - .privateKeyFromPath(privateKey) - .merchantSerialNumber(payment.getMerchantSerialNumber()) - .wechatPayCertificatesFromPath(apiclientCertFile) - .build(); - System.out.println("✅ 开发环境RSA证书配置成功"); - } catch (Exception rsaException) { - System.err.println("RSA证书配置失败: " + rsaException.getMessage()); - throw rsaException; + System.out.println("=== 使用数据库支付配置 ==="); + System.out.println("商户号: " + payment.getMchId()); + System.out.println("序列号: " + payment.getMerchantSerialNumber()); + System.out.println("API密钥: 已配置(长度:" + payment.getApiKey().length() + ")"); + + // 临时使用RSA配置替代自动证书配置,避免404错误 + System.out.println("=== 注意:使用RSA配置替代自动证书配置 ==="); + System.out.println("原因:商户平台可能未开启API安全功能或未申请微信支付公钥"); + + // 首先检查是否配置了公钥,如果有则优先使用公钥模式 + if (payment.getPubKey() != null && !payment.getPubKey().isEmpty() && + payment.getPubKeyId() != null && !payment.getPubKeyId().isEmpty()) { + + try { + // 开发环境固定使用 wechatpay_public_key.pem + String tenantCertPath = "dev/wechat/" + order.getTenantId(); + String pubKeyPath = tenantCertPath + "/wechatpay_public_key.pem"; + + System.out.println("开发环境公钥文件路径: " + pubKeyPath); + + // 检查公钥文件是否存在 + if (certificateLoader.certificateExists(pubKeyPath)) { + System.out.println("=== 检测到公钥配置,使用RSA公钥模式 ==="); + System.out.println("公钥文件: " + payment.getPubKey()); + System.out.println("公钥ID: " + payment.getPubKeyId()); + + String pubKeyFile = certificateLoader.loadCertificatePath(pubKeyPath); + System.out.println("✅ 开发环境公钥文件加载成功: " + pubKeyFile); + + config = new RSAPublicKeyConfig.Builder() + .merchantId(payment.getMchId()) + .privateKeyFromPath(privateKey) + .publicKeyFromPath(pubKeyFile) + .publicKeyId(payment.getPubKeyId()) + .merchantSerialNumber(payment.getMerchantSerialNumber()) + .apiV3Key(payment.getApiKey()) + .build(); + System.out.println("✅ 开发环境RSA公钥配置成功"); + } else { + System.out.println("⚠️ 开发环境公钥文件不存在,跳过公钥模式: " + pubKeyPath); + // 跳过公钥配置,继续后续的自动证书配置 + } + } catch (Exception e) { + System.err.println("❌ 开发环境公钥配置检查失败: " + e.getMessage()); + // 跳过公钥配置,继续后续的自动证书配置 + } } - } else { - System.err.println("❌ 商户证书文件不存在: " + apiclientCertPath); - System.err.println("⚠️ 尝试方案2: 使用最小化配置..."); - // 方案2:使用最小化的RSA配置(仅私钥和序列号) - try { - // 创建一个最基础的配置,不依赖平台证书 - config = new com.wechat.pay.java.core.RSAConfig.Builder() - .merchantId(payment.getMchId()) - .privateKeyFromPath(privateKey) - .merchantSerialNumber(payment.getMerchantSerialNumber()) - .build(); - System.out.println("✅ 开发环境最小化RSA配置成功"); - } catch (Exception minimalException) { - System.err.println("最小化配置也失败: " + minimalException.getMessage()); - throw new RuntimeException("所有配置方案都失败,请检查私钥文件和商户配置", e); + // 如果没有公钥配置或公钥文件不存在,尝试自动证书配置 + if (config == null) { + // 没有公钥配置,尝试自动证书配置 + try { + System.out.println("=== 尝试创建自动证书配置 ==="); + System.out.println("商户号: " + payment.getMchId()); + System.out.println("私钥路径: " + privateKey); + System.out.println("序列号: " + payment.getMerchantSerialNumber()); + System.out.println("API密钥长度: " + (payment.getApiKey() != null ? payment.getApiKey().length() : 0)); + + config = wechatCertAutoConfig.createAutoConfig( + payment.getMchId(), + privateKey, + payment.getMerchantSerialNumber(), + payment.getApiKey() + ); + System.out.println("✅ 开发环境自动证书配置成功"); + } catch (Exception e) { + System.err.println("❌ 自动证书配置失败: " + e.getMessage()); + System.err.println("错误类型: " + e.getClass().getName()); + e.printStackTrace(); + + // 检查是否是证书相关的错误 + if (e.getMessage() != null && ( + e.getMessage().contains("certificate") || + e.getMessage().contains("X509Certificate") || + e.getMessage().contains("getSerialNumber") || + e.getMessage().contains("404") || + e.getMessage().contains("API安全"))) { + + System.err.println("🔍 证书问题诊断:"); + System.err.println("1. 检查商户平台是否已开启API安全功能"); + System.err.println("2. 检查是否已申请使用微信支付公钥"); + System.err.println("3. 检查网络连接是否正常"); + System.err.println("4. 检查商户证书序列号是否正确"); + System.err.println("5. 参考文档:https://pay.weixin.qq.com/doc/v3/merchant/4012153196"); + + // 开发环境回退到基础RSA配置 + System.err.println("⚠️ 开发环境回退到基础RSA配置..."); + try { + // 方案1:尝试使用RSA证书配置(需要商户证书文件) + String tenantCertPath = "dev/wechat/" + order.getTenantId(); + String apiclientCertPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getApiclientCertFile(); + + if (certificateLoader.certificateExists(apiclientCertPath)) { + String apiclientCertFile = certificateLoader.loadCertificatePath(apiclientCertPath); + System.out.println("方案1: 使用RSA证书配置作为回退方案"); + System.out.println("商户证书路径: " + apiclientCertFile); + + try { + config = new RSAConfig.Builder() + .merchantId(payment.getMchId()) + .privateKeyFromPath(privateKey) + .merchantSerialNumber(payment.getMerchantSerialNumber()) + .wechatPayCertificatesFromPath(apiclientCertFile) + .build(); + System.out.println("✅ 开发环境RSA证书配置成功"); + } catch (Exception rsaException) { + System.err.println("RSA证书配置失败: " + rsaException.getMessage()); + throw rsaException; + } + } else { + System.err.println("❌ 商户证书文件不存在: " + apiclientCertPath); + System.err.println("⚠️ 尝试方案2: 使用最小化配置..."); + + // 方案2:使用最小化的RSA配置(仅私钥和序列号) + try { + // 创建一个最基础的配置,不依赖平台证书 + config = new com.wechat.pay.java.core.RSAConfig.Builder() + .merchantId(payment.getMchId()) + .privateKeyFromPath(privateKey) + .merchantSerialNumber(payment.getMerchantSerialNumber()) + .build(); + System.out.println("✅ 开发环境最小化RSA配置成功"); + } catch (Exception minimalException) { + System.err.println("最小化配置也失败: " + minimalException.getMessage()); + throw new RuntimeException("所有配置方案都失败,请检查私钥文件和商户配置", e); + } + } + } catch (Exception fallbackException) { + System.err.println("❌ 手动证书配置失败: " + fallbackException.getMessage()); + fallbackException.printStackTrace(); + + // 最后的回退:抛出详细错误信息 + System.err.println("=== 最终错误诊断 ==="); + System.err.println("1. 自动证书配置失败原因: " + e.getMessage()); + System.err.println("2. 手动证书配置失败原因: " + fallbackException.getMessage()); + System.err.println("3. 建议解决方案:"); + System.err.println(" - 检查微信商户平台是否开启API安全功能"); + System.err.println(" - 确认已申请使用微信支付公钥"); + System.err.println(" - 验证商户证书序列号是否正确"); + System.err.println(" - 检查私钥文件是否完整且格式正确"); + + throw new RuntimeException("微信支付配置失败,请检查商户平台API安全设置和证书配置。原始错误: " + e.getMessage() + ", 回退错误: " + fallbackException.getMessage(), e); + } + } else { + throw new RuntimeException("微信支付配置失败:" + e.getMessage(), e); + } + } } - } - } catch (Exception fallbackException) { - System.err.println("❌ 手动证书配置失败: " + fallbackException.getMessage()); - fallbackException.printStackTrace(); - - // 最后的回退:抛出详细错误信息 - System.err.println("=== 最终错误诊断 ==="); - System.err.println("1. 自动证书配置失败原因: " + e.getMessage()); - System.err.println("2. 手动证书配置失败原因: " + fallbackException.getMessage()); - System.err.println("3. 建议解决方案:"); - System.err.println(" - 检查微信商户平台是否开启API安全功能"); - System.err.println(" - 确认已申请使用微信支付公钥"); - System.err.println(" - 验证商户证书序列号是否正确"); - System.err.println(" - 检查私钥文件是否完整且格式正确"); - - throw new RuntimeException("微信支付配置失败,请检查商户平台API安全设置和证书配置。原始错误: " + e.getMessage() + ", 回退错误: " + fallbackException.getMessage(), e); - } - } else { - throw new RuntimeException("微信支付配置失败:" + e.getMessage(), e); - } - } - } - } else { - // 生产环境也优先检查公钥配置 - if (payment.getPubKey() != null && !payment.getPubKey().isEmpty() && - payment.getPubKeyId() != null && !payment.getPubKeyId().isEmpty()) { - - System.out.println("=== 生产环境检测到公钥配置,使用RSA公钥模式 ==="); - System.out.println("公钥文件路径: " + payment.getPubKey()); - System.out.println("公钥ID: " + payment.getPubKeyId()); - - try { - // 生产环境处理公钥路径 - String pubKeyPath = payment.getPubKey(); - - // 如果路径不是以 /file 开头,需要添加 /file 前缀 - if (!pubKeyPath.startsWith("/file/") && !pubKeyPath.startsWith("file/")) { - pubKeyPath = "file/" + pubKeyPath; - System.out.println("生产环境公钥路径修正: " + payment.getPubKey() + " -> " + pubKeyPath); } else { - System.out.println("生产环境公钥路径: " + pubKeyPath); + // 生产环境也优先检查公钥配置 + if (payment.getPubKey() != null && !payment.getPubKey().isEmpty() && + payment.getPubKeyId() != null && !payment.getPubKeyId().isEmpty()) { + + System.out.println("=== 生产环境检测到公钥配置,使用RSA公钥模式 ==="); + System.out.println("公钥文件路径: " + payment.getPubKey()); + System.out.println("公钥ID: " + payment.getPubKeyId()); + + try { + // 生产环境处理公钥路径 + String pubKeyPath = payment.getPubKey(); + + // 如果路径不是以 /file 开头,需要添加 /file 前缀 + if (!pubKeyPath.startsWith("/file/") && !pubKeyPath.startsWith("file/")) { + pubKeyPath = "file/" + pubKeyPath; + System.out.println("生产环境公钥路径修正: " + payment.getPubKey() + " -> " + pubKeyPath); + } else { + System.out.println("生产环境公钥路径: " + pubKeyPath); + } + + String pubKeyFile = certificateLoader.loadCertificatePath(pubKeyPath); + System.out.println("✅ 生产环境公钥文件加载成功: " + pubKeyFile); + + config = new RSAPublicKeyConfig.Builder() + .merchantId(payment.getMchId()) + .privateKeyFromPath(privateKey) + .publicKeyFromPath(pubKeyFile) + .publicKeyId(payment.getPubKeyId()) + .merchantSerialNumber(payment.getMerchantSerialNumber()) + .apiV3Key(payment.getApiKey()) + .build(); + System.out.println("✅ 生产环境RSA公钥配置成功"); + } catch (Exception pubKeyException) { + System.err.println("❌ 生产环境RSA公钥配置失败: " + pubKeyException.getMessage()); + pubKeyException.printStackTrace(); + throw new RuntimeException("生产环境RSA公钥配置失败: " + pubKeyException.getMessage(), pubKeyException); + } + } else { + // 没有公钥配置,使用自动证书配置 + System.out.println("=== 生产环境使用自动证书配置 ==="); + System.out.println("商户号: " + payment.getMchId()); + System.out.println("序列号: " + payment.getMerchantSerialNumber()); + System.out.println("API密钥: 已配置(长度:" + payment.getApiKey().length() + ")"); + + try { + // 优先使用自动证书配置,避免证书过期和序列号不匹配问题 + config = wechatCertAutoConfig.createAutoConfig( + payment.getMchId(), + privateKey, + payment.getMerchantSerialNumber(), + payment.getApiKey() + ); + System.out.println("✅ 生产环境自动证书配置成功"); + } catch (Exception autoConfigException) { + System.err.println("⚠️ 自动证书配置失败,回退到手动证书配置"); + System.err.println("自动配置错误: " + autoConfigException.getMessage()); + System.err.println("错误类型: " + autoConfigException.getClass().getName()); + autoConfigException.printStackTrace(); + + // 检查是否是证书相关的错误 + if (autoConfigException.getMessage() != null && ( + autoConfigException.getMessage().contains("certificate") || + autoConfigException.getMessage().contains("X509Certificate") || + autoConfigException.getMessage().contains("getSerialNumber") || + autoConfigException.getMessage().contains("404") || + autoConfigException.getMessage().contains("API安全"))) { + + System.err.println("🔍 生产环境证书问题诊断:"); + System.err.println("1. 检查商户平台是否已开启API安全功能"); + System.err.println("2. 检查是否已申请使用微信支付公钥"); + System.err.println("3. 检查网络连接是否正常"); + System.err.println("4. 检查商户证书序列号是否正确"); + } + + try { + // 回退到手动证书配置 + if (payment.getPubKey() != null && !payment.getPubKey().isEmpty()) { + System.out.println("使用RSA公钥配置作为回退方案"); + config = new RSAPublicKeyConfig.Builder() + .merchantId(payment.getMchId()) + .privateKeyFromPath(privateKey) + .publicKeyFromPath(pubKey) + .publicKeyId(payment.getPubKeyId()) + .merchantSerialNumber(payment.getMerchantSerialNumber()) + .apiV3Key(payment.getApiKey()) + .build(); + System.out.println("✅ 生产环境RSA公钥配置成功"); + } else if (apiclientCert != null && !apiclientCert.isEmpty()) { + System.out.println("使用RSA证书配置作为回退方案"); + config = new RSAConfig.Builder() + .merchantId(payment.getMchId()) + .privateKeyFromPath(privateKey) + .merchantSerialNumber(payment.getMerchantSerialNumber()) + .wechatPayCertificatesFromPath(apiclientCert) + .build(); + System.out.println("✅ 生产环境RSA证书配置成功"); + } else { + throw new RuntimeException("生产环境缺少必要的证书文件,无法创建手动证书配置", autoConfigException); + } + } catch (Exception fallbackException) { + System.err.println("❌ 生产环境手动证书配置也失败: " + fallbackException.getMessage()); + throw new RuntimeException("生产环境微信支付配置失败,请检查商户平台API安全设置和证书配置", autoConfigException); + } + } + } } - String pubKeyFile = certificateLoader.loadCertificatePath(pubKeyPath); - System.out.println("✅ 生产环境公钥文件加载成功: " + pubKeyFile); - - config = new RSAPublicKeyConfig.Builder() - .merchantId(payment.getMchId()) - .privateKeyFromPath(privateKey) - .publicKeyFromPath(pubKeyFile) - .publicKeyId(payment.getPubKeyId()) - .merchantSerialNumber(payment.getMerchantSerialNumber()) - .apiV3Key(payment.getApiKey()) - .build(); - System.out.println("✅ 生产环境RSA公钥配置成功"); - } catch (Exception pubKeyException) { - System.err.println("❌ 生产环境RSA公钥配置失败: " + pubKeyException.getMessage()); - pubKeyException.printStackTrace(); - throw new RuntimeException("生产环境RSA公钥配置失败: " + pubKeyException.getMessage(), pubKeyException); - } - } else { - // 没有公钥配置,使用自动证书配置 - System.out.println("=== 生产环境使用自动证书配置 ==="); - System.out.println("商户号: " + payment.getMchId()); - System.out.println("序列号: " + payment.getMerchantSerialNumber()); - System.out.println("API密钥: 已配置(长度:" + payment.getApiKey().length() + ")"); - - try { - // 优先使用自动证书配置,避免证书过期和序列号不匹配问题 - config = wechatCertAutoConfig.createAutoConfig( - payment.getMchId(), - privateKey, - payment.getMerchantSerialNumber(), - payment.getApiKey() - ); - System.out.println("✅ 生产环境自动证书配置成功"); - } catch (Exception autoConfigException) { - System.err.println("⚠️ 自动证书配置失败,回退到手动证书配置"); - System.err.println("自动配置错误: " + autoConfigException.getMessage()); - System.err.println("错误类型: " + autoConfigException.getClass().getName()); - autoConfigException.printStackTrace(); - - // 检查是否是证书相关的错误 - if (autoConfigException.getMessage() != null && ( - autoConfigException.getMessage().contains("certificate") || - autoConfigException.getMessage().contains("X509Certificate") || - autoConfigException.getMessage().contains("getSerialNumber") || - autoConfigException.getMessage().contains("404") || - autoConfigException.getMessage().contains("API安全"))) { - - System.err.println("🔍 生产环境证书问题诊断:"); - System.err.println("1. 检查商户平台是否已开启API安全功能"); - System.err.println("2. 检查是否已申请使用微信支付公钥"); - System.err.println("3. 检查网络连接是否正常"); - System.err.println("4. 检查商户证书序列号是否正确"); - } - - try { - // 回退到手动证书配置 - if (payment.getPubKey() != null && !payment.getPubKey().isEmpty()) { - System.out.println("使用RSA公钥配置作为回退方案"); - config = new RSAPublicKeyConfig.Builder() - .merchantId(payment.getMchId()) - .privateKeyFromPath(privateKey) - .publicKeyFromPath(pubKey) - .publicKeyId(payment.getPubKeyId()) - .merchantSerialNumber(payment.getMerchantSerialNumber()) - .apiV3Key(payment.getApiKey()) - .build(); - System.out.println("✅ 生产环境RSA公钥配置成功"); - } else if (apiclientCert != null && !apiclientCert.isEmpty()) { - System.out.println("使用RSA证书配置作为回退方案"); - config = new RSAConfig.Builder() - .merchantId(payment.getMchId()) - .privateKeyFromPath(privateKey) - .merchantSerialNumber(payment.getMerchantSerialNumber()) - .wechatPayCertificatesFromPath(apiclientCert) - .build(); - System.out.println("✅ 生产环境RSA证书配置成功"); - } else { - throw new RuntimeException("生产环境缺少必要的证书文件,无法创建手动证书配置", autoConfigException); - } - } catch (Exception fallbackException) { - System.err.println("❌ 生产环境手动证书配置也失败: " + fallbackException.getMessage()); - throw new RuntimeException("生产环境微信支付配置失败,请检查商户平台API安全设置和证书配置", autoConfigException); - } - } + // 构建service + return new JsapiServiceExtension.Builder().config(config).build(); + } catch (Exception e) { + System.err.println("=== 构建微信支付服务失败 ==="); + System.err.println("错误信息: " + e.getMessage()); + System.err.println("错误类型: " + e.getClass().getName()); + e.printStackTrace(); + throw new RuntimeException("构建微信支付服务失败:" + e.getMessage(), e); } - } - - // 构建service - return new JsapiServiceExtension.Builder().config(config).build(); - } catch (Exception e) { - System.err.println("=== 构建微信支付服务失败 ==="); - System.err.println("错误信息: " + e.getMessage()); - System.err.println("错误类型: " + e.getClass().getName()); - e.printStackTrace(); - throw new RuntimeException("构建微信支付服务失败:" + e.getMessage(), e); - } } - @Override - public BigDecimal total() { - try { - // 使用数据库聚合查询统计订单总金额,性能更高 - BigDecimal total = baseMapper.selectTotalAmount(); - - if (total == null) { - total = BigDecimal.ZERO; - } + @Override + public BigDecimal total() { + try { + // 使用数据库聚合查询统计订单总金额,性能更高 + BigDecimal total = baseMapper.selectTotalAmount(); - log.info("统计订单总金额完成,总金额:{}", total); - return total; + if (total == null) { + total = BigDecimal.ZERO; + } - } catch (Exception e) { - log.error("统计订单总金额失败", e); - return BigDecimal.ZERO; - } - } + log.info("统计订单总金额完成,总金额:{}", total); + return total; + } catch (Exception e) { + log.error("统计订单总金额失败", e); + return BigDecimal.ZERO; + } + } - } +} diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderUpdate10550ServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderUpdate10550ServiceImpl.java new file mode 100644 index 0000000..e94f075 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderUpdate10550ServiceImpl.java @@ -0,0 +1,90 @@ +package com.gxwebsoft.shop.service.impl; + +import cn.hutool.core.date.DateUtil; +import com.gxwebsoft.common.core.utils.RequestUtil; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.system.entity.User; +import com.gxwebsoft.shop.entity.*; +import com.gxwebsoft.shop.service.*; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.LinkedHashMap; +import java.util.List; + +/** + * + * @author 科技小王子 + * @since 2025-01-11 10:45:12 + */ +@Service +public class ShopOrderUpdate10550ServiceImpl implements ShopOrderUpdate10550Service { + @Resource + private RequestUtil requestUtil; + @Resource + private ShopDealerOrderService shopDealerOrderService; + @Resource + private ShopDealerCapitalService shopDealerCapitalService; + @Resource + private ShopOrderGoodsService shopOrderGoodsService; + @Resource + private ShopGoodsService shopGoodsService; + + @Override + public void update(ShopOrder order){ + requestUtil.setTenantId(order.getTenantId().toString()); + ApiResult partnerConditionReq = requestUtil.pageDictData(1460); + if (partnerConditionReq.getCode().equals(0) && partnerConditionReq.getData() != null) { + LinkedHashMap dictDataMap = (LinkedHashMap) partnerConditionReq.getData(); + List dictDataList = (List) dictDataMap.get("list"); + String dictDataCode = (String) dictDataList.get(0).get("dictDataCode"); + BigDecimal partnerCondition = new BigDecimal(dictDataCode); + + User user = requestUtil.getByUserIdWithoutLogin(order.getUserId()); + if (user != null) { + user.setExpendMoney(user.getExpendMoney().add(order.getPayPrice())); + if (user.getExpendMoney().compareTo(partnerCondition) >= 0) { + user.setGradeId(3); + } + requestUtil.updateWithoutLogin(user); + + // 上级 + User parent = requestUtil.getParent(order.getUserId()); + if (parent != null) { + + List shopOrderGoodsList = shopOrderGoodsService.getListByOrderId(order.getOrderId()); + List goodsIds = shopOrderGoodsList.stream().map(ShopOrderGoods::getGoodsId).toList(); + List shopGoodsList = shopGoodsService.listByIds(goodsIds); + BigDecimal commission = BigDecimal.ZERO; + for (ShopOrderGoods shopOrderGoods : shopOrderGoodsList) { + ShopGoods shopGoods = shopGoodsList.stream().filter(sG -> sG.getGoodsId().equals(shopOrderGoods.getGoodsId())).findFirst().orElse(null); + if (shopGoods != null) { + commission = commission.add(shopGoods.getCommission().multiply(BigDecimal.valueOf(shopOrderGoods.getTotalNum()))); + } + } + parent.setBalance(parent.getBalance().add(commission)); + requestUtil.updateWithoutLogin(user); + + // 分销订单 + ShopDealerOrder shopDealerOrder = new ShopDealerOrder(); + shopDealerOrder.setUserId(parent.getUserId()); + shopDealerOrder.setOrderId(order.getOrderId()); + shopDealerOrder.setOrderPrice(order.getTotalPrice()); + shopDealerOrder.setFirstUserId(order.getUserId()); + shopDealerOrder.setFirstMoney(commission); + shopDealerOrder.setIsSettled(1); + shopDealerOrder.setSettleTime(DateUtil.currentSeconds()); + shopDealerOrderService.save(shopDealerOrder); + + // 分销资明细 + ShopDealerCapital shopDealerCapital = new ShopDealerCapital(); + shopDealerCapital.setUserId(parent.getUserId()); + shopDealerCapital.setOrderId(order.getOrderId()); + shopDealerCapital.setFlowType(10); + shopDealerCapitalService.save(shopDealerCapital); + } + } + } + } +} diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopUserCouponServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopUserCouponServiceImpl.java index 73934f9..ea2e3d3 100644 --- a/src/main/java/com/gxwebsoft/shop/service/impl/ShopUserCouponServiceImpl.java +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopUserCouponServiceImpl.java @@ -1,5 +1,6 @@ package com.gxwebsoft.shop.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.gxwebsoft.shop.mapper.ShopUserCouponMapper; import com.gxwebsoft.shop.service.ShopUserCouponService; @@ -44,4 +45,13 @@ public class ShopUserCouponServiceImpl extends ServiceImpl userList(Integer userId) { + return list( + new LambdaQueryWrapper() + .eq(ShopUserCoupon::getUserId, userId) + ); + } + } diff --git a/src/test/java/com/gxwebsoft/generator/ShopGenerator.java b/src/test/java/com/gxwebsoft/generator/ShopGenerator.java index 1dd164a..357ac98 100644 --- a/src/test/java/com/gxwebsoft/generator/ShopGenerator.java +++ b/src/test/java/com/gxwebsoft/generator/ShopGenerator.java @@ -27,9 +27,9 @@ public class ShopGenerator { // 输出目录 private static final String OUTPUT_DIR = "/src/main/java"; // Vue文件输出位置 - private static final String OUTPUT_LOCATION_VUE = "/Users/gxwebsoft/VUE/mp-vue"; + private static final String OUTPUT_LOCATION_VUE = "/Users/liangxin/Project/Html/web/mp-vue"; // Vue文件输出目录 - private static final String OUTPUT_LOCATION_UNIAPP = "/Users/gxwebsoft/VUE/template-10550"; + private static final String OUTPUT_LOCATION_UNIAPP = "/Users/liangxin/Project/Html/miniProgram/template-10550"; // Vue文件输出目录 private static final String OUTPUT_DIR_VUE = "/src"; // 作者名称 @@ -37,7 +37,7 @@ public class ShopGenerator { // 是否在xml中添加二级缓存配置 private static final boolean ENABLE_CACHE = false; // 数据库连接配置 - private static final String DB_URL = "jdbc:mysql://47.119.165.234:3308/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8"; + private static final String DB_URL = "jdbc:mysql://8.134.169.209:13306/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8"; private static final String DB_DRIVER = "com.mysql.cj.jdbc.Driver"; private static final String DB_USERNAME = "modules"; private static final String DB_PASSWORD = "8YdLnk7KsPAyDXGA"; @@ -100,6 +100,7 @@ public class ShopGenerator { // "shop_express", // "shop_express_template", // "shop_express_template_detail" + "shop_gift" }; // 需要去除的表前缀 private static final String[] TABLE_PREFIX = new String[]{