<?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.backendsys.modules.system.dao.SysUserDao">

    <sql id="includeUser">
        u.id id,
        COALESCE(u.username, '') username,
        COALESCE(u.phone, '') phone,
        COALESCE(u.phone_area_code, '') phone_area_code,

        uf.user_id user_id,
        COALESCE(uf.nickname, '') nickname,
        COALESCE(uf.email, '') email,
        COALESCE(uf.gender, '') gender,
        COALESCE(uf.avatar, '') AS avatar,
        COALESCE(uf.last_login_ip, '') last_login_ip,
        COALESCE(uf.last_login_uuid, '') last_login_uuid,
        COALESCE(uf.last_login_time, '') last_login_time,
        uf.is_super is_super,
        uf.point_balance point_balance,
        uf.invite_code invite_code,
        uf.status status,
        uf.audit_status audit_status,
        uf.audit_note audit_note,
        uf.create_time create_time,
        uf.update_time update_time,
        uf.del_flag del_flag
    </sql>

    <resultMap id="resultMapUserList" type="java.util.LinkedHashMap">
        <id property="id" column="id" jdbcType="BIGINT" />
        <result property="user_id" column="user_id" />
        <result property="username" column="username" />
        <result property="phone" column="phone" />
        <result property="phone_area_code" column="phone_area_code" />
        <result property="nickname" column="nickname" />
        <result property="email" column="email" />
        <result property="gender" column="gender" javaType="java.lang.Integer"/>
        <result property="avatar" column="avatar" />
        <result property="last_login_ip" column="last_login_ip" />
        <result property="last_login_uuid" column="last_login_uuid" />
        <result property="last_login_time" column="last_login_time" />
        <result property="is_super" column="is_super" javaType="java.lang.Integer"/>
        <result property="point_balance" column="point_balance" javaType="java.lang.Float"/>
        <result property="invite_code" column="invite_code" />
        <result property="status" column="status" javaType="java.lang.Integer"/>
        <result property="audit_status" column="audit_status" javaType="java.lang.Integer"/>
        <result property="audit_note" column="audit_note" />
        <result property="create_time" column="create_time" />
        <result property="update_time" column="update_time" />
        <result property="del_flag" column="del_flag" javaType="java.lang.Integer"/>
        <collection property="role_ids" javaType="java.util.List"
                    ofType="java.lang.Long" column="role_id">
            <id property="role_id" column="role_id" />
        </collection>
    </resultMap>
    <resultMap id="resultMapUserDetail" type="java.util.LinkedHashMap">
        <id property="id" column="id" jdbcType="BIGINT" />
        <result property="user_id" column="user_id" />
        <result property="username" column="username" />
        <result property="phone" column="phone" />
        <result property="phone_area_code" column="phone_area_code" />
        <result property="nickname" column="nickname" />
        <result property="email" column="email" />
        <result property="gender" column="gender" javaType="java.lang.Integer"/>
        <result property="avatar" column="avatar" />
        <result property="last_login_ip" column="last_login_ip" />
        <result property="last_login_uuid" column="last_login_uuid" />
        <result property="last_login_time" column="last_login_time" />
        <result property="is_super" column="is_super" javaType="java.lang.Integer"/>
        <result property="point_balance" column="point_balance" javaType="java.lang.Float"/>
        <result property="invite_code" column="invite_code" />
        <result property="status" column="status" javaType="java.lang.Integer"/>
        <result property="audit_status" column="audit_status" javaType="java.lang.Integer"/>
        <result property="audit_note" column="audit_note" />
        <result property="create_time" column="create_time" />
        <result property="update_time" column="update_time" />
        <result property="del_flag" column="del_flag" javaType="java.lang.Integer"/>
        <collection property="roles" javaType="java.util.List" ofType="java.util.LinkedHashMap"
                    select="queryRoleById" column="id">
            <id property="id" column="id" />
            <result property="role_name" column="role_name" />
            <result property="sort" column="sort" />
        </collection>
    </resultMap>

    <!-- [多对多，使用子查询] -->
    <!-- [嵌套查询] 用户角色 / 角色权限 -->
    <select id="queryRoleById" resultType="java.util.LinkedHashMap">
        SELECT ur.id, ur.role_name,
               GROUP_CONCAT(m.id) AS module_ids
        FROM sys_user_role_relation urr
                 LEFT JOIN sys_user_role ur ON urr.role_id = ur.id
                 LEFT JOIN sys_user_role_module_relation mr ON urr.role_id = mr.role_id
                 LEFT JOIN sys_user_role_module m ON mr.module_id = m.id
        WHERE urr.user_id = #{userId}
        GROUP BY ur.id
        ORDER BY ur.sort ASC
    </select>

    <!--, um.module_code-->
    <!--    <select id="queryModulesByRoleId" resultType="java.util.LinkedHashMap">-->
    <!--        SELECT id, um.module_name-->
    <!--        FROM sys_user_role_module um-->
    <!--        WHERE um.id IN (-->
    <!--            SELECT module_id FROM sys_user_role_module_relation-->
    <!--            WHERE role_id IN-->
    <!--            <foreach collection="roles" item="role" open="(" separator="," close=")">-->
    <!--                #{role.id}-->
    <!--            </foreach>-->
    <!--        )-->
    <!--    </select>-->
    <!--WHERE role_id = #{roleId}-->

    <!-- 根据 ID 或 账号 查询是否存在 (用于校验密码是否正确) -->
    <select id="queryUserByIdOrName" resultType="java.util.LinkedHashMap">
        SELECT id, username, phone, password FROM sys_user
        <where>
            <if test="username != null and username != ''">
                AND username = #{username}
            </if>
            <if test="phone != null and phone != ''">
                AND phone = #{phone}
            </if>
            <if test="phone_area_code != null and phone_area_code != ''">
                AND phone_area_code = #{phone_area_code}
            </if>
            <if test="id != null and id != ''">
                AND id = #{id}
            </if>
        </where>
    </select>
    <!-- 逻辑删除时，查询加这一段判断
    AND id IN (
        SELECT user_id FROM sys_user_info WHERE del_flag = -1
    )
    -->

    <!-- 查询 用户列表 (分页) (嵌套查询) -->
    <select id="queryUserList" resultMap="resultMapUserList">
        SELECT
        <include refid="includeUser" />,
        urr.role_id role_id
        FROM sys_user u
        LEFT JOIN sys_user_info uf ON u.id = uf.user_id
        LEFT JOIN sys_user_role_relation urr ON uf.user_id = urr.user_id
        <where>
            AND uf.del_flag != 1
            <if test="username != null and username != ''">
                AND u.username LIKE CONCAT('%', #{username}, '%')
            </if>
            <if test="phone != null and phone != ''">
                AND u.phone LIKE CONCAT('%', #{phone}, '%')
            </if>
            <if test="phone_area_code != null and phone_area_code != ''">
                AND u.phone_area_code = #{phone_area_code}
            </if>
            <if test="nickname != null and nickname != ''">
                AND uf.nickname LIKE CONCAT('%', #{nickname}, '%')
            </if>
            <if test="email != null and email != ''">
                AND uf.email LIKE CONCAT('%', #{email}, '%')
            </if>
            <if test="status != null and status != ''">
                AND uf.status = #{status}
            </if>
            <if test="audit_status != null and audit_status != ''">
                AND uf.audit_status = #{audit_status}
            </if>
            <if test="role_id != null and role_id != ''">
                AND urr.role_id IN
                <foreach collection="role_id" item="role" open="(" separator="," close=")">
                    #{role}
                </foreach>
            </if>
            <if test="is_super != null and is_super != ''">
                AND uf.is_super = #{is_super}
            </if>
            AND uf.id != 1
        </where>
        ORDER BY uf.create_time DESC
    </select>

    <!-- 查询 用户详情 -->
    <select id="queryUserDetail" resultMap="resultMapUserDetail">
        SELECT
        <include refid="includeUser" />
        FROM sys_user u
        LEFT JOIN sys_user_info uf ON u.id = uf.user_id
        WHERE u.id = #{user_id}
        AND uf.del_flag = -1
    </select>

    <select id="queryUserUUIDSByIds" resultType="java.util.LinkedHashMap">
        SELECT last_login_uuid
        FROM sys_user_info
        WHERE user_id IN
        <foreach item="id" collection="ids" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>


    <!-- 查询当前在线用户的信息 -->
    <select id="queryUserWithLogined" resultType="java.util.LinkedHashMap">
        SELECT
        u.id id,
        COALESCE(u.username, '') username,
        COALESCE(u.phone, '') phone,
        COALESCE(u.phone_area_code, '') phone_area_code,

        COALESCE(uf.nickname, '') nickname,
        COALESCE(uf.email, '') email,
        COALESCE(uf.avatar, '') avatar,
        uf.is_super is_super,
        uf.status status,
        uf.audit_status audit_status,
        uf.audit_note audit_note
        FROM sys_user u
        LEFT JOIN sys_user_info uf ON u.id = uf.user_id
        WHERE uf.last_login_uuid IN
        <foreach collection="last_login_uuids" item="last_login_uuid" open="(" separator="," close=")">
            #{last_login_uuid}
        </foreach>
    </select>

    <!-- 创建用户 -->
    <insert id="insertUser" parameterType="com.backendsys.entity.System.SysUserDTO" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO sys_user (password
            <if test="username != null and username != ''">, username</if>
            <if test="phone != null and phone != ''">, phone</if>
            <if test="phone_area_code != null and phone_area_code != ''">, phone_area_code</if>
        )
        VALUES (#{password}
            <if test="username != null and username != ''">, #{username}</if>
            <if test="phone != null and phone != ''">, #{phone}</if>
            <if test="phone_area_code != null and phone_area_code != ''">, #{phone_area_code}</if>
        );
        SET @last_user_id = LAST_INSERT_ID();

        INSERT INTO sys_user_info (user_id
            <if test="nickname != null and nickname != ''">, nickname</if>
            <if test="email != null and email != ''">, email</if>
            <if test="gender != null and gender != ''">, gender</if>
            <if test="avatar != null and avatar != ''">, avatar</if>
            <if test="status != null and status != ''">, status</if>
            <if test="invite_code != null and invite_code != ''">, invite_code</if>
        ) VALUES (@last_user_id
            <if test="nickname != null and nickname != ''">, #{nickname}</if>
            <if test="email != null and email != ''">, #{email}</if>
            <if test="gender != null and gender != ''">, #{gender}</if>
            <if test="avatar != null and avatar != ''">, #{avatar}</if>
            <if test="status != null and status != ''">, #{status}</if>
            <if test="invite_code != null and invite_code != ''">, #{invite_code}</if>
        );

        <if test="role_id != null and role_id.size() > 0">
            INSERT INTO sys_user_role_relation (user_id, role_id)
            VALUES
            <foreach collection="role_id" item="id" separator=",">
                (@last_user_id, #{id})
            </foreach>
        </if>
    </insert>

<!--    <if test="roles != null and roles.size() > 0">-->
<!--        INSERT INTO sys_user_role_relation (user_id, role_id)-->
<!--        VALUES-->
<!--        <foreach collection="roles" item="role" separator=",">-->
<!--            (@last_user_id, #{role.id})-->
<!--        </foreach>-->
<!--    </if>-->

    <!-- 编辑 用户信息 -->
    <update id="updateUserInfo" parameterType="com.backendsys.entity.System.SysUserDTO" useGeneratedKeys="true" keyProperty="id">
        UPDATE sys_user_info SET
        <trim suffixOverrides="," suffix=" ">
            <if test="nickname != null and nickname != ''">nickname = #{nickname},</if>
            <if test="email != null and email != ''">email = #{email},</if>
            <if test="gender != null and gender != ''">gender = #{gender},</if>
            <if test="avatar != null and avatar != ''">avatar = #{avatar},</if>
            <if test="point_balance != null">point_balance = #{point_balance},</if>
            <if test="invite_code != null">invite_code = #{invite_code},</if>
            <if test="status != null and status != ''">status = #{status},</if>
            <if test="last_login_ip != null">last_login_ip = #{last_login_ip},</if>
            <if test="last_login_uuid != null">last_login_uuid = #{last_login_uuid},</if>
            <if test="last_login_time != null">last_login_time = #{last_login_time},</if>
        </trim>
        WHERE user_id = #{user_id};

        <!--判断是否有新的数据需要插入-->
        <if test="role_id != null and role_id.size() > 0">
            <!--删除符合条件的数据-->
            DELETE FROM sys_user_role_relation WHERE user_id = #{user_id};
            <!--插入-->
            INSERT INTO sys_user_role_relation (user_id, role_id)
            VALUES
            <foreach collection="role_id" item="id" separator=",">
                (#{user_id}, #{id})
            </foreach>
        </if>
    </update>
    <!--删掉全部关联，再重新关联-->



    <!-- 审核用户 -->
    <update id="auditUser" parameterType="com.backendsys.entity.System.SysUserDTO">
        UPDATE sys_user_info SET
        <trim suffixOverrides="," suffix=" ">
            <if test="audit_status != null and audit_status != ''">audit_status = #{audit_status},</if>
            <if test="audit_note != null and audit_note != ''">audit_note = #{audit_note},</if>
        </trim>
        WHERE user_id = #{user_id};
    </update>


    <!-- 查询 用户密码 -->
    <select id="queryUserPassword" parameterType="com.backendsys.entity.System.SysUserDTO">
        SELECT password FROM sys_user WHERE id = #{user_id}
    </select>
    <!-- 编辑 用户密码 -->
    <update id="updateUserPassword" parameterType="com.backendsys.entity.System.SysUserDTO">
        UPDATE sys_user SET password = #{password} WHERE id = #{user_id}
    </update>

    <!-- 编辑 用户积分 -->
    <update id="updateUserPoint" parameterType="com.backendsys.entity.System.SysUserPointsDTO">
        UPDATE sys_user_info SET point_balance = #{point_balance} WHERE user_id = #{target_user_id}
    </update>
    <!-- 查询 用户积分 -->
    <select id="queryUserPoint" resultType="java.util.LinkedHashMap">
        SELECT point_balance FROM sys_user_info WHERE user_id = #{target_user_id}
    </select>

    <!-- 创建 用户积分操作记录 -->
    <insert id="insertUserPointHistory" parameterType="com.backendsys.entity.System.SysUserPointsDTO"
            useGeneratedKeys="true" keyProperty="target_user_id">
        INSERT INTO sys_user_points_history (
        target_user_id, point_adjustment, point_balance, activity_type, activity_type_description, operator_type
        <if test="activity_detail != null and activity_detail != ''">, activity_detail</if>
        <if test="operator_user_id != null and operator_user_id != ''">, operator_user_id</if>
        ) VALUES (
        #{target_user_id}, #{point_adjustment}, #{point_balance}, #{activity_type}, #{activity_type_description},  #{operator_type}
        <if test="activity_detail != null and activity_detail != ''">, #{activity_detail}</if>
        <if test="operator_user_id != null and operator_user_id != ''">, #{operator_user_id}</if>
        )
    </insert>

</mapper>