<?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.tmerclub.cloud.user.mapper.UserExtensionMapper">
    <resultMap id="userExtensionMap" type="com.tmerclub.cloud.user.model.UserExtension">
        <id column="user_extension_id" property="userExtensionId"/>
        <result column="user_id" property="userId"/>
        <result column="level" property="level"/>
        <result column="level_type" property="levelType"/>
        <result column="growth" property="growth"/>
        <result column="score" property="score"/>
        <result column="balance" property="balance"/>
        <result column="actual_balance" property="actualBalance"/>
        <result column="allinpay_balance" property="allinpayBalance"/>
        <result column="allinpay_actual_balance" property="allinpayActualBalance"/>
        <result column="allinpay_create" property="allinpayCreate"/>
        <result column="allinpay_real_name_set" property="allinpayRealNameSet"/>
        <result column="allinpay_phone_bind" property="allinpayPhoneBind"/>
        <result column="allinpay_pay_pwd_set" property="allinpayPayPwdSet"/>
        <result column="allinpay_protocol_sign" property="allinpayProtocolSign"/>
        <result column="allinpay_pay_acct_bind" property="allinpayPayAcctBind"/>
        <result column="version" property="version"/>
        <result column="sign_day" property="signDay"/>
        <result column="vip_level" property="vipLevel"/>
    </resultMap>
    <sql id="Vo_Column_List">
        `user_extension_id`,
        `create_time`,
        `update_time`,
        `user_id`,
        `level`,
        `level_type`,
        `growth`,
        `score`,
        `balance`,
        `actual_balance`,
        `allinpay_balance`,
        `allinpay_actual_balance`,
        `allinpay_real_name_set`,
        `allinpay_phone_bind`,
        `allinpay_pay_pwd_set`,
        `allinpay_protocol_sign`,
        `allinpay_pay_acct_bind`,
        `version`,
        `sign_day`
    </sql>
    <select id="list" resultType="com.tmerclub.cloud.user.vo.UserExtensionVO">
        select
        <include refid="Vo_Column_List"/>
        from user_extension
        order by user_extension_id desc
    </select>
    <select id="getByUserExtensionId" resultType="com.tmerclub.cloud.user.model.UserExtension">
        select
        <include refid="Vo_Column_List"/>
        from user_extension
        where user_extension_id = #{userExtensionId}
    </select>
    <insert id="save"  useGeneratedKeys="true" keyProperty="userExtensionId">
        insert into user_extension (
            `user_id`, `level`, `level_type`, `growth`, `score`, `balance`, `actual_balance`,
            `allinpay_balance`, `allinpay_actual_balance`, `allinpay_real_name_set`,
            `allinpay_phone_bind`, `allinpay_pay_pwd_set`, `allinpay_protocol_sign`,
            `allinpay_pay_acct_bind`, `version`, `sign_day` )
        values (
            #{userExtension.userId}, #{userExtension.level}, #{userExtension.levelType}, #{userExtension.growth},
            #{userExtension.score}, #{userExtension.balance}, #{userExtension.actualBalance}, #{userExtension.allinpayBalance},
            #{userExtension.allinpayActualBalance}, #{userExtension.allinpayRealNameSet}, #{userExtension.allinpayPhoneBind},
            #{userExtension.allinpayPayPwdSet}, #{userExtension.allinpayProtocolSign}, #{userExtension.allinpayPayAcctBind},
            #{userExtension.version}, #{userExtension.signDay});
    </insert>

    <select id="filterExistExtensions" resultType="com.tmerclub.cloud.user.model.UserExtension">
        select * from (
        <foreach collection="userExtensions" item="userExtension" separator="UNION ALL">
            SELECT #{userExtension.userId} `user_id`, #{userExtension.level} `level`, #{userExtension.levelType} `level_type`, #{userExtension.growth} `growth`,
            #{userExtension.score} `score`, #{userExtension.balance} `balance`, #{userExtension.actualBalance} `actual_balance`,
            #{userExtension.version} `version`, #{userExtension.signDay} `sign_day`,#{userExtension.vipLevel} `vip_level`,
            #{userExtension.allinpayBalance} allinpay_balance, #{userExtension.allinpayActualBalance} allinpay_actual_balance,
            #{userExtension.allinpayRealNameSet} allinpay_real_name_set, #{userExtension.allinpayPhoneBind} allinpay_phone_bind,
            #{userExtension.allinpayPayPwdSet} allinpay_pay_pwd_set, #{userExtension.allinpayProtocolSign} allinpay_protocol_sign,
            #{userExtension.allinpayPayAcctBind} allinpay_pay_acct_bind
            FROM DUAL
        </foreach>
        ) a WHERE NOT EXISTS (SELECT `user_id` FROM `user_extension` b WHERE a.`user_id` = b.`user_id`)
    </select>

    <insert id="saveBatch" parameterType="java.util.List">
        insert into user_extension (
            `user_id`, `level`, `level_type`, `growth`, `score`, `balance`, `actual_balance`,
            `version`, `sign_day`,`vip_level`, `allinpay_balance`, `allinpay_actual_balance`, `allinpay_real_name_set`, `allinpay_phone_bind`,
            `allinpay_pay_pwd_set`, `allinpay_protocol_sign`, `allinpay_pay_acct_bind` )
        values
            <foreach collection="userExtensions" item="userExtension" separator=",">
                ( #{userExtension.userId}, #{userExtension.level}, #{userExtension.levelType}, #{userExtension.growth},
                #{userExtension.score}, #{userExtension.balance}, #{userExtension.actualBalance}, #{userExtension.version},
                #{userExtension.signDay}, #{userExtension.vipLevel}, #{userExtension.allinpayBalance}, #{userExtension.allinpayActualBalance},
                #{userExtension.allinpayRealNameSet}, #{userExtension.allinpayPhoneBind}, #{userExtension.allinpayPayPwdSet},
                #{userExtension.allinpayProtocolSign}, #{userExtension.allinpayPayAcctBind} )
            </foreach>
    </insert>

    <update id="update">
        update user_extension
        <set>
            <if test="userExtension.level != null">
                `level` = #{userExtension.level},
            </if>
            <if test="userExtension.levelType != null">
                `level_type` = #{userExtension.levelType},
            </if>
            <if test="userExtension.growth != null">
                `growth` = #{userExtension.growth},
            </if>
            <if test="userExtension.score != null">
                `score` = #{userExtension.score},
            </if>
            <if test="userExtension.balance != null">
                `balance` = #{userExtension.balance},
            </if>
            <if test="userExtension.actualBalance != null">
                `actual_balance` = #{userExtension.actualBalance},
            </if>
            <if test="userExtension.allinpayBalance != null">
                `allinpay_balance` = #{userExtension.allinpayBalance},
            </if>
            <if test="userExtension.allinpayActualBalance != null">
                `allinpay_actual_balance` = #{userExtension.allinpayActualBalance},
            </if>
            <if test="userExtension.allinpayCreate != null">
                `allinpay_create` = #{userExtension.allinpayCreate},
            </if>
            <if test="userExtension.allinpayRealNameSet != null">
                `allinpay_real_name_set` = #{userExtension.allinpayRealNameSet},
            </if>
            <if test="userExtension.allinpayPhoneBind != null">
                `allinpay_phone_bind` = #{userExtension.allinpayPhoneBind},
            </if>
            <if test="userExtension.allinpayPayPwdSet != null">
                `allinpay_pay_pwd_set` = #{userExtension.allinpayPayPwdSet},
            </if>
            <if test="userExtension.allinpayProtocolSign != null">
                `allinpay_protocol_sign` = #{userExtension.allinpayProtocolSign},
            </if>
            <if test="userExtension.allinpayPayAcctBind != null">
                `allinpay_pay_acct_bind` = #{userExtension.allinpayPayAcctBind},
            </if>
            <if test="userExtension.version != null">
                `version` = #{userExtension.version} + 1,
            </if>
            <if test="userExtension.signDay != null">
                `sign_day` = #{userExtension.signDay},
            </if>
        </set>
        where user_extension_id = #{userExtension.userExtensionId}
          and `version` = #{userExtension.version}
    </update>
    <delete id="deleteById">
        delete
        from user_extension
        where user_extension_id = #{userExtensionId}
    </delete>

    <update id="updateUserLevel">
        UPDATE
                user_extension
        SET `level` = #{level}
                WHERE level_type = 1
                  AND growth &gt; #{minGrowth}
        <if test="maxGrowth != null">
            AND growth &lt; #{maxGrowth}
        </if>
    </update>

    <update id="updateUserScoreOrGrowth">
        UPDATE user_extension SET `version`   = `version` + 1
                                , update_time = NOW()
        <if test="score != null">
            , score = case when score + #{score} &lt; 0 then 0 ELSE score + #{score} end
        </if>
        <if test="growth != null">
            , growth = case when growth + #{growth} &lt; 0 then 0 ELSE growth + #{growth} end
        </if>
        WHERE user_id IN
        <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
            #{userId}
        </foreach>
    </update>
    <update id="batchUpdateLevelByUserIds" parameterType="java.util.List">
        UPDATE `user_extension` ue
        SET ue.level = (
                SELECT IFNULL( (SELECT `level` FROM `user_level` WHERE level_type = #{levelType} AND need_growth &lt;= ue.growth  ORDER BY `level` DESC LIMIT 1),
                                (SELECT MIN(`level`) FROM `user_level` WHERE level_type = 0)
                ) AS `level`)
                WHERE ue.user_id IN
        <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
            #{userId}
        </foreach>
    </update>
    <update id="updateBatchUserBalanceByUserIds">
        <!-- 用户总余额(balance)是不会减少的 -->
        UPDATE user_extension SET `version`      = `version` + 1
                                , actual_balance = case
                when actual_balance + #{balance} &lt; 0 then 0
                ELSE actual_balance + #{balance} end
        <if test="balance > 0">
            , balance = balance + #{balance}
        </if>
        <if test="now != null">
            , update_time = #{now}
        </if>
        WHERE user_id IN
        <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
            #{userId}
        </foreach>
    </update>

    <select id="getByUserIdsAndLevelType" resultMap="userExtensionMap">
        SELECT
            user_extension_id,
            user_id,
            `level`,
            level_type,
            growth,
            score,
            balance,
            `version`,
            `sign_day`,
            vip_level,
            actual_balance
        FROM
            user_extension
        WHERE
            user_id IN
                <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
                    #{userId}
                </foreach>
    </select>

    <select id="getByUserId" resultMap="userExtensionMap">
        SELECT user_extension_id,
               user_id,
               `level`,
               level_type,
               growth,
               score,
               balance,
               actual_balance,
                actual_balance,
                allinpay_balance,
                allinpay_actual_balance,
                allinpay_create,
                allinpay_real_name_set,
                allinpay_phone_bind,
                allinpay_pay_pwd_set,
                allinpay_protocol_sign,
                allinpay_pay_acct_bind,
               `version`,
               sign_day,
               `vip_level`
        FROM user_extension
        WHERE user_id = #{userId}
    </select>

    <update id="updateByUserRecharge">
        update user_extension
        set growth  = #{userRechargeVO.presGrowth} + growth,
            score   = #{userRechargeVO.presScore} + score,
            balance = #{userRechargeVO.presAmount} + balance + #{userBalanceLog.changeBalance},
            actual_balance = #{userRechargeVO.presAmount} + actual_balance + #{userBalanceLog.changeBalance}
        where user_id = #{userBalanceLog.userId}
    </update>

    <update id="addByUserBalanceLog">
        update user_extension
        set
        <!-- 退款增加的余额不需要加到总余额中 -->
        <if test="userBalanceLog.type != 4">
            balance =  balance + #{userBalanceLog.changeBalance},
        </if>
        actual_balance = actual_balance + #{userBalanceLog.changeBalance}
        where user_id = #{userBalanceLog.userId}
    </update>

    <update id="deductionUserBalance">
        update user_extension set actual_balance =  actual_balance - #{changeBalance}
        where user_id = #{userId} and actual_balance &gt;= #{changeBalance}
    </update>

    <update id="updateUserLevelByBuyVip">
        update user_extension set vip_level = #{afterLevel},level_type = 1 where user_id = #{userId}
    </update>
    <update id="batchUpdateScore" parameterType="java.util.List">
        UPDATE user_extension SET `version`   = `version` + 1
        ,update_time = NOW(),
        <trim prefix="score = case" suffix="else `score` end">
            <foreach collection="userExtensions" item="userExtension" index="index">
                when user_id = #{userExtension.userId} and #{userExtension.score} is not null
                then (case when `score` + #{userExtension.score} &lt; 0 then 0 ELSE `score` + #{userExtension.score} end)
            </foreach>
        </trim>
        WHERE user_id IN
        <foreach collection="userExtensions" item="userExtension" open="(" close=")" separator=",">
            #{userExtension.userId}
        </foreach>
    </update>

    <update id="lockScoreBySubmitOrder">
        UPDATE user_extension set score = score - #{useScore} where user_id = #{userId} and score &gt;= #{useScore}
    </update>

    <update id="updateScoreByUserId">
        UPDATE user_extension
        set score = score + #{useScore}
        where user_id = #{userId}
    </update>

    <update id="updateBalanceByVersion">
        update user_extension
        set `level`       = #{userExtension.level},
            level_type    = #{userExtension.levelType},
            growth        = #{userExtension.growth},
            score         = #{userExtension.score},
            balance       = #{userExtension.balance},
            actual_balance = #{userExtension.actualBalance},
            update_time   = #{userExtension.updateTime},
            version       = version + 1
        where user_id = #{userExtension.userId}
          AND version = #{userExtension.version}
    </update>
    <update id="batchChangeLevelByUserIdsAndLevel">
        UPDATE user_extension
        SET `version` = `version` + 1, update_time = NOW()
        , `level` =  `level` + #{level}
        WHERE user_id IN
        <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
            #{userId}
        </foreach>
    </update>

    <update id="batchUpdateTypeAndLevelByUserIds">
        <foreach collection="userExtensionList" item="userExtension" separator=";">
            UPDATE `user_extension` ue
            SET ue.level_type = #{afterLevelType},ue.vip_level = NULL,level = #{userExtension.level}
            WHERE ue.level_type = #{currentLevelType}
            AND ue.user_id = #{userExtension.userId}
        </foreach>
    </update>

    <update id="updateBatchStatus">
        UPDATE
            `user_extension`
        <set>
            <if test="userExtensionDTO.allinpayCreate != null">
                allinpay_create = #{userExtensionDTO.allinpayCreate},
            </if>
            <if test="userExtensionDTO.allinpayRealNameSet != null">
                allinpay_real_name_set = #{userExtensionDTO.allinpayRealNameSet},
            </if>
            <if test="userExtensionDTO.allinpayPhoneBind != null">
                allinpay_phone_bind = #{userExtensionDTO.allinpayPhoneBind},
            </if>
            <if test="userExtensionDTO.allinpayPayPwdSet != null">
                allinpay_pay_pwd_set = #{userExtensionDTO.allinpayPayPwdSet},
            </if>
            <if test="userExtensionDTO.allinpayProtocolSign != null">
                allinpay_protocol_sign = #{userExtensionDTO.allinpayProtocolSign},
            </if>
            <if test="userExtensionDTO.allinpayPayAcctBind != null">
                allinpay_pay_acct_bind = #{userExtensionDTO.allinpayPayAcctBind}
            </if>
        </set>
        WHERE
            user_id IN
            <foreach collection="userIds" item="userId" open="(" separator="," close=")">
                #{userId}
            </foreach>
    </update>

    <select id="countMemberByParam" resultType="java.lang.Integer">
        SELECT ifnull(COUNT(*),0) FROM `user` u
        <where>
            <if test="param.dateTime != null">
                AND u.create_time &lt;= #{param.dateTime}
            </if>
            <if test="param.dateTime == null and param.startTime != null and param.endTime != null">
                AND ( u.create_time  &gt;= #{param.startTime} AND u.create_time  &lt;= #{param.endTime})
            </if>
            <choose>
                <when test="param.memberType == 1">
                    AND u.level_type = 0
                </when>
                <when test="param.memberType == 2">
                    AND u.level_type = 1
                </when>
            </choose>
        </where>
    </select>

    <select id="countByMemberTypeConditions" resultType="com.tmerclub.cloud.user.vo.UserExtensionVO">
        SELECT ue.user_id,ue.level_type FROM `user_extension` ue
        <where>
        and ue.user_id in
            <foreach collection="param.userIds" item="userId" separator="," open="(" close=")">
                #{userId}
            </foreach>
        </where>
    </select>

    <select id="getGrowthLevelMismatchUserByLevelType" resultType="java.lang.Long">
        SELECT ue.user_id FROM `user_extension` ue
        WHERE ue.level !=
        (
            SELECT IFNULL( (SELECT `level` FROM `user_level` WHERE level_type = #{levelType} AND need_growth &lt;= ue.growth  ORDER BY `level` DESC LIMIT 1),
                           (SELECT MIN(`level`) FROM `user_level` WHERE level_type = #{levelType})
            ) AS `level`
        )
    </select>
    <select id="getLevelAndLevelType" resultType="com.tmerclub.cloud.user.model.UserExtension">
        SELECT * FROM `user_extension` ue
        WHERE `level` = #{level}
        <if test="levelType != null">
            AND level_type = #{levelType}
        </if>
    </select>

    <select id="listUserExtensions" resultType="com.tmerclub.cloud.user.vo.UserExtensionVO">
        SELECT
            *
        FROM
            `user_extension`
        <where>
            <if test="userExtensionDTO.allinpayCreate != null">
                allinpay_create = #{userExtensionDTO.allinpayCreate}
            </if>
            <if test="userExtensionDTO.allinpayRealNameSet != null">
                AND allinpay_real_name_set = #{userExtensionDTO.allinpayRealNameSet}
            </if>
            <if test="userExtensionDTO.allinpayPhoneBind != null">
                AND allinpay_phone_bind = #{userExtensionDTO.allinpayPhoneBind}
            </if>
            <if test="userExtensionDTO.allinpayPayPwdSet != null">
                AND allinpay_pay_pwd_set = #{userExtensionDTO.allinpayPayPwdSet}
            </if>
            <if test="userExtensionDTO.allinpayProtocolSign != null">
                AND allinpay_protocol_sign = #{userExtensionDTO.allinpayProtocolSign}
            </if>
            <if test="userExtensionDTO.allinpayPayAcctBind != null">
                AND allinpay_pay_acct_bind = #{userExtensionDTO.allinpayPayAcctBind}
            </if>
        </where>
    </select>
</mapper>
