puzhibing
2026-09-09 4a5e1477afc559cf870b34e4693f41d85e9580d1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.account.mapper.TChargingCardMapper">
 
    <select id="selectCardPage" resultType="com.ruoyi.account.api.model.TChargingCard">
        SELECT id,
               card_no,
               balance,
               status,
               del_flag,
               create_time,
               create_by,
               update_time,
               update_by
        FROM t_charging_card
        WHERE del_flag = 0
        <if test="query.cardNo != null and query.cardNo != ''">
            AND card_no LIKE CONCAT('%', #{query.cardNo}, '%')
        </if>
        <if test="query.status != null">
            AND status = #{query.status}
        </if>
        ORDER BY create_time DESC, id DESC
    </select>
 
    <select id="selectExportList" resultType="com.ruoyi.account.api.dto.ChargingCardExcelDTO">
        SELECT card_no,
               balance,
               status
        FROM t_charging_card
        WHERE del_flag = 0
        <if test="query.cardNo != null and query.cardNo != ''">
            AND card_no LIKE CONCAT('%', #{query.cardNo}, '%')
        </if>
        <if test="query.status != null">
            AND status = #{query.status}
        </if>
        ORDER BY create_time DESC, id DESC
    </select>
 
    <select id="countByCardNo" resultType="int">
        SELECT COUNT(1)
        FROM t_charging_card
        WHERE card_no = #{cardNo}
        <if test="excludeId != null">
            AND id != #{excludeId}
        </if>
    </select>
 
    <!-- 人工调账:仍保持"增加不超过上限、扣减不低过 0"的运营约束,并叠加充电锁定条件兜底(V0.2 定稿) -->
    <update id="adjustBalance">
        UPDATE t_charging_card
        SET balance = balance
            <choose>
                <when test="type == 1">+ #{amount}</when>
                <otherwise>- #{amount}</otherwise>
            </choose>,
            update_time = NOW(),
            update_by = #{updateBy}
        WHERE del_flag = 0
          AND charging_flag = 0
          AND id IN
        <foreach collection="ids" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
        <choose>
            <when test="type == 1">
                AND balance &lt;= #{maxAmount} - #{amount}
            </when>
            <otherwise>
                AND balance &gt;= #{amount}
            </otherwise>
        </choose>
    </update>
 
    <insert id="insertBalanceRecord">
        INSERT INTO t_charging_card_balance_record
            (card_id, change_type, amount, remark, create_time, create_by)
        VALUES
            (#{cardId}, #{type}, #{amount}, #{remark}, NOW(), #{createBy})
    </insert>
 
    <!-- 锁定:仅空闲卡可锁定,条件更新防止同卡并发多单 -->
    <update id="lockCardForCharging">
        UPDATE t_charging_card
        SET charging_flag = 1,
            charging_order_code = #{orderCode},
            update_time = NOW()
        WHERE id = #{cardId}
          AND del_flag = 0
          AND charging_flag = 0
    </update>
 
    <!-- 解锁:带订单号比对,防止误释放其他进行中订单;已解锁(order_code 已清空)时影响行数为 0 -->
    <update id="unlockCardForCharging">
        UPDATE t_charging_card
        SET charging_flag = 0,
            charging_order_code = NULL,
            update_time = NOW()
        WHERE id = #{cardId}
          AND del_flag = 0
          AND charging_order_code = #{orderCode}
    </update>
 
    <!-- 订单结算原子扣款:只按卡 ID 扣减,禁止带 balance &gt;= amount 下限条件,允许扣成负数 -->
    <update id="deductBalanceByCardId">
        UPDATE t_charging_card
        SET balance = balance - #{amount},
            update_time = NOW()
        WHERE id = #{cardId}
          AND del_flag = 0
    </update>
 
    <!-- 订单结算扣款流水:charging_order_code 唯一索引即扣款幂等键(uk_order_code) -->
    <insert id="insertOrderDeductRecord">
        INSERT INTO t_charging_card_balance_record
            (card_id, change_type, amount, remark, charging_order_code, create_time, create_by)
        VALUES
            (#{cardId}, 3, #{amount}, #{orderCode}, #{orderCode}, NOW(), #{createBy})
    </insert>
 
</mapper>