<?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.cms.doc.mapper.CmsDocMapper">

    <resultMap type="com.microservices.cms.doc.domain.CmsDoc" id="CmsDocResult">
        <result property="id" column="id"/>
        <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="name" column="name"/>
        <result property="fileName" column="file_name"/>
        <result property="filePath" column="file_path"/>
        <result property="fileSha" column="file_sha"/>
        <result property="fileSize" column="file_size"/>
        <result property="fileUrl" column="file_url"/>
        <result property="htmlUrl" column="html_url"/>
        <result property="visits" column="visits"/>
        <result property="sort" column="sort"/>
        <result property="publishTime" column="publish_time"/>
        <result property="publishUser" column="publish_user"/>
        <result property="publishUserUrl" column="publish_user_url"/>
        <result property="publishUserImage" column="publish_user_image"/>
        <result property="publishUserNickname" column="publish_user_nickname"/>
        <result property="summary" column="summary"/>
        <result property="isDir" column="is_dir"/>
        <result property="headImg" column="head_img"/>
        <result property="dirName" column="dir_name"/>
        <result property="deptId" column="dept_id"/>
        <result property="issueId" column="issue_id"/>
        <result property="isHomepage" column="is_homepage"/>
        <result property="editorType" column="editor_type"/>
        <result property="auditStatus" column="audit_status"/>
        <result property="auditType" column="audit_type"/>
        <result property="auditTmpBranchName" column="audit_tmp_branch_name"/>
        <result property="auditPrNumber" column="audit_pr_number"/>
        <result property="keywords" column="keywords"/>
        <result property="remark" column="remark"/>
    </resultMap>

    <sql id="selectCmsDocVo">
        select id,
               create_by,
               create_time,
               update_by,
               update_time,
               name,
               file_name,
               file_path,
               file_sha,
               file_size,
               file_url,
               html_url,
               visits,
               sort,
               publish_time,
               publish_user,
               publish_user_image,
               publish_user_url,
               publish_user_nickname,
               summary,
               head_img,
               dir_name,
               dept_id,
               issue_id,
               is_homepage,
               editor_type,
               is_dir,
               audit_status,
               audit_type,
               audit_tmp_branch_name,
               keywords,
               audit_pr_number,
               remark
        from cms_doc
    </sql>

    <sql id="selectCmsDocAliasVo">
        select cd.id,
               cd.create_by,
               cd.create_time,
               cd.update_by,
               cd.update_time,
               cd.name,
               cd.file_name,
               cd.file_path,
               cd.file_sha,
               cd.file_size,
               cd.file_url,
               cd.html_url,
               cd.visits,
               cd.sort,
               cd.publish_time,
               cd.publish_user,
               cd.publish_user_image,
               cd.publish_user_url,
               cd.publish_user_nickname,
               cd.summary,
               cd.head_img,
               cd.dir_name,
               cd.dept_id,
               cd.issue_id,
               cd.is_homepage,
               cd.editor_type,
               cd.keywords,
               cd.is_dir,
               cd.remark
        from cms_doc cd
    </sql>

    <sql id="selectCmsDocWithScoreVo">
        select cd.id,
               cd.create_by,
               cd.create_time,
               cd.update_by,
               cd.update_time,
               cd.name,
               cd.file_name,
               cd.file_path,
               cd.file_sha,
               cd.file_size,
               cd.file_url,
               cd.html_url,
               cd.visits,
               cd.sort,
               cd.publish_time,
               cd.publish_user,
               cd.publish_user_image,
               cd.publish_user_url,
               cd.publish_user_nickname,
               cd.summary,
               cd.head_img,
               cd.dir_name,
               cd.dept_id,
               cd.issue_id,
               cd.is_homepage,
               cd.editor_type,
               cd.keywords,
               cd.is_dir,
               -- 计算全文搜索相关度评分
               MATCH(cd.name, cd.summary) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE) AS search_score,
               cd.remark
        from cms_doc cd
    </sql>

    <sql id="selectCmsDocAliasSetDefaultHeadImgVo">
        select cd.id,
               cd.create_by,
               cd.create_time,
               cd.update_by,
               cd.update_time,
               cd.name,
               cd.file_name,
               cd.file_path,
               cd.file_sha,
               cd.file_size,
               cd.file_url,
               cd.html_url,
               cd.visits,
               cd.sort,
               cd.publish_time,
               cd.publish_user,
               cd.publish_user_image,
               cd.publish_user_url,
               cd.publish_user_nickname,
               cd.summary,
               -- 处理文章和栏目头图为NULL或空字符串的情况
               CASE
                   -- 文章头图不为空（非NULL且非空字符串）
                   WHEN cd.head_img IS NOT NULL AND TRIM(cd.head_img) != '' THEN cd.head_img
                   -- 栏目存在且头图不为空
                   WHEN dir.head_img IS NOT NULL AND TRIM(dir.head_img) != '' THEN dir.head_img
                   END AS head_img,
               cd.dir_name,
               cd.dept_id,
               cd.issue_id,
               cd.is_homepage,
               cd.editor_type,
               cd.keywords,
               cd.is_dir,
               cd.remark
        from cms_doc cd
                 left join cms_doc dir on cd.dir_name = dir.name and cd.dept_id = dir.dept_id and dir.is_dir=1
    </sql>

    <select id="selectCmsDocAndDirListByDept" resultMap="CmsDocResult">
        <include refid="selectCmsDocVo"/>
        where dept_id=#{deptId}
    </select>

    <select id="selectCmsDocList" parameterType="com.microservices.cms.doc.domain.CmsDocSearchVo"
            resultMap="CmsDocResult">
        <include refid="selectCmsDocVo"/>
        <include refid="selectListWhere"/>
        ORDER BY
        sort DESC,
        update_time DESC,
        create_time DESC
    </select>

    <select id="selectCmsDocById" parameterType="Long" resultMap="CmsDocResult">
        <include refid="selectCmsDocVo"/>
        where id = #{id}
    </select>

    <select id="selectCmsDocByNameAndDeptId" resultMap="CmsDocResult">
        <include refid="selectCmsDocVo"/>
        <where>
            and name = #{name}
            and dept_id = #{deptId}
            <choose>
                <when test="dirName != null">
                    and dir_name = #{dirName}
                </when>
                <otherwise>
                    and is_dir = 1
                </otherwise>
            </choose>
        </where>
    </select>
    <select id="selectCmsDocDirByNameAndDeptId" resultMap="CmsDocResult">
        <include refid="selectCmsDocVo"/>
        where name = #{name} and dept_id = #{deptId} and is_dir = 1
    </select>
    <select id="selectCmsDocDirById" resultMap="CmsDocResult">
        <include refid="selectCmsDocVo"/>
        where id = #{id} and is_dir = 1
    </select>
    <select id="selectCmsDocByFilePathAndDeptId" resultMap="CmsDocResult">
        <include refid="selectCmsDocVo"/>
        where file_path = #{filePath} and dept_id = #{deptId} and is_dir = 0
    </select>
    <select id="selectHotCmsDocList" parameterType="com.microservices.cms.doc.domain.CmsDoc" resultMap="CmsDocResult">
        <include refid="selectCmsDocAliasSetDefaultHeadImgVo"/>
        <include refid="selectListWhereAlias"/>
        ORDER BY
        cd.visits DESC,
        cd.sort DESC,
        cd.update_time DESC,
        cd.create_time DESC

    </select>
    <select id="selectCmsDocCount" resultType="java.lang.Integer">
        select count(0) from cms_doc
        <include refid="selectListWhere"/>
    </select>
    <sql id="selectListWhere">
        <where>
            <if test="name != null  and name != ''">and name like concat('%', #{name}, '%')</if>
            <if test="keywords != null  and keywords != ''">and keywords like concat('%', #{keywords}, '%')</if>
            <if test="fileName != null  and fileName != ''">and file_name like concat('%', #{fileName}, '%')</if>
            <if test="filePath != null  and filePath != ''">and file_path = #{filePath}</if>
            <if test="publishTime != null ">and publish_time = #{publishTime}</if>
            <if test="isDir != null ">and is_dir = #{isDir}</if>
            <if test="dirName != null ">and dir_name = #{dirName}</if>
            <if test="deptId != null ">and dept_id = #{deptId}</if>
            <if test="isHomepage != null ">and is_homepage = #{isHomepage}</if>
            <if test="auditStatus != null and auditStatus != '-1' ">and audit_status = #{auditStatus}</if>
            <if test="auditStatus == null ">and audit_status = '1'</if>
            <if test="createBy != null and createBy != '' ">and create_by = #{createBy}</if>
        </where>
    </sql>

    <sql id="selectListWhereAlias">
        <where>
            <if test="name != null  and name != ''">and cd.name like concat('%', #{name}, '%')</if>
            <if test="keywords != null  and keywords != ''">and cd.keywords like concat('%', #{keywords}, '%')</if>
            <if test="fileName != null  and fileName != ''">and cd.file_name like concat('%', #{fileName}, '%')</if>
            <if test="filePath != null  and filePath != ''">and cd.file_path = #{filePath}</if>
            <if test="publishTime != null ">and cd.publish_time = #{publishTime}</if>
            <if test="isDir != null ">and cd.is_dir = #{isDir}</if>
            <if test="dirName != null ">and cd.dir_name = #{dirName}</if>
            <if test="deptId != null ">and cd.dept_id = #{deptId}</if>
            <if test="isHomepage != null ">and cd.is_homepage = #{isHomepage}</if>
            <if test="auditStatus != null and auditStatus != '-1' ">and cd.audit_status = #{auditStatus}</if>
            <if test="auditStatus == null ">and cd.audit_status = '1'</if>
            <if test="createBy != null and createBy != '' ">and cd.create_by = #{createBy}</if>
        </where>
    </sql>

    <select id="selectCmsDocDirByDeptIdAndInName" resultMap="CmsDocResult">
        <include refid="selectCmsDocVo"/>
        where dept_id = #{deptId} and is_dir = 1
        and name in
        <foreach collection="cmsDirNameList" item="name" index="index"
                 separator="," open="(" close=")">
            #{name}
        </foreach>
    </select>
    <select id="selectCmsDocByDeptIdAndInFilePath" resultMap="CmsDocResult">
        <include refid="selectCmsDocVo"/>
        where dept_id = #{deptId} and is_dir = 0
        and file_path in
        <foreach collection="filePathList" item="filePath" index="index"
                 separator="," open="(" close=")">
            #{filePath}
        </foreach>
    </select>
    <select id="selectCmsDirListByDeptId" resultMap="CmsDocResult">
        <include refid="selectCmsDocVo"/>
        where dept_id = #{deptId} and is_dir = 1
        order by sort ASC
    </select>
    <select id="getCmsCountByDeptId" resultType="java.lang.Long">
        select count(0)
        from cms_doc
        where dept_id = #{deptId}
          and is_dir = 0
          and audit_status = '1'
    </select>
    <select id="selectCmsMaxSortByDeptId" resultType="java.lang.Integer">
        select MAX(sort)
        from cms_doc
        where dept_id = #{deptId}
          and is_dir = #{isDir};
    </select>
    <select id="hasSortCmsByDeptId" resultType="java.lang.Boolean">
        SELECT EXISTS(select * from cms_doc where dept_id = #{deptId} and is_dir = #{isDir} and sort = #{sort});
    </select>
    <select id="selectCmsByOrderAndDeptId" resultType="com.microservices.cms.doc.domain.CmsDoc">
        <include refid="selectCmsDocVo"/>
        where dept_id=#{oldCmsDoc.deptId}
        and is_dir=#{oldCmsDoc.isDir}
        <if test="isChangeOnDir">
            and dir_name = #{oldCmsDoc.dirName}
        </if>
        <if test="!isContainsSelf">
            and id &lt;&gt; #{oldCmsDoc.id}
        </if>
        <choose>
            <when test='oldCmsDoc.isDir == 1'>
                ORDER BY sort ASC
            </when>
            <otherwise>
                ORDER BY sort DESC
            </otherwise>
        </choose>
        LIMIT ${order-1},1
    </select>
    <select id="selectCmsMinSortByDeptId" resultType="java.lang.Integer">
        select MIN(sort)
        from cms_doc
        where dept_id = #{deptId}
          and is_dir = #{isDir};
    </select>
    <select id="selectHomepageCountByDeptIdAndDirName" resultType="java.lang.Integer">
        select count(0)
        from cms_doc
        where dept_id = #{deptId}
        and is_dir = 0
        and is_homepage = 1
        <if test="dirName != null ">and dir_name = #{dirName}</if>
    </select>
    <select id="selectNotDirCmsDocList" resultType="com.microservices.cms.doc.domain.CmsDoc">
        <include refid="selectCmsDocVo"/>
        WHERE
        dir_name NOT IN ( SELECT `name` FROM `cms_doc` WHERE is_dir = 1 AND dept_id = #{deptId} )
        AND is_dir = 0
        AND dept_id = #{deptId}
        AND audit_status = '1'
    </select>
    <select id="selectCmsDocByDeptIdAndFilePath" resultType="com.microservices.cms.doc.domain.CmsDoc">
        <include refid="selectCmsDocVo"/>
        where dept_id = #{deptId} and file_path = #{filePath} and audit_status = '1'
    </select>
    <select id="hasSourceDoc" resultType="java.lang.Integer">
        SELECT COUNT(*) AS count
        FROM cms_doc
        WHERE SUBSTRING_INDEX(audit_type, '-', -1) = #{id}
          and audit_status = '2';
    </select>
    <select id="getNotAuditCmsCountByDeptId" resultType="java.lang.Long">
        select count(0)
        from cms_doc
        where dept_id = #{deptId}
          and is_dir = 0
          and audit_status = '2'
    </select>
    <select id="getCmsDocVisitsByDeptId" resultType="java.lang.Long">
        select SUM(visits)
        from cms_doc
        where dept_id = #{deptId};
    </select>
    <select id="selectCmsDocListSetDefaultHeadImg"  parameterType="com.microservices.cms.doc.domain.CmsDocSearchVo"
            resultMap="CmsDocResult">
        <include refid="selectCmsDocAliasSetDefaultHeadImgVo"/>
        <include refid="selectListWhereAlias"/>
        ORDER BY
        cd.sort DESC,
        cd.update_time DESC,
        cd.create_time DESC
    </select>

    <insert id="insertCmsDoc" parameterType="com.microservices.cms.doc.domain.CmsDoc" useGeneratedKeys="true"
            keyProperty="id">
        insert into cms_doc
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <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="name != null">name,</if>
            <if test="fileName != null">file_name,</if>
            <if test="filePath != null">file_path,</if>
            <if test="fileSha != null and fileSha != ''">file_sha,</if>
            <if test="fileSize != null">file_size,</if>
            <if test="fileUrl != null">file_url,</if>
            <if test="htmlUrl != null">html_url,</if>
            <if test="visits != null">visits,</if>
            <if test="sort != null">sort,</if>
            <if test="publishTime != null">publish_time,</if>
            <if test="publishUser != null">publish_user,</if>
            <if test="publishUserImage != null">publish_user_image,</if>
            <if test="publishUserUrl != null">publish_user_url,</if>
            <if test="publishUserNickname != null">publish_user_nickname,</if>
            <if test="summary != null">summary,</if>
            <if test="isDir != null">is_dir,</if>
            <if test="headImg != null">head_img,</if>
            <if test="dirName != null">dir_name,</if>
            <if test="deptId != null">dept_id,</if>
            <if test="issueId != null">issue_id,</if>
            <if test="isHomepage != null">is_homepage,</if>
            <if test="editorType != null">editor_type,</if>
            <if test="auditStatus != null">audit_status,</if>
            <if test="auditType != null">audit_type,</if>
            <if test="auditTmpBranchName != null">audit_tmp_branch_name,</if>
            <if test="auditPrNumber != null">audit_pr_number,</if>
            <if test="keywords != null">keywords,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <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="name != null">#{name},</if>
            <if test="fileName != null">#{fileName},</if>
            <if test="filePath != null">#{filePath},</if>
            <if test="fileSha != null and fileSha != ''">#{fileSha},</if>
            <if test="fileSize != null">#{fileSize},</if>
            <if test="fileUrl != null">#{fileUrl},</if>
            <if test="htmlUrl != null">#{htmlUrl},</if>
            <if test="visits != null">#{visits},</if>
            <if test="sort != null">#{sort},</if>
            <if test="publishTime != null">#{publishTime},</if>
            <if test="publishUser != null">#{publishUser},</if>
            <if test="publishUserImage != null">#{publishUserImage},</if>
            <if test="publishUserUrl != null">#{publishUserUrl},</if>
            <if test="publishUserNickname != null">#{publishUserNickname},</if>
            <if test="summary != null">#{summary},</if>
            <if test="isDir != null">#{isDir},</if>
            <if test="headImg != null">#{headImg},</if>
            <if test="dirName != null">#{dirName},</if>
            <if test="deptId != null">#{deptId},</if>
            <if test="issueId != null">#{issueId},</if>
            <if test="isHomepage != null">#{isHomepage},</if>
            <if test="editorType != null">#{editorType},</if>
            <if test="auditStatus != null">#{auditStatus},</if>
            <if test="auditType != null">#{auditType},</if>
            <if test="auditTmpBranchName != null">#{auditTmpBranchName},</if>
            <if test="auditPrNumber != null">#{auditPrNumber},</if>
            <if test="keywords != null">#{keywords},</if>
        </trim>
    </insert>

    <update id="updateCmsDoc" parameterType="com.microservices.cms.doc.domain.CmsDoc">
        update cms_doc
        <trim prefix="SET" suffixOverrides=",">
            <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="name != null">name = #{name},</if>
            <if test="fileName != null">file_name = #{fileName},</if>
            <if test="filePath != null">file_path = #{filePath},</if>
            <if test="fileSha != null and fileSha != ''">file_sha = #{fileSha},</if>
            <if test="fileSize != null">file_size = #{fileSize},</if>
            <if test="fileUrl != null">file_url = #{fileUrl},</if>
            <if test="htmlUrl != null">html_url = #{htmlUrl},</if>
            <if test="visits != null">visits = #{visits},</if>
            <if test="sort != null">sort = #{sort},</if>
            <if test="publishTime != null">publish_time = #{publishTime},</if>
            <if test="publishUser != null">publish_user = #{publishUser},</if>
            <if test="publishUserImage != null">publish_user_image = #{publishUserImage},</if>
            <if test="publishUserUrl != null">publish_user_url = #{publishUserUrl},</if>
            <if test="publishUserNickname != null">publish_user_nickname = #{publishUserNickname},</if>
            <if test="summary != null">summary = #{summary},</if>
            <if test="isDir != null">is_dir = #{isDir},</if>
            <if test="headImg != null">head_img = #{headImg},</if>
            <if test="dirName != null">dir_name = #{dirName},</if>
            <if test="deptId != null">dept_id = #{deptId},</if>
            <if test="issueId != null">issue_id = #{issueId},</if>
            <if test="isHomepage != null">is_homepage = #{isHomepage},</if>
            <if test="auditStatus != null">audit_status = #{auditStatus},</if>
            <if test="auditType != null">audit_type = #{auditType},</if>
            <if test="auditTmpBranchName != null">audit_tmp_branch_name = #{auditTmpBranchName},</if>
            <if test="auditPrNumber != null">audit_pr_number = #{auditPrNumber},</if>
            <if test="keywords != null">keywords = #{keywords},</if>
            <if test="remark != null">remark = #{remark},</if>
        </trim>
        where id = #{id}
    </update>
    <update id="batchUpdateCmsSortIncreased">
        update cms_doc
        set sort=sort + 1
        where sort &gt;= #{setSort}
          and dept_id = #{deptId}
          and is_dir = #{isDir};
    </update>
    <update id="batchUpdateCmsSortDecrease">
        update cms_doc
        set sort=sort - 1
        where sort &lt;= #{setSort}
          and dept_id = #{deptId}
          and is_dir = #{isDir};
    </update>
    <update id="updateCmsDocShaByPathAndDeptId">
        update cms_doc
        set file_sha=#{sha}
        where file_path=#{filePath}
        and dept_id=#{deptId}
    </update>

    <delete id="deleteCmsDocById" parameterType="Long">
        delete
        from cms_doc
        where id = #{id}
    </delete>

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

    <!-- 全局搜索 - 全文索引查询（含 LIKE 后备搜索） -->
    <select id="globalSearch" resultMap="CmsDocResult">
        <include refid="selectCmsDocAliasVo"/>
        WHERE
            cd.is_dir = 0
            AND cd.audit_status = '1'
            AND (
                MATCH(cd.name, cd.summary) AGAINST(#{keyword} IN BOOLEAN MODE)
                OR cd.name LIKE CONCAT('%', #{keyword}, '%')
                OR cd.summary LIKE CONCAT('%', #{keyword}, '%')
            )
            <if test="deptId != null">
                AND cd.dept_id = #{deptId}
            </if>
        ORDER BY
            CASE
                WHEN MATCH(cd.name, cd.summary) AGAINST(#{keyword} IN BOOLEAN MODE) > 0 THEN 1
                ELSE 2
            END,
            cd.update_time DESC
        LIMIT #{offset}, #{pageSize}
    </select>

    <select id="globalSearchCount" resultType="java.lang.Long">
        SELECT COUNT(*)
        FROM cms_doc cd
        WHERE
            cd.is_dir = 0
            AND cd.audit_status = '1'
            AND (
                MATCH(cd.name, cd.summary) AGAINST(#{keyword} IN BOOLEAN MODE)
                OR cd.name LIKE CONCAT('%', #{keyword}, '%')
                OR cd.summary LIKE CONCAT('%', #{keyword}, '%')
            )
            <if test="deptId != null">
                AND cd.dept_id = #{deptId}
            </if>
    </select>

    <!-- ResultMap for CmsDocWithScore -->
    <resultMap type="com.microservices.cms.doc.domain.CmsDocWithScore" id="CmsDocWithScoreResult" extends="CmsDocResult">
        <result property="searchScore" column="search_score"/>
    </resultMap>

    <!-- 全局搜索 - 带评分的全文索引查询 -->
    <select id="globalSearchWithScore" resultMap="CmsDocWithScoreResult">
            <include refid="selectCmsDocWithScoreVo"/>
        WHERE
            cd.is_dir = 0
            AND cd.audit_status = '1'
            AND (
                MATCH(cd.name, cd.summary) AGAINST(#{keyword} IN BOOLEAN MODE)
                OR cd.name LIKE CONCAT('%', #{keyword}, '%')
                OR cd.summary LIKE CONCAT('%', #{keyword}, '%')
            )
            <if test="deptId != null">
                AND cd.dept_id = #{deptId}
            </if>
        ORDER BY
            -- 主要排序：按相关度评分降序
            search_score DESC,
            -- 次要排序：更新时间降序
            cd.update_time DESC
        LIMIT #{offset}, #{pageSize}
    </select>
</mapper>