From f0818dc99d7f3e22c916ae74b37f354ba7651e7c Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Wed, 8 Jan 2025 16:22:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E9=80=80=E6=AC=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/800pjcloudx_wallet.sql | 46 ++--- .../api/constant/order/HardOrderTypeEnum.java | 7 + .../refund/HardAfterSaleOperateTypeEnum.java | 26 +++ .../constant/refund/HardRefundStatusEnum.java | 16 ++ .../constant/refund/HardSaleStatusEnum.java | 35 ++++ .../hard/api/dto/order/HardDisagreeDto.java | 14 ++ .../api/entity/order/HardAfterSaleEntity.java | 6 +- .../entity/order/HardAfterSaleLogEntity.java | 6 +- .../hard/api/vo/order/HardAfterSaleVo.java | 19 +- .../hard/api/vo/order/HardOrderVo.java | 17 +- pjcloud-hardware/pjcloud-hardware-biz/pom.xml | 6 + .../order/HardAfterSaleController.java | 71 ++++--- .../hard/service/HardAfterSaleService.java | 35 ++++ .../impl/order/HardAfterSaleServiceImpl.java | 185 +++++++++++++++++- .../impl/order/HardCarServiceImpl.java | 4 +- .../impl/order/HardwareOrderServiceImpl.java | 27 ++- .../api/constant/WalletRefundStatusEnum.java | 17 ++ .../dto/recharge/WalletRechargeRefundDto.java | 37 ++++ .../entity/recharge/WalletRechargeEntity.java | 20 +- .../feign/RemoteWalletRechargeService.java | 23 +++ .../feign/RemoteWalletTransactionService.java | 1 - ...mework.cloud.openfeign.FeignClient.imports | 1 + .../recharge/WalletRechargeController.java | 11 ++ .../wallet/mapper/WalletManageMapper.java | 25 +++ .../wallet/service/WalletRechargeService.java | 15 ++ .../impl/WalletTransactionServiceImpl.java | 3 + .../WalletRechargeApplyServiceImpl.java | 4 +- .../recharge/WalletRechargeServiceImpl.java | 39 +++- .../mapper/recharge/WalletRechargeMapper.xml | 2 +- 29 files changed, 653 insertions(+), 65 deletions(-) create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardAfterSaleOperateTypeEnum.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardRefundStatusEnum.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardSaleStatusEnum.java create mode 100644 pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/order/HardDisagreeDto.java create mode 100644 pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletRefundStatusEnum.java create mode 100644 pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargeRefundDto.java create mode 100644 pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargeService.java diff --git a/db/800pjcloudx_wallet.sql b/db/800pjcloudx_wallet.sql index ec5d4e307..308b06571 100644 --- a/db/800pjcloudx_wallet.sql +++ b/db/800pjcloudx_wallet.sql @@ -324,28 +324,30 @@ create table wallet_recharge_package DROP TABLE IF EXISTS wallet_recharge; create table wallet_recharge ( - id bigint NOT NULL COMMENT '编号', - wallet_id bigint NOT NULL COMMENT '会员钱包 id', - total_price int NOT NULL COMMENT '用户实际到账余额,例如充 100 送 20,则该值是 120', - pay_price int NOT NULL COMMENT '实际支付金额', - bonus_price int NOT NULL COMMENT '钱包赠送金额', - package_id bigint NULL COMMENT '充值套餐编号', - pay_status bit default b'0' NOT NULL COMMENT '是否已支付:[0:未支付 1:已经支付过]', - pay_order_id bigint NULL COMMENT '支付订单编号', - pay_channel_code varchar(16) NULL COMMENT '支付成功的支付渠道', - pay_time datetime NULL COMMENT '订单支付时间', - pay_refund_id bigint NULL COMMENT '支付退款单编号', - refund_total_price int default 0 NOT NULL COMMENT '退款金额,包含赠送金额', - refund_pay_price int default 0 NOT NULL COMMENT '退款支付金额', - refund_bonus_price int default 0 NOT NULL COMMENT '退款钱包赠送金额', - refund_time datetime NULL COMMENT '退款时间', - refund_status int default 0 NOT NULL COMMENT '退款状态', - create_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', - create_time datetime DEFAULT NULL COMMENT '创建时间', - update_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人', - update_time datetime DEFAULT NULL COMMENT '修改时间', - del_flag char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记', - tenant_id bigint DEFAULT NULL COMMENT '租户ID', + id bigint NOT NULL COMMENT '编号', + wallet_id bigint NOT NULL COMMENT '会员钱包 id', + total_price int NOT NULL COMMENT '用户实际到账余额,例如充 100 送 20,则该值是 120', + pay_price int NOT NULL COMMENT '实际支付金额', + bonus_price int NOT NULL COMMENT '钱包赠送金额', + package_id bigint NULL COMMENT '充值套餐编号', + pay_status bit default b'0' NOT NULL COMMENT '是否已支付:[0:未支付 1:已经支付过]', + pay_order_id bigint NULL COMMENT '支付订单编号', + pay_channel_code varchar(16) NULL COMMENT '支付成功的支付渠道', + pay_time datetime NULL COMMENT '订单支付时间', + pay_refund_order_id bigint NULL COMMENT '退款订单号', + pay_refund_after_sale_id bigint NULL COMMENT '售后单号id', + pay_refund_code varchar(256) NULL COMMENT '支付退款单code', + refund_total_price int default 0 NOT NULL COMMENT '退款金额,包含赠送金额', + refund_pay_price int default 0 NOT NULL COMMENT '退款支付金额', + refund_bonus_price int default 0 NOT NULL COMMENT '退款钱包赠送金额', + refund_time datetime NULL COMMENT '退款时间', + refund_status char(10) default '0' NOT NULL COMMENT '退款状态', + create_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', + create_time datetime DEFAULT NULL COMMENT '创建时间', + update_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人', + update_time datetime DEFAULT NULL COMMENT '修改时间', + del_flag char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记', + tenant_id bigint DEFAULT NULL COMMENT '租户ID', PRIMARY KEY (id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='会员钱包充值'; diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/order/HardOrderTypeEnum.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/order/HardOrderTypeEnum.java index ad4a5eaf2..da92d1354 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/order/HardOrderTypeEnum.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/order/HardOrderTypeEnum.java @@ -5,6 +5,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import java.util.Arrays; +import java.util.List; /** * 硬件订单类型 @@ -25,4 +26,10 @@ public enum HardOrderTypeEnum { return Arrays.stream(values()).filter(v -> ObjectUtil.equals(type, v.getType())).findFirst().get(); } + public static final List refundList = List.of(BELOW, RESERVE); + + public static boolean isRefund(HardOrderTypeEnum type) { + return refundList.contains(type); + } + } diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardAfterSaleOperateTypeEnum.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardAfterSaleOperateTypeEnum.java new file mode 100644 index 000000000..53883c3e5 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardAfterSaleOperateTypeEnum.java @@ -0,0 +1,26 @@ +package com.bsd.pjcloud.hard.api.constant.refund; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 硬件售后操作类型的枚举 + */ +@AllArgsConstructor +@Getter +public enum HardAfterSaleOperateTypeEnum { + + MEMBER_CREATE("10", "会员申请退款"), + ADMIN_AGREE_APPLY("11", "商家同意退款"), + ADMIN_DISAGREE_APPLY("12", "商家拒绝退款"), + MEMBER_DELIVERY("20", "会员填写退货物流信息,快递公司:{deliveryName},快递单号:{logisticsNo}"), + ADMIN_AGREE_RECEIVE("21", "商家收货"), + ADMIN_DISAGREE_RECEIVE("22", "商家拒绝收货,原因:{reason}"), + ADMIN_REFUND("30", "商家退款"), + MEMBER_CANCEL("40", "会员取消退款"), + ; + + private final String type; + private final String content; +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardRefundStatusEnum.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardRefundStatusEnum.java new file mode 100644 index 000000000..582c0fb52 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardRefundStatusEnum.java @@ -0,0 +1,16 @@ +package com.bsd.pjcloud.hard.api.constant.refund; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public enum HardRefundStatusEnum { + NONE("0", "未售后"), + APPLY("10", "售后中"), + SUCCESS("20", "售后成功"), + REJECT("30", "售后失败"), + ; + private final String status; + private final String name; +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardSaleStatusEnum.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardSaleStatusEnum.java new file mode 100644 index 000000000..834e6c361 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/constant/refund/HardSaleStatusEnum.java @@ -0,0 +1,35 @@ +package com.bsd.pjcloud.hard.api.constant.refund; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Collection; +import java.util.Collections; + +@AllArgsConstructor +@Getter +public enum HardSaleStatusEnum { + /** + * 【申请售后】 + */ + APPLY("10", "申请中", "会员申请退款"), // 有赞的状态提示:退款申请待商家处理 + /** + * 完成退款【退款成功】 + */ + COMPLETE("50", "完成", "商家确认退款"), // 有赞的状态提示:退款成功 + /** + * 【买家取消】 + */ + BUYER_CANCEL("61", "买家取消售后", "会员取消退款"), // 有赞的状态提示:退款关闭 + /** + * 卖家拒绝售后;商家拒绝【商家拒绝】 + */ + SELLER_DISAGREE("62", "卖家拒绝", "商家拒绝退款"), // 有赞的状态提示:商家不同意退款申请 + ; + + public static final Collection APPLYING_STATUSES = Collections.singletonList(APPLY.getStatus()); + + private final String status; + private final String name; + private final String content; +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/order/HardDisagreeDto.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/order/HardDisagreeDto.java new file mode 100644 index 000000000..5825f9617 --- /dev/null +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/dto/order/HardDisagreeDto.java @@ -0,0 +1,14 @@ +package com.bsd.pjcloud.hard.api.dto.order; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class HardDisagreeDto { + @NotNull(message = "售后编号不能为空") + private Long id; + + @NotEmpty(message = "审批备注不能为空") + private String auditReason; +} diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardAfterSaleEntity.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardAfterSaleEntity.java index def0a5756..9379c0514 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardAfterSaleEntity.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardAfterSaleEntity.java @@ -3,8 +3,7 @@ package com.bsd.pjcloud.hard.api.entity.order; import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; +import lombok.*; import com.bsd.pjcloud.common.core.util.TenantTable; import java.time.LocalDateTime; @@ -14,6 +13,9 @@ import java.time.LocalDateTime; * @author dzc * @date 2025-01-07 17:23:08 */ +@Builder +@AllArgsConstructor +@NoArgsConstructor @Data @TenantTable @TableName("hard_after_sale") diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardAfterSaleLogEntity.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardAfterSaleLogEntity.java index 28b89f3ab..d61f7d264 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardAfterSaleLogEntity.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardAfterSaleLogEntity.java @@ -3,8 +3,7 @@ package com.bsd.pjcloud.hard.api.entity.order; import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; +import lombok.*; import com.bsd.pjcloud.common.core.util.TenantTable; import java.time.LocalDateTime; @@ -14,6 +13,9 @@ import java.time.LocalDateTime; * @author dzc * @date 2025-01-07 17:23:25 */ +@Builder +@AllArgsConstructor +@NoArgsConstructor @Data @TenantTable @TableName("hard_after_sale_log") diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/order/HardAfterSaleVo.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/order/HardAfterSaleVo.java index ec478e9a1..2e0a6528d 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/order/HardAfterSaleVo.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/order/HardAfterSaleVo.java @@ -1,8 +1,25 @@ package com.bsd.pjcloud.hard.api.vo.order; +import com.bsd.pjcloud.admin.api.vo.base.BaseDeptInterface; +import com.bsd.pjcloud.admin.api.vo.base.BaseUserInterface; import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleEntity; import lombok.Data; @Data -public class HardAfterSaleVo extends HardAfterSaleEntity { +public class HardAfterSaleVo extends HardAfterSaleEntity implements BaseUserInterface, BaseDeptInterface { + /** + * 用户相关 + */ + private String username; + + private String userMobile; + + private String userAvatar; + + /** + * 部门相关 + */ + private Long deptId; + + private String deptName; } diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/order/HardOrderVo.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/order/HardOrderVo.java index f85fa99a3..61590c55f 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/order/HardOrderVo.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/vo/order/HardOrderVo.java @@ -1,8 +1,23 @@ package com.bsd.pjcloud.hard.api.vo.order; +import com.bsd.pjcloud.admin.api.vo.base.BaseDeptInterface; +import com.bsd.pjcloud.admin.api.vo.base.BaseUserInterface; import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity; import lombok.Data; @Data -public class HardOrderVo extends HardOrderEntity { +public class HardOrderVo extends HardOrderEntity implements BaseUserInterface, BaseDeptInterface { + /** + * 用户相关 + */ + private String username; + + private String userMobile; + + private String userAvatar; + + /** + * 部门相关 + */ + private String deptName; } diff --git a/pjcloud-hardware/pjcloud-hardware-biz/pom.xml b/pjcloud-hardware/pjcloud-hardware-biz/pom.xml index 7465116a0..686e24b41 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/pom.xml +++ b/pjcloud-hardware/pjcloud-hardware-biz/pom.xml @@ -116,6 +116,12 @@ 5.7.0 compile + + org.apache.seata + seata-all + 2.1.0 + compile + diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/order/HardAfterSaleController.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/order/HardAfterSaleController.java index 5e9ab3454..a6c00f267 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/order/HardAfterSaleController.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/controller/order/HardAfterSaleController.java @@ -7,9 +7,14 @@ 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.service.PjcloudUser; +import com.bsd.pjcloud.common.security.util.SecurityUtils; import com.bsd.pjcloud.hard.api.dto.order.HardAfterSaleDto; +import com.bsd.pjcloud.hard.api.dto.order.HardDisagreeDto; import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleEntity; +import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleLogEntity; import com.bsd.pjcloud.hard.service.HardAfterSaleService; +import io.swagger.v3.oas.annotations.Parameter; import org.springframework.security.access.prepost.PreAuthorize; import com.bsd.pjcloud.common.excel.annotation.ResponseExcel; import io.swagger.v3.oas.annotations.security.SecurityRequirement; @@ -31,63 +36,83 @@ import java.util.Objects; */ @RestController @RequiredArgsConstructor -@RequestMapping("/hard-after-sale" ) -@Tag(description = "hard-after-sale" , name = "售后订单管理" ) +@RequestMapping("/hard-after-sale") +@Tag(description = "hard-after-sale", name = "售后订单管理") @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) public class HardAfterSaleController { private final HardAfterSaleService hardAfterSaleService; - @Operation(summary = "分页查询" , description = "分页查询" ) - @GetMapping("/page" ) - @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_view')" ) + @GetMapping(value = "/history") + @Operation(summary = "查询售后进度") + public R> history(@RequestParam Long id) { + return R.ok(hardAfterSaleService.getHistory(id)); + } + + @PutMapping("/agree") + @Operation(summary = "同意售后") + public R agreeRefund(@RequestParam Long id) { + PjcloudUser user = SecurityUtils.getUser(); + return R.ok(hardAfterSaleService.agreeAfterSale(user.getId(), id)); + } + + @PutMapping("/disagree") + @Operation(summary = "拒绝售后") + public R disagreeRefund(@RequestBody HardDisagreeDto dto) { + PjcloudUser user = SecurityUtils.getUser(); + return R.ok(hardAfterSaleService.disagreeRefund(user.getId(), dto)); + } + + @Operation(summary = "分页查询", description = "分页查询") + @GetMapping("/page") + @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_view')") public R getHardAfterSalePage(@ParameterObject Page page, @ParameterObject HardAfterSaleEntity hardAfterSale) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); return R.ok(hardAfterSaleService.page(page, wrapper)); } - @Operation(summary = "分页复杂查询" , description = "分页复杂查询" ) - @GetMapping("/page-join" ) - @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_view')" ) + @Operation(summary = "分页复杂查询", description = "分页复杂查询") + @GetMapping("/page-join") + @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_view')") public R pageJoin(@ParameterObject Page page, @ParameterObject HardAfterSaleDto dto) { return R.ok(hardAfterSaleService.pageJoin(page, dto)); } - @Operation(summary = "通过id查询" , description = "通过id查询" ) - @GetMapping("/{id}" ) - @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_view')" ) - public R getById(@PathVariable("id" ) Long id) { + @Operation(summary = "通过id查询", description = "通过id查询") + @GetMapping("/{id}") + @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_view')") + public R getById(@PathVariable("id") Long id) { return R.ok(hardAfterSaleService.getById(id)); } - @Operation(summary = "新增售后订单" , description = "新增售后订单" ) - @SysLog("新增售后订单" ) + @Operation(summary = "新增售后订单", description = "新增售后订单") + @SysLog("新增售后订单") @PostMapping - @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_add')" ) + @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_add')") public R save(@RequestBody HardAfterSaleEntity hardAfterSale) { return R.ok(hardAfterSaleService.save(hardAfterSale)); } - @Operation(summary = "修改售后订单" , description = "修改售后订单" ) - @SysLog("修改售后订单" ) + @Operation(summary = "修改售后订单", description = "修改售后订单") + @SysLog("修改售后订单") @PutMapping - @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_edit')" ) + @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_edit')") public R updateById(@RequestBody HardAfterSaleEntity hardAfterSale) { return R.ok(hardAfterSaleService.updateById(hardAfterSale)); } - @Operation(summary = "通过id删除售后订单" , description = "通过id删除售后订单" ) - @SysLog("通过id删除售后订单" ) + @Operation(summary = "通过id删除售后订单", description = "通过id删除售后订单") + @SysLog("通过id删除售后订单") @DeleteMapping - @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_del')" ) + @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_del')") public R removeById(@RequestBody Long[] ids) { return R.ok(hardAfterSaleService.removeBatchByIds(CollUtil.toList(ids))); } @ResponseExcel @GetMapping("/export") - @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_export')" ) - public List export(HardAfterSaleEntity hardAfterSale,Long[] ids) { + @PreAuthorize("@pms.hasPermission('hard_hardAfterSale_export')") + public List export(HardAfterSaleEntity hardAfterSale, Long[] ids) { return hardAfterSaleService.list(Wrappers.lambdaQuery(hardAfterSale).in(ArrayUtil.isNotEmpty(ids), HardAfterSaleEntity::getId, ids)); } } \ No newline at end of file diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardAfterSaleService.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardAfterSaleService.java index 34c796bb2..ae0f6be7f 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardAfterSaleService.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/HardAfterSaleService.java @@ -3,10 +3,45 @@ package com.bsd.pjcloud.hard.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.bsd.pjcloud.hard.api.dto.order.HardAfterSaleDto; +import com.bsd.pjcloud.hard.api.dto.order.HardDisagreeDto; import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleEntity; +import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleLogEntity; import com.bsd.pjcloud.hard.api.vo.order.HardAfterSaleVo; +import java.util.List; + public interface HardAfterSaleService extends IService { Page pageJoin(Page page, HardAfterSaleDto dto); + + /** + * 获取售后进度 + * + * @param id 售后id + */ + List getHistory(Long id); + + /** + * 退款 + * + * @param afterSaleId 售后id + */ + void refund(Long afterSaleId); + + /** + * 同意售后 + * + * @param userId 用户id + * @param id + */ + Boolean agreeAfterSale(Long userId, Long id); + + /** + * 拒绝售后 + * + * @param userId 用户id + * @param dto + * @return + */ + Boolean disagreeRefund(Long userId, HardDisagreeDto dto); } \ No newline at end of file diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java index d4be740bf..4b0583d53 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java @@ -1,13 +1,49 @@ package com.bsd.pjcloud.hard.service.impl.order; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.extra.spring.SpringUtil; +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; +import com.bsd.pjcloud.admin.api.entity.SysUser; +import com.bsd.pjcloud.admin.api.feign.RemoteDeptService; +import com.bsd.pjcloud.admin.api.feign.RemoteUserService; +import com.bsd.pjcloud.admin.api.utils.DataUtil; +import com.bsd.pjcloud.common.core.util.BeanUtils; +import com.bsd.pjcloud.common.core.util.CollectionUtils; +import com.bsd.pjcloud.common.core.util.R; +import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum; +import com.bsd.pjcloud.hard.api.constant.order.HardOrderTypeEnum; +import com.bsd.pjcloud.hard.api.constant.refund.HardAfterSaleOperateTypeEnum; +import com.bsd.pjcloud.hard.api.constant.refund.HardRefundStatusEnum; +import com.bsd.pjcloud.hard.api.constant.refund.HardSaleStatusEnum; import com.bsd.pjcloud.hard.api.dto.order.HardAfterSaleDto; +import com.bsd.pjcloud.hard.api.dto.order.HardDisagreeDto; import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleEntity; +import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleLogEntity; +import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity; import com.bsd.pjcloud.hard.api.vo.order.HardAfterSaleVo; +import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo; +import com.bsd.pjcloud.hard.mapper.order.HardAfterSaleLogMapper; import com.bsd.pjcloud.hard.mapper.order.HardAfterSaleMapper; import com.bsd.pjcloud.hard.service.HardAfterSaleService; +import com.bsd.pjcloud.hard.service.HardOrderService; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundDto; +import com.bsd.pjcloud.wallet.api.feign.RemoteWalletRechargeService; +import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeVo; +import io.seata.spring.annotation.GlobalTransactional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; /** * 售后订单 @@ -15,11 +51,158 @@ import org.springframework.stereotype.Service; * @author dzc * @date 2025-01-07 17:23:08 */ +@Validated +@Slf4j +@RequiredArgsConstructor @Service public class HardAfterSaleServiceImpl extends ServiceImpl implements HardAfterSaleService { + private final HardAfterSaleLogMapper hardAfterSaleLogMapper; + private final HardOrderService hardOrderService; + + private final RemoteUserService userService; + private final RemoteDeptService deptService; + private final RemoteWalletRechargeService walletRechargeService; + + @Override public Page pageJoin(Page page, HardAfterSaleDto dto) { - return baseMapper.pageJoin(page, dto); + Page list = baseMapper.pageJoin(page, dto); + if (ObjectUtil.isNotEmpty(list.getRecords())) { + // 用户 + List userIds = list.getRecords().stream().map(HardAfterSaleVo::getUserId).distinct().toList(); + R> userList = userService.getUserById(new ArrayList<>(userIds)); + if (ObjectUtil.isNotEmpty(userList.getData())) { + DataUtil.convertUserList(list.getRecords(), CollectionUtils.convertMap(userList.getData(), SysUser::getUserId)); + } + // 部门 + List deptIds = list.getRecords().stream().map(HardAfterSaleVo::getDeptId).distinct().toList(); + R> deptList = deptService.getDeptByDeptIds(deptIds); + if (ObjectUtil.isNotEmpty(deptList.getData())) { + DataUtil.convertDeptList(list.getRecords(), deptList.getData()); + } + } + return list; + } + + @Override + public List getHistory(Long id) { + return hardAfterSaleLogMapper.selectList(new LambdaQueryWrapper() + .eq(HardAfterSaleLogEntity::getAfterSaleId, id) + ); + } + + @Override + @GlobalTransactional + @Transactional(rollbackFor = Exception.class) + public void refund(Long afterSaleId) { + HardAfterSaleEntity afterSale = baseMapper.selectById(afterSaleId); + if (ObjectUtil.isEmpty(afterSale)) throw new RuntimeException("售后订单不存在"); + // 校验订单是否可以退款 + HardOrderVo order = validateOrderCanRefund(afterSale.getOrderId()); + // 生成退款单号 + String refundCode = "hard_" + order.getId(); + // 创建退款单 + WalletRechargeRefundDto hardRefundDto = WalletRechargeRefundDto.builder().orderId(order.getId()).afterSaleId(afterSale.getId()).refundCode(refundCode).reason("订单退款").price(order.getPayPrice()).build(); + R walletRefundResult = walletRechargeService.refund(hardRefundDto); + WalletRechargeVo walletRefund = Optional.of(walletRefundResult).map(R::getData).orElseThrow(() -> new RuntimeException("钱包退款错误")); + HardOrderEntity updateObj = HardOrderEntity.builder() + .id(order.getId()) + .orderStatus(HardOrderStatusEnum.REFUND.getType()) + .refundStatus(HardRefundStatusEnum.SUCCESS.getStatus()) + .payRefundId(walletRefund.getId()) + .refundPrice(order.getPayPrice()) + .refundTime(LocalDateTime.now()) + .build(); + hardOrderService.updateById(updateObj); + } + + @Override + public Boolean agreeAfterSale(Long userId, Long id) { + HardAfterSaleEntity afterSale = validateAfterSaleAuditable(id); + HardOrderEntity order = hardOrderService.getById(afterSale.getOrderId()); + if (order == null) throw new RuntimeException("设备订单不存在"); + // 更新售后单的状态 + HardAfterSaleEntity updateRefundObj = HardAfterSaleEntity.builder() + .id(id) + .status(HardSaleStatusEnum.COMPLETE.getStatus()) + .auditUserId(userId) + .auditTime(LocalDateTime.now()) + .build(); + baseMapper.updateById(updateRefundObj); + // 记录售后日志 + HardAfterSaleLogEntity saveLogObj = HardAfterSaleLogEntity.builder() + .afterSaleId(afterSale.getId()) + .userId(userId) + .operateType(HardAfterSaleOperateTypeEnum.ADMIN_AGREE_APPLY.getType()) + .beforeStatus(order.getOrderStatus()) + .afterStatus(order.getOrderStatus()) + .content(HardSaleStatusEnum.COMPLETE.getContent()) + .build(); + hardAfterSaleLogMapper.insert(saveLogObj); + // 执行退款 + getSelf().refund(updateRefundObj.getId()); + return true; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean disagreeRefund(Long userId, HardDisagreeDto dto) { + HardAfterSaleEntity afterSale = validateAfterSaleAuditable(dto.getId()); + HardOrderEntity order = hardOrderService.getById(afterSale.getOrderId()); + if (order == null) throw new RuntimeException("设备订单不存在"); + // 更新售后单的状态 + HardAfterSaleEntity updateRefundObj = HardAfterSaleEntity.builder() + .id(dto.getId()) + .status(HardSaleStatusEnum.SELLER_DISAGREE.getStatus()) + .auditUserId(userId) + .auditTime(LocalDateTime.now()) + .applyReason(dto.getAuditReason()) + .build(); + baseMapper.updateById(updateRefundObj); + // 记录售后日志 + HardAfterSaleLogEntity saveLogObj = HardAfterSaleLogEntity.builder() + .afterSaleId(afterSale.getId()) + .userId(userId) + .operateType(HardAfterSaleOperateTypeEnum.ADMIN_DISAGREE_APPLY.getType()) + .beforeStatus(order.getOrderStatus()) + .afterStatus(order.getOrderStatus()) + .content(HardSaleStatusEnum.SELLER_DISAGREE.getContent()) + .build(); + hardAfterSaleLogMapper.insert(saveLogObj); + // 更新交易订单项的售后状态为【售后失败】 + HardOrderEntity updateOrderObj = HardOrderEntity.builder().id(order.getId()).refundStatus(HardRefundStatusEnum.REJECT.getStatus()).refundTime(LocalDateTime.now()).build(); + hardOrderService.updateById(updateOrderObj); + return true; + } + + // 校验订单是否可以退款 + private HardOrderVo validateOrderCanRefund(Long orderId) { + HardOrderEntity order = hardOrderService.getById(orderId); + if (ObjectUtil.isEmpty(order)) throw new RuntimeException("示例订单不存在"); + HardOrderVo orderVo = BeanUtils.toBean(order, HardOrderVo.class); + // 检查是否可以退款 + HardOrderTypeEnum orderTypeEnum = HardOrderTypeEnum.valueOfByType(order.getOrderType()); + if (HardOrderTypeEnum.isRefund(orderTypeEnum)) { + throw new RuntimeException("该订单类型不支持退款"); + } + // 校验订单是否已退款 + if (ObjectUtil.isNotEmpty(order.getPayRefundId())) { + throw new RuntimeException("发起退款失败,示例订单已退款"); + } + return orderVo; + } + + private HardAfterSaleEntity validateAfterSaleAuditable(Long id) { + HardAfterSaleEntity afterSale = baseMapper.selectById(id); + if (afterSale == null) throw new RuntimeException("售后单不存在"); + if (ObjectUtil.notEqual(afterSale.getStatus(), HardSaleStatusEnum.APPLY.getStatus())) { + throw new RuntimeException("审批失败,售后状态不处于审批中"); + } + return afterSale; + } + + private HardAfterSaleServiceImpl getSelf() { + return SpringUtil.getBean(getClass()); } } \ No newline at end of file diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardCarServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardCarServiceImpl.java index 7660c91cd..2c25c1132 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardCarServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardCarServiceImpl.java @@ -5,10 +5,8 @@ import cn.hutool.extra.spring.SpringUtil; 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.canteen.api.feign.RemoteCanteenSpuService; import com.bsd.pjcloud.canteen.api.feign.RemoteOnlineCanteenSpuService; import com.bsd.pjcloud.canteen.entity.CanteenOnlineSpuEntity; -import com.bsd.pjcloud.canteen.entity.CanteenSpuEntity; import com.bsd.pjcloud.common.core.util.BeanUtils; import com.bsd.pjcloud.hard.api.constant.HardTypeEnum; import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum; @@ -110,7 +108,7 @@ public class HardCarServiceImpl extends ServiceImpl { // 查询食堂商品 - List supList = onlineCanteenSpuService.getSpuListByIds(productIds).getData(); + List supList = onlineCanteenSpuService.getSpuListByIds(productIds).getData(); AtomicInteger canteenTotalPrice = new AtomicInteger(); for (HardCreateCarDto v : list) { supList.stream().filter(i -> ObjectUtil.equals(i.getId(), v.getProductId())).findFirst().ifPresent(spu -> { diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardwareOrderServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardwareOrderServiceImpl.java index 1cc546896..3aa0b3025 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardwareOrderServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardwareOrderServiceImpl.java @@ -3,7 +3,13 @@ package com.bsd.pjcloud.hard.service.impl.order; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bsd.pjcloud.admin.api.entity.SysDept; +import com.bsd.pjcloud.admin.api.entity.SysUser; +import com.bsd.pjcloud.admin.api.feign.RemoteDeptService; +import com.bsd.pjcloud.admin.api.feign.RemoteUserService; +import com.bsd.pjcloud.admin.api.utils.DataUtil; import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum; +import com.bsd.pjcloud.common.core.util.CollectionUtils; import com.bsd.pjcloud.common.core.util.R; import com.bsd.pjcloud.hard.api.constant.HardTypeEnum; import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum; @@ -31,6 +37,7 @@ import com.bsd.pjcloud.wallet.api.entity.WalletTransactionEntity; import com.bsd.pjcloud.wallet.api.feign.*; import com.bsd.pjcloud.wallet.api.vo.MchManageVo; import com.bsd.pjcloud.wallet.api.vo.WalletSettingVo; +import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeApplyVo; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -43,6 +50,7 @@ import java.math.RoundingMode; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; /** @@ -67,10 +75,27 @@ public class HardwareOrderServiceImpl extends ServiceImpl pageJoin(Page page, HardOrderDto dto) { - return baseMapper.pageJoin(page, dto); + Page list = baseMapper.pageJoin(page, dto); + if (ObjectUtil.isNotEmpty(list.getRecords())) { + // 用户 + List userIds = list.getRecords().stream().map(HardOrderVo::getUserId).distinct().toList(); + R> userList = userService.getUserById(new ArrayList<>(userIds)); + if (ObjectUtil.isNotEmpty(userList.getData())) { + DataUtil.convertUserList(list.getRecords(), CollectionUtils.convertMap(userList.getData(), SysUser::getUserId)); + } + // 部门 + List deptIds = list.getRecords().stream().map(HardOrderVo::getDeptId).distinct().toList(); + R> deptList = deptService.getDeptByDeptIds(deptIds); + if (ObjectUtil.isNotEmpty(deptList.getData())) { + DataUtil.convertDeptList(list.getRecords(), deptList.getData()); + } + } + return list; } @Override diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletRefundStatusEnum.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletRefundStatusEnum.java new file mode 100644 index 000000000..bd8f9290c --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletRefundStatusEnum.java @@ -0,0 +1,17 @@ +package com.bsd.pjcloud.wallet.api.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum WalletRefundStatusEnum { + + WAITING("0", "未退款"), + SUCCESS("10", "退款成功"), + FAILURE("20", "退款失败"), + ; + + private final String status; + private final String name; +} diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargeRefundDto.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargeRefundDto.java new file mode 100644 index 000000000..7ab691b62 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/recharge/WalletRechargeRefundDto.java @@ -0,0 +1,37 @@ +package com.bsd.pjcloud.wallet.api.dto.recharge; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Data +public class WalletRechargeRefundDto { + + @NotNull(message = "钱包id不能为空") + private Long walletId; + + @NotNull(message = "订单编号不能为空") + private Long orderId; + + @NotNull(message = "售后订单id不能为空") + private Long afterSaleId; + + @NotEmpty(message = "退款code不能为空") + private String refundCode; + + @NotEmpty(message = "退款描述不能为空") + @Length(max = 128, message = "退款描述长度不能超过 128") + private String reason; + + @NotNull(message = "退款金额不能为空") + @Min(value = 1, message = "退款金额必须大于零") + private Integer price; +} diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/recharge/WalletRechargeEntity.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/recharge/WalletRechargeEntity.java index 1b5da70ab..fe5dda8a6 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/recharge/WalletRechargeEntity.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/recharge/WalletRechargeEntity.java @@ -79,10 +79,22 @@ public class WalletRechargeEntity extends Model { private LocalDateTime payTime; /** - * 支付退款单编号 + * 退款订单号 */ - @Schema(description = "支付退款单编号") - private Long payRefundId; + @Schema(description = "退款订单号") + private Long payRefundOrderId; + + /** + * 售后单号 + */ + @Schema(description = "售后单号") + private Long payRefundAfterSaleId; + + /** + * 支付退款单code + */ + @Schema(description = "支付退款单code") + private String payRefundCode; /** * 退款金额,包含赠送金额 @@ -112,7 +124,7 @@ public class WalletRechargeEntity extends Model { * 退款状态 */ @Schema(description = "退款状态") - private Integer refundStatus; + private String refundStatus; /** * 创建人 diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargeService.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargeService.java new file mode 100644 index 000000000..21d538928 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletRechargeService.java @@ -0,0 +1,23 @@ +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.wallet.api.dto.recharge.WalletRechargeRefundDto; +import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeVo; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(contextId = "remoteWalletRechargeService", value = ServiceNameConstants.WALLET_SERVICE) +public interface RemoteWalletRechargeService { + + /** + * 退款 + * + * @param dto + * @return + */ + @PostMapping("/wallet-recharge/refund") + R refund(@RequestBody WalletRechargeRefundDto dto); + +} diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletTransactionService.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletTransactionService.java index 0c508bc0f..4ae83e223 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletTransactionService.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/feign/RemoteWalletTransactionService.java @@ -5,7 +5,6 @@ import com.bsd.pjcloud.common.core.util.R; import com.bsd.pjcloud.common.feign.annotation.NoToken; import com.bsd.pjcloud.wallet.api.dto.WalletBalanceTransactionDto; import com.bsd.pjcloud.wallet.api.entity.WalletTransactionEntity; -import com.bsd.pjcloud.wallet.api.vo.WalletSettingVo; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody; diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports b/pjcloud-wallet/pjcloud-wallet-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports index d586cd832..a79583531 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports @@ -1,5 +1,6 @@ com.bsd.pjcloud.wallet.api.feign.RemoteWalletService com.bsd.pjcloud.wallet.api.feign.RemoteCodeUseService +com.bsd.pjcloud.wallet.api.feign.RemoteWalletRechargeService com.bsd.pjcloud.wallet.api.feign.RemoteMchService com.bsd.pjcloud.wallet.api.feign.RemoteWalletSettingService com.bsd.pjcloud.wallet.api.feign.RemoteWalletTransactionService \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeController.java index 487c9c8d8..5d65384ee 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/recharge/WalletRechargeController.java @@ -8,9 +8,12 @@ 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.wallet.api.dto.recharge.WalletRechargeDto; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundDto; import com.bsd.pjcloud.wallet.api.dto.recharge.app.WalletAppRechargeDto; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeEntity; +import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeVo; import com.bsd.pjcloud.wallet.service.WalletRechargeService; +import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import com.bsd.pjcloud.common.excel.annotation.ResponseExcel; import io.swagger.v3.oas.annotations.security.SecurityRequirement; @@ -38,6 +41,14 @@ public class WalletRechargeController { private final WalletRechargeService walletRechargeService; + /* ************************************* start 远程调用 start ************************************* */ + @Operation(summary = "远程调用-退款", description = "远程调用-退款") + @PostMapping("/refund") + public R refund(@Valid @RequestBody WalletRechargeRefundDto dto) { + return R.ok(walletRechargeService.refund(dto)); + } + /* ************************************* end 远程调用 end ************************************* */ + /* ************************************* start app start ************************************* */ @Operation(summary = "模拟充值", description = "模拟充值") @PostMapping("/app/create") 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 0dab91775..d47840b53 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 @@ -14,6 +14,12 @@ import org.apache.ibatis.annotations.Param; @Mapper public interface WalletManageMapper extends PjcloudBaseMapper { + /** + * 当消费时候, 更新钱包 + * + * @param id 钱包 id + * @param price 消费金额 + */ default int updateWhenConsumption(Long id, Integer price) { LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() .setSql(" balance = balance - " + price + ", total_expense = total_expense + " + price) @@ -22,6 +28,25 @@ public interface WalletManageMapper extends PjcloudBaseMapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .setSql(" balance = balance + " + price + ", total_expense = total_expense - " + price) + .eq(WalletManageEntity::getId, id); + return update(null, lambdaUpdateWrapper); + } + + /** + * 当充值的时候,更新钱包 + * + * @param id 钱包 id + * @param price 钱包金额 + */ default int updateWhenRecharge(Long id, Integer price) { LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() .setSql(" balance = balance + " + price + ", total_recharge = total_recharge + " + price) 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 63ffb7e99..088e85468 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 @@ -3,6 +3,7 @@ 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.WalletRechargeDto; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundDto; import com.bsd.pjcloud.wallet.api.dto.recharge.app.WalletAppRechargeDto; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeEntity; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeVo; @@ -17,4 +18,18 @@ public interface WalletRechargeService extends IService { * @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/impl/WalletTransactionServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletTransactionServiceImpl.java index 93499be1c..87f88a8f9 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 @@ -105,6 +105,9 @@ public class WalletTransactionServiceImpl extends ServiceImpl userIds = list.getRecords().stream().map(WalletRechargeApplyVo::getUserId).distinct().toList(); R> userList = userService.getUserById(new ArrayList<>(userIds)); if (ObjectUtil.isNotEmpty(userList.getData())) { - DataUtil.convertUserList(page.getRecords(), CollectionUtils.convertMap(userList.getData(), SysUser::getUserId)); + DataUtil.convertUserList(list.getRecords(), CollectionUtils.convertMap(userList.getData(), SysUser::getUserId)); } // 部门 List deptIds = list.getRecords().stream().map(WalletRechargeApplyVo::getDeptId).distinct().toList(); R> deptList = deptService.getDeptByDeptIds(deptIds); if (ObjectUtil.isNotEmpty(deptList.getData())) { - DataUtil.convertDeptList(page.getRecords(), deptList.getData()); + DataUtil.convertDeptList(list.getRecords(), deptList.getData()); } } return list; diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeServiceImpl.java index f083b89fe..278b4ac48 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeServiceImpl.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/recharge/WalletRechargeServiceImpl.java @@ -1,16 +1,19 @@ package com.bsd.pjcloud.wallet.service.impl.recharge; import cn.hutool.core.util.ObjectUtil; +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.common.core.util.BeanUtils; +import com.bsd.pjcloud.hard.api.constant.refund.HardRefundStatusEnum; import com.bsd.pjcloud.wallet.api.constant.WalletBizEnum; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeDto; +import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundDto; import com.bsd.pjcloud.wallet.api.dto.recharge.app.WalletAppRechargeDto; import com.bsd.pjcloud.wallet.api.entity.WalletManageEntity; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeEntity; import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargePackageEntity; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeVo; -import com.bsd.pjcloud.wallet.mapper.WalletManageMapper; import com.bsd.pjcloud.wallet.mapper.recharge.WalletRechargeMapper; import com.bsd.pjcloud.wallet.service.WalletManageService; import com.bsd.pjcloud.wallet.service.WalletRechargePackageService; @@ -23,6 +26,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.time.LocalDateTime; + /** * 会员钱包充值 @@ -67,4 +72,36 @@ public class WalletRechargeServiceImpl extends ServiceImpl() + .eq(WalletRechargeEntity::getPayRefundOrderId, refundId) + ); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public WalletRechargeVo refund(WalletRechargeRefundDto dto) { + // 查询钱包 + WalletManageEntity wallet = walletManageService.getWallet(dto.getWalletId()); + if (ObjectUtil.isEmpty(wallet)) throw new RuntimeException("用户钱包不存在"); + WalletRechargeEntity refund = getByRefundId(dto.getOrderId()); + if (ObjectUtil.isNotEmpty(refund)) throw new RuntimeException("已经存在退款单"); + WalletRechargeEntity recharge = WalletRechargeEntity.builder() + .walletId(wallet.getId()) + .payRefundCode(dto.getRefundCode()) + .payRefundOrderId(dto.getAfterSaleId()) + .payRefundAfterSaleId(dto.getAfterSaleId()) + .refundPayPrice(dto.getPrice()) + .refundBonusPrice(0) + .refundTotalPrice(dto.getPrice()) + .refundStatus(HardRefundStatusEnum.SUCCESS.getStatus()) + .refundTime(LocalDateTime.now()) + .build(); + baseMapper.insert(recharge); + // 增加金额 + walletTransactionService.addWalletBalance(wallet.getId(), recharge.getTotalPrice(), String.valueOf(dto.getAfterSaleId()), WalletBizEnum.REFUND); + return BeanUtils.toBean(recharge, WalletRechargeVo.class); + } } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/recharge/WalletRechargeMapper.xml b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/recharge/WalletRechargeMapper.xml index 050e3d0c2..3bf2bd9ad 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/recharge/WalletRechargeMapper.xml +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/recharge/WalletRechargeMapper.xml @@ -13,7 +13,7 @@ - +