<?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.microservices.zone.project.mapper.ZoneProjectMapper">

    <resultMap type="com.microservices.zone.project.domain.ZoneProject" id="ZoneProjectResult">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="gitlinkProjectId" column="gitlink_project_id"/>
        <result property="projectTypeId" column="project_type_id"/>
        <result property="deptId" column="dept_id"/>
        <result property="delFlag" column="del_flag"/>
        <result property="createBy" column="create_by"/>
        <result property="createTime" column="create_time"/>
        <result property="updateBy" column="update_by"/>
        <result property="updateTime" column="update_time"/>
        <result property="fullName" column="full_name"/>
        <result property="zoneId" column="zone_id"/>
        <result property="sort" column="sort"/>
        <result property="isHomepage" column="is_homepage"/>
        <result property="auditStatus" column="audit_status"/>
        <result property="auditTime" column="audit_time"/>
        <result property="auditBy" column="audit_by"/>
        <result property="isPointsTop" column="is_points_top"/>
        <result property="expiryTime" column="expiry_time"/>
        <result property="remark" column="remark"/>
        <association property="dept" column="dept_id" javaType="com.microservices.system.api.domain.SysDept"
                     resultMap="deptResult"/>
        <association property="zoneProjectType" column="project_type_id"
                     javaType="com.microservices.zone.project.domain.ZoneProjectType"
                     resultMap="projectTypeResult"/>
    </resultMap>

    <resultMap id="deptResult" type="com.microservices.system.api.domain.SysDept">
        <id property="deptId" column="dept_id"/>
        <result property="parentId" column="parent_id"/>
        <result property="deptName" column="dept_name"/>
        <result property="ancestors" column="ancestors"/>
        <result property="orderNum" column="order_num"/>
        <result property="leader" column="leader"/>
        <result property="status" column="dept_status"/>
    </resultMap>

    <resultMap id="projectTypeResult" type="com.microservices.zone.project.domain.ZoneProjectType">
        <id property="id" column="id"/>
        <result property="name" column="type_name"/>
        <result property="deptId" column="type_dept_id"/>
    </resultMap>

    <resultMap type="com.microservices.zone.project.domain.ZoneProjectWithScore"
               id="ZoneProjectWithScoreResult" extends="ZoneProjectResult">
        <result property="searchScore" column="search_score"/>
    </resultMap>

    <sql id="selectZoneProjectVo">
        select id,
               name,
               sort,
               full_name,
               gitlink_project_id,
               project_type_id,
               dept_id,
               zone_id,
               del_flag,
               create_by,
               create_time,
               update_by,
               is_homepage,
               update_time,
               audit_status,
               audit_time,
               audit_by,
               is_points_top,
               expiry_time,
               remark
        from zone_project
    </sql>

    <sql id="selectZoneProjectAliasVo">
        select zp.id,
               zp.name,
               zp.sort,
               zp.full_name,
               zp.gitlink_project_id,
               zp.dept_id,
               zp.zone_id,
               zp.del_flag,
               zp.create_by,
               zp.create_time,
               zp.update_by,
               zp.update_time,
               zp.project_type_id,
               zp.is_homepage,
               zp.audit_status,
               zp.audit_time,
               zp.audit_by,
               zp.is_points_top,
               zp.expiry_time,
               d.dept_id,
               d.parent_id,
               d.ancestors,
               d.dept_name,
               d.order_num,
               d.leader,
               d.status    as dept_status,
               zpt.id,
               zpt.name    as type_name,
               zpt.dept_id as type_dept_id,
               zp.remark
        from zone_project as zp
                 left join sys_dept as d on zp.dept_id = d.dept_id
                 left join zone_project_type as zpt on zp.project_type_id = zpt.id
    </sql>

    <select id="selectZoneProjectList" parameterType="ZoneProjectSearchVo" resultMap="ZoneProjectResult">
        <include refid="selectZoneProjectAliasVo"/>
        <where>
            <if test="name != null  and name != ''">
                <choose>
                    <when test='name.contains("_")'>
                        <!--
                        <bind> 是 mybatis 用来存储临时变量的标签。

                        contentVal 是前端转来的值，
                        contentTmp 是临时变量，mybatis 对 contentVal 值中的 _ 替换 /_ ，并保存在 contentTmp 。
                         -->
                        <bind name="contentTmp" value='name.replaceAll("_","/_")'/>
                        and zp.name like concat('%', #{ contentTmp }, '%') escape '/'
                    </when>
                    <otherwise>
                        and zp.name like concat('%', #{name}, '%')
                    </otherwise>

                </choose>

            </if>
            <if test="projectTypeId != null ">and zp.project_type_id = #{projectTypeId}</if>
            <if test="zoneId != null ">and zp.zone_id = #{zoneId}</if>
            <if test="createBy != null and createBy != ''">and zp.create_by = #{createBy}</if>
            <choose>
                <when test="excludesFailure != null and excludesFailure">
                    and zp.audit_status != '2'
                </when>
                <otherwise>
                    <choose>
                        <when test="auditStatus != null and auditStatus !=''">
                            and zp.audit_status = #{auditStatus}
                        </when>
                        <otherwise>
                            and zp.audit_status = '1'
                        </otherwise>
                    </choose>
                </otherwise>
            </choose>
            <if test="isHomepage != null ">and zp.is_homepage = #{isHomepage}</if>
            <if test="excludeId != null ">and zp.id != #{excludeId}</if>

            <!-- 数据范围过滤 -->
            ${params.dataScope}
        </where>
        ORDER BY sort DESC
    </select>

    <select id="selectZoneProjectById" parameterType="Long" resultMap="ZoneProjectResult">
        <include refid="selectZoneProjectVo"/>
        where id = #{id}
    </select>
    <select id="selectZoneProjectListCount" resultType="java.lang.Integer">
        select count(0) from zone_project as zp
        <where>
            <if test="name != null  and name != ''">and zp.name like concat('%', #{name}, '%')</if>
            <if test="projectTypeId != null ">and zp.project_type_id = #{projectTypeId}</if>
            <if test="zoneId != null ">and zp.zone_id = #{zoneId}</if>
            <choose>
                <when test="excludesFailure != null and excludesFailure">
                    and zp.audit_status != '2'
                </when>
                <otherwise>
                    <choose>
                        <when test="auditStatus != null and auditStatus !=''">
                            and zp.audit_status = #{auditStatus}
                        </when>
                        <otherwise>
                            and zp.audit_status = '1'
                        </otherwise>
                    </choose>
                </otherwise>
            </choose>
            <!-- 数据范围过滤 -->
            ${params.dataScope}
        </where>
    </select>
    <select id="selectZoneProjectByGitLinkProjectIdAndZoneId" resultMap="ZoneProjectResult">
        <include refid="selectZoneProjectAliasVo"/>
        where zp.zone_id = #{zoneId}
        and zp.gitlink_project_id = #{gitlinkProjectId}
        and zp.audit_status != '2'
    </select>
    <select id="selectMaxSortByZoneId" resultType="java.lang.Integer">
        select MAX(sort)
        from zone_project
        where zone_id = #{zoneId};
    </select>
    <select id="selectCountByZoneId" resultType="java.lang.Integer">
        select count(0)
        from zone_project
        where zone_id = #{zoneId}
    </select>
    <select id="selectDataByOrderAndZoneId" resultType="com.microservices.zone.project.domain.ZoneProject">
        <include refid="selectZoneProjectVo"/>
        where zone_id=#{data.zoneId}
        <if test="!isContainsSelf">
            and id &lt;&gt; #{data.id}
        </if>
        ORDER BY sort DESC
        LIMIT ${order-1},1
    </select>
    <select id="selectMinSortByZoneId" resultType="java.lang.Integer">
        select MIN(sort)
        from zone_project
        where zone_id = #{zoneId};
    </select>
    <select id="selectHomepageCount" resultType="java.lang.Integer">
        select count(0)
        from zone_project
        where zone_id = #{zoneId}
          and is_homepage = 1
    </select>

    <insert id="insertZoneProject" parameterType="ZoneProject" useGeneratedKeys="true" keyProperty="id">
        insert into zone_project
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name != null and name != ''">name,</if>
            <if test="fullName != null and fullName != ''">full_name,</if>
            <if test="gitlinkProjectId != null">gitlink_project_id,</if>
            <if test="projectTypeId != null">project_type_id,</if>
            <if test="deptId != null">dept_id,</if>
            <if test="zoneId != null">zone_id,</if>
            <if test="sort != null">sort,</if>
            <if test="delFlag != null">del_flag,</if>
            <if test="createBy != null">create_by,</if>
            <if test="createTime != null">create_time,</if>
            <if test="updateBy != null">update_by,</if>
            <if test="updateTime != null">update_time,</if>
            <if test="auditStatus != null">audit_status,</if>
            <if test="auditTime != null">audit_time,</if>
            <if test="auditBy != null">audit_by,</if>
            <if test="isPointsTop != null">is_points_top,</if>
            <if test="expiryTime != null">expiry_time,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="name != null and name != ''">#{name},</if>
            <if test="fullName != null and fullName != ''">#{fullName},</if>
            <if test="gitlinkProjectId != null">#{gitlinkProjectId},</if>
            <if test="projectTypeId != null">#{projectTypeId},</if>
            <if test="deptId != null">#{deptId},</if>
            <if test="zoneId != null">#{zoneId},</if>
            <if test="sort != null">#{sort},</if>
            <if test="delFlag != null">#{delFlag},</if>
            <if test="createBy != null">#{createBy},</if>
            <if test="createTime != null">#{createTime},</if>
            <if test="updateBy != null">#{updateBy},</if>
            <if test="updateTime != null">#{updateTime},</if>
            <if test="auditStatus != null">#{auditStatus},</if>
            <if test="auditTime != null">#{auditTime},</if>
            <if test="auditBy != null">#{auditBy},</if>
            <if test="isPointsTop != null">#{isPointsTop},</if>
            <if test="expiryTime != null">#{expiryTime},</if>
        </trim>
    </insert>

    <update id="updateZoneProject" parameterType="ZoneProject">
        update zone_project
        <trim prefix="SET" suffixOverrides=",">
            <if test="name != null and name != ''">name = #{name},</if>
            <if test="gitlinkProjectId != null">gitlink_project_id = #{gitlinkProjectId},</if>
            <if test="projectTypeId != null">project_type_id = #{projectTypeId},</if>
            <if test="deptId != null">dept_id = #{deptId},</if>
            <if test="delFlag != null">del_flag = #{delFlag},</if>
            <if test="createBy != null">create_by = #{createBy},</if>
            <if test="createTime != null">create_time = #{createTime},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="sort != null">sort = #{sort},</if>
            <if test="isHomepage != null">is_homepage = #{isHomepage},</if>
            <if test="auditStatus != null">audit_status = #{auditStatus},</if>
            <if test="auditTime != null">audit_time = #{auditTime},</if>
            <if test="auditBy != null">audit_by = #{auditBy},</if>
            <if test="isPointsTop != null">is_points_top = #{isPointsTop},</if>
            <if test="expiryTime != null">expiry_time = #{expiryTime},</if>
            <if test="remark != null">remark = #{remark},</if>
        </trim>
        where id = #{id}
    </update>

    <update id="updateZoneProjectNameAndFullName">
        update zone_project
        <trim prefix="SET" suffixOverrides=",">
            <if test="name != null and name != ''">`name` = #{name},</if>
            <if test="fullName != null and fullName != ''">full_name = #{fullName},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
        </trim>
        where id = #{zoneProjectId}

    </update>
    <update id="batchUpdateSortDecrease">
        update zone_project
        set sort=sort - 1
        where sort &lt;= #{setSort}
          and zone_id = #{zoneId};
    </update>

    <delete id="deleteZoneProjectById" parameterType="Long">
        delete
        from zone_project
        where id = #{id}
    </delete>

    <delete id="deleteZoneProjectByIds" parameterType="String">
        delete from zone_project where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
    <delete id="deleteZoneProjectByZoneId">
        delete
        from zone_project
        where zone_id = #{zoneId}
    </delete>

    <!-- 全局搜索 - 带评分的全文索引查询 -->
    <select id="globalSearchWithScore" resultMap="ZoneProjectWithScoreResult">
        SELECT
            zp.id, zp.name, zp.sort, zp.full_name, zp.gitlink_project_id,
            zp.dept_id, zp.zone_id, zp.del_flag, zp.create_by, zp.create_time,
            zp.update_by, zp.update_time, zp.project_type_id, zp.is_homepage,
            zp.audit_status, zp.audit_time, zp.audit_by, zp.is_points_top, zp.expiry_time,
            MATCH(zp.name) AGAINST(#{keyword} IN BOOLEAN MODE) AS search_score
        FROM zone_project zp
        WHERE zp.zone_id = #{zoneId}
          AND zp.audit_status = '1'
          AND (
              MATCH(zp.name) AGAINST(#{keyword} IN BOOLEAN MODE)
              OR zp.name LIKE CONCAT('%', #{keyword}, '%')
          )
        ORDER BY search_score DESC, zp.update_time DESC
        LIMIT #{offset}, #{pageSize}
    </select>

    <select id="globalSearchCount" resultType="java.lang.Long">
        SELECT COUNT(*)
        FROM zone_project zp
        WHERE zp.audit_status = '1'
          AND (
              MATCH(zp.name) AGAINST(#{keyword} IN BOOLEAN MODE)
              OR zp.name LIKE CONCAT('%', #{keyword}, '%')
          )
            <if test="zoneId != null">
                AND zp.zone_id = #{zoneId}
            </if>
            <if test="deptId != null">
                AND zp.dept_id = #{deptId}
            </if>
    </select>
    <select id="selectZoneProjectGitlinkIdList" resultType="java.lang.String">
        select gitlink_project_id from zone_project
        where zone_id=#{zoneId}
        <if test="projectTypeId != null">
            AND project_type_id = #{projectTypeId}
        </if>
    </select>
    <select id="selectZoneProjectListFromGitlinkProjectIdList" resultMap="ZoneProjectWithScoreResult">
        <include refid="selectZoneProjectVo"/>
        where zone_id=#{zoneId}
        and gitlink_project_id in
        <foreach item="gitlinkProjectId" collection="gitlinkProjectIdList" open="(" separator="," close=")">
            #{gitlinkProjectId}
        </foreach>
    </select>

    <!-- 查询当前用户在指定专区下的置顶项目 -->
    <select id="selectPointsTopByZoneIdAndCreateBy" resultMap="ZoneProjectResult">
        <include refid="selectZoneProjectVo"/>
        where zone_id = #{zoneId}
          and create_by = #{createBy}
          and is_points_top = '1'
          and audit_status = '1'
        order by expiry_time desc
        limit 1
    </select>

    <!-- 批量取消已过期的积分置顶 -->
    <update id="updateExpiredPointsTop">
        update zone_project
        set is_points_top = 0,
            expiry_time   = null
        where is_points_top = 1
          and expiry_time &lt; NOW()
    </update>

    <!-- 查询专区下置顶项目列表（过期时间晚于当前时间，用于前台展示） -->
    <select id="selectTopProjectList" resultMap="ZoneProjectResult">
        <include refid="selectZoneProjectVo"/>
        where zone_id = #{zoneId}
          and is_points_top = '1'
          and audit_status = '1'
          and expiry_time > NOW()
        order by create_time desc
    </select>
</mapper>