<?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.system.mapper.UserWalletMapper">

    <resultMap type="UserWallet" id="UserWalletResult">
        <result property="id"    column="id"    />
        <result property="userId"    column="userId"    />
        <result property="pointsWallet"    column="points_wallet"    />
        <result property="balanceWallet"    column="balance_wallet"    />
        <result property="version"    column="version"   />
    </resultMap>

    <sql id="selectUserWalletVo">
        select id, userId, points_wallet, balance_wallet, version from user_wallet
    </sql>

    <select id="selectUserWalletList" parameterType="UserWallet" resultMap="UserWalletResult">
        <include refid="selectUserWalletVo"/>
        <where>
            <if test="pointsWallet != null "> and points_wallet = #{pointsWallet}</if>
            <if test="balanceWallet != null "> and balance_wallet = #{balanceWallet}</if>
        </where>
    </select>

    <select id="selectUserWalletById" parameterType="Long" resultMap="UserWalletResult">
        <include refid="selectUserWalletVo"/>
        where id = #{id}
    </select>

    <insert id="insertUserWallet" parameterType="UserWallet" useGeneratedKeys="true" keyProperty="id">
        insert into user_wallet
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="userId != null">userId,</if>
            <if test="pointsWallet != null">points_wallet,</if>
            <if test="balanceWallet != null">balance_wallet,</if>
            <if test="version != null">version,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="userId != null">#{userId},</if>
            <if test="pointsWallet != null">#{pointsWallet},</if>
            <if test="balanceWallet != null">#{balanceWallet},</if>
            <if test="version != null">#{version},</if>
        </trim>
    </insert>

    <update id="updateUserWallet" parameterType="UserWallet">
        update user_wallet
        <trim prefix="SET" suffixOverrides=",">
            <if test="userId != null">userId = #{userId},</if>
            <if test="pointsWallet != null">points_wallet = #{pointsWallet},</if>
            <if test="balanceWallet != null">balance_wallet = #{balanceWallet},</if>
            <if test="version != null">version = #{version},</if>
        </trim>
        where id = #{id}
    </update>

    <!-- 检查余额是否足够 -->
    <select id="checkBalanceSufficient" resultType="boolean">
        select 
        <if test="pointsWallet != null and balanceWallet != null">
            (points_wallet + (#{pointsWallet}) >= 0) and (balance_wallet + (#{balanceWallet}) >= 0)
        </if>
        <if test="pointsWallet != null and balanceWallet == null">
            points_wallet + (#{pointsWallet}) >= 0
        </if>
        <if test="pointsWallet == null and balanceWallet != null">
            balance_wallet + (#{balanceWallet}) >= 0
        </if>
        from user_wallet 
        where id = #{id} and version = #{version}
    </select>

    <!-- 获取余额检查结果详情 -->
    <select id="getBalanceCheckResult" resultType="map">
        select 
            id,
            points_wallet as currentPointsWallet,
            balance_wallet as currentBalanceWallet,
            version,
            <if test="pointsWallet != null">
                points_wallet + (#{pointsWallet}) as afterPointsWallet,
                (points_wallet + (#{pointsWallet}) >= 0) as pointsWalletSufficient,
            </if>
            <if test="balanceWallet != null">
                balance_wallet + (#{balanceWallet}) as afterBalanceWallet,
                (balance_wallet + (#{balanceWallet}) >= 0) as balanceWalletSufficient,
            </if>
            <if test="pointsWallet != null and balanceWallet != null">
                ((points_wallet + (#{pointsWallet}) >= 0) and (balance_wallet + (#{balanceWallet}) >= 0)) as allSufficient
            </if>
            <if test="pointsWallet != null and balanceWallet == null">
                (points_wallet + (#{pointsWallet}) >= 0) as allSufficient
            </if>
            <if test="pointsWallet == null and balanceWallet != null">
                (balance_wallet + (#{balanceWallet}) >= 0) as allSufficient
            </if>
        from user_wallet 
        where id = #{id} and version = #{version}
    </select>

    <update id="updateUserWalletWithLock">
        update user_wallet 
        <set>
            version = version+1,
            <if test="pointsWallet != null">points_wallet = points_wallet + (#{pointsWallet}),</if>
            <if test="balanceWallet != null">balance_wallet = balance_wallet + (#{balanceWallet}),</if>
        </set>
        <where>
            id = #{id} and version = #{version}
            <if test="pointsWallet != null">and points_wallet + (#{pointsWallet}) >= 0</if>
            <if test="balanceWallet != null">and balance_wallet + (#{balanceWallet}) >= 0</if>
        </where>
    </update>

    <delete id="deleteUserWalletById" parameterType="Long">
        delete from user_wallet where id = #{id}
    </delete>

    <delete id="deleteUserWalletByIds" parameterType="String">
        delete from user_wallet where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>
