main^2^2
黄海 11 months ago
parent b4b600ed2f
commit 7f50807170

@ -332,7 +332,7 @@ public class UserRefundServiceImpl {
return OutData.ERROR("该账户不允许在线退款。"); return OutData.ERROR("该账户不允许在线退款。");
} }
} }
//检查是否存在未结束的订单 //检查是否存在未结束的订单,存在未结束的订单,则不能申请退款
int chargeOrderNum = userRefundMapper.countOrderFromRefund(userId); int chargeOrderNum = userRefundMapper.countOrderFromRefund(userId);
if (chargeOrderNum > 0) { if (chargeOrderNum > 0) {
return OutData.ERROR("存在未结束的订单,请等订单结束后申请!"); return OutData.ERROR("存在未结束的订单,请等订单结束后申请!");
@ -342,7 +342,7 @@ public class UserRefundServiceImpl {
Map rechargeMap; Map rechargeMap;
double refundFee; double refundFee;
//t_user_refund //t_user_refund
//用户退款表 //用户申请退款表
String orderNO = "UT" + Tools.getDate4() + userId;//订单号 String orderNO = "UT" + Tools.getDate4() + userId;//订单号
refundMap.put("userId", userId); refundMap.put("userId", userId);
refundMap.put("order_no", orderNO); refundMap.put("order_no", orderNO);
@ -353,12 +353,13 @@ public class UserRefundServiceImpl {
refundMap.put("comm", "");//备注 refundMap.put("comm", "");//备注
refundMap.put("create_time", now); refundMap.put("create_time", now);
refundMap.put("update_time", now); refundMap.put("update_time", now);
userRefundMapper.insertUserRefund(refundMap);//插入退款表 userRefundMapper.insertUserRefund(refundMap);//插入用户申请退款表
//退款金额 //退款金额
if (null == cash) { if (null == cash) {
cash = "0.0"; cash = "0.0";
} }
//用户可以申请退款的金额
Double userAbleReal = Double.parseDouble(cash); Double userAbleReal = Double.parseDouble(cash);
//进行所有充值订单的退款合法性校验 //进行所有充值订单的退款合法性校验
@ -370,21 +371,34 @@ public class UserRefundServiceImpl {
//进行退款订单是否自动退款的判断 //进行退款订单是否自动退款的判断
boolean autoRefund = false; boolean autoRefund = false;
//产品管理配置+数据字典配置+退款金额<=退款阈值 才能自动退款 //产品管理配置+数据字典配置+退款金额<=退款阈值 才能自动退款
// select value from t_biz_parameter where state = 1 and code = 'automatic_refund.enabled'
// 系统当前值是0即不开启自动退款
String autoRefundCheck = commonMapper.getAutoRefundCheck(Const.AUTO_REFUND_CHECK); String autoRefundCheck = commonMapper.getAutoRefundCheck(Const.AUTO_REFUND_CHECK);
//自动退款阈值
// select * from t_dict where code='automaticRefundAmount'
// select dict_key from t_dict where code = 'automaticRefundAmount' and parent_id != 0 and is_deleted = 0 and is_sealed = 0 order by id desc limit 1
// 在数据库中就没有找到这个自动退款的阀值,原因不明
String autoRefundAmount = commonMapper.getAutoRefundAmount(Const.AUTOMATIC_REFUND_AMOUNT); String autoRefundAmount = commonMapper.getAutoRefundAmount(Const.AUTOMATIC_REFUND_AMOUNT);
if (StringUtils.isNotEmpty(autoRefundCheck) && Const.AUTOMATIC_REFUND_OPEN.equals(autoRefundCheck) && StringUtils.isNotEmpty(autoRefundAmount) if (StringUtils.isNotEmpty(autoRefundCheck) //自动退款标识存在
&& Const.AUTOMATIC_REFUND_OPEN.equals(autoRefundCheck)//而且自动退款标识为1目前数据库中是0
&& StringUtils.isNotEmpty(autoRefundAmount)//自动退款阀值不为空
//申请退款的金额小于自动退款阀值
&& BigDecimal.valueOf(userAbleReal).doubleValue() <= (new BigDecimal(autoRefundAmount)).doubleValue()) { && BigDecimal.valueOf(userAbleReal).doubleValue() <= (new BigDecimal(autoRefundAmount)).doubleValue()) {
autoRefund = true; autoRefund = true;//可以自动退款
} }
UserAccount uaInfo = userAccountMapper.selectAccount(userId); UserAccount uaInfo = userAccountMapper.selectAccount(userId);
//如果退款金额大于用户充值金额
//Q:为什么会出现这样的情况?
//t_user_account表中有一个字段ua_real_balance表示用户可用退款金额
// 这里这样判断应该是怕因为程序BUG导致退款金额大于用户充值金额对系统的一种保护策略
if (userAbleReal > uaInfo.getUa_real_balance()) {//用户充值金额 if (userAbleReal > uaInfo.getUa_real_balance()) {//用户充值金额
userAbleReal = uaInfo.getUa_real_balance();//退款金额不能大于用户充值金额 userAbleReal = uaInfo.getUa_real_balance();//退款金额不能大于用户充值金额
} }
//遍历每个退款申请
for (int i = 0; i < ids.length; i++) { for (int i = 0; i < ids.length; i++) {
String idParam = ids[i]; String idParam = ids[i];
if (userAbleReal <= 0) { if (userAbleReal <= 0) {//userAbleReal在循环内应该是逐渐变小当不再需要继续退款的时候跳出循环
break; break;
} }
PayConfig payBean = payRepository.findByPridAndUserId(idParam, userId); PayConfig payBean = payRepository.findByPridAndUserId(idParam, userId);
@ -398,11 +412,13 @@ public class UserRefundServiceImpl {
return OutData.ERROR("退款失败"); return OutData.ERROR("退款失败");
} }
Double payMoney = payBean.getPayMoney(); Double payMoney = payBean.getPayMoney();
//本笔充值金额大于用户可以退款的金额
if (payMoney > userAbleReal) { if (payMoney > userAbleReal) {
//本次充值金额部分退掉就够了
refundFee = userAbleReal; refundFee = userAbleReal;
// payBean.setRefundMoney(String.valueOf(uaInfo.getUa_real_balance())); // payBean.setRefundMoney(String.valueOf(uaInfo.getUa_real_balance()));
} else { } else {
//本次充值金额全部退掉
refundFee = payBean.getPayMoney(); refundFee = payBean.getPayMoney();
//payBean.setRefundMoney(String.valueOf(payBean.getPayMoney())); //payBean.setRefundMoney(String.valueOf(payBean.getPayMoney()));
} }

@ -2,72 +2,88 @@
#### 原始需求 #### 原始需求
- 没有参加充值活动并且账户余额小于50元后台可以设置,系统自动退款原路返回。 - 没有参加充值活动,并且,账户余额小于$50$元(后台可以设置),系统自动退款原路返回。
- 个人用户----用户充值 ---- 充电消费----余额到用户钱包,可以下次消费,如果没有参加充值送券活动,则该笔充值可以申请退款。后审核信息无误,可以原路退回。 - 个人用户----用户充值 ---- 充电消费----余额到用户钱包,可以下次消费,如果没有参加充值送券活动,则该笔充值可以申请退款。后审核信息无误,可以原路退回。
#### 开发思路 #### 源码解读与分析
- 微信小程序端调用 /financeapi/userRefund/recDataListNew 获取可以退款的订单列表。 **$Q_1:$ 用户的账户是通过什么方式进行充值的?**
><h3><font color='red'>解释:原来就有的接口,必须小程序来调用</font></h3> 答:每次充值,是存在一个充值账单的,表名:$t\_account\_recharge$,每次充值都要向这张表中添加一条充值记录,充值有两种情况,一种是不参加活动的,另一种是参加活动的,在系统设计之初就明确了参加活动的充值单是不能参加退款的,后面还会有详细的论述。
- 微信小程序将拿到的订单ids传递给后端接口 xxxxx: **$Q_2$:账户余额是怎么产生的?有什么特殊需要注意的地方?**
接口逻辑如下
(1) 获取允许退款的余额阀值,如果小于这个阀值才可以自动退款 - 用户通过$N$次充值,使得账户余额增加,通过$M$次充电消费,使得账户余额减少。
(2) 没有参加过充值活动的 充值时可能因为充值活动等原因,实际得到的金额大于充值金额,最终汇集到余额中。
删除一些无效ID后生成一个新的ids列表返回给微信小程序,告诉小程序,这些是真的可以自动恳求的订单 举个例子:如果用户充了$100$元,因为活动的原因,实得$120$元,那么用户的余额就是$120$元。如果他充电消费了$20$元,那么他的账户余额就是$100$元。很明显,此时账户内的余额是不能进行退款的,要不电站就赔了
所以,系统设计者发现:**不能提供余额退款功能!**
既然不能按余额进行退款,那就不退了吗?人家用户假设充了$30$元,用了$25$元,没有参加活动,有余额$5$元,以后也不想来充电了,电站不提供退款肯定是说不通。
- 微信小程序循环所有ids,调用 /financeapi/userRefund/apply 发起此笔订单的退款申请,这样,在数据库中就生成了这些有效的退款申请单。
><h3><font color='red'>解释:原来就有的接口,必须小程序来调用</font></h3>
系统设计者在这样的前提下,想到不能退款的原因是:参加了充值活动造成余额是虚的,是不是可以把参加活动的充值单不参加讨论就能解决问题呢?
按这个思路思考,把充值订单进行区分,划分为两类:
- 微信小程序调用 后端接口yyyyy,将ids作为参数让后端接口把此人的所有已申请的退款记录通过审核。 1. 不参加活动的订单 (有效退款订单)
```html
http://10.10.14.77:7003/financeapi/userRefund/agreeV2?rechargeId=431052&memo=%E6%88%91%E5%90%8C%E6%84%8F&rechargeOperer=superadmin&refundFee=171.03
```
2. 参加活动的订单 (无效退款订单)
同时,系统设计者在用户账户表上就做了分类处理:
![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202408170858077.png)
> **下面是相关的一些细节**
#### 阀值 ### 系统源码上是支持用户申请退款,然后系统自动完成退款的,逻辑也是
tkMoneyFaZhi - 不参加活动的充值
| tkMoneyFaZhi | 退款金额阀值 | 50 | - 低于约定的阀值
| ------------ | ------------ | ---- |
| | | |
- ### 但不清楚为什么现在的配置上没有开启自动退款,需要向快卜的开发人员咨询。
``` ```java
D:\dsWork\YltProject\Ylt\ms-finance\src\main\java\com\charge\finance\controller\RecManageController.java //进行退款订单是否自动退款的判断
``` boolean autoRefund = false;
//产品管理配置+数据字典配置+退款金额<=退款阈值 才能自动退款
// select value from t_biz_parameter where state = 1 and code = 'automatic_refund.enabled'
$Q$:如何知道一条充值订单是不是可以退款? // 系统当前值是0即不开启自动退款
String autoRefundCheck = commonMapper.getAutoRefundCheck(Const.AUTO_REFUND_CHECK);
//自动退款阈值
// select * from t_dict where code='automaticRefundAmount'
// select dict_key from t_dict where code = 'automaticRefundAmount' and parent_id != 0 and is_deleted = 0 and is_sealed = 0 order by id desc limit 1
// 在数据库中就没有找到这个自动退款的阀值,原因不明
String autoRefundAmount = commonMapper.getAutoRefundAmount(Const.AUTOMATIC_REFUND_AMOUNT);
if (StringUtils.isNotEmpty(autoRefundCheck) //自动退款标识存在
&& Const.AUTOMATIC_REFUND_OPEN.equals(autoRefundCheck)//而且自动退款标识为1目前数据库中是0
&& StringUtils.isNotEmpty(autoRefundAmount)//自动退款阀值不为空
//申请退款的金额小于自动退款阀值
&& BigDecimal.valueOf(userAbleReal).doubleValue() <= (new BigDecimal(autoRefundAmount)).doubleValue()) {
autoRefund = true;//可以自动退款
}
用户在申请退款时,如果这笔充值参加了活动,用户就不能选择这笔充值退款。
$refund\_state$ $6$款状态0未退款 1已退款 2 退款失败 3退款申请审核 4未退款驳回 5建帮活动不可退款 ...
![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202408151410729.png)
//自动退款逻辑
```sql if (autoRefund) {
select * from t_account_recharge where user_id=53958 and refund_state=6 order by id desc autoRefundAsync(payBean.getId(), refundReason);
}
``` ```
![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202408170846535.png)

Loading…
Cancel
Save