|
|
|
|
|
|
|
|
#### 原始需求
|
|
|
|
|
|
- 没有参加充值活动,并且,账户余额小于$50$元(后台可以设置),系统自动退款原路返回。
|
|
|
- 个人用户----用户充值 ---- 充电消费----余额到用户钱包,可以下次消费,如果没有参加充值送券活动,则该笔充值可以申请退款。后面审核信息无误,可以原路退回。
|
|
|
|
|
|
|
|
|
|
|
|
#### 源码解读与分析
|
|
|
|
|
|
**$Q_1:$ 用户的账户是通过什么方式进行充值的?**
|
|
|
|
|
|
答:每次充值,是存在一个充值账单的,表名:$t\_account\_recharge$,每次充值都要向这张表中添加一条充值记录,充值有两种情况,一种是不参加活动的,另一种是参加活动的,在系统设计之初就明确了参加活动的充值单是不能参加退款的,后面还会有详细的论述。
|
|
|
|
|
|
|
|
|
|
|
|
**$Q_2$:账户余额是怎么产生的?有什么特殊需要注意的地方?**
|
|
|
|
|
|
答:
|
|
|
|
|
|
- 用户通过$N$次充值,使得账户余额增加,通过$M$次充电消费,使得账户余额减少。
|
|
|
|
|
|
充值时可能因为充值活动等原因,实际得到的金额大于充值金额,最终汇集到余额中。
|
|
|
|
|
|
举个例子:如果用户充了$100$元,因为活动的原因,实得$120$元,那么用户的余额就是$120$元。如果他充电消费了$20$元,那么他的账户余额就是$100$元。很明显,此时账户内的余额是不能进行退款的,要不电站就赔了。
|
|
|
|
|
|
所以,系统设计者发现:**不能提供余额退款功能!**
|
|
|
|
|
|
既然不能按余额进行退款,那就不退了吗?人家用户假设充了$30$元,用了$25$元,没有参加活动,有余额$5$元,以后也不想来充电了,电站不提供退款肯定是说不通。
|
|
|
|
|
|
|
|
|
|
|
|
系统设计者在这样的前提下,想到不能退款的原因是:参加了充值活动造成余额是虚的,是不是可以把参加活动的充值单不参加讨论就能解决问题呢?
|
|
|
|
|
|
按这个思路思考,把充值订单进行区分,划分为两类:
|
|
|
|
|
|
1. 不参加活动的订单 (有效退款订单)
|
|
|
|
|
|
2. 参加活动的订单 (无效退款订单)
|
|
|
|
|
|
同时,系统设计者在用户账户表上就做了分类处理:
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
### 系统源码上是支持用户申请退款,然后系统自动完成退款的,逻辑也是
|
|
|
|
|
|
- 不参加活动的充值
|
|
|
|
|
|
- 低于约定的阀值
|
|
|
|
|
|
### 但不清楚为什么现在的配置上没有开启自动退款,需要向快卜的开发人员咨询。
|
|
|
|
|
|
```java
|
|
|
//进行退款订单是否自动退款的判断
|
|
|
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);
|
|
|
//自动退款阈值
|
|
|
// 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;//可以自动退款
|
|
|
}
|
|
|
|
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
//自动退款逻辑
|
|
|
if (autoRefund) {
|
|
|
autoRefundAsync(payBean.getId(), refundReason);
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|

|
|
|
|