You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4.1 KiB
4.1 KiB
原始需求
- 没有参加充值活动,并且,账户余额小于
50
元(后台可以设置),系统自动退款原路返回。 - 个人用户----用户充值 ---- 充电消费----余额到用户钱包,可以下次消费,如果没有参加充值送券活动,则该笔充值可以申请退款。后面审核信息无误,可以原路退回。
源码解读与分析
Q_1:
用户的账户是通过什么方式进行充值的?
答:每次充值,是存在一个充值账单的,表名:t\_account\_recharge
,每次充值都要向这张表中添加一条充值记录,充值有两种情况,一种是不参加活动的,另一种是参加活动的,在系统设计之初就明确了参加活动的充值单是不能参加退款的,后面还会有详细的论述。
Q_2
:账户余额是怎么产生的?有什么特殊需要注意的地方?
答:
- 用户通过
N
次充值,使得账户余额增加,通过M
次充电消费,使得账户余额减少。
充值时可能因为充值活动等原因,实际得到的金额大于充值金额,最终汇集到余额中。
举个例子:如果用户充了100
元,因为活动的原因,实得120
元,那么用户的余额就是120
元。如果他充电消费了20
元,那么他的账户余额就是100
元。很明显,此时账户内的余额是不能进行退款的,要不电站就赔了。
所以,系统设计者发现:不能提供余额退款功能!
既然不能按余额进行退款,那就不退了吗?人家用户假设充了30
元,用了25
元,没有参加活动,有余额5
元,以后也不想来充电了,电站不提供退款肯定是说不通。
系统设计者在这样的前提下,想到不能退款的原因是:参加了充值活动造成余额是虚的,是不是可以把参加活动的充值单不参加讨论就能解决问题呢?
按这个思路思考,把充值订单进行区分,划分为两类:
-
不参加活动的订单 (有效退款订单)
-
参加活动的订单 (无效退款订单)
同时,系统设计者在用户账户表上就做了分类处理:
系统源码上是支持用户申请退款,然后系统自动完成退款的,逻辑也是
-
不参加活动的充值
-
低于约定的阀值
但不清楚为什么现在的配置上没有开启自动退款,需要向快卜的开发人员咨询。
//进行退款订单是否自动退款的判断
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);
}