V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
zxr615
V2EX  ›  问与答

有什么好点的顺序扣款实现方案

  •  1
     
  •   zxr615 · 2020-08-26 00:08:01 +08:00 · 1099 次点击
    这是一个创建于 1555 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在货币体系有:Q 币、Q 点、点券

    例小明账户:Q 币:30Q 点:20 点券:60

    现在有一个订单需要扣 100 元,要实现顺序扣款成功,要怎么实现比较好,现在的实现方式感觉很傻。

    目前的实现方法:

    应扣余额==100 如果账户余额加起来都不够,false 如果 Q 币足够,则扣除 100 扣款成功,否则扣去全部 Q 币, 结果:应扣余额==70 如果 Q 点大于应扣余额,扣除 Q 点 70 返回成功,否则扣除全部 Q 点 结果:应扣余额==50 如果点券大于应扣余额,扣除点券 50,否则扣除全部点券 结果:应扣余额==0 账户剩余:0 Q 币:0 Q 点:10 点券 事务提交

    以下是伪代码

    # 应支付
    payable = 100
    
    # 先查询出用户余额
    user_qb = 30
    user_qd = 20
    user_dq = 100
    
    # 如果余额小于应付款扣款失败
    if ((user_qb + user_qd + user_dq) < payable) {
    	return false;
    }
    
    if(user_qb >= 100) {
    	pay(qb, 100)
    	payable = 0;
    } else {
    	pay(qb, user_qb)
    	payable = payable - user_qb
    }
    
    if (payabel > 0 && user_qd >= payabel) {
    	pay(qd, payable)
    	payable = 0;
    } else {
    	pay(qd, user_qd)
    	payable = payable - user_qd;
    }
    
    if (payable > 0) {
    	pay(dq, payable);
    }
    
    db->commit;
    return true;
    
    2 条回复    2020-08-26 09:35:31 +08:00
    2067
        1
    2067  
       2020-08-26 00:59:46 +08:00
    总的来说
    算法描述->伪代码->代码
    应该都是一致的

    个人观点,如果你觉得事务判断代码太复杂,应该从优化判断规则入手
    whileFalse
        2
    whileFalse  
       2020-08-26 09:35:31 +08:00
    你的实现方式足够明确了,也不是很冗长。但如果你想要短一点……

    # 执行读出逻辑
    qb_new = max(0, qb - pay)
    qd_new = max(0, qd - max(0, pay - qb))
    dq_new = dq - max(0, pay - qb - qd)

    if dq_new < 0:
    return False
    else:
    # 执行写入操作
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3132 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 14:40 · PVG 22:40 · LAX 06:40 · JFK 09:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.