From 9317daa90de71e53609af984a9e98e2191d7d211 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Sun, 29 Mar 2026 21:37:23 +0800 Subject: [PATCH 01/17] =?UTF-8?q?feat:=E4=BC=98=E5=8C=96=E6=B6=A8=E4=BB=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../canteen/entity/CanteenSpuEntity.java | 237 +++++++++--------- .../canteen/vo/ADCanteenDailyMenuListVO.java | 6 + .../canteen/vo/ADCanteenSpuListVO.java | 25 +- .../service/impl/CanteenSpuServiceImpl.java | 28 ++- .../mapper/CanteenDailyMenuMapper.xml | 2 + .../hard/api/dto/hard/HardCreateOrderDto.java | 3 + .../hard/api/dto/order/HardCreateCarDto.java | 3 + .../hard/api/entity/order/HardCarEntity.java | 6 + .../hard/service/HardOrderService.java | 3 +- .../impl/order/HardAfterSaleServiceImpl.java | 32 ++- .../impl/order/HardCarServiceImpl.java | 19 ++ .../impl/order/HardOrderServiceImpl.java | 28 ++- .../resources/mapper/order/HardCarMapper.xml | 21 +- .../wallet/api/vo/WalletXfjDiscounts.java | 5 + .../impl/WalletSettingServiceImpl.java | 1 + 15 files changed, 249 insertions(+), 170 deletions(-) diff --git a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/CanteenSpuEntity.java b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/CanteenSpuEntity.java index 51ef5acc0..7a4e3e42c 100644 --- a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/CanteenSpuEntity.java +++ b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/CanteenSpuEntity.java @@ -10,6 +10,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import com.bsd.pjcloud.common.core.util.TenantTable; + import java.time.LocalDateTime; /** @@ -26,182 +27,184 @@ import java.time.LocalDateTime; public class CanteenSpuEntity extends Model { - /** - * 商品 SPU 编号,自增 - */ + /** + * 商品 SPU 编号,自增 + */ @TableId(type = IdType.ASSIGN_ID) - @Schema(description="商品 SPU 编号,自增") + @Schema(description = "商品 SPU 编号,自增") private Long id; - /** - * 商品名称 - */ - @Schema(description="商品名称") + /** + * 商品名称 + */ + @Schema(description = "商品名称") private String name; - /** - * 商品简介 - */ - @Schema(description="商品简介") + /** + * 商品简介 + */ + @Schema(description = "商品简介") private String introduction; - /** - * 商品详情 - */ - @Schema(description="商品详情") + /** + * 商品详情 + */ + @Schema(description = "商品详情") private String description; - /** - * 商品分类编号 - */ - @Schema(description="商品分类编号") + /** + * 商品分类编号 + */ + @Schema(description = "商品分类编号") private Long categoryId; - /** - * 商品封面图 - */ - @Schema(description="商品封面图") + /** + * 商品封面图 + */ + @Schema(description = "商品封面图") private String picUrl; - /** - * 商品轮播图地址 - 数组,以逗号分隔 - 最多上传15张 - */ - @Schema(description="商品轮播图") + /** + * 商品轮播图地址 + * 数组,以逗号分隔 + * 最多上传15张 + */ + @Schema(description = "商品轮播图") private String sliderPicUrls; - /** - * 排序字段 - */ - @Schema(description="排序字段") + /** + * 排序字段 + */ + @Schema(description = "排序字段") private Integer sort; - /** - * 商品状态: 1 上架(开启) 0 下架(禁用) -1 回收 - */ - @Schema(description="商品状态: 1 上架(开启) 0 下架(禁用) -1 回收") + /** + * 商品状态: 1 上架(开启) 0 下架(禁用) -1 回收 + */ + @Schema(description = "商品状态: 1 上架(开启) 0 下架(禁用) -1 回收") private Integer status; - /** - * 规格类型:0 单规格 1 多规格 - */ - @Schema(description="规格类型:0 单规格 1 多规格") + /** + * 规格类型:0 单规格 1 多规格 + */ + @Schema(description = "规格类型:0 单规格 1 多规格") private Boolean specType; - /** - * 商品价格,单位使用:分 - */ - @Schema(description="商品价格,单位使用:分") + /** + * 商品价格,单位使用:分 + */ + @Schema(description = "商品价格,单位使用:分") // @JsonSerialize(using = MoneySerializer.class) // 分 -> 元 // @JsonDeserialize(using = MoneyDeserializer.class) // 元 -> 分 private Integer price; - /** - * 市场价,单位使用:分 - */ - @Schema(description="市场价,单位使用:分") + /** + * 市场价,单位使用:分 + */ + @Schema(description = "市场价,单位使用:分") // @JsonSerialize(using = MoneySerializer.class) // 分 -> 元 // @JsonDeserialize(using = MoneyDeserializer.class) // 元 -> 分 private Integer marketPrice; - /** - * 成本价,单位: 分 - */ - @Schema(description="成本价,单位: 分") + /** + * 成本价,单位: 分 + */ + @Schema(description = "成本价,单位: 分") // @JsonSerialize(using = MoneySerializer.class) // 分 -> 元 // @JsonDeserialize(using = MoneyDeserializer.class) // 元 -> 分 private Integer costPrice; - /** - * 库存 - */ - @Schema(description="库存") + /** + * 库存 + */ + @Schema(description = "库存") private Integer stock; - /** - * 赠送积分 - */ - @Schema(description="赠送积分") + /** + * 赠送积分 + */ + @Schema(description = "赠送积分") private Integer giveIntegral; - /** - * 商品销量 - */ - @Schema(description="商品销量") + /** + * 商品销量 + */ + @Schema(description = "商品销量") private Integer salesCount; - /** - * 虚拟销量 - */ - @Schema(description="虚拟销量") + /** + * 虚拟销量 + */ + @Schema(description = "虚拟销量") private Integer virtualSalesCount; - /** - * 商品点击量 - */ - @Schema(description="商品点击量") + /** + * 商品点击量 + */ + @Schema(description = "商品点击量") private Integer browseCount; + @TableLogic + @TableField(fill = FieldFill.INSERT) + @Schema(description = "是否删除 -1:已删除 0:正常") + private String delFlag; - @TableLogic - @TableField(fill = FieldFill.INSERT) - @Schema(description = "是否删除 -1:已删除 0:正常") - private String delFlag; - - /** - * 系统类型 2每日 3在线订餐 - */ - @Schema(description="系统类型 2每日 3在线订餐") + /** + * 系统类型 2每日 3在线订餐 + */ + @Schema(description = "系统类型 2每日 3在线订餐") private Long systemType; - /** - * 商户编号 - */ - @Schema(description="商户编号") + /** + * 商户编号 + */ + @Schema(description = "商户编号") private Long merchantId; - /** - * 部门id - */ - @Schema(description="部门id") + /** + * 部门id + */ + @Schema(description = "部门id") private Long deptId; - /** - * 创建人 - */ - @TableField(fill = FieldFill.INSERT) - @Schema(description="创建人") + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + @Schema(description = "创建人") private String createBy; - /** - * 创建时间 - */ - @TableField(fill = FieldFill.INSERT) - @Schema(description="创建时间") + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + @Schema(description = "创建时间") private LocalDateTime createTime; - /** - * 更新人 - */ - @TableField(fill = FieldFill.INSERT_UPDATE) - @Schema(description="更新人") + /** + * 更新人 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + @Schema(description = "更新人") private String updateBy; - /** - * 更新时间 - */ - @TableField(fill = FieldFill.INSERT_UPDATE) - @Schema(description="更新时间") + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + @Schema(description = "更新时间") private LocalDateTime updateTime; - /** - * 租户编号 - */ - @Schema(description="租户编号") + /** + * 租户编号 + */ + @Schema(description = "租户编号") private Long tenantId; - @Schema(description="是否显示") - private String isShow; + @Schema(description = "是否显示") + private String isShow; + + @Schema(description = "是否涨价") + private String isPriceIncreased; } \ No newline at end of file diff --git a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/vo/ADCanteenDailyMenuListVO.java b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/vo/ADCanteenDailyMenuListVO.java index 3f522b01e..ecb1f1636 100644 --- a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/vo/ADCanteenDailyMenuListVO.java +++ b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/vo/ADCanteenDailyMenuListVO.java @@ -1,5 +1,6 @@ package com.bsd.pjcloud.canteen.vo; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data @@ -44,4 +45,9 @@ public class ADCanteenDailyMenuListVO { * 排序 */ private Integer sort; + + /** + * 是否涨价 + */ + private String isPriceIncreased; } diff --git a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/vo/ADCanteenSpuListVO.java b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/vo/ADCanteenSpuListVO.java index d7460b143..168a37e0e 100644 --- a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/vo/ADCanteenSpuListVO.java +++ b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/vo/ADCanteenSpuListVO.java @@ -15,71 +15,72 @@ public class ADCanteenSpuListVO { /** * 商品 SPU 编号,自增 */ - @Schema(description="商品 SPU 编号,自增") + @Schema(description = "商品 SPU 编号,自增") private Long id; /** * 商品名称 */ - @Schema(description="商品名称") + @Schema(description = "商品名称") private String name; /** * 商品分类编号 */ - @Schema(description="商品分类编号") + @Schema(description = "商品分类编号") private Long categoryId; /** * 商品封面图 */ - @Schema(description="商品封面图") + @Schema(description = "商品封面图") private String picUrl; /** * 商品价格,单位使用:分 */ - @Schema(description="商品价格,单位使用:分") + @Schema(description = "商品价格,单位使用:分") private Integer price; /** * 市场价,单位使用:分 */ - @Schema(description="市场价,单位使用:分") + @Schema(description = "市场价,单位使用:分") private Integer marketPrice; /** * 库存 */ - @Schema(description="库存") + @Schema(description = "库存") private Integer stock; /** * 商品销量 */ - @Schema(description="商品销量") + @Schema(description = "商品销量") private Integer salesCount; /** * 商户编号 */ - @Schema(description="商户编号") + @Schema(description = "商户编号") private Long merchantId; /** * 部门id */ - @Schema(description="部门id") + @Schema(description = "部门id") private Long deptId; + @Schema(description = "是否涨价") + private String isPriceIncreased; - - @Schema(description="餐段类型") + @Schema(description = "餐段类型") private String categoryType; } diff --git a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/CanteenSpuServiceImpl.java b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/CanteenSpuServiceImpl.java index 7f0b1de3a..8241ee60a 100644 --- a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/CanteenSpuServiceImpl.java +++ b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/CanteenSpuServiceImpl.java @@ -46,6 +46,7 @@ public class CanteenSpuServiceImpl extends ServiceImpl wrapper) { return baseMapper.selectListByScope(wrapper, DataScope.of()); @@ -59,11 +60,11 @@ public class CanteenSpuServiceImpl extends ServiceImpl spu.getStock()) { - R.failed(spu.getName()+"库存不足,无法完成操作"); + R.failed(spu.getName() + "库存不足,无法完成操作"); } int i = baseMapper.updateStock(item.getId(), item.getIncrCount()); // if (item.getIncrCount() <= 0) { @@ -89,7 +90,7 @@ public class CanteenSpuServiceImpl extends ServiceImpl> listMap = canteenCategoryEntities.stream().collect(Collectors.groupingBy(CanteenCategoryEntity::getId)); bean.forEach(item -> { - if (null!=listMap.get(item.getCategoryId()).get(0).getCategoryType()){ + if (null != listMap.get(item.getCategoryId()).get(0).getCategoryType()) { item.setCategoryType(listMap.get(item.getCategoryId()).get(0).getCategoryType()); } }); @@ -127,7 +128,7 @@ public class CanteenSpuServiceImpl extends ServiceImpl canteenCategoryEntityLambdaQueryWrapper = new LambdaQueryWrapper<>(); canteenCategoryEntityLambdaQueryWrapper.like(CanteenCategoryEntity::getCategoryType, canteenDailySpuDTO.getHourType()); List canteenCategoryEntities = canteenCategoryMapper.selectList(canteenCategoryEntityLambdaQueryWrapper); - List caIds = canteenCategoryEntities.stream().map(CanteenCategoryEntity::getId).collect(Collectors.toList()); + List caIds = canteenCategoryEntities.stream().map(CanteenCategoryEntity::getId).collect(Collectors.toList()); wrapper.in(!CollectionUtils.isEmpty(caIds), CanteenSpuEntity::getCategoryId, caIds); // wrapper.orderByAsc(CanteenSpuEntity::getSort); @@ -164,32 +165,32 @@ public class CanteenSpuServiceImpl extends ServiceImpl pageData = baseMapper.selectPageByScope(page, wrapper, DataScope.of()); List records = pageData.getRecords(); - + // 构建返回的VO列表 List resultList = new ArrayList<>(); - + if (!CollectionUtils.isEmpty(records)) { // 获取所有SPU ID List spuIds = records.stream() .map(CanteenSpuEntity::getId) .collect(Collectors.toList()); - + // 查询对应的库存信息 LambdaQueryWrapper stockWrapper = Wrappers.lambdaQuery(); stockWrapper.in(CanteenStockEntity::getItemId, spuIds); stockWrapper.eq(CanteenStockEntity::getItemType, "2"); // 假设"成品"表示菜品的类型 List stockList = canteenStockMapper.selectList(stockWrapper); - + // 将库存信息映射到SPU ID Map stockMap = stockList.stream() .collect(Collectors.toMap(CanteenStockEntity::getItemId, stock -> stock, (v1, v2) -> v1)); - + // 构建返回结果 for (CanteenSpuEntity spu : records) { CanteenSpuStockVO vo = new CanteenSpuStockVO(); vo.setName(spu.getName()); vo.setPicUrl(spu.getPicUrl()); - + // 设置库存信息 CanteenStockEntity stock = stockMap.get(spu.getId()); if (stock != null) { @@ -205,11 +206,11 @@ public class CanteenSpuServiceImpl extends ServiceImpl resultPage = new Page<>(); resultPage.setRecords(resultList); @@ -217,7 +218,7 @@ public class CanteenSpuServiceImpl extends ServiceImpl wrapper = new LambdaQueryWrapper<>(); wrapper.like(StrUtil.isNotBlank(canteenSpu.getName()), CanteenSpuEntity::getName, canteenSpu.getName()); wrapper.eq(Objects.nonNull(canteenSpu.getCategoryId()), CanteenSpuEntity::getCategoryId, canteenSpu.getCategoryId()); + wrapper.eq(Objects.nonNull(canteenSpu.getIsPriceIncreased()), CanteenSpuEntity::getIsPriceIncreased, canteenSpu.getIsPriceIncreased()); wrapper.orderByAsc(CanteenSpuEntity::getSort).orderByDesc(CanteenSpuEntity::getId); LambdaQueryWrapper canteenOnlineSpuEntityLambdaQueryWrapper = new LambdaQueryWrapper<>(); diff --git a/pjcloud-canteen/pjcloud-canteen-biz/src/main/resources/mapper/CanteenDailyMenuMapper.xml b/pjcloud-canteen/pjcloud-canteen-biz/src/main/resources/mapper/CanteenDailyMenuMapper.xml index f47debe6c..97c691e96 100644 --- a/pjcloud-canteen/pjcloud-canteen-biz/src/main/resources/mapper/CanteenDailyMenuMapper.xml +++ b/pjcloud-canteen/pjcloud-canteen-biz/src/main/resources/mapper/CanteenDailyMenuMapper.xml @@ -28,6 +28,7 @@ + - \ No newline at end of file From 0894e86d8cf01aad0b6868e90b93ba9aacd3118e Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Mon, 30 Mar 2026 11:58:07 +0800 Subject: [PATCH 05/17] =?UTF-8?q?feat:=E9=A3=9F=E5=A0=82=E8=8F=9C=E5=93=81?= =?UTF-8?q?=E4=BB=B7=E6=A0=BC=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/bsd/pjcloud/canteen/entity/CanteenSpuEntity.java | 4 ++++ .../pjcloud/canteen/service/impl/CanteenSpuServiceImpl.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/CanteenSpuEntity.java b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/CanteenSpuEntity.java index 7a4e3e42c..61309568f 100644 --- a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/CanteenSpuEntity.java +++ b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/CanteenSpuEntity.java @@ -207,4 +207,8 @@ public class CanteenSpuEntity extends Model { @Schema(description = "是否涨价") private String isPriceIncreased; + + @Schema(description = "大于等于的价格") + @TableField(exist = false) + private Long gePrice; } \ No newline at end of file diff --git a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/CanteenSpuServiceImpl.java b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/CanteenSpuServiceImpl.java index 8241ee60a..59bdccbfe 100644 --- a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/CanteenSpuServiceImpl.java +++ b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/CanteenSpuServiceImpl.java @@ -1,5 +1,6 @@ package com.bsd.pjcloud.canteen.service.impl; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -228,6 +229,9 @@ public class CanteenSpuServiceImpl extends ServiceImpl 0) { + wrapper.ge(CanteenSpuEntity::getPrice, canteenSpu.getGePrice() * 100); + } wrapper.orderByAsc(CanteenSpuEntity::getSort).orderByDesc(CanteenSpuEntity::getId); LambdaQueryWrapper canteenOnlineSpuEntityLambdaQueryWrapper = new LambdaQueryWrapper<>(); From eec07ac7183cd19c6c3a0e5708593846925299f5 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Tue, 31 Mar 2026 16:26:04 +0800 Subject: [PATCH 06/17] =?UTF-8?q?feat:=E6=A0=A1=E9=AA=8C=E7=94=B3=E8=AF=B7?= =?UTF-8?q?=E7=9A=84=E5=85=85=E5=80=BC/=E6=89=A3=E6=AC=BE=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BD=93=E5=89=8D=E6=98=AF=E5=90=A6=E5=90=88=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/constant/WalletBizRechargeEnum.java | 5 ++ .../WalletRechargeValidateErrorVo.java | 52 ++++++++++++++++ .../WalletRechargeApplyController.java | 7 +++ .../service/WalletRechargeApplyService.java | 6 ++ .../WalletRechargeApplyServiceImpl.java | 61 +++++++++++++++++++ 5 files changed, 131 insertions(+) create mode 100644 pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/vo/recharge/WalletRechargeValidateErrorVo.java diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletBizRechargeEnum.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletBizRechargeEnum.java index 7215ee316..60aae9e7e 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletBizRechargeEnum.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletBizRechargeEnum.java @@ -19,6 +19,11 @@ public enum WalletBizRechargeEnum { private final String desc; + public static List reductionList = List.of( + REDUCTION, + RETURN_CANTEEN + ); + public static List reductionCodes() { return Arrays.asList(REDUCTION.getCode(), RETURN_CANTEEN.getCode()); } diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/vo/recharge/WalletRechargeValidateErrorVo.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/vo/recharge/WalletRechargeValidateErrorVo.java new file mode 100644 index 000000000..145e6275a --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/vo/recharge/WalletRechargeValidateErrorVo.java @@ -0,0 +1,52 @@ +package com.bsd.pjcloud.wallet.api.vo.recharge; + +import com.bsd.pjcloud.admin.api.vo.base.BaseUserInterface; +import lombok.Data; + +import java.util.List; + +@Data +public class WalletRechargeValidateErrorVo implements BaseUserInterface { + + /** + * 用户相关 + */ + private Long userId; + + private String username; + + private String userMobile; + + private String userAvatar; + + /** + * 饭卡类型id + */ + private Long walletTypeId; + + /** + * 钱包余额 + */ + private Integer walletBlance; + + /** + * 操作类型 + */ + private String bizType; + + /** + * 操作金额 + */ + private Integer price; + + /** + * 操作后的金额 + */ + private Integer afterPrice; + + /** + * 错误信息 + */ + private List errorList; + +} diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java index 3cb568db6..3ae259564 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java @@ -20,6 +20,7 @@ import com.bsd.pjcloud.wallet.api.dto.recharge.excel.WalletRechargeExcelDto; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeApplyEntity; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeApplyCompareAceVo; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeImportVo; +import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeValidateErrorVo; import com.bsd.pjcloud.wallet.api.vo.recharge.excel.WalletRechargeByApplyExcelVo; import com.bsd.pjcloud.wallet.service.WalletRechargeApplyService; import com.bsd.pjcloud.wallet.service.WalletRechargeApplyComposeService; @@ -55,6 +56,12 @@ public class WalletRechargeApplyController { } /* ************************************* start callback start ************************************* */ + @GetMapping("/validate-error") + @Operation(summary = "校验申请的充值/扣款数据当前是否合法") + public R> validateError(@RequestParam Long applyId) { + return R.ok(walletRechargeApplyService.validateError(applyId)); + } + @PostMapping("/save-topup") @Operation(summary = "新增充值") @Idempotent(expireTime = 3, key = "'/wallet-recharge-apply/save-topup' + #dto.getInvoiceId()", info = "正在充值中,请勿重复操作") diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargeApplyService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargeApplyService.java index 8b641c875..0473ef48c 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargeApplyService.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargeApplyService.java @@ -12,6 +12,7 @@ import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeSaveTopupDto; import com.bsd.pjcloud.wallet.api.dto.recharge.excel.WalletRechargeExcelDto; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeApplyEntity; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeApplyVo; +import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeValidateErrorVo; import com.bsd.pjcloud.wallet.api.vo.recharge.excel.WalletRechargeByApplyExcelVo; import jakarta.servlet.http.HttpServletResponse; import org.springframework.validation.BindingResult; @@ -72,4 +73,9 @@ public interface WalletRechargeApplyService extends IService validateError(Long applyId); } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeApplyServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeApplyServiceImpl.java index 7df8a5440..ea51fce61 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeApplyServiceImpl.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeApplyServiceImpl.java @@ -57,6 +57,7 @@ import com.bsd.pjcloud.wallet.api.utils.WalletDataUtil; import com.bsd.pjcloud.wallet.api.vo.WalletManageVo; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeApplyVo; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeImportVo; +import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeValidateErrorVo; import com.bsd.pjcloud.wallet.api.vo.recharge.excel.WalletRechargeByApplyExcelVo; import com.bsd.pjcloud.wallet.mapper.WalletManageMapper; import com.bsd.pjcloud.wallet.mapper.WalletTransactionMapper; @@ -554,6 +555,66 @@ public class WalletRechargeApplyServiceImpl extends ServiceImpl validateError(Long applyId) { + + List resultList = new ArrayList<>(); + + WalletRechargeApplyEntity detail = baseMapper.selectById(applyId); + if (ObjectUtil.isEmpty(detail)) return null; + // 校验判断回不回出现扣减之后为负数的情况 + List reductionList = WalletBizRechargeEnum.reductionList.stream().map(WalletBizRechargeEnum::getCode).toList(); + if (reductionList.contains(detail.getBizType())) { + List importList = rechargeImportService.list(new LambdaQueryWrapper().eq(WalletRechargeImportEntity::getApplyId, applyId)); + if (ObjectUtil.isEmpty(importList)) { + return null; + } + List userIds = importList.stream().map(WalletRechargeImportEntity::getUserId).filter(ObjectUtil::isNotEmpty).distinct().toList(); + // 查询现在这些用户的钱包余额 + WalletManageDto walletQueryDto = new WalletManageDto(); + walletQueryDto.setWalletTypeId(detail.getWalletTypeId()); + walletQueryDto.setUserIds(userIds); + List walletList = walletManageMapper.list(walletQueryDto); + // 判断每一个人的每一个钱包余额是否满足扣减 + for (WalletManageEntity wallet : walletList) { + List list = importList.stream().filter(v -> ObjectUtil.equals(v.getUserId(), wallet.getUserId())).toList(); + if (ObjectUtil.isEmpty(list)) continue; + Integer reductionPrice = list.stream().map(WalletRechargeImportEntity::getPrice).reduce(Integer::sum).orElse(0); + + int price = wallet.getBalance() - reductionPrice; + + if (price < 0) { + WalletRechargeValidateErrorVo item = new WalletRechargeValidateErrorVo(); + item.setUserId(wallet.getUserId()); + item.setBizType(detail.getBizType()); + item.setWalletTypeId(detail.getWalletTypeId()); + item.setWalletBlance(wallet.getBalance()); + item.setPrice(reductionPrice); + item.setAfterPrice(price); + item.setErrorList(new ArrayList() {{ + add("钱包余额不足以扣款,请尽快联系该用户"); + }}); + resultList.add(item); + } + + } + } + + // 处理`resultList`结果 + if (ObjectUtil.isNotEmpty(resultList)) { + List userIds = resultList.stream().map(WalletRechargeValidateErrorVo::getUserId).filter(ObjectUtil::isNotEmpty).distinct().toList(); + List userList = userService.getInnerUserById(userIds).getData(); + if (ObjectUtil.isNotEmpty(userList)) { + DataUtil.convertUserList(resultList, CollectionUtils.convertMap(userList, SysUser::getUserId)); + } + } + + return resultList; + } + /** * 导出充值/扣款申请 */ From bb1def88d9dbb2393ffe5795409d56115fb481bf Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Tue, 14 Apr 2026 18:32:51 +0800 Subject: [PATCH 07/17] =?UTF-8?q?feat:=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/810pjcloudx_wallet_act.sql | 31 +++++----- .../entity/pay/ThirdPayOrderEntity.java | 12 ++++ .../pay/wechat/ThirdMiniWechatQueryVo.java | 15 +++++ .../wechat/ThirdMiniWechatRefundQueryVo.java | 16 ++++- .../service/ThirdMiniAppWechatService.java | 6 ++ .../service/ThirdPayOrderService.java | 5 ++ .../impl/miniapp/ThirdMiniAppServiceImpl.java | 58 ++++++++++++++++-- .../ThirdMiniAppWechatServiceImpl.java | 44 +++++++++++++- .../src/main/resources/application.yml | 4 +- .../resources/mapper/ThirdPayOrderMapper.xml | 5 ++ .../recharge/WalletRechargePaySuccess.java | 28 +++++++++ .../RemoteWalletRechargePackageService.java | 8 +++ .../WalletRechargePackageController.java | 9 +++ .../service/WalletRechargePackageService.java | 7 +++ .../wallet/service/WalletRechargeService.java | 9 --- .../service/WalletTransactionService.java | 16 ----- .../WalletRechargePackageServiceImpl.java | 59 +++++++++++++++++-- 17 files changed, 278 insertions(+), 54 deletions(-) create mode 100644 pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargePaySuccess.java diff --git a/db/810pjcloudx_wallet_act.sql b/db/810pjcloudx_wallet_act.sql index fd86effd1..aa4b3912f 100644 --- a/db/810pjcloudx_wallet_act.sql +++ b/db/810pjcloudx_wallet_act.sql @@ -6,15 +6,15 @@ create table act_cancel notice_id BIGINT(19) not null comment '公告id', active_org_price INT(10) null comment '活动原价', active_cancel_price INT(10) not null comment '活动核销价', - start_time DATETIME null comment '开始时间', - expire_time DATETIME not null comment '到期时间', - act_status CHAR(32) not null comment '活动状态(1:正常 2:关闭)', - act_title CHAR(32) not null comment '活动标题', - act_content CHAR(32) null comment '活动内容', - create_by VARCHAR(64) null comment '创建人', - create_time DATETIME null comment '创建时间', - update_by VARCHAR(64) null comment '修改人', - update_time DATETIME null comment '修改时间', + start_time DATETIME null comment '开始时间', + expire_time DATETIME not null comment '到期时间', + act_status CHAR(32) not null comment '活动状态(1:正常 2:关闭)', + act_title CHAR(32) not null comment '活动标题', + act_content CHAR(32) null comment '活动内容', + create_by VARCHAR(64) null comment '创建人', + create_time DATETIME null comment '创建时间', + update_by VARCHAR(64) null comment '修改人', + update_time DATETIME null comment '修改时间', del_flag CHAR default '0' null comment '删除标记', tenant_id BIGINT(19) null comment '租户ID' ); @@ -47,6 +47,7 @@ DROP TABLE IF EXISTS act_coupon; CREATE TABLE act_coupon ( id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '优惠券ID', + parent_act_id BIGINT(20) DEFAULT NULL COMMENT '父活动id', name VARCHAR(128) NOT NULL COMMENT '优惠券名称', type VARCHAR(64) NOT NULL COMMENT '优惠券类型 (1:满减券 2:折扣券 3:立减券 4:兑换券)', face_value INT DEFAULT 0 COMMENT '面额/折扣 (满减/立减单位:分, 折扣单位:百分比)', @@ -71,8 +72,8 @@ CREATE TABLE act_coupon del_flag char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记', tenant_id bigint DEFAULT NULL COMMENT '租户ID', PRIMARY KEY (id), - KEY idx_status (status), - KEY idx_valid_end_time (valid_end_time) + KEY idx_status (status), + KEY idx_valid_end_time (valid_end_time) ) ENGINE = InnoDB COMMENT ='优惠券活动'; DROP TABLE IF EXISTS act_coupon_record; @@ -109,8 +110,8 @@ CREATE TABLE act_coupon_record PRIMARY KEY (id), UNIQUE KEY uk_coupon_code (coupon_code), - KEY idx_user_id (user_id), - KEY idx_coupon_id (coupon_id), - KEY idx_end_time (end_time), - KEY idx_status (status) + KEY idx_user_id (user_id), + KEY idx_coupon_id (coupon_id), + KEY idx_end_time (end_time), + KEY idx_status (status) ) ENGINE = InnoDB COMMENT ='优惠券领取记录表'; \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/pay/ThirdPayOrderEntity.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/pay/ThirdPayOrderEntity.java index 11c27dbd4..8207b6ae2 100755 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/pay/ThirdPayOrderEntity.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/pay/ThirdPayOrderEntity.java @@ -81,6 +81,12 @@ public class ThirdPayOrderEntity extends Model { @Schema(description = "支付时间") private LocalDateTime payTime; + /** + * 支付参数 + */ + @Schema(description = "支付参数") + private String payRep; + /** * 支付返回 */ @@ -99,6 +105,12 @@ public class ThirdPayOrderEntity extends Model { @Schema(description = "退款时间") private LocalDateTime refundTime; + /** + * 退款参数 + */ + @Schema(description = "退款参数") + private String refundRep; + /** * 退款返回 */ diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/oathmini/pay/wechat/ThirdMiniWechatQueryVo.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/oathmini/pay/wechat/ThirdMiniWechatQueryVo.java index c444c19b7..27c956cee 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/oathmini/pay/wechat/ThirdMiniWechatQueryVo.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/oathmini/pay/wechat/ThirdMiniWechatQueryVo.java @@ -122,4 +122,19 @@ public class ThirdMiniWechatQueryVo { public boolean isPaySucess() { return ObjectUtil.equals(ThirdMiniWechatQueryVo.SUCCESS, result_code); } + + public static String wechantError() { + return "" + + "" + + "" + + ""; + } + + public static String wechantSuccess() { + return "" + + " " + + " \n" + + ""; + } + } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/oathmini/pay/wechat/ThirdMiniWechatRefundQueryVo.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/oathmini/pay/wechat/ThirdMiniWechatRefundQueryVo.java index 4b335d07b..92f2a4e13 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/oathmini/pay/wechat/ThirdMiniWechatRefundQueryVo.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/vo/oathmini/pay/wechat/ThirdMiniWechatRefundQueryVo.java @@ -92,11 +92,25 @@ public class ThirdMiniWechatRefundQueryVo { private Long refund_fee; public boolean isHttpSucess() { - return ObjectUtil.equals(ThirdMiniWechatRefundQueryVo.SUCCESS, err_code); + return ObjectUtil.equals(ThirdMiniWechatRefundQueryVo.SUCCESS, err_code) || ObjectUtil.isEmpty(err_code); } public boolean isPaySucess() { return ObjectUtil.equals(ThirdMiniWechatRefundQueryVo.SUCCESS, result_code); } + public static String wechantError() { + return "" + + "" + + "" + + ""; + } + + public static String wechantSuccess() { + return "" + + " " + + " \n" + + ""; + } + } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppWechatService.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppWechatService.java index fcac1eb70..552543ced 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppWechatService.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppWechatService.java @@ -3,6 +3,7 @@ package com.bsd.pjcloud.thirdparty.service; import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import com.bsd.pjcloud.thirdparty.dto.oathmini.pay.wechat.*; +import com.bsd.pjcloud.thirdparty.entity.pay.ThirdPayOrderEntity; import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.wechat.*; import org.springframework.http.HttpEntity; import org.springframework.web.bind.annotation.RequestHeader; @@ -46,6 +47,11 @@ public interface ThirdMiniAppWechatService { */ ThirdMiniWechatRefundQueryVo refundQuery(ThirdMiniWechatRefundQueryDto dto); + /** + * 支付的回调通知 + */ + ThirdPayOrderEntity payCallback(String body, @RequestHeader Map headers); + /** * 退款回调 */ diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdPayOrderService.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdPayOrderService.java index e32d92e9e..68b9c61ea 100755 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdPayOrderService.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdPayOrderService.java @@ -1,5 +1,6 @@ package com.bsd.pjcloud.thirdparty.service; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.bsd.pjcloud.common.data.datascope.DataScope; @@ -11,4 +12,8 @@ public interface ThirdPayOrderService extends IService { Page scopePage(Page page, ThirdPayOrderDto dto, DataScope dataScope); + default ThirdPayOrderEntity getByPayNo(String payNo) { + return getOne(new LambdaQueryWrapper().eq(ThirdPayOrderEntity::getPayNo, payNo)); + } + } \ No newline at end of file diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java index 3ed3ab022..9f30b1b91 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java @@ -3,6 +3,8 @@ package com.bsd.pjcloud.thirdparty.service.impl.miniapp; import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.XmlUtil; +import cn.hutool.json.JSONUtil; import com.bsd.pjcloud.admin.api.dto.UserInfo; import com.bsd.pjcloud.admin.api.dto.UserTokenDTO; import com.bsd.pjcloud.admin.api.feign.RemoteTokenService; @@ -14,11 +16,12 @@ import com.bsd.pjcloud.app.api.feign.RemoteAppUserService; import com.bsd.pjcloud.thirdparty.constant.miniplatform.MiniPlatformLoginErrorEnum; import com.bsd.pjcloud.thirdparty.constant.miniplatform.MiniPlatformTypeEnum; import com.bsd.pjcloud.thirdparty.constant.pay.ThirdPayOrderBizTypeEnum; +import com.bsd.pjcloud.thirdparty.constant.pay.ThirdPayOrderStatusEnum; import com.bsd.pjcloud.thirdparty.dto.oathmini.ThirdMiniAppGetUniqueDto; import com.bsd.pjcloud.thirdparty.dto.oathmini.ThirdMiniAppOAth2LoginDto; import com.bsd.pjcloud.thirdparty.dto.oathmini.ThirdMiniAppPayDto; import com.bsd.pjcloud.thirdparty.dto.oathmini.pay.wechat.ThirdMiniJsapiPayDto; -import com.bsd.pjcloud.thirdparty.entity.api.ThirdPayLogEntity; +import com.bsd.pjcloud.thirdparty.entity.pay.ThirdPayOrderEntity; import com.bsd.pjcloud.thirdparty.service.ThirdMiniAppAliPayService; import com.bsd.pjcloud.thirdparty.service.ThirdMiniAppService; import com.bsd.pjcloud.thirdparty.service.ThirdMiniAppWechatService; @@ -26,6 +29,9 @@ import com.bsd.pjcloud.thirdparty.service.ThirdPayLogService; import com.bsd.pjcloud.thirdparty.vo.oathmini.ThirdMinAppOAth2LoginVo; import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.ThirdMiniAppPayVo; import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.wechat.ThirdMiniJsapiPayVo; +import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.wechat.ThirdMiniWechatQueryVo; +import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.wechat.ThirdMiniWechatRefundQueryVo; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePaySuccess; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargePackageEntity; import com.bsd.pjcloud.wallet.api.feign.RemoteWalletRechargePackageService; import lombok.RequiredArgsConstructor; @@ -36,7 +42,6 @@ import org.springframework.validation.annotation.Validated; import javax.net.ssl.*; import java.time.LocalDateTime; import java.time.ZoneId; -import java.util.Date; import java.util.Map; /** @@ -146,7 +151,7 @@ public class ThirdMiniAppServiceImpl implements ThirdMiniAppService { if (ObjectUtil.isEmpty(walletPackage)) { throw new RuntimeException("错误的充值配置"); } - int price = walletPackage.getPayPrice() + walletPackage.getBonusPrice(); + int price = walletPackage.getPayPrice(); if (price <= 0) { throw new RuntimeException("错误的充值配置"); } @@ -194,7 +199,52 @@ public class ThirdMiniAppServiceImpl implements ThirdMiniAppService { */ @Override public String miniPayCallback(String body, Map headers) { - return ""; + MiniPlatformTypeEnum platformType = checkMiniPlatformType(body); + // 微信小程序 + if (ObjectUtil.equals(platformType, MiniPlatformTypeEnum.WECHAT)) { + ThirdPayOrderEntity thirdPayOrder = thirdMiniAppWechatService.payCallback(body, headers); + if (ObjectUtil.isEmpty(thirdPayOrder)) { + return ThirdMiniWechatQueryVo.wechantError(); + } + // 根据订单bizType来处理 + boolean isSuccess = disposePaySuccessAfter(thirdPayOrder); + return isSuccess ? ThirdMiniWechatQueryVo.wechantSuccess() : ThirdMiniWechatQueryVo.wechantError(); + } + // 支付宝 + else if (ObjectUtil.equals(platformType, MiniPlatformTypeEnum.ALI_PAY)) { + return null; + } + // 不支持的支付类型 + else { + return null; + } + } + + private MiniPlatformTypeEnum checkMiniPlatformType(String body) { + ThirdMiniWechatRefundQueryVo vo = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(body)), ThirdMiniWechatRefundQueryVo.class); + // 查询订单 + if (ObjectUtil.isNotEmpty(vo) && ObjectUtil.isNotEmpty(vo.getTransaction_id())) { + return MiniPlatformTypeEnum.WECHAT; + } + return null; + } + + public boolean disposePaySuccessAfter(ThirdPayOrderEntity thirdPayOrder) { + if (ObjectUtil.notEqual(thirdPayOrder.getStatus(), ThirdPayOrderStatusEnum.PAY_SUCCESS.getType())) { + return true; + } + // 已经支付 + try { + WalletRechargePaySuccess dto = new WalletRechargePaySuccess(); + dto.setPayNo(thirdPayOrder.getPayNo()); + dto.setUserId(thirdPayOrder.getUserId()); + dto.setBizId(thirdPayOrder.getBizId()); + dto.setBizType(thirdPayOrder.getBizType()); + return remoteWalletRechargePackageService.remotePaySuccess(dto).getData(); + } catch (Exception e) { + log.error("处理小程序支付成功回调异常", e); + return false; + } } /** diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppWechatServiceImpl.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppWechatServiceImpl.java index 13b0a5daa..980d66631 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppWechatServiceImpl.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppWechatServiceImpl.java @@ -68,6 +68,7 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService payOrder.setUserCode(dto.getOpenid()); payOrder.setPrice(dto.getAmount()); payOrder.setStatus(ThirdPayOrderStatusEnum.PAY_UNPAID.getType()); + payOrder.setPayNo(dto.getOutTradeNo()); try { Map params = new HashMap<>(); // 公众账号ID @@ -85,7 +86,7 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService // 商户订单号 params.put("out_trade_no", dto.getOutTradeNo()); // 商户回调地址 - params.put("notify_url", wechatConfig.getRefundCallbackUrl()); + params.put("notify_url", wechatConfig.getPayCallbackUrl()); // 订单总金额,单位为分 params.put("total_fee", dto.getAmount()); // 终端IP @@ -97,7 +98,11 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService // 生成签名 params.put("sign", generateSign(params)); ThirdMiniWechantPayConstant.Api api = initApi(ThirdMiniWechantPayConstant.WECHAT_PAY); - String res = api.getHttpRequest().body(XmlUtil.mapToXmlStr(params)).execute().body(); + + String xmlStr = XmlUtil.mapToXmlStr(params); + payOrder.setPayRep(xmlStr); + + String res = api.getHttpRequest().body(xmlStr).execute().body(); log.debug("JSAPI/小程序下单,json,xml|{}", res); if (ObjectUtil.isEmpty(res)) { log.error("JSAPI/小程序下单,res为空"); @@ -297,7 +302,10 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService params.put("sign", generateSign(params)); ThirdMiniWechantPayConstant.Api api = initApi(ThirdMiniWechantPayConstant.REFUND); api.setSslSocketFactory(createSSLSocketFactory()); - String res = api.getHttpRequest().body(XmlUtil.mapToXmlStr(params)).execute().body(); + + String xmlStr = XmlUtil.mapToXmlStr(params); + + String res = api.getHttpRequest().body(xmlStr).execute().body(); log.debug("|{}|申请退款,json,xml|{}", TAG, res); if (ObjectUtil.isEmpty(res)) { log.error("|{}|申请退款,res为空", TAG); @@ -356,6 +364,36 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService } } + /** + * 支付的回调通知 + */ + @Override + public ThirdPayOrderEntity payCallback(String body, Map headers) { + String bodyJson = JSONUtil.toJsonStr(XmlUtil.xmlToMap(body)); + ThirdMiniWechatRefundQueryVo vo = JSONUtil.toBean(bodyJson, ThirdMiniWechatRefundQueryVo.class); + if (ObjectUtil.isEmpty(vo) || !vo.isHttpSucess()) { + return null; + } + boolean paySucess = vo.isPaySucess(); + // 查询订单 + ThirdPayOrderEntity payOrderEntity = thirdPayOrderService.getByPayNo(vo.getOut_trade_no()); + if (ObjectUtil.isEmpty(payOrderEntity)) { + log.error("|{}|payCallback,意外的错误,订单不存在,微信返回json|{}|", TAG, bodyJson); + return null; + } + // 重复的回调 + if (ObjectUtil.notEqual(payOrderEntity.getStatus(), ThirdPayOrderStatusEnum.PAY_UNPAID.getType())) { + log.error("|{}|payCallback,意外的错误,重复的回调,微信返回json|{}|", TAG, bodyJson); + return null; + } + // 更新订单状态 + ThirdPayOrderEntity updateObj = new ThirdPayOrderEntity(); + updateObj.setId(payOrderEntity.getId()); + updateObj.setStatus(paySucess ? ThirdPayOrderStatusEnum.PAY_SUCCESS.getType() : ThirdPayOrderStatusEnum.PAY_FAILED.getType()); + thirdPayOrderService.updateById(updateObj); + return thirdPayOrderService.getById(payOrderEntity.getId()); + } + /** * 退款回调 */ diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml index a1250c208..f7dd38a16 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml @@ -182,8 +182,8 @@ mini-platform: merchant-id: 1106210589 api-v2-key: qr0w9WkAu6GG3uuxPjDT7bcdIVoBr0rw merchant-serial-path: /Users/dengzhangchen/Desktop/backups/pay/third_cert/apiclient_cert.p12 - pay-callback-url: https://rj4jv5rwqs.by.takin.cc/third/third-mini-app-pay/app/pay-callback - refund-callback-url: https://rj4jv5rwqs.by.takin.cc/hard/hard-wechant-pay/app/refund-callback + pay-callback-url: https://dzc-test-1.fy.takin.cc/third/third-mini-app-pay/app/pay-callback + refund-callback-url: https://dzc-test-1.fy.takin.cc/third/third-mini-app-pay/app/refund-callback spbill-create-ip: 59.202.170.152 base-url: https://api.mch.weixin.qq.com ali-pay-config: diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/mapper/ThirdPayOrderMapper.xml b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/mapper/ThirdPayOrderMapper.xml index ca6862101..376a66a5a 100755 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/mapper/ThirdPayOrderMapper.xml +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/mapper/ThirdPayOrderMapper.xml @@ -13,9 +13,11 @@ a.status, a.pay_no, a.pay_time, + a.pay_rep, a.pay_res, a.refund_no, a.refund_time, + a.refund_rep, a.refund_res, a.expire_time, a.create_time, @@ -28,6 +30,9 @@ a.del_flag = '0' + + and a.pay_no LIKE concat('%',#{dto.payNo},'%') + and a.id = #{dto.id} diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargePaySuccess.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargePaySuccess.java new file mode 100644 index 000000000..25518965b --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargePaySuccess.java @@ -0,0 +1,28 @@ +package com.bsd.pjcloud.wallet.api.dto.recharge; + +import lombok.Data; + +@Data +public class WalletRechargePaySuccess { + + /** + * 订单号 + */ + private String payNo; + + /** + * 用户id + */ + private Long userId; + + /** + * 业务类型 + */ + private String bizType; + + /** + * 业务id + */ + private String bizId; + +} diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargePackageService.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargePackageService.java index 1a6ca9eaf..b2db8d400 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargePackageService.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargePackageService.java @@ -2,10 +2,14 @@ package com.bsd.pjcloud.wallet.api.feign; import com.bsd.pjcloud.common.core.constant.ServiceNameConstants; import com.bsd.pjcloud.common.core.util.R; +import com.bsd.pjcloud.common.feign.annotation.NoToken; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePaySuccess; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargePackageEntity; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; @FeignClient(contextId = "remoteWalletRechargePackageService", value = ServiceNameConstants.WALLET_SERVICE) public interface RemoteWalletRechargePackageService { @@ -13,4 +17,8 @@ public interface RemoteWalletRechargePackageService { @GetMapping("/wallet-recharge-package/remote/{id}") R remoteGetById(@PathVariable("id") Long id); + @NoToken + @PostMapping("/wallet-recharge-package/remote/pay-success") + R remotePaySuccess(@RequestBody WalletRechargePaySuccess dto); + } diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java index 94dfe8a03..cb2b5af8d 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java @@ -7,7 +7,9 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.bsd.pjcloud.common.core.util.R; import com.bsd.pjcloud.common.log.annotation.SysLog; +import com.bsd.pjcloud.common.security.annotation.Inner; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePackageDto; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePaySuccess; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargePackageEntity; import com.bsd.pjcloud.wallet.service.WalletRechargePackageService; import org.springframework.security.access.prepost.PreAuthorize; @@ -43,6 +45,13 @@ public class WalletRechargePackageController { public R remoteGetById(@PathVariable("id") Long id) { return R.ok(walletRechargePackageService.getById(id)); } + + @Inner + @Operation(summary = "支付成功", description = "支付成功") + @PostMapping("/remote/pay-success") + public R remotePaySuccess(@RequestBody WalletRechargePaySuccess dto) { + return R.ok(walletRechargePackageService.remotePaySuccess(dto)); + } /* ************************************* end remote end ************************************* */ /* ************************************* start app start ************************************* */ diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargePackageService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargePackageService.java index 533f005c4..8c173d9d1 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargePackageService.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargePackageService.java @@ -3,15 +3,22 @@ package com.bsd.pjcloud.wallet.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePackageDto; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePaySuccess; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargePackageEntity; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargePackageVo; public interface WalletRechargePackageService extends IService { + /** + * 支付成功 + */ + Boolean remotePaySuccess(WalletRechargePaySuccess dto); + Page pageJoin(Page page, WalletRechargePackageDto dto); /** * 校验是否有效 + * * @param packageId * @return */ diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargeService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargeService.java index 5913a3a91..ff599ce08 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargeService.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargeService.java @@ -17,25 +17,16 @@ public interface WalletRechargeService extends IService { /** * app充值 - * - * @param dto - * @return */ WalletRechargeEntity createWalletRecharge(WalletAppRechargeDto dto); /** * 远程调用-退款 - * - * @param dto - * @return */ WalletRechargeVo refund(WalletRechargeRefundDto dto); - /** * 根据退款id查询 - * - * @return */ WalletRechargeEntity getByRefundId(Long refundId); } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletTransactionService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletTransactionService.java index 05a25fa45..66f7f9174 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletTransactionService.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletTransactionService.java @@ -38,32 +38,16 @@ public interface WalletTransactionService extends IService implements WalletRechargePackageService { + static private final String TAG = "充值套餐"; + + private final WalletManageService walletManageService; + private final WalletTransactionService walletTransactionService; + + /** + * 支付成功的回调 + */ + @Override + public Boolean remotePaySuccess(WalletRechargePaySuccess dto) { + // 小程序用户钱包充值 + if (ObjectUtil.equals(dto.getBizType(), ThirdPayOrderBizTypeEnum.MINI_APP_WALLET_RECHARGE.getType())) { + // 查询充值套餐 + WalletRechargePackageEntity rechargePackage = baseMapper.selectById(dto.getBizId()); + if (ObjectUtil.isEmpty(rechargePackage)) { + log.error("{}支付成功的回调,充值套餐不存在,dto:{}", TAG, JSONUtil.toJsonStr(dto)); + return false; + } + // 需要充值的金额 + Integer totalPrice = rechargePackage.getPayPrice() + rechargePackage.getBonusPrice(); + if (totalPrice <= 0) { + log.error("{}支付成功的回调,充值套餐金额<=0,dto:{}", TAG, JSONUtil.toJsonStr(dto)); + return false; + } + // 查询这个用户的充值钱包 + WalletManageEntity topupWallet = walletManageService.getWallet(dto.getUserId(), WalletTypeEnum.TOPUP); + if (ObjectUtil.isEmpty(topupWallet)) { + log.error("{}支付成功的回调,查询这个用户的充值钱包,dto:{}", TAG, JSONUtil.toJsonStr(dto)); + return false; + } + // 进行充值 + WalletTransactionEntity walletTransaction = walletTransactionService.addWalletBalance(topupWallet.getId(), totalPrice, dto.getPayNo(), WalletBizEnum.RECHARGE); + return ObjectUtil.isNotEmpty(walletTransaction); + } + // 不支持的类型 + else { + log.error("{}支付成功的回调,不支持的类型,dto:{}", TAG, JSONUtil.toJsonStr(dto)); + return false; + } + } + @Override public Page pageJoin(Page page, WalletRechargePackageDto dto) { return baseMapper.pageJoin(page, dto); From 075a9cc8765233603b993cd922424e56a601de2e Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Thu, 16 Apr 2026 09:46:20 +0800 Subject: [PATCH 08/17] =?UTF-8?q?feat:=E9=80=80=E6=AC=BE=20fix:=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hard/api/dto/order/HardOrderDto.java | 6 ++ .../pay/wechat/ThirdMiniWechatRefundDto.java | 14 +-- .../entity/pay/ThirdPayOrderEntity.java | 12 +++ .../mini/ThirdMinAppPayCotroller.java | 14 ++- .../service/ThirdMiniAppService.java | 6 ++ .../service/ThirdMiniAppWechatService.java | 4 +- .../impl/miniapp/ThirdMiniAppServiceImpl.java | 96 ++++++++++++++++--- .../ThirdMiniAppWechatServiceImpl.java | 77 +++++++++++---- .../resources/mapper/ThirdPayOrderMapper.xml | 4 +- pjcloud-wallet/pjcloud-wallet-api/pom.xml | 82 +++++++++++++++- .../recharge/WalletRechargeRefundSuccess.java | 28 ++++++ .../wallet/api/entity/WalletManageEntity.java | 8 ++ .../api/entity/WalletTransactionEntity.java | 7 ++ .../RemoteWalletRechargePackageService.java | 4 + pjcloud-wallet/pjcloud-wallet-biz/pom.xml | 6 ++ .../WalletTransactionController.java | 3 - .../WalletRechargePackageController.java | 8 ++ .../wallet/mapper/WalletManageMapper.java | 11 ++- .../mapper/WalletTransactionMapper.java | 24 +---- .../service/WalletRechargePackageService.java | 6 ++ .../service/impl/WalletManageServiceImpl.java | 6 -- .../impl/WalletTransactionServiceImpl.java | 7 +- .../WalletRechargePackageServiceImpl.java | 37 +++++++ .../resources/mapper/WalletManageMapper.xml | 20 +--- .../mapper/WalletTransactionMapper.xml | 45 ++++++++- .../bsd/pjcloud/WalletTransactionTest.java | 29 ++++++ 26 files changed, 467 insertions(+), 97 deletions(-) create mode 100644 pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargeRefundSuccess.java create mode 100644 pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/WalletTransactionTest.java diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/order/HardOrderDto.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/order/HardOrderDto.java index 25e791773..aaa7960bd 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/order/HardOrderDto.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/order/HardOrderDto.java @@ -3,6 +3,7 @@ package com.bsd.pjcloud.hard.api.dto.order; import com.bsd.pjcloud.admin.api.vo.base.BaseIsIncludeTreeInterface; import com.bsd.pjcloud.common.core.constant.enums.DateRangeTypeEnum; import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDate; @@ -84,4 +85,9 @@ public class HardOrderDto extends HardOrderEntity implements BaseIsIncludeTreeIn */ private Boolean productDescIsNotEmpty = false; + /** + * 是否为优惠商品 + */ + private String isDiscountsProduct; + } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/oathmini/pay/wechat/ThirdMiniWechatRefundDto.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/oathmini/pay/wechat/ThirdMiniWechatRefundDto.java index 1b4f25a79..c0212b233 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/oathmini/pay/wechat/ThirdMiniWechatRefundDto.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/oathmini/pay/wechat/ThirdMiniWechatRefundDto.java @@ -1,5 +1,7 @@ package com.bsd.pjcloud.thirdparty.dto.oathmini.pay.wechat; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -14,14 +16,12 @@ import lombok.NoArgsConstructor; @NoArgsConstructor public class ThirdMiniWechatRefundDto { - private Long orderId; - - private String wechantOrderId; - - private Long refundId; - - private Integer orderPrice; + @NotEmpty + private String payNo; + /** + * 为null就全额退款 + */ private Integer refundPrice; } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/pay/ThirdPayOrderEntity.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/pay/ThirdPayOrderEntity.java index 8207b6ae2..e00e0a93c 100755 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/pay/ThirdPayOrderEntity.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/entity/pay/ThirdPayOrderEntity.java @@ -87,6 +87,12 @@ public class ThirdPayOrderEntity extends Model { @Schema(description = "支付参数") private String payRep; + /** + * 支付回调返回 + */ + @Schema(description = "支付回调返回") + private String payCallbackRes; + /** * 支付返回 */ @@ -99,6 +105,12 @@ public class ThirdPayOrderEntity extends Model { @Schema(description = "退款订单号") private String refundNo; + /** + * 退款回调返回 + */ + @Schema(description = "退款回调返回") + private String refundCallbackRes; + /** * 退款时间 */ diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/mini/ThirdMinAppPayCotroller.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/mini/ThirdMinAppPayCotroller.java index 9cb3ad44c..08d8d85a5 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/mini/ThirdMinAppPayCotroller.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/mini/ThirdMinAppPayCotroller.java @@ -5,12 +5,13 @@ import com.bsd.pjcloud.common.security.annotation.Inner; import com.bsd.pjcloud.common.security.service.PjcloudUser; import com.bsd.pjcloud.common.security.util.SecurityUtils; import com.bsd.pjcloud.thirdparty.dto.oathmini.ThirdMiniAppPayDto; +import com.bsd.pjcloud.thirdparty.dto.oathmini.pay.wechat.ThirdMiniWechatRefundDto; import com.bsd.pjcloud.thirdparty.service.ThirdMiniAppService; -import com.bsd.pjcloud.thirdparty.vo.oathmini.ThirdMinAppOAth2LoginVo; import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.ThirdMiniAppPayVo; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -28,6 +29,15 @@ public class ThirdMinAppPayCotroller { private final ThirdMiniAppService thirdMiniAppService; + + @Operation(summary = "小程序支付退款") + @PostMapping("/refund") + public R miniRefund(@Valid @RequestBody ThirdMiniWechatRefundDto dto) { + return R.ok(thirdMiniAppService.miniRefund(dto)); + } + + /* ************************************* start app start ************************************* */ + @Operation(summary = "小程序支付") @PostMapping("/app/pay") public R miniPay(@Validated @RequestBody ThirdMiniAppPayDto dto) { @@ -51,4 +61,6 @@ public class ThirdMinAppPayCotroller { return R.ok(thirdMiniAppService.miniRefundCallback(body, headers)); } + /* ************************************* end app end ************************************* */ + } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppService.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppService.java index c2887ecc9..9a78cde66 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppService.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppService.java @@ -3,6 +3,7 @@ package com.bsd.pjcloud.thirdparty.service; import com.bsd.pjcloud.thirdparty.dto.oathmini.ThirdMiniAppGetUniqueDto; import com.bsd.pjcloud.thirdparty.dto.oathmini.ThirdMiniAppOAth2LoginDto; import com.bsd.pjcloud.thirdparty.dto.oathmini.ThirdMiniAppPayDto; +import com.bsd.pjcloud.thirdparty.dto.oathmini.pay.wechat.ThirdMiniWechatRefundDto; import com.bsd.pjcloud.thirdparty.vo.oathmini.ThirdMinAppOAth2LoginVo; import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.ThirdMiniAppPayVo; @@ -25,6 +26,11 @@ public interface ThirdMiniAppService { */ ThirdMiniAppPayVo miniPay(Long userId, ThirdMiniAppPayDto dto); + /** + * 小程序退款 + */ + ThirdMiniAppPayVo miniRefund(ThirdMiniWechatRefundDto dto); + /** * 小程序支付回调 */ diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppWechatService.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppWechatService.java index 552543ced..cd34623ab 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppWechatService.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/ThirdMiniAppWechatService.java @@ -40,7 +40,7 @@ public interface ThirdMiniAppWechatService { /** * 申请退款 */ - ThirdMiniWechatRefundVo refund(ThirdMiniWechatRefundDto dto); + ThirdMiniWechatRefundVo refund(ThirdPayOrderEntity thirdPayOrder, ThirdMiniWechatRefundDto dto); /** * 查询退款 @@ -55,6 +55,6 @@ public interface ThirdMiniAppWechatService { /** * 退款回调 */ - String refundCallback(HttpEntity httpEntity, @RequestHeader Map headers); + ThirdPayOrderEntity refundCallback(String body, @RequestHeader Map headers); } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java index 9f30b1b91..6df041c07 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java @@ -21,17 +21,14 @@ import com.bsd.pjcloud.thirdparty.dto.oathmini.ThirdMiniAppGetUniqueDto; import com.bsd.pjcloud.thirdparty.dto.oathmini.ThirdMiniAppOAth2LoginDto; import com.bsd.pjcloud.thirdparty.dto.oathmini.ThirdMiniAppPayDto; import com.bsd.pjcloud.thirdparty.dto.oathmini.pay.wechat.ThirdMiniJsapiPayDto; +import com.bsd.pjcloud.thirdparty.dto.oathmini.pay.wechat.ThirdMiniWechatRefundDto; import com.bsd.pjcloud.thirdparty.entity.pay.ThirdPayOrderEntity; -import com.bsd.pjcloud.thirdparty.service.ThirdMiniAppAliPayService; -import com.bsd.pjcloud.thirdparty.service.ThirdMiniAppService; -import com.bsd.pjcloud.thirdparty.service.ThirdMiniAppWechatService; -import com.bsd.pjcloud.thirdparty.service.ThirdPayLogService; +import com.bsd.pjcloud.thirdparty.service.*; import com.bsd.pjcloud.thirdparty.vo.oathmini.ThirdMinAppOAth2LoginVo; import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.ThirdMiniAppPayVo; -import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.wechat.ThirdMiniJsapiPayVo; -import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.wechat.ThirdMiniWechatQueryVo; -import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.wechat.ThirdMiniWechatRefundQueryVo; +import com.bsd.pjcloud.thirdparty.vo.oathmini.pay.wechat.*; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePaySuccess; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundSuccess; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargePackageEntity; import com.bsd.pjcloud.wallet.api.feign.RemoteWalletRechargePackageService; import lombok.RequiredArgsConstructor; @@ -53,9 +50,12 @@ import java.util.Map; @RequiredArgsConstructor public class ThirdMiniAppServiceImpl implements ThirdMiniAppService { + static private final String TAG = "小程序服务类"; + private final ThirdMiniAppWechatService thirdMiniAppWechatService; private final ThirdMiniAppAliPayService thirdMiniAppAliPayService; private final ThirdPayLogService thirdPayLogService; + private final ThirdPayOrderService thirdPayOrderService; private final RemoteUserService remoteUserService; private final RemoteTokenService remoteTokenService; @@ -193,6 +193,31 @@ public class ThirdMiniAppServiceImpl implements ThirdMiniAppService { return result; } + /** + * 小程序退款 + */ + @Override + public ThirdMiniAppPayVo miniRefund(ThirdMiniWechatRefundDto dto) { + // 查询详情 + ThirdPayOrderEntity thirdPayOrder = thirdPayOrderService.getByPayNo(dto.getPayNo()); + if (ObjectUtil.isEmpty(thirdPayOrder)) { + log.error("|{}|小程序退款错误,订单不存在dto:|{}|", TAG, JSONUtil.toJsonStr(dto)); + throw new RuntimeException("订单不存在"); + } + // 微信小程序 + if (ObjectUtil.equals(thirdPayOrder.getPayPlatformType(), MiniPlatformTypeEnum.WECHAT.getType())) { + thirdMiniAppWechatService.refund(thirdPayOrder, dto); + } + // 支付宝 + else if (ObjectUtil.equals(thirdPayOrder.getPayPlatformType(), MiniPlatformTypeEnum.ALI_PAY.getType())) { + + } + // 不支持的支付类型 + else { + throw new RuntimeException("不支持的支付类型"); + } + return null; + } /** * 小程序支付回调 @@ -220,6 +245,32 @@ public class ThirdMiniAppServiceImpl implements ThirdMiniAppService { } } + /** + * 小程序退款回调 + */ + @Override + public String miniRefundCallback(String body, Map headers) { + MiniPlatformTypeEnum platformType = checkRefundMiniPlatformType(body); + // 微信小程序 + if (ObjectUtil.equals(platformType, MiniPlatformTypeEnum.WECHAT)) { + ThirdPayOrderEntity thirdPayOrder = thirdMiniAppWechatService.refundCallback(body, headers); + if (ObjectUtil.isEmpty(thirdPayOrder)) { + return ThirdMiniWechantRefunCallbackVo.wechantError(); + } + // 根据订单bizType来处理 + boolean isSuccess = disposeRefundSuccessAfter(thirdPayOrder); + return isSuccess ? ThirdMiniWechatQueryVo.wechantSuccess() : ThirdMiniWechatQueryVo.wechantError(); + } + // 支付宝 + else if (ObjectUtil.equals(platformType, MiniPlatformTypeEnum.ALI_PAY)) { + return null; + } + // 不支持的支付类型 + else { + return null; + } + } + private MiniPlatformTypeEnum checkMiniPlatformType(String body) { ThirdMiniWechatRefundQueryVo vo = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(body)), ThirdMiniWechatRefundQueryVo.class); // 查询订单 @@ -229,6 +280,15 @@ public class ThirdMiniAppServiceImpl implements ThirdMiniAppService { return null; } + private MiniPlatformTypeEnum checkRefundMiniPlatformType(String body) { + ThirdMiniWechantRefunCallbackSoureVo vo = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(body)), ThirdMiniWechantRefunCallbackSoureVo.class); + // 查询订单 + if (ObjectUtil.isNotEmpty(vo) && ObjectUtil.isNotEmpty(vo.getAppid()) && ObjectUtil.isNotEmpty(vo.getMch_id()) && ObjectUtil.isNotEmpty(vo.getNonce_str()) && ObjectUtil.isNotEmpty(vo.getReq_info())) { + return MiniPlatformTypeEnum.WECHAT; + } + return null; + } + public boolean disposePaySuccessAfter(ThirdPayOrderEntity thirdPayOrder) { if (ObjectUtil.notEqual(thirdPayOrder.getStatus(), ThirdPayOrderStatusEnum.PAY_SUCCESS.getType())) { return true; @@ -247,12 +307,22 @@ public class ThirdMiniAppServiceImpl implements ThirdMiniAppService { } } - /** - * 小程序退款回调 - */ - @Override - public String miniRefundCallback(String body, Map headers) { - return ""; + private boolean disposeRefundSuccessAfter(ThirdPayOrderEntity thirdPayOrder) { + if (ObjectUtil.notEqual(thirdPayOrder.getStatus(), ThirdPayOrderStatusEnum.REFUND_SUCCESS.getType())) { + return true; + } + // 已退款 + try { + WalletRechargeRefundSuccess dto = new WalletRechargeRefundSuccess(); + dto.setRefundNo(thirdPayOrder.getRefundNo()); + dto.setUserId(thirdPayOrder.getUserId()); + dto.setBizId(thirdPayOrder.getBizId()); + dto.setBizType(thirdPayOrder.getBizType()); + return remoteWalletRechargePackageService.remoteRefundSuccess(dto).getData(); + } catch (Exception e) { + log.error("处理小程序退款成功回调异常", e); + return false; + } } } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppWechatServiceImpl.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppWechatServiceImpl.java index 980d66631..167d13b98 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppWechatServiceImpl.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppWechatServiceImpl.java @@ -100,7 +100,7 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService ThirdMiniWechantPayConstant.Api api = initApi(ThirdMiniWechantPayConstant.WECHAT_PAY); String xmlStr = XmlUtil.mapToXmlStr(params); - payOrder.setPayRep(xmlStr); + payOrder.setPayRep(JSONUtil.toJsonStr(params)); String res = api.getHttpRequest().body(xmlStr).execute().body(); log.debug("JSAPI/小程序下单,json,xml|{}", res); @@ -108,13 +108,14 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService log.error("JSAPI/小程序下单,res为空"); return null; } - ThirdMiniJsapiPayVo vo = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(res)), ThirdMiniJsapiPayVo.class); + String jsonVo = JSONUtil.toJsonStr(XmlUtil.xmlToMap(res)); + ThirdMiniJsapiPayVo vo = JSONUtil.toBean(jsonVo, ThirdMiniJsapiPayVo.class); log.debug("|{}|JSAPI/小程序下单,json,res|{}", TAG, JSONUtil.toJsonStr(vo)); if (!vo.isHttpSucess()) { return null; } payOrder.setPayTime(LocalDateTime.now()); - payOrder.setPayRes(res); + payOrder.setPayRes(jsonVo); // 生成小程序 paySign String nonceStr = RandomUtil.randomString(32); long timeStamp = System.currentTimeMillis() / 1000; @@ -268,12 +269,30 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService } } + private String getTransactionIdByThirdPayOrder(ThirdPayOrderEntity thirdPayOrder) { + if (ObjectUtil.isEmpty(thirdPayOrder) || ObjectUtil.isEmpty(thirdPayOrder.getPayRes())) { + return null; + } + String payRes = thirdPayOrder.getPayCallbackRes(); + ThirdMiniWechantRefunCallbackVo thirdMiniJsapiPay = JSONUtil.toBean(payRes, ThirdMiniWechantRefunCallbackVo.class); + return thirdMiniJsapiPay.getTransaction_id(); + } + /** * 申请退款 */ @Override - public ThirdMiniWechatRefundVo refund(ThirdMiniWechatRefundDto dto) { + public ThirdMiniWechatRefundVo refund(ThirdPayOrderEntity thirdPayOrder, ThirdMiniWechatRefundDto dto) { MiniAppConfig.WechatConfig wechatConfig = miniAppConfig.getWechatConfig(); + + ThirdPayOrderEntity updateObj = new ThirdPayOrderEntity(); + updateObj.setId(thirdPayOrder.getId()); + + Integer refundFee = dto.getRefundPrice(); + if (ObjectUtil.isEmpty(refundFee)) { + refundFee = thirdPayOrder.getPrice(); + } + String refundNo = "refund_" + thirdPayOrder.getPayNo(); try { Map params = new HashMap<>(); // 公众账号ID @@ -287,15 +306,15 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService // 签名类型 params.put("sign_type", "MD5"); // 微信支付订单号 - params.put("transaction_id", dto.getWechantOrderId()); + params.put("transaction_id", getTransactionIdByThirdPayOrder(thirdPayOrder)); // 商户订单号 - params.put("out_trade_no", dto.getOrderId()); + params.put("out_trade_no", thirdPayOrder.getPayNo()); // 商户退款单号 - params.put("out_refund_no", dto.getRefundId()); + params.put("out_refund_no", refundNo); // 订单金额 - params.put("total_fee", dto.getOrderPrice()); + params.put("total_fee", thirdPayOrder.getPrice()); // 退款金额 - params.put("refund_fee", dto.getRefundPrice()); + params.put("refund_fee", refundFee); // 退款结果通知url params.put("notify_url", wechatConfig.getRefundCallbackUrl()); // 生成签名 @@ -303,6 +322,7 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService ThirdMiniWechantPayConstant.Api api = initApi(ThirdMiniWechantPayConstant.REFUND); api.setSslSocketFactory(createSSLSocketFactory()); + updateObj.setRefundRep(JSONUtil.toJsonStr(params)); String xmlStr = XmlUtil.mapToXmlStr(params); String res = api.getHttpRequest().body(xmlStr).execute().body(); @@ -311,15 +331,22 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService log.error("|{}|申请退款,res为空", TAG); return null; } + String jsonVo = JSONUtil.toJsonStr(XmlUtil.xmlToMap(res)); + updateObj.setRefundRes(jsonVo); ThirdMiniWechatRefundVo vo = JSONUtil.toBean(JSONUtil.toJsonStr(XmlUtil.xmlToMap(res)), ThirdMiniWechatRefundVo.class); log.debug("|{}|申请退款,json,res|{}", TAG, JSONUtil.toJsonStr(vo)); if (!vo.isHttpSucess()) { return null; } + updateObj.setRefundNo(refundNo); + updateObj.setRefundTime(LocalDateTime.now()); + updateObj.setStatus(ThirdPayOrderStatusEnum.REFUNDING.getType()); return vo; } catch (Exception e) { log.error("|{}|申请退款,异常", TAG, e); return null; + } finally { + thirdPayOrderService.updateById(updateObj); } } @@ -389,6 +416,7 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService // 更新订单状态 ThirdPayOrderEntity updateObj = new ThirdPayOrderEntity(); updateObj.setId(payOrderEntity.getId()); + updateObj.setPayCallbackRes(bodyJson); updateObj.setStatus(paySucess ? ThirdPayOrderStatusEnum.PAY_SUCCESS.getType() : ThirdPayOrderStatusEnum.PAY_FAILED.getType()); thirdPayOrderService.updateById(updateObj); return thirdPayOrderService.getById(payOrderEntity.getId()); @@ -398,15 +426,30 @@ public class ThirdMiniAppWechatServiceImpl implements ThirdMiniAppWechatService * 退款回调 */ @Override - public String refundCallback(HttpEntity httpEntity, Map headers) { - String body = httpEntity.getBody(); - ThirdMiniWechantRefunCallbackVo decrypt = decrypt(body); - if (ObjectUtil.isEmpty(decrypt)) { - // 告诉微信错误 - return ThirdMiniWechantRefunCallbackVo.wechantError(); + public ThirdPayOrderEntity refundCallback(String body, Map headers) { + ThirdMiniWechantRefunCallbackVo vo = decrypt(body); + if (ObjectUtil.isEmpty(vo)) { + return null; } - boolean isSuccess = true; - return isSuccess ? ThirdMiniWechantRefunCallbackVo.wechantSuccess() : ThirdMiniWechantRefunCallbackVo.wechantError(); + // 查询订单 + ThirdPayOrderEntity payOrderEntity = thirdPayOrderService.getByPayNo(vo.getOut_trade_no()); + if (ObjectUtil.isEmpty(payOrderEntity)) { + log.error("|{}|refundCallback,意外的错误,订单不存在,微信返回json|{}|", TAG, JSONUtil.toJsonStr(vo)); + return null; + } + // 重复的回调 + if (ObjectUtil.notEqual(payOrderEntity.getStatus(), ThirdPayOrderStatusEnum.REFUNDING.getType())) { + log.error("|{}|refundCallback,意外的错误,重复的回调,微信返回json|{}|", TAG, JSONUtil.toJsonStr(vo)); + return null; + } + // 更新订单状态 + boolean refundSuccess = vo.isAllSuccess(); + ThirdPayOrderEntity updateObj = new ThirdPayOrderEntity(); + updateObj.setId(payOrderEntity.getId()); + updateObj.setRefundCallbackRes(JSONUtil.toJsonStr(vo)); + updateObj.setStatus(refundSuccess ? ThirdPayOrderStatusEnum.REFUND_SUCCESS.getType() : ThirdPayOrderStatusEnum.REFUND_FAILED.getType()); + thirdPayOrderService.updateById(updateObj); + return thirdPayOrderService.getById(payOrderEntity.getId()); } /** diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/mapper/ThirdPayOrderMapper.xml b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/mapper/ThirdPayOrderMapper.xml index 376a66a5a..4200b3807 100755 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/mapper/ThirdPayOrderMapper.xml +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/mapper/ThirdPayOrderMapper.xml @@ -15,10 +15,12 @@ a.pay_time, a.pay_rep, a.pay_res, + a.pay_callback_res, a.refund_no, a.refund_time, a.refund_rep, a.refund_res, + a.refund_callback_res, a.expire_time, a.create_time, a.update_time, @@ -30,7 +32,7 @@ a.del_flag = '0' - + and a.pay_no LIKE concat('%',#{dto.payNo},'%') diff --git a/pjcloud-wallet/pjcloud-wallet-api/pom.xml b/pjcloud-wallet/pjcloud-wallet-api/pom.xml index 574f71758..a561ee3b1 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/pom.xml +++ b/pjcloud-wallet/pjcloud-wallet-api/pom.xml @@ -12,7 +12,11 @@ pjcloud-wallet-api - + + 2.2.20 + + + com.github.yulichang @@ -52,5 +56,81 @@ com.bsd pjcloud-upms-api + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + src/main/java + target/generated-sources/annotations + + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + + default-compile + none + + + default-testCompile + none + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + + + diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargeRefundSuccess.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargeRefundSuccess.java new file mode 100644 index 000000000..a89f6330e --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargeRefundSuccess.java @@ -0,0 +1,28 @@ +package com.bsd.pjcloud.wallet.api.dto.recharge; + +import lombok.Data; + +@Data +public class WalletRechargeRefundSuccess { + + /** + * 订单号 + */ + private String refundNo; + + /** + * 用户id + */ + private Long userId; + + /** + * 业务类型 + */ + private String bizType; + + /** + * 业务id + */ + private String bizId; + +} diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/WalletManageEntity.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/WalletManageEntity.java index a05fe259d..1250b2550 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/WalletManageEntity.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/WalletManageEntity.java @@ -95,11 +95,19 @@ public class WalletManageEntity extends Model { /** * 饭卡绑定状态 + * * @see WalleCardStatusEnum */ @Schema(description = "饭卡绑定状态") private String status; + /** + * 版本号 + */ + @Version + @Schema(description = "版本号") + private Integer version = 0; + /** * 创建人 */ diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/WalletTransactionEntity.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/WalletTransactionEntity.java index 55d771e39..a18bcfc38 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/WalletTransactionEntity.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/WalletTransactionEntity.java @@ -78,6 +78,13 @@ public class WalletTransactionEntity extends Model { @Schema(description = "余额, 单位分") private Integer balance; + /** + * 乐观锁 + */ + @Version + @Schema(description = "乐观锁") + private Integer version = 0; + /** * 创建人 */ diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargePackageService.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargePackageService.java index b2db8d400..7507bcd5e 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargePackageService.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargePackageService.java @@ -4,6 +4,7 @@ import com.bsd.pjcloud.common.core.constant.ServiceNameConstants; import com.bsd.pjcloud.common.core.util.R; import com.bsd.pjcloud.common.feign.annotation.NoToken; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePaySuccess; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundSuccess; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargePackageEntity; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @@ -21,4 +22,7 @@ public interface RemoteWalletRechargePackageService { @PostMapping("/wallet-recharge-package/remote/pay-success") R remotePaySuccess(@RequestBody WalletRechargePaySuccess dto); + @NoToken + @PostMapping("/wallet-recharge-package/remote/refund-success") + R remoteRefundSuccess(@RequestBody WalletRechargeRefundSuccess dto); } diff --git a/pjcloud-wallet/pjcloud-wallet-biz/pom.xml b/pjcloud-wallet/pjcloud-wallet-biz/pom.xml index 7458306d7..c173c8348 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/pom.xml +++ b/pjcloud-wallet/pjcloud-wallet-biz/pom.xml @@ -13,6 +13,12 @@ pjcloud-wallet-biz + + + com.baomidou + lock4j-redis-template-spring-boot-starter + 2.2.7 + com.bsd diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletTransactionController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletTransactionController.java index f9e362697..a59c229ae 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletTransactionController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletTransactionController.java @@ -37,9 +37,6 @@ import java.util.concurrent.TimeUnit; /** * 会员钱包流水表 - * - * @author pjcloud - * @date 2024-12-30 09:17:49 */ @RestController @RequiredArgsConstructor diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java index cb2b5af8d..44aaf55e7 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java @@ -10,6 +10,7 @@ import com.bsd.pjcloud.common.log.annotation.SysLog; import com.bsd.pjcloud.common.security.annotation.Inner; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePackageDto; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePaySuccess; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundSuccess; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargePackageEntity; import com.bsd.pjcloud.wallet.service.WalletRechargePackageService; import org.springframework.security.access.prepost.PreAuthorize; @@ -52,6 +53,13 @@ public class WalletRechargePackageController { public R remotePaySuccess(@RequestBody WalletRechargePaySuccess dto) { return R.ok(walletRechargePackageService.remotePaySuccess(dto)); } + + @Inner + @Operation(summary = "退款成功", description = "退款成功") + @PostMapping("/remote/refund-success") + public R remoteRefundSuccess(@RequestBody WalletRechargeRefundSuccess dto) { + return R.ok(walletRechargePackageService.remoteRefundSuccess(dto)); + } /* ************************************* end remote end ************************************* */ /* ************************************* start app start ************************************* */ diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletManageMapper.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletManageMapper.java index 84ddbdf51..a3134caad 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletManageMapper.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletManageMapper.java @@ -64,7 +64,7 @@ public interface WalletManageMapper extends PjcloudBaseMapper lambdaUpdateWrapper = new LambdaUpdateWrapper() - .setSql(" balance = balance - " + price + ", total_expense = total_expense + " + price) + .setSql(" balance = balance - " + price + ", total_expense = total_expense + " + price + ", version = version + 1") .eq(WalletManageEntity::getId, id); if (ObjectUtil.isEmpty(force) || !force) { lambdaUpdateWrapper.ge(WalletManageEntity::getBalance, price); @@ -80,7 +80,7 @@ public interface WalletManageMapper extends PjcloudBaseMapper lambdaUpdateWrapper = new LambdaUpdateWrapper() - .setSql(" balance = balance + " + price + ", total_expense = total_expense - " + price) + .setSql(" balance = balance + " + price + ", total_expense = total_expense - " + price + ", version = version + 1") .eq(WalletManageEntity::getId, id); return update(null, lambdaUpdateWrapper); } @@ -91,10 +91,11 @@ public interface WalletManageMapper extends PjcloudBaseMapper lambdaUpdateWrapper = new LambdaUpdateWrapper() - .setSql(" balance = balance + " + price + ", total_recharge = total_recharge + " + price) - .eq(WalletManageEntity::getId, id); + .setSql(" balance = balance + " + price + ", total_recharge = total_recharge + " + price + ", version = version + 1") + .eq(WalletManageEntity::getId, id) + .eq(WalletManageEntity::getVersion, version); return update(null, lambdaUpdateWrapper); } diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletTransactionMapper.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletTransactionMapper.java index 69076ad4c..01bd96812 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletTransactionMapper.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletTransactionMapper.java @@ -4,21 +4,16 @@ import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.bsd.pjcloud.common.core.util.BeanUtils; import com.bsd.pjcloud.common.data.datascope.DataScope; import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper; import com.bsd.pjcloud.wallet.api.dto.WalletTransactionDto; import com.bsd.pjcloud.wallet.api.dto.WalletTransactionSumAndCountDto; -import com.bsd.pjcloud.wallet.api.entity.WalletManageEntity; import com.bsd.pjcloud.wallet.api.entity.WalletTransactionEntity; -import com.bsd.pjcloud.wallet.api.entity.WalletTypeEntity; import com.bsd.pjcloud.wallet.api.vo.WalletExportCzTotalPerson; import com.bsd.pjcloud.wallet.api.vo.WalletTransactionSumAndCountVo; import com.bsd.pjcloud.wallet.api.vo.WalletTypeCountVo; -import com.bsd.pjcloud.wallet.api.vo.WalletTypeTotalVo; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeApplySelectCompareVo; import com.bsd.pjcloud.wallet.api.vo.transaction.WalletTransactionVo; -import com.github.yulichang.wrapper.MPJLambdaWrapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -65,25 +60,16 @@ public interface WalletTransactionMapper extends PjcloudBaseMapper scopePageList(Page page, WalletTransactionDto dto, DataScope dataScope) { - Page list = selectPageByScope(page, commonWrapperQuery(dto), dataScope); - list.setRecords(BeanUtils.toBean(list.getRecords(), WalletTransactionVo.class)); - return list; - } + Page scopePageList(Page page, @Param("dto") WalletTransactionDto dto, DataScope dataScope); + + List scopeList(@Param("dto") WalletTransactionDto dto, DataScope dataScope); + + Long count(@Param("dto") WalletTransactionDto dto, DataScope dataScope); WalletTypeCountVo walletTypetotal(@Param("dto") WalletTransactionDto dto, @Param("dataScope") DataScope dataScope); List walletTypetotalByDept(@Param("dto") WalletTransactionDto dto, @Param("dataScope") DataScope dataScope); - default List scopeList(WalletTransactionDto dto, DataScope dataScope) { - List list = selectListByScope(commonWrapperQuery(dto), dataScope); - return BeanUtils.toBean(list, WalletTransactionVo.class); - } - - default Long count(WalletTransactionDto dto, DataScope dataScope) { - return selectCountByScope(commonWrapperQuery(dto), dataScope); - } - Page scopeJzPageList(Page page, @Param("dto") WalletTransactionDto dto, DataScope dataScope); Integer getTransactionPriceCount(@Param("month") String importTimeStr, @Param("walletId") Long walletId, diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargePackageService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargePackageService.java index 8c173d9d1..4df1e28ee 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargePackageService.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRechargePackageService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePackageDto; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargePaySuccess; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundSuccess; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargePackageEntity; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargePackageVo; @@ -14,6 +15,11 @@ public interface WalletRechargePackageService extends IService pageJoin(Page page, WalletRechargePackageDto dto); /** diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletManageServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletManageServiceImpl.java index 4beac8317..f09f478cf 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletManageServiceImpl.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletManageServiceImpl.java @@ -29,7 +29,6 @@ import com.bsd.pjcloud.common.core.util.CollectionUtils; import com.bsd.pjcloud.common.core.util.R; import com.bsd.pjcloud.common.data.datascope.DataScope; import com.bsd.pjcloud.common.data.resolver.ParamResolver; -import com.bsd.pjcloud.common.data.tenant.TenantContextHolder; import com.bsd.pjcloud.wallet.api.constant.WalletTypeEnum; import com.bsd.pjcloud.wallet.api.dto.WalletManageBalanceDto; import com.bsd.pjcloud.wallet.api.dto.WalletManageDto; @@ -59,14 +58,9 @@ import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CopyOnWriteArrayList; /** * 钱包管理 - * - * @author dzc - * @date 2024-12-30 09:06:35 */ @Validated @Slf4j diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletTransactionServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletTransactionServiceImpl.java index 707d5c220..31570995d 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletTransactionServiceImpl.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletTransactionServiceImpl.java @@ -10,6 +10,8 @@ import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.fill.FillConfig; import com.alibaba.fastjson.JSON; +import com.baomidou.lock.annotation.Lock4j; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.bsd.pjcloud.admin.api.entity.SysDept; @@ -127,6 +129,7 @@ public class WalletTransactionServiceImpl extends ServiceImpl pageJoin(Page page, WalletRechargePackageDto dto) { return baseMapper.pageJoin(page, dto); diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletManageMapper.xml b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletManageMapper.xml index 83c892c8a..86811bc37 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletManageMapper.xml +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletManageMapper.xml @@ -2,25 +2,6 @@ - - - - - - - - - - - - - - - - - - - select a.id, @@ -35,6 +16,7 @@ a.is_freeze, a.active_bind_time, a.status, + a.version, a.create_by, a.create_time, a.update_by, diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletTransactionMapper.xml b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletTransactionMapper.xml index 1778351a6..340200903 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletTransactionMapper.xml +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletTransactionMapper.xml @@ -22,12 +22,13 @@ a.title, a.price, a.balance, + a.version, a.create_by, a.create_time, a.update_by, a.update_time, a.del_flag, - a.tenant_id, + a.tenant_id @@ -102,7 +103,7 @@ + + + + + + + \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/WalletTransactionTest.java b/pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/WalletTransactionTest.java new file mode 100644 index 000000000..42e70bf80 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/WalletTransactionTest.java @@ -0,0 +1,29 @@ +package com.bsd.pjcloud; + +import com.bsd.pjcloud.wallet.WalletApp; +import com.bsd.pjcloud.wallet.api.constant.WalletBizEnum; +import com.bsd.pjcloud.wallet.service.WalletTransactionService; +import jakarta.annotation.Resource; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +@SpringBootTest(classes = WalletApp.class) +public class WalletTransactionTest { + + @Resource + private WalletTransactionService walletTransactionService; + + @Test + public void eruptAdd() { + // 4.24 + Long walletId = 1877309001545244673L; + int price = 1; + String bizId = "-1"; + + for (int i = 0; i < 5; i++) { + walletTransactionService.addWalletBalance(walletId, price, bizId, WalletBizEnum.RECHARGE); + } + } + +} From c36a04375168d7027d7dd69609ca8d4d13f2acf4 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Thu, 16 Apr 2026 20:20:49 +0800 Subject: [PATCH 09/17] 1 --- .../src/main/resources/application.yml | 28 +++---- .../controller/SysUserFaceController.java | 13 +++- .../admin/mapper/SysUserFaceMapper.java | 3 + .../admin/service/SysUserFaceService.java | 2 + .../service/impl/SysUserFaceServiceImpl.java | 12 +++ .../resources/mapper/SysUserFaceMapper.xml | 75 +++++++++++++++---- .../wallet/api/dto/WalletManageDto.java | 6 +- .../controller/WalletManageController.java | 3 - .../wallet/mapper/WalletManageMapper.java | 5 +- 9 files changed, 110 insertions(+), 37 deletions(-) diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml index f7dd38a16..35eae8cdb 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/resources/application.yml @@ -174,17 +174,17 @@ hikvision: register-appointment: /api/visitor/v1/order/register # 新增登记接口 visitor-checkout: /api/visitor/v1/visitor/out # 新增签离接口 -mini-platform: - mini-app: - wechat-config: - app-id: wx11771c7bf2913cb2 - app-secret: a6b0d036b229117595687a7c1705d332 - merchant-id: 1106210589 - api-v2-key: qr0w9WkAu6GG3uuxPjDT7bcdIVoBr0rw - merchant-serial-path: /Users/dengzhangchen/Desktop/backups/pay/third_cert/apiclient_cert.p12 - pay-callback-url: https://dzc-test-1.fy.takin.cc/third/third-mini-app-pay/app/pay-callback - refund-callback-url: https://dzc-test-1.fy.takin.cc/third/third-mini-app-pay/app/refund-callback - spbill-create-ip: 59.202.170.152 - base-url: https://api.mch.weixin.qq.com - ali-pay-config: - app-id: +#mini-platform: +# mini-app: +# wechat-config: +# app-id: wx11771c7bf2913cb2 +# app-secret: a6b0d036b229117595687a7c1705d332 +# merchant-id: 1106210589 +# api-v2-key: qr0w9WkAu6GG3uuxPjDT7bcdIVoBr0rw +# merchant-serial-path: /Users/dengzhangchen/Desktop/backups/pay/third_cert/apiclient_cert.p12 +# pay-callback-url: https://dzc-test-1.fy.takin.cc/third/third-mini-app-pay/app/pay-callback +# refund-callback-url: https://dzc-test-1.fy.takin.cc/third/third-mini-app-pay/app/refund-callback +# spbill-create-ip: 59.202.170.152 +# base-url: https://api.mch.weixin.qq.com +# ali-pay-config: +# app-id: diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserFaceController.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserFaceController.java index 0bad98b75..1ec032d71 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserFaceController.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/SysUserFaceController.java @@ -104,14 +104,23 @@ public class SysUserFaceController { /* ************************************* start android start ************************************* */ @Operation(summary = "android查询人脸数据库", description = "android查询人脸数据库") @GetMapping("/ad/find-face") - public R adFinFace(@ParameterObject Page page, @RequestParam(required = false) Long userId, - @RequestParam(required = false) Long merchantDeptId) { + public R adFinFace(@ParameterObject Page page, @RequestParam(required = false) Long userId, @RequestParam(required = false) Long merchantDeptId) { SysUserFaceDto dto = new SysUserFaceDto(); dto.setUserId(userId); dto.setMerchantDeptIdOrGlobal(merchantDeptId); dto.setProcessStatus(TaskCheckStatusEnum.RESULT.getCode()); return R.ok(sysUserFaceService.pageJoin(page, dto).getRecords()); } + + @Operation(summary = "android查询人脸数据库", description = "android查询人脸数据库") + @GetMapping("/ad/v2/find-face") + public R adV2FinFace(@ParameterObject Page page, @RequestParam(required = false) Long userId, @RequestParam(required = false) Long merchantDeptId) { + SysUserFaceDto dto = new SysUserFaceDto(); + dto.setUserId(userId); + dto.setMerchantDeptIdOrGlobal(merchantDeptId); + dto.setProcessStatus(TaskCheckStatusEnum.RESULT.getCode()); + return R.ok(sysUserFaceService.allPageJoin(page, dto).getRecords()); + } /* ************************************* start android start ************************************* */ @Operation(summary = "设置为全局人脸", description = "设置为全局人脸") diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/mapper/SysUserFaceMapper.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/mapper/SysUserFaceMapper.java index a5a996461..586092a7f 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/mapper/SysUserFaceMapper.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/mapper/SysUserFaceMapper.java @@ -69,4 +69,7 @@ public interface SysUserFaceMapper extends PjcloudBaseMapper } return selectJoinPage(page, SysUserFaceVo.class, wrapper); } + + Page allPageJoin(Page page, @Param("pa") SysUserFaceDto pa); + } \ No newline at end of file diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysUserFaceService.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysUserFaceService.java index 1ef233b84..2f23be4c7 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysUserFaceService.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysUserFaceService.java @@ -23,6 +23,8 @@ public interface SysUserFaceService extends IService { Page scopePageList(Page page, SysUserFaceDto dto, DataScope dataScope); + Page allPageJoin(Page page, SysUserFaceDto dto); + Page pageJoin(Page page, SysUserFaceDto dto); SysUserFaceVo join(Long id); diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserFaceServiceImpl.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserFaceServiceImpl.java index 28129b22b..c98b8f52d 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserFaceServiceImpl.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/impl/SysUserFaceServiceImpl.java @@ -176,6 +176,18 @@ public class SysUserFaceServiceImpl extends ServiceImpl allPageJoin(Page page, SysUserFaceDto dto) { + if (ObjectUtil.isNotEmpty(dto.getMerchantDeptIdOrGlobal())) { + List deptList = sysDeptService.listDescendant(dto.getMerchantDeptIdOrGlobal()); + if (ObjectUtil.isNotEmpty(deptList)) { + List deptIds = deptList.stream().map(SysDept::getDeptId).toList(); + dto.setDeptIds(deptIds); + } + } + return baseMapper.allPageJoin(page, dto); + } + @Override public Page pageJoin(Page page, SysUserFaceDto dto) { if (ObjectUtil.isNotEmpty(dto.getMerchantDeptIdOrGlobal())) { diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/SysUserFaceMapper.xml b/pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/SysUserFaceMapper.xml index 7057675ed..6f13c9201 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/SysUserFaceMapper.xml +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/resources/mapper/SysUserFaceMapper.xml @@ -2,17 +2,6 @@ - - - - - - - - - - - select a.id, @@ -35,9 +24,18 @@ and a.user_id = #{pa.userId} + + and a.user_id in + + #{v} + + and a.process_status = #{pa.processStatus} + + and a.process_id is not null + + + + \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/WalletManageDto.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/WalletManageDto.java index c2611195f..182230123 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/WalletManageDto.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/WalletManageDto.java @@ -4,7 +4,6 @@ import com.bsd.pjcloud.admin.api.vo.base.BaseIsIncludeTreeInterface; import com.bsd.pjcloud.wallet.api.entity.WalletManageEntity; import lombok.Data; -import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -27,4 +26,9 @@ public class WalletManageDto extends WalletManageEntity implements BaseIsInclude */ private Boolean isInclude; + /** + * 钱包余额大于等于 + */ + private Integer leBalance; + } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletManageController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletManageController.java index eae9312ca..15c8802f6 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletManageController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletManageController.java @@ -36,9 +36,6 @@ import java.util.List; /** * 钱包管理 - * - * @author dzc - * @date 2024-12-30 09:06:35 */ @RestController @RequiredArgsConstructor diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletManageMapper.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletManageMapper.java index a3134caad..29964905c 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletManageMapper.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/WalletManageMapper.java @@ -40,9 +40,10 @@ public interface WalletManageMapper extends PjcloudBaseMapper Date: Fri, 17 Apr 2026 15:52:11 +0800 Subject: [PATCH 10/17] 111 --- .../bsd/pjcloud/app/api/entity/AppUser.java | 12 +- .../thirdparty/dto/ThirdIsVerifyDeviceTo.java | 18 +++ .../controller/ThirdPartyOAth2Cotroller.java | 103 ++++++++++-------- .../controller/WalletManageController.java | 8 ++ 4 files changed, 91 insertions(+), 50 deletions(-) create mode 100644 pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/ThirdIsVerifyDeviceTo.java diff --git a/pjcloud-app-server/pjcloud-app-server-api/src/main/java/com/bsd/pjcloud/app/api/entity/AppUser.java b/pjcloud-app-server/pjcloud-app-server-api/src/main/java/com/bsd/pjcloud/app/api/entity/AppUser.java index f0a99a884..4d7e4826d 100644 --- a/pjcloud-app-server/pjcloud-app-server-api/src/main/java/com/bsd/pjcloud/app/api/entity/AppUser.java +++ b/pjcloud-app-server/pjcloud-app-server-api/src/main/java/com/bsd/pjcloud/app/api/entity/AppUser.java @@ -110,6 +110,12 @@ public class AppUser extends Model { @Schema(description = "第三方登录扩展字段") private String loginExtJson; + /** + * openId + */ + @Schema(description = "openId") + private String openid; + /** * 创建人 */ @@ -164,10 +170,4 @@ public class AppUser extends Model { @Schema(description = "锁定标记") private String lockFlag; - /** - * openId - */ - @Schema(description = "openId") - private String openid; - } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/ThirdIsVerifyDeviceTo.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/ThirdIsVerifyDeviceTo.java new file mode 100644 index 000000000..3ba41dd67 --- /dev/null +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/ThirdIsVerifyDeviceTo.java @@ -0,0 +1,18 @@ +package com.bsd.pjcloud.thirdparty.dto; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class ThirdIsVerifyDeviceTo { + + @NotEmpty(message = "用户手机号不能为空") + private String mobile; + + /** + * 会校验`mobile`是否属于`userId` + */ + private Long userId; + +} diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java index 193d6a0ba..c6e6a50a4 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java @@ -1,6 +1,8 @@ package com.bsd.pjcloud.thirdparty.controller; +import cn.hutool.core.util.ObjectUtil; +import com.bsd.pjcloud.admin.api.dto.UserInfo; import com.bsd.pjcloud.admin.api.dto.UserTokenDTO; import com.bsd.pjcloud.admin.api.entity.SysUser; import com.bsd.pjcloud.admin.api.entity.UserTrustedDeviceEntity; @@ -13,10 +15,7 @@ import com.bsd.pjcloud.common.core.util.R; import com.bsd.pjcloud.common.core.util.WebUtils; import com.bsd.pjcloud.common.log.annotation.SysLog; import com.bsd.pjcloud.common.security.annotation.Inner; -import com.bsd.pjcloud.thirdparty.dto.DeviceVerifyDTO; -import com.bsd.pjcloud.thirdparty.dto.SHJNSSODTO; -import com.bsd.pjcloud.thirdparty.dto.UrlTokenDTO; -import com.bsd.pjcloud.thirdparty.dto.ZZDUserDTO; +import com.bsd.pjcloud.thirdparty.dto.*; import com.bsd.pjcloud.thirdparty.service.SmsService; import com.bsd.pjcloud.thirdparty.service.ThirdPartyOAuth2Service; import com.bsd.pjcloud.thirdparty.service.ThirdPartyUserService; @@ -43,8 +42,8 @@ import java.util.concurrent.TimeUnit; @RestController @RequiredArgsConstructor -@RequestMapping("/thirdPartyOAth2" ) -@Tag(description = "thirdPartyOAth2" , name = "第三方单点接口" ) +@RequestMapping("/thirdPartyOAth2") +@Tag(description = "thirdPartyOAth2", name = "第三方单点接口") @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) public class ThirdPartyOAth2Cotroller { @@ -72,10 +71,10 @@ public class ThirdPartyOAth2Cotroller { // // } - @Operation(summary = "诗画token" ) - @GetMapping("/sh/sso" ) - public R getThirdPartyshsso(@RequestParam("accountId") String accountId,@RequestParam("sessionId") String sessionId) { - return R.ok(thirdPartyOAuth2Service.shjnsso(accountId,sessionId)); + @Operation(summary = "诗画token") + @GetMapping("/sh/sso") + public R getThirdPartyshsso(@RequestParam("accountId") String accountId, @RequestParam("sessionId") String sessionId) { + return R.ok(thirdPartyOAuth2Service.shjnsso(accountId, sessionId)); } @@ -92,7 +91,7 @@ public class ThirdPartyOAth2Cotroller { @Transactional(rollbackFor = Exception.class) public R zzdsso(@RequestBody UrlTokenDTO urlTokenDTO) { String token = urlTokenDTO.getToken(); - if (StringUtils.isBlank(token)){ + if (StringUtils.isBlank(token)) { return R.failed("token不能为空"); } @@ -134,13 +133,13 @@ public class ThirdPartyOAth2Cotroller { R r; //1.根据手机号或者钉钉号先查询是否有这个人 R> userByMobileOrEmployeeCode = remoteUserService.getUserByMobileOrEmployeeCode(employeeCode, mobile); - List sysUserList = userByMobileOrEmployeeCode.getData(); - if(!CollectionUtils.isEmpty(sysUserList)){ + List sysUserList = userByMobileOrEmployeeCode.getData(); + if (!CollectionUtils.isEmpty(sysUserList)) { //登录成功生成token UserTokenDTO userTokenDTO = new UserTokenDTO(); userTokenDTO.setSysUser(sysUserList.get(0)); r = remoteTokenService.generateToken(userTokenDTO); - }else { + } else { //2.根据浙政钉的员工钉钉号查询是否有这个人 // List thirdPartyUserEntityList = thirdPartyUserService.getUserByEmployeeCode(employeeCode); // UserDTO userDTO = new UserDTO(); @@ -191,13 +190,12 @@ public class ThirdPartyOAth2Cotroller { HashMap objectObjectHashMap = new HashMap<>(); Object accessToken = r.getData().get("accessToken"); Object refreshToken = r.getData().get("refreshToken"); - objectObjectHashMap.put("refreshToken",refreshToken); - objectObjectHashMap.put("accessToken",accessToken); + objectObjectHashMap.put("refreshToken", refreshToken); + objectObjectHashMap.put("accessToken", accessToken); return R.ok(objectObjectHashMap); } - /** * 诗画sdk获取参数 * @@ -210,31 +208,31 @@ public class ThirdPartyOAth2Cotroller { @SysLog("诗画江南单点登录") @Transactional @GlobalTransactional - public R shjnsso(@RequestBody @Valid SHJNSSODTO shjnsso,HttpServletRequest httpServletRequest) { + public R shjnsso(@RequestBody @Valid SHJNSSODTO shjnsso, HttpServletRequest httpServletRequest) { //检查设备指纹 - ZZDUserDTO zzdUserDTO = thirdPartyOAuth2Service.shjnsso(shjnsso.getAccountId(), shjnsso.getSessionId()); - if (null==zzdUserDTO){ + ZZDUserDTO zzdUserDTO = thirdPartyOAuth2Service.shjnsso(shjnsso.getAccountId(), shjnsso.getSessionId()); + if (null == zzdUserDTO) { throw new RuntimeException(""); } ZZDUserDTO.Ext ext = zzdUserDTO.getExt(); String mobile = zzdUserDTO.getMobile(); R> userByMobileOrEmployeeCode = remoteUserService.getUserByMobileOrEmployeeCode(null, mobile); - List sysUserList = userByMobileOrEmployeeCode.getData(); - if(!CollectionUtils.isEmpty(sysUserList)){ + List sysUserList = userByMobileOrEmployeeCode.getData(); + if (!CollectionUtils.isEmpty(sysUserList)) { SysUser sysUser = sysUserList.get(0); //判断当前用户设备是否信任 String md5 = DeviceFingerprintUtil.generate(httpServletRequest); R userTrustedDeviceR = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(sysUser.getPhone(), md5); UserTrustedDeviceEntity userTrustedDevice = userTrustedDeviceR.getData(); - if (userTrustedDevice == null || userTrustedDevice.getExpireTime().isBefore(LocalDateTime.now())){ - return R.failed(-1,"请先信任设备"); + if (userTrustedDevice == null || userTrustedDevice.getExpireTime().isBefore(LocalDateTime.now())) { + return R.failed(-1, "请先信任设备"); } //登录成功生成token UserTokenDTO userTokenDTO = new UserTokenDTO(); userTokenDTO.setSysUser(sysUser); return remoteTokenService.generateToken(userTokenDTO); - }else { + } else { //自动注册 // UserDTO userDTO = new UserDTO(); //// userDTO.setDeptId(1865990541445263361L); @@ -256,6 +254,7 @@ public class ThirdPartyOAth2Cotroller { } } + @Inner(value = false) @GetMapping("/getAuthToken/{token}") public R info(@PathVariable(name = "token") String token) { @@ -281,7 +280,7 @@ public class ThirdPartyOAth2Cotroller { @PostMapping("/verify-device") @SysLog("设备验证") @Inner(value = false) - public R verifyDevice(@RequestBody DeviceVerifyDTO dto,HttpServletRequest httpServletRequest) { + public R verifyDevice(@RequestBody DeviceVerifyDTO dto, HttpServletRequest httpServletRequest) { // 1. 校验验证码 String redisKey = "smsCode_" + dto.getMobilePhone(); String storedCode = (String) redisTemplate.opsForValue().get(redisKey); @@ -289,18 +288,18 @@ public class ThirdPartyOAth2Cotroller { return R.failed("验证码错误"); } - // 验证成功后移除验证码(可选) - redisTemplate.delete(redisKey); + // 验证成功后移除验证码(可选) + redisTemplate.delete(redisKey); // 2. 记录信任设备 //查询之前的是否有过期的数据,有就更新 String generate = DeviceFingerprintUtil.generate(httpServletRequest); R userTrustedDeviceR = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(dto.getMobilePhone(), generate); - if (userTrustedDeviceR.getData() != null){ + if (userTrustedDeviceR.getData() != null) { userTrustedDeviceR.getData().setExpireTime(LocalDateTime.now().plusMonths(3)); remoteUserTrustedDeviceService.updateById(userTrustedDeviceR.getData()); - }else { + } else { UserTrustedDeviceEntity userTrustedDevice = new UserTrustedDeviceEntity(); userTrustedDevice.setMobilePhone(dto.getMobilePhone()); userTrustedDevice.setExpireTime(LocalDateTime.now().plusMonths(3)); @@ -311,31 +310,50 @@ public class ThirdPartyOAth2Cotroller { return R.ok(); } + @PostMapping("/is-verify-device") + @SysLog("判断该设备是否被验证") + @Inner(value = false) + public R isVerifyDevice(@RequestBody ThirdIsVerifyDeviceTo body, HttpServletRequest httpServletRequest) { + if (ObjectUtil.isNotEmpty(body.getUserId())) { + UserInfo userInfo = remoteUserService.getInnerByUserId(body.getUserId()).getData(); + if (ObjectUtil.isEmpty(userInfo)) { + throw new RuntimeException("用户不存在"); + } + if (ObjectUtil.notEqual(userInfo.getSysUser().getPhone(), body.getMobile())) { + throw new RuntimeException("手机号和登录的账号不一致"); + } + } + String generate = DeviceFingerprintUtil.generate(httpServletRequest); + UserTrustedDeviceEntity userTrustedDevice = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(body.getMobile(), generate).getData(); + return R.ok(ObjectUtil.isNotEmpty(userTrustedDevice)); + } + /** * 诗画浦江端 + * * @param mobilePhone * @param httpServletRequest - * @param type 短信区分标识 if null 诗画登录短信 1 访客登录短信 + * @param type 短信区分标识 if null 诗画登录短信 1 访客登录短信 * @return */ @PostMapping("/loginSms") @Operation(summary = "发送登录短信") @SysLog("发送登录短信") @Inner(value = false) - public R loginSms(@RequestParam String mobilePhone,HttpServletRequest httpServletRequest, - @RequestParam(value = "type",required = false)Integer type) { - Map stringHashMap = new LinkedHashMap<>(); + public R loginSms(@RequestParam String mobilePhone, HttpServletRequest httpServletRequest, + @RequestParam(value = "type", required = false) Integer type) { + Map stringHashMap = new LinkedHashMap<>(); String s = SmsCodeUtil.generateNumberCode(6); - stringHashMap.put("code",s); - stringHashMap.put("date","5"); - smsService.sendSms(mobilePhone, "20657",stringHashMap, WebUtils.getIP()); + stringHashMap.put("code", s); + stringHashMap.put("date", "5"); + smsService.sendSms(mobilePhone, "20657", stringHashMap, WebUtils.getIP()); // null 适配之前诗画的,=1访客,先else - if (null==type){ - redisTemplate.opsForValue().set(CacheConstants.SMS_CODE_KEY +mobilePhone,s, 5, TimeUnit.MINUTES); - }else { - stringRedisTemplate.opsForValue().set(CacheConstants.SMS_VISITOR_CODE_KEY +mobilePhone,s, 5, TimeUnit.MINUTES); + if (null == type) { + redisTemplate.opsForValue().set(CacheConstants.SMS_CODE_KEY + mobilePhone, s, 5, TimeUnit.MINUTES); + } else { + stringRedisTemplate.opsForValue().set(CacheConstants.SMS_VISITOR_CODE_KEY + mobilePhone, s, 5, TimeUnit.MINUTES); } // redisTemplate.opsForValue().set(CacheConstants.SMS_CODE_KEY +mobilePhone,s, 5, TimeUnit.MINUTES); @@ -343,7 +361,4 @@ public class ThirdPartyOAth2Cotroller { } - - - } diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletManageController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletManageController.java index 15c8802f6..51effbb2f 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletManageController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/WalletManageController.java @@ -204,6 +204,14 @@ public class WalletManageController { PjcloudUser user = SecurityUtils.getUser(); return R.ok(walletManageService.isUseDoor(user.getId())); } + + @GetMapping("/app/topup-wallet") + @Operation(summary = "创建充值钱包") + public R createTopupWallet() { + PjcloudUser user = SecurityUtils.getUser(); + walletManageService.createWallet(user.getId()); + return R.ok(); + } /* ************************************* end app end ************************************* */ @Operation(summary = "分页查询", description = "分页查询") From 810038864d248f736af48baa26aa0436f2296380 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Tue, 28 Apr 2026 15:39:09 +0800 Subject: [PATCH 11/17] =?UTF-8?q?feat:=E4=BA=91=E9=9F=B3=E7=AE=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hard/api/constant/HardTypeEnum.java | 1 + .../com/bsd/pjcloud/hard/config/YyxConf.java | 22 ++++ .../bsd/pjcloud/hard/service/YyxService.java | 11 ++ .../impl/order/HardOrderServiceImpl.java | 4 + .../hard/service/impl/yyx/YyxServiceImpl.java | 113 ++++++++++++++++++ .../WalletRechargePackageController.java | 9 +- 6 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/config/YyxConf.java create mode 100644 pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/YyxService.java create mode 100644 pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/yyx/YyxServiceImpl.java diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/HardTypeEnum.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/HardTypeEnum.java index 97f8887bc..1ad3afdcf 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/HardTypeEnum.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/HardTypeEnum.java @@ -23,6 +23,7 @@ public enum HardTypeEnum { OTHER("6", "其他支付方式(第三方接口对接)"), MERCHANT_ACT("7", "商户活动"), FARMER("8", "共富商城(助农)"), + YYX("10", "4G云音响"), ; private final String type; private final String description; diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/config/YyxConf.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/config/YyxConf.java new file mode 100644 index 000000000..66fc982b2 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/config/YyxConf.java @@ -0,0 +1,22 @@ +package com.bsd.pjcloud.hard.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "yyx") +@Data +public class YyxConf { + + private String url; + + /** + * 模板 + * ${price}-价格 + * ${phone-last}-手机尾号 + * 浦江智慧后勤,收款${price}元 + */ + private String template; + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/YyxService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/YyxService.java new file mode 100644 index 000000000..75978f66a --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/YyxService.java @@ -0,0 +1,11 @@ +package com.bsd.pjcloud.hard.service; + +/** + * @author liusiyang_dxm + * @since 2026/4/28 + */ +public interface YyxService { + + void send(Long mchId, Integer payPrice, String phone); + +} diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java index ab0230ed4..87bd66fbc 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java @@ -161,6 +161,7 @@ public class HardOrderServiceImpl extends ServiceImpl yyxList = hardManagerMapper.selectList(new LambdaQueryWrapper().eq(HardManagerEntity::getMerchantId, mchId) + .eq(HardManagerEntity::getType, HardTypeEnum.YYX.getType()) + ); + if (ObjectUtil.isEmpty(yyxList)) { + return; + } + + String yuanPrice = fenToYuan(payPrice); + String lastPhone = phoneToLastPhone(phone); + + String template = yyxConf.getTemplate(); + + // 把`template`中的`${price}`替换为`yuanPrice` + template = template.replace("${price}", yuanPrice); + // 把`template`中的`${phone}`替换为`lastPhone` + template = template.replace("${phone-last}", lastPhone); + + + String finalTemplate = template; + yyxList.forEach(v -> httpSend(v.getUniqueCode(), finalTemplate)); + } + + private boolean httpSend(String deviceId, String msg) { + String msgid = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) + RandomUtil.randomString(8); + try { + HashMap data = new HashMap<>(); + data.put("cmd", "voice"); + data.put("msg", msg); + data.put("msgid", msgid); + + HashMap body = new HashMap<>(); + body.put("sbx_id", deviceId); + body.put("agent_id", JSONUtil.toJsonStr(data)); + + String res = HttpUtil.post(yyxConf.getUrl(), JSONUtil.toJsonStr(body)); + if (ObjectUtil.isEmpty(res)) { + log.error("|{}|发送失败,返回结果为空", TAG); + return false; + } + JSON resJson = JSONUtil.parse(res); + String requestId = resJson.getByPath("RequestId", String.class); + if (ObjectUtil.isEmpty(requestId)) { + log.error("|{}|发送失败,返回结果错误res:|{}|", res, TAG); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + log.error("|{}|发送失败,异常:{}", TAG, e.getMessage()); + return false; + } + } + + private String phoneToLastPhone(String phone) { + if (ObjectUtil.isEmpty(phone)) { + return ""; + } + return phone.substring(phone.length() - 4); + } + + private String fenToYuan(Integer payPrice) { + if (ObjectUtil.isEmpty(payPrice)) { + return "0"; + } + BigDecimal fen = new BigDecimal(payPrice); + return fen.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).toString(); + } + +} diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java index 44aaf55e7..e86265ce8 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargePackageController.java @@ -27,9 +27,6 @@ import java.util.List; /** * 充值套餐表 - * - * @author dzc - * @date 2025-01-03 18:33:55 */ @RestController @RequiredArgsConstructor @@ -66,7 +63,10 @@ public class WalletRechargePackageController { @Operation(summary = "查询全部", description = "查询全部") @GetMapping("/app/list") public R appList() { - return R.ok(walletRechargePackageService.list(new LambdaQueryWrapper<>())); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.orderByAsc(WalletRechargePackageEntity::getPayPrice); + wrapper.orderByDesc(WalletRechargePackageEntity::getCreateTime); + return R.ok(walletRechargePackageService.list(wrapper)); } /* ************************************* end app end ************************************* */ @@ -75,6 +75,7 @@ public class WalletRechargePackageController { @PreAuthorize("@pms.hasPermission('wallet_walletRechargePackage_view')") public R getWalletRechargePackagePage(@ParameterObject Page page, @ParameterObject WalletRechargePackageEntity walletRechargePackage) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.orderByAsc(WalletRechargePackageEntity::getPayPrice); wrapper.orderByDesc(WalletRechargePackageEntity::getCreateTime); return R.ok(walletRechargePackageService.page(page, wrapper)); } From e68298d177eaae12acf55e9230a8ad437dbe094a Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Tue, 28 Apr 2026 15:39:58 +0800 Subject: [PATCH 12/17] =?UTF-8?q?feat:=E4=BA=91=E9=9F=B3=E7=AE=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hard/service/impl/yyx/YyxServiceImpl.java | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/yyx/YyxServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/yyx/YyxServiceImpl.java index 8acda2799..b68a54bb5 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/yyx/YyxServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/yyx/YyxServiceImpl.java @@ -39,30 +39,34 @@ public class YyxServiceImpl implements YyxService { @Override public void send(Long mchId, Integer payPrice, String phone) { - if (!ObjectUtil.isAllNotEmpty(mchId, payPrice, phone)) { - return; + try { + if (!ObjectUtil.isAllNotEmpty(mchId, payPrice, phone)) { + return; + } + // 查询商户绑定的云音箱设备 + List yyxList = hardManagerMapper.selectList(new LambdaQueryWrapper().eq(HardManagerEntity::getMerchantId, mchId) + .eq(HardManagerEntity::getType, HardTypeEnum.YYX.getType()) + ); + if (ObjectUtil.isEmpty(yyxList)) { + return; + } + + String yuanPrice = fenToYuan(payPrice); + String lastPhone = phoneToLastPhone(phone); + + String template = yyxConf.getTemplate(); + + // 把`template`中的`${price}`替换为`yuanPrice` + template = template.replace("${price}", yuanPrice); + // 把`template`中的`${phone}`替换为`lastPhone` + template = template.replace("${phone-last}", lastPhone); + + + String finalTemplate = template; + yyxList.forEach(v -> httpSend(v.getUniqueCode(), finalTemplate)); + } catch (Exception e) { + log.error("|{}|发送失败,异常:{}", TAG, e.getMessage()); } - // 查询商户绑定的云音箱设备 - List yyxList = hardManagerMapper.selectList(new LambdaQueryWrapper().eq(HardManagerEntity::getMerchantId, mchId) - .eq(HardManagerEntity::getType, HardTypeEnum.YYX.getType()) - ); - if (ObjectUtil.isEmpty(yyxList)) { - return; - } - - String yuanPrice = fenToYuan(payPrice); - String lastPhone = phoneToLastPhone(phone); - - String template = yyxConf.getTemplate(); - - // 把`template`中的`${price}`替换为`yuanPrice` - template = template.replace("${price}", yuanPrice); - // 把`template`中的`${phone}`替换为`lastPhone` - template = template.replace("${phone-last}", lastPhone); - - - String finalTemplate = template; - yyxList.forEach(v -> httpSend(v.getUniqueCode(), finalTemplate)); } private boolean httpSend(String deviceId, String msg) { From 1c66276bb101313c03ea6dba7894289534d25fa7 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Tue, 28 Apr 2026 16:03:33 +0800 Subject: [PATCH 13/17] =?UTF-8?q?feat:=E5=BC=82=E6=AD=A5=E8=AF=AD=E9=9F=B3?= =?UTF-8?q?=E6=92=AD=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pjcloud/hard/service/impl/order/HardOrderServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java index 87bd66fbc..4b8ff9105 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardOrderServiceImpl.java @@ -785,7 +785,7 @@ public class HardOrderServiceImpl extends ServiceImpl yyxService.send(orderObj.getMerchantId(), orderObj.getPayPrice(), userDetail.getSysUser().getPhone())); return orderObj.getId(); } From c1a11d8f8691afd32d66a1dc7dd05c0a4b0292b8 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Tue, 28 Apr 2026 17:56:01 +0800 Subject: [PATCH 14/17] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0=E8=80=97=E6=97=B6?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/miniapp/ThirdMiniAppServiceImpl.java | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java index 6df041c07..e5c5dbf5c 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java @@ -67,11 +67,17 @@ public class ThirdMiniAppServiceImpl implements ThirdMiniAppService { */ @Override public ThirdMinAppOAth2LoginVo adminLogin(ThirdMiniAppOAth2LoginDto dto) { + long startTime = System.currentTimeMillis(); + ThirdMinAppOAth2LoginVo vo = new ThirdMinAppOAth2LoginVo(); // 微信小程序 if (ObjectUtil.equals(dto.getMiniPlatformType().getType(), MiniPlatformTypeEnum.WECHAT.getType())) { // 获取手机号 + long getPhoneStartTime = System.currentTimeMillis(); WxMaPhoneNumberInfo phoneInfo = thirdMiniAppWechatService.getPhone(dto.getPhoneCode()); + long getPhoneEndTime = System.currentTimeMillis(); + log.info("|{}|getPhone耗时: {} ms", TAG, (getPhoneEndTime - getPhoneStartTime)); + if (ObjectUtil.isEmpty(phoneInfo)) { vo.setErrorCode(MiniPlatformLoginErrorEnum.GET_PHONE_ERROR.getType()); return vo; @@ -83,22 +89,28 @@ public class ThirdMiniAppServiceImpl implements ThirdMiniAppService { return vo; } // 获取用户唯一编号 + long getUnicodeStartTime = System.currentTimeMillis(); ThirdMiniAppGetUniqueDto getUniqueDto = new ThirdMiniAppGetUniqueDto(); getUniqueDto.setMiniPlatformType(MiniPlatformTypeEnum.WECHAT); getUniqueDto.setCode(dto.getPhoneCode()); getUniqueDto.setUserId(userInfo.getSysUser().getUserId()); String uniqueCode = getUniqueCode(getUniqueDto); + long getUnicodeEndTime = System.currentTimeMillis(); + log.info("|{}|getUniqueCode耗时: {} ms", TAG, (getUnicodeEndTime - getUnicodeStartTime)); + // 同步到社交用户 - AppAdminSyncDto appAdminSyncDto = new AppAdminSyncDto(); - appAdminSyncDto.setUniqueCode(uniqueCode); - appAdminSyncDto.setUserTypeEnum(AppUserTypeEnum.MINI_WECHAT); - appAdminSyncDto.setAdminUserId(userInfo.getSysUser().getUserId()); - appAdminSyncDto.setUsername(userInfo.getSysUser().getUsername()); - appAdminSyncDto.setAvatarImage(userInfo.getSysUser().getAvatar()); - AppUserInfo appUserInfo = remoteAppUserService.syncAdminAccountInfo(appAdminSyncDto).getData(); - if (ObjectUtil.isEmpty(appUserInfo)) { - vo.setErrorCode(MiniPlatformLoginErrorEnum.LOGIN_ERROR.getType()); - return vo; + if (ObjectUtil.isNotEmpty(uniqueCode)) { + AppAdminSyncDto appAdminSyncDto = new AppAdminSyncDto(); + appAdminSyncDto.setUniqueCode(uniqueCode); + appAdminSyncDto.setUserTypeEnum(AppUserTypeEnum.MINI_WECHAT); + appAdminSyncDto.setAdminUserId(userInfo.getSysUser().getUserId()); + appAdminSyncDto.setUsername(userInfo.getSysUser().getUsername()); + appAdminSyncDto.setAvatarImage(userInfo.getSysUser().getAvatar()); + AppUserInfo appUserInfo = remoteAppUserService.syncAdminAccountInfo(appAdminSyncDto).getData(); + if (ObjectUtil.isEmpty(appUserInfo)) { + vo.setErrorCode(MiniPlatformLoginErrorEnum.LOGIN_ERROR.getType()); + return vo; + } } // 执行登录 UserTokenDTO userTokenDTO = new UserTokenDTO(); @@ -115,6 +127,8 @@ public class ThirdMiniAppServiceImpl implements ThirdMiniAppService { else if (ObjectUtil.equals(dto.getMiniPlatformType().getType(), MiniPlatformTypeEnum.ALI_PAY.getType())) { } + long endTime = System.currentTimeMillis(); + log.info("|{}|adminLogin耗时: {} ms", TAG, (startTime - endTime)); return vo; } From 2332dfba38c09c4a2da13246048d08e83de644a5 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Tue, 28 Apr 2026 17:58:12 +0800 Subject: [PATCH 15/17] =?UTF-8?q?feat:=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/miniapp/ThirdMiniAppServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java index e5c5dbf5c..a15e928f2 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/service/impl/miniapp/ThirdMiniAppServiceImpl.java @@ -92,7 +92,7 @@ public class ThirdMiniAppServiceImpl implements ThirdMiniAppService { long getUnicodeStartTime = System.currentTimeMillis(); ThirdMiniAppGetUniqueDto getUniqueDto = new ThirdMiniAppGetUniqueDto(); getUniqueDto.setMiniPlatformType(MiniPlatformTypeEnum.WECHAT); - getUniqueDto.setCode(dto.getPhoneCode()); + getUniqueDto.setCode(dto.getUserCode()); getUniqueDto.setUserId(userInfo.getSysUser().getUserId()); String uniqueCode = getUniqueCode(getUniqueDto); long getUnicodeEndTime = System.currentTimeMillis(); From 8422ed1d4bc3f7f8e1cdc1b97e55b44e803c2345 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Tue, 28 Apr 2026 20:36:01 +0800 Subject: [PATCH 16/17] =?UTF-8?q?feat:=E8=AE=BE=E5=A4=87=E6=8E=88=E6=9D=83?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thirdparty/dto/ThirdIsVerifyDeviceTo.java | 10 ++++ .../controller/ThirdPartyOAth2Cotroller.java | 43 +++++++++++++++-- .../feign/RemoteUserTrustedDeviceService.java | 4 +- .../UserTrustedDeviceController.java | 48 ++++++++++--------- .../service/UserTrustedDeviceService.java | 4 +- .../impl/UserTrustedDeviceServiceImpl.java | 4 +- 6 files changed, 82 insertions(+), 31 deletions(-) diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/ThirdIsVerifyDeviceTo.java b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/ThirdIsVerifyDeviceTo.java index 3ba41dd67..2d9237a90 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/ThirdIsVerifyDeviceTo.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-api/src/main/java/com/bsd/pjcloud/thirdparty/dto/ThirdIsVerifyDeviceTo.java @@ -15,4 +15,14 @@ public class ThirdIsVerifyDeviceTo { */ private Long userId; + /** + * 唯一值,小程序是openId + */ + private String uniqueCode; + + /** + * 设备信息 + */ + private String deviceJson; + } diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java index c6e6a50a4..bb29441a8 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java @@ -34,6 +34,7 @@ import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.http.HttpHeaders; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; @@ -47,6 +48,9 @@ import java.util.concurrent.TimeUnit; @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) public class ThirdPartyOAth2Cotroller { + static final String MINI_MAP_APP_DEVICE_NAME = "微信小程序设备认证"; + static final String SH_DEVICE_NAME = "诗画设备认证"; + private final ThirdPartyOAuth2Service thirdPartyOAuth2Service; private final RemoteUserService remoteUserService; @@ -222,7 +226,7 @@ public class ThirdPartyOAth2Cotroller { SysUser sysUser = sysUserList.get(0); //判断当前用户设备是否信任 String md5 = DeviceFingerprintUtil.generate(httpServletRequest); - R userTrustedDeviceR = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(sysUser.getPhone(), md5); + R userTrustedDeviceR = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(sysUser.getPhone(), md5, SH_DEVICE_NAME); UserTrustedDeviceEntity userTrustedDevice = userTrustedDeviceR.getData(); if (userTrustedDevice == null || userTrustedDevice.getExpireTime().isBefore(LocalDateTime.now())) { return R.failed(-1, "请先信任设备"); @@ -295,7 +299,7 @@ public class ThirdPartyOAth2Cotroller { // 2. 记录信任设备 //查询之前的是否有过期的数据,有就更新 String generate = DeviceFingerprintUtil.generate(httpServletRequest); - R userTrustedDeviceR = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(dto.getMobilePhone(), generate); + R userTrustedDeviceR = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(dto.getMobilePhone(), generate, SH_DEVICE_NAME); if (userTrustedDeviceR.getData() != null) { userTrustedDeviceR.getData().setExpireTime(LocalDateTime.now().plusMonths(3)); remoteUserTrustedDeviceService.updateById(userTrustedDeviceR.getData()); @@ -303,7 +307,38 @@ public class ThirdPartyOAth2Cotroller { UserTrustedDeviceEntity userTrustedDevice = new UserTrustedDeviceEntity(); userTrustedDevice.setMobilePhone(dto.getMobilePhone()); userTrustedDevice.setExpireTime(LocalDateTime.now().plusMonths(3)); - userTrustedDevice.setDeviceName("诗画设备认证"); + userTrustedDevice.setDeviceName(SH_DEVICE_NAME); + userTrustedDevice.setDeviceFingerprint(generate); + remoteUserTrustedDeviceService.save(userTrustedDevice); + } + return R.ok(); + } + + @PostMapping("/mini-app/verify-device") + @SysLog("小程序设备验证") + @Inner(value = false) + public R miniVerifyDevice(@RequestBody DeviceVerifyDTO dto, HttpServletRequest httpServletRequest) { + + // 1. 校验验证码 + String redisKey = "smsCode_" + dto.getMobilePhone(); + String storedCode = (String) redisTemplate.opsForValue().get(redisKey); + if (!dto.getCode().equals(storedCode)) { + return R.failed("验证码错误"); + } + // 验证成功后移除验证码(可选) + redisTemplate.delete(redisKey); + // 2. 记录信任设备 + //查询之前的是否有过期的数据,有就更新 + String generate = DeviceFingerprintUtil.generate(httpServletRequest); + R userTrustedDeviceR = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(dto.getMobilePhone(), generate, MINI_MAP_APP_DEVICE_NAME); + if (userTrustedDeviceR.getData() != null) { + userTrustedDeviceR.getData().setExpireTime(LocalDateTime.now().plusMonths(3)); + remoteUserTrustedDeviceService.updateById(userTrustedDeviceR.getData()); + } else { + UserTrustedDeviceEntity userTrustedDevice = new UserTrustedDeviceEntity(); + userTrustedDevice.setMobilePhone(dto.getMobilePhone()); + userTrustedDevice.setExpireTime(LocalDateTime.now().plusMonths(3)); + userTrustedDevice.setDeviceName(MINI_MAP_APP_DEVICE_NAME); userTrustedDevice.setDeviceFingerprint(generate); remoteUserTrustedDeviceService.save(userTrustedDevice); } @@ -324,7 +359,7 @@ public class ThirdPartyOAth2Cotroller { } } String generate = DeviceFingerprintUtil.generate(httpServletRequest); - UserTrustedDeviceEntity userTrustedDevice = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(body.getMobile(), generate).getData(); + UserTrustedDeviceEntity userTrustedDevice = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(body.getMobile(), generate, MINI_MAP_APP_DEVICE_NAME).getData(); return R.ok(ObjectUtil.isNotEmpty(userTrustedDevice)); } diff --git a/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/feign/RemoteUserTrustedDeviceService.java b/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/feign/RemoteUserTrustedDeviceService.java index c917b5344..7c0eb61b0 100644 --- a/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/feign/RemoteUserTrustedDeviceService.java +++ b/pjcloud-upms/pjcloud-upms-api/src/main/java/com/bsd/pjcloud/admin/api/feign/RemoteUserTrustedDeviceService.java @@ -48,8 +48,8 @@ public interface RemoteUserTrustedDeviceService { @NoToken - @GetMapping("/userTrustedDevice/getUserTrustedDeviceByIdAndMD5" ) - R getUserTrustedDeviceByIdAndMD5(@RequestParam("mobilePhone")String mobilePhone,@RequestParam("md5") String md5); + @GetMapping("/userTrustedDevice/getUserTrustedDeviceByIdAndMD5") + R getUserTrustedDeviceByIdAndMD5(@RequestParam("mobilePhone") String mobilePhone, @RequestParam("md5") String md5, @RequestParam("deviceName") String deviceName); @PostMapping("/userTrustedDevice/save") diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/UserTrustedDeviceController.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/UserTrustedDeviceController.java index e80365561..0a674d082 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/UserTrustedDeviceController.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/controller/UserTrustedDeviceController.java @@ -30,22 +30,23 @@ import java.util.List; */ @RestController @RequiredArgsConstructor -@RequestMapping("/userTrustedDevice" ) -@Tag(description = "userTrustedDevice" , name = "设备指纹管理" ) +@RequestMapping("/userTrustedDevice") +@Tag(description = "userTrustedDevice", name = "设备指纹管理") @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) public class UserTrustedDeviceController { - private final UserTrustedDeviceService userTrustedDeviceService; + private final UserTrustedDeviceService userTrustedDeviceService; /** * 分页查询 - * @param page 分页对象 + * + * @param page 分页对象 * @param userTrustedDevice 设备指纹 * @return */ - @Operation(summary = "分页查询" , description = "分页查询" ) - @GetMapping("/page" ) - @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_view')" ) + @Operation(summary = "分页查询", description = "分页查询") + @GetMapping("/page") + @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_view')") public R getUserTrustedDevicePage(@ParameterObject Page page, @ParameterObject UserTrustedDeviceEntity userTrustedDevice) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); return R.ok(userTrustedDeviceService.page(page, wrapper)); @@ -54,22 +55,24 @@ public class UserTrustedDeviceController { /** * 通过id查询设备指纹 + * * @param id id * @return R */ - @Operation(summary = "通过id查询" , description = "通过id查询" ) - @GetMapping("/{id}" ) - @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_view')" ) - public R getById(@PathVariable("id" ) Long id) { + @Operation(summary = "通过id查询", description = "通过id查询") + @GetMapping("/{id}") + @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_view')") + public R getById(@PathVariable("id") Long id) { return R.ok(userTrustedDeviceService.getById(id)); } /** * 新增设备指纹 + * * @param userTrustedDevice 设备指纹 * @return R */ - @Operation(summary = "新增设备指纹" , description = "新增设备指纹" ) + @Operation(summary = "新增设备指纹", description = "新增设备指纹") @PostMapping("/save") @Inner public R save(@RequestBody UserTrustedDeviceEntity userTrustedDevice) { @@ -78,11 +81,12 @@ public class UserTrustedDeviceController { /** * 修改设备指纹 + * * @param userTrustedDevice 设备指纹 * @return R */ - @Operation(summary = "修改设备指纹" , description = "修改设备指纹" ) - @SysLog("修改设备指纹" ) + @Operation(summary = "修改设备指纹", description = "修改设备指纹") + @SysLog("修改设备指纹") @PutMapping("/update") @Inner public R updateById(@RequestBody UserTrustedDeviceEntity userTrustedDevice) { @@ -91,23 +95,23 @@ public class UserTrustedDeviceController { /** * 通过id删除设备指纹 + * * @param ids id列表 * @return R */ - @Operation(summary = "通过id删除设备指纹" , description = "通过id删除设备指纹" ) - @SysLog("通过id删除设备指纹" ) + @Operation(summary = "通过id删除设备指纹", description = "通过id删除设备指纹") + @SysLog("通过id删除设备指纹") @DeleteMapping - @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_del')" ) + @PreAuthorize("@pms.hasPermission('admin_userTrustedDevice_del')") public R removeById(@RequestBody Long[] ids) { return R.ok(userTrustedDeviceService.removeBatchByIds(CollUtil.toList(ids))); } - - @Operation(summary = "通过md5和用户查询设备" , description = "通过md5和用户查询设备" ) - @GetMapping("/getUserTrustedDeviceByIdAndMD5" ) + @Operation(summary = "通过md5和用户查询设备", description = "通过md5和用户查询设备") + @GetMapping("/getUserTrustedDeviceByIdAndMD5") @Inner - public R getUserTrustedDeviceByIdAndMD5(@RequestParam("mobilePhone")String mobilePhone,@RequestParam("md5") String md5) { - return R.ok(userTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(mobilePhone,md5)); + public R getUserTrustedDeviceByIdAndMD5(@RequestParam("mobilePhone") String mobilePhone, @RequestParam("md5") String md5, @RequestParam("deviceName") String deviceName) { + return R.ok(userTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(mobilePhone, md5, deviceName)); } } \ No newline at end of file diff --git a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/UserTrustedDeviceService.java b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/UserTrustedDeviceService.java index 14bc5a1e0..d2e468d95 100644 --- a/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/UserTrustedDeviceService.java +++ b/pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/UserTrustedDeviceService.java @@ -8,12 +8,12 @@ public interface UserTrustedDeviceService extends IService userTrustedDeviceEntityLambdaQueryWrapper = new LambdaQueryWrapper<>(); userTrustedDeviceEntityLambdaQueryWrapper.eq(UserTrustedDeviceEntity::getMobilePhone, mobilePhone); userTrustedDeviceEntityLambdaQueryWrapper.eq(UserTrustedDeviceEntity::getDeviceFingerprint, md5); + userTrustedDeviceEntityLambdaQueryWrapper.eq(UserTrustedDeviceEntity::getDeviceName, deviceName); return baseMapper.selectOne(userTrustedDeviceEntityLambdaQueryWrapper); } From 7f8f1608632048e301c7f9d7c05d551d8c2d3eea Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Wed, 29 Apr 2026 11:12:37 +0800 Subject: [PATCH 17/17] =?UTF-8?q?feat:=E9=92=B1=E5=8C=85=E7=94=B3=E8=AF=B7?= =?UTF-8?q?=E9=98=B2=E6=AD=A2=E9=87=8D=E5=A4=8D=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pjcloud-flow-task-biz/pom.xml | 4 ++++ .../flow/task/controller/TaskController.java | 3 ++- .../recharge/WalletRechargeApplyController.java | 6 +++--- .../recharge/WalletRechargeInvoiceController.java | 15 ++++----------- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/pjcloud-flow/pjcloud-flow-task/pjcloud-flow-task-biz/pom.xml b/pjcloud-flow/pjcloud-flow-task/pjcloud-flow-task-biz/pom.xml index fa6c81aad..ef8f1ad62 100644 --- a/pjcloud-flow/pjcloud-flow-task/pjcloud-flow-task-biz/pom.xml +++ b/pjcloud-flow/pjcloud-flow-task/pjcloud-flow-task-biz/pom.xml @@ -98,6 +98,10 @@ org.springframework.boot spring-boot-starter-test + + com.bsd + pjcloud-common-idempotent + diff --git a/pjcloud-flow/pjcloud-flow-task/pjcloud-flow-task-biz/src/main/java/com/bsd/pjcloud/flow/task/controller/TaskController.java b/pjcloud-flow/pjcloud-flow-task/pjcloud-flow-task-biz/src/main/java/com/bsd/pjcloud/flow/task/controller/TaskController.java index 9fb201efe..0033ed531 100644 --- a/pjcloud-flow/pjcloud-flow-task/pjcloud-flow-task-biz/src/main/java/com/bsd/pjcloud/flow/task/controller/TaskController.java +++ b/pjcloud-flow/pjcloud-flow-task/pjcloud-flow-task-biz/src/main/java/com/bsd/pjcloud/flow/task/controller/TaskController.java @@ -1,6 +1,7 @@ package com.bsd.pjcloud.flow.task.controller; import com.bsd.pjcloud.common.core.util.R; +import com.bsd.pjcloud.common.idempotent.annotation.Idempotent; import com.bsd.pjcloud.flow.task.dto.BatchCompleteTaskDto; import com.bsd.pjcloud.flow.task.dto.TaskParamDto; import com.bsd.pjcloud.flow.task.service.ITaskService; @@ -51,8 +52,8 @@ public class TaskController { */ @SneakyThrows @PostMapping("completeTask") + @Idempotent(expireTime = 3, key = "'/task/completeTask/' + #completeParamDto.getTaskId()", info = "正在操作中,请勿重复操作") public R completeTask(@RequestBody TaskParamDto completeParamDto) { - return taskService.completeTask(completeParamDto); } diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java index 3ae259564..1372be199 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeApplyController.java @@ -86,7 +86,7 @@ public class WalletRechargeApplyController { @SysLog("提交申请") @GetMapping("/apply") @PreAuthorize("@pms.hasPermission('wallet_walletRechargeApply_apply')") - @Idempotent(expireTime = 5, info = "正在申请中,请勿重复操作") + @Idempotent(expireTime = 5, key = "'/wallet-recharge-apply/apply/' + #id", info = "正在申请中,请勿重复操作") public R apply(@RequestParam Long id) { walletRechargeApplyService.apply(id); return R.ok(true); @@ -173,13 +173,13 @@ public class WalletRechargeApplyController { } @PostMapping("/read-excel") - @Idempotent(expireTime = 3, info = "正在上传中,请勿重复操作") + @Idempotent(expireTime = 3, key = "'/wallet-recharge-apply/read-excel'", info = "正在上传中,请勿重复操作") public R readExcel(@RequestExcel List excelVOList, BindingResult bindingResult, @RequestParam(required = false) String bizType) { return walletRechargeApplyService.readExcel(excelVOList, bindingResult, bizType); } @PostMapping("/read-topup-excel") - @Idempotent(expireTime = 3, info = "正在上传中,请勿重复操作") + @Idempotent(expireTime = 3, key = "'/wallet-recharge-apply/read-topup-excel'", info = "正在上传中,请勿重复操作") public R readTopupExcel(@RequestExcel List excelVOList, BindingResult bindingResult) { return walletRechargeApplyService.readTopupExcel(excelVOList, bindingResult); } diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeInvoiceController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeInvoiceController.java index b06501219..b890d4f29 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeInvoiceController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeInvoiceController.java @@ -1,21 +1,14 @@ package com.bsd.pjcloud.wallet.controller.recharge; -import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.collection.CollUtil; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.bsd.pjcloud.admin.api.entity.SysUser; import com.bsd.pjcloud.common.core.util.R; import com.bsd.pjcloud.common.data.datascope.DataScope; import com.bsd.pjcloud.common.idempotent.annotation.Idempotent; import com.bsd.pjcloud.common.log.annotation.SysLog; import com.bsd.pjcloud.common.security.annotation.Inner; -import com.bsd.pjcloud.common.security.service.PjcloudUser; -import com.bsd.pjcloud.common.security.util.SecurityUtils; import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum; import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto; -import com.bsd.pjcloud.wallet.api.constant.WalletInvoiceStatusCheckEnum; -import com.bsd.pjcloud.wallet.api.dto.WalletManageBalanceDto; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeBindInvoiceDto; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeInvoiceApplyDto; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeInvoiceRefreshDto; @@ -34,8 +27,6 @@ import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; -import java.util.List; - /** * 充值/扣款申请发票记录 */ @@ -59,7 +50,7 @@ public class WalletRechargeInvoiceController { @Operation(summary = "重新生成发票", description = "重新生成发票") @SysLog("重新生成发票") @PostMapping("/refreshInvoice") - @Idempotent(expireTime = 10, info = "正在重新生成发票中,请勿重复操作") + @Idempotent(expireTime = 3, key = "'/walletRechargeInvoice/refreshInvoice/' + #dto.getId()", info = "正在重新生成发票中,请勿重复操作") public R refreshInvoice(@Valid @RequestBody WalletRechargeInvoiceRefreshDto dto) { walletRechargeInvoiceService.refreshInvoice(dto); return R.ok(true); @@ -68,7 +59,7 @@ public class WalletRechargeInvoiceController { @Operation(summary = "提交申请", description = "提交申请") @SysLog("提交申请") @PostMapping("/apply") - @Idempotent(expireTime = 3, info = "正在申请中,请勿重复操作") + @Idempotent(expireTime = 3, key = "'/walletRechargeInvoice/apply/' + #body.getId()", info = "正在申请中,请勿重复操作") public R apply(@Valid @RequestBody WalletRechargeInvoiceApplyDto body) { walletRechargeInvoiceService.apply(body); return R.ok(true); @@ -83,6 +74,7 @@ public class WalletRechargeInvoiceController { @GetMapping("/back") @Operation(summary = "退回作废发票") + @Idempotent(expireTime = 3, key = "'/walletRechargeInvoice/back/' + #id", info = "正在退回中,请勿重复操作") public R backInvoice(@RequestParam("id") Long id) { walletRechargeInvoiceService.backInvoice(id); return R.ok(); @@ -90,6 +82,7 @@ public class WalletRechargeInvoiceController { @PostMapping("/bind-invoice") @Operation(summary = "绑定发票") + @Idempotent(expireTime = 3, key = "'/walletRechargeInvoice/bind-invoice/' + #dto.getApplyId()", info = "正在申请中,请勿重复操作") public R bindInvoice(@Valid @RequestBody WalletRechargeBindInvoiceDto dto) { walletRechargeInvoiceService.bindInvoice(dto); return R.ok();