<?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.ems.mapper.CustomReportMapper">

    <!-- ==================== ResultMap定义 ==================== -->

    <resultMap type="com.ruoyi.ems.domain.ReportDatasource" id="DatasourceResult">
        <id property="id" column="id"/>
        <result property="dsCode" column="ds_code"/>
        <result property="dsName" column="ds_name"/>
        <result property="dsDesc" column="ds_desc"/>
        <result property="mainTable" column="main_table"/>
        <result property="mainAlias" column="main_alias"/>
        <result property="baseWhere" column="base_where"/>
        <result property="defaultOrder" column="default_order"/>
        <result property="category" column="category"/>
        <result property="icon" column="icon"/>
        <result property="sortOrder" column="sort_order"/>
        <result property="status" column="status"/>
        <result property="remark" column="remark"/>
        <result property="createBy" column="create_by"/>
        <result property="createTime" column="create_time"/>
        <result property="updateBy" column="update_by"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>

    <resultMap type="com.ruoyi.ems.domain.ReportField" id="FieldResult">
        <id property="id" column="id"/>
        <result property="dsCode" column="ds_code"/>
        <result property="fieldCode" column="field_code"/>
        <result property="fieldName" column="field_name"/>
        <result property="fieldAlias" column="field_alias"/>
        <result property="fieldExpr" column="field_expr"/>
        <result property="fieldType" column="field_type"/>
        <result property="fieldFormat" column="field_format"/>
        <result property="decimals" column="decimals"/>
        <result property="unit" column="unit"/>
        <result property="dictType" column="dict_type"/>
        <result property="isDefault" column="is_default"/>
        <result property="isRequired" column="is_required"/>
        <result property="isFilterable" column="is_filterable"/>
        <result property="isSortable" column="is_sortable"/>
        <result property="isAggregatable" column="is_aggregatable"/>
        <result property="aggregateFunc" column="aggregate_func"/>
        <result property="groupName" column="group_name"/>
        <result property="width" column="width"/>
        <result property="minWidth" column="min_width"/>
        <result property="sortOrder" column="sort_order"/>
        <result property="status" column="status"/>
        <result property="remark" column="remark"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>

    <resultMap type="com.ruoyi.ems.domain.ReportFieldCondition" id="FieldConditionResult">
        <id property="id" column="id"/>
        <result property="dsCode" column="ds_code"/>
        <result property="fieldCode" column="field_code"/>
        <result property="conditionType" column="condition_type"/>
        <result property="conditionName" column="condition_name"/>
        <result property="conditionSymbol" column="condition_symbol"/>
        <result property="valueCount" column="value_count"/>
        <result property="defaultValue" column="default_value"/>
        <result property="isDefault" column="is_default"/>
        <result property="sortOrder" column="sort_order"/>
        <result property="status" column="status"/>
    </resultMap>

    <resultMap type="com.ruoyi.ems.domain.ReportRelation" id="RelationResult">
        <id property="id" column="id"/>
        <result property="dsCode" column="ds_code"/>
        <result property="relationCode" column="relation_code"/>
        <result property="relationName" column="relation_name"/>
        <result property="joinType" column="join_type"/>
        <result property="joinTable" column="join_table"/>
        <result property="joinAlias" column="join_alias"/>
        <result property="joinCondition" column="join_condition"/>
        <result property="isAutoJoin" column="is_auto_join"/>
        <result property="sortOrder" column="sort_order"/>
        <result property="status" column="status"/>
        <result property="remark" column="remark"/>
    </resultMap>

    <resultMap type="com.ruoyi.ems.domain.ReportTemplate" id="TemplateResult">
        <id property="id" column="id"/>
        <result property="templateCode" column="template_code"/>
        <result property="templateName" column="template_name"/>
        <result property="templateDesc" column="template_desc"/>
        <result property="dsCode" column="ds_code"/>
        <result property="configJson" column="config_json"/>
        <result property="isPublic" column="is_public"/>
        <result property="isSystem" column="is_system"/>
        <result property="useCount" column="use_count"/>
        <result property="userId" column="user_id"/>
        <result property="userName" column="user_name"/>
        <result property="deptId" column="dept_id"/>
        <result property="status" column="status"/>
        <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="dsName" column="ds_name"/>
    </resultMap>

    <!-- ==================== 数据源管理SQL ==================== -->

    <sql id="selectDatasourceSql">
        SELECT id, ds_code, ds_name, ds_desc, main_table, main_alias, base_where,
               default_order, category, icon, sort_order, status, remark,
               create_by, create_time, update_by, update_time
        FROM adm_report_datasource
    </sql>

    <select id="selectDatasourceList" resultMap="DatasourceResult">
        <include refid="selectDatasourceSql"/>
        <where>
            status = 1
            <if test="category != null and category != ''">
                AND category = #{category}
            </if>
        </where>
        ORDER BY sort_order ASC, ds_code ASC
    </select>

    <select id="selectDatasourceByCode" resultMap="DatasourceResult">
        <include refid="selectDatasourceSql"/>
        WHERE ds_code = #{dsCode}
    </select>

    <insert id="insertDatasource" parameterType="com.ruoyi.ems.domain.ReportDatasource" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO adm_report_datasource (
            ds_code, ds_name, ds_desc, main_table, main_alias, base_where,
            default_order, category, icon, sort_order, status, remark, create_by, create_time
        ) VALUES (
                     #{dsCode}, #{dsName}, #{dsDesc}, #{mainTable}, #{mainAlias}, #{baseWhere},
                     #{defaultOrder}, #{category}, #{icon}, #{sortOrder}, #{status}, #{remark}, #{createBy}, NOW()
                 )
    </insert>

    <update id="updateDatasource" parameterType="com.ruoyi.ems.domain.ReportDatasource">
        UPDATE adm_report_datasource
        <set>
            <if test="dsName != null and dsName != ''">ds_name = #{dsName},</if>
            <if test="dsDesc != null">ds_desc = #{dsDesc},</if>
            <if test="mainTable != null and mainTable != ''">main_table = #{mainTable},</if>
            <if test="mainAlias != null">main_alias = #{mainAlias},</if>
            <if test="baseWhere != null">base_where = #{baseWhere},</if>
            <if test="defaultOrder != null">default_order = #{defaultOrder},</if>
            <if test="category != null">category = #{category},</if>
            <if test="icon != null">icon = #{icon},</if>
            <if test="sortOrder != null">sort_order = #{sortOrder},</if>
            <if test="status != null">status = #{status},</if>
            <if test="remark != null">remark = #{remark},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
            update_time = NOW()
        </set>
        WHERE ds_code = #{dsCode}
    </update>

    <delete id="deleteDatasource">
        DELETE FROM adm_report_datasource WHERE ds_code = #{dsCode}
    </delete>

    <!-- ==================== 字段管理SQL ==================== -->

    <sql id="selectFieldSql">
        SELECT id, ds_code, field_code, field_name, field_alias, field_expr, field_type,
               field_format, decimals, unit, dict_type, is_default, is_required,
               is_filterable, is_sortable, is_aggregatable, aggregate_func, group_name,
               width, min_width, sort_order, status, remark, create_time, update_time
        FROM adm_report_field
    </sql>

    <select id="selectFieldsByDsCode" resultMap="FieldResult">
        <include refid="selectFieldSql"/>
        WHERE ds_code = #{dsCode} AND status = 1
        ORDER BY sort_order ASC, field_code ASC
    </select>

    <select id="selectField" resultMap="FieldResult">
        <include refid="selectFieldSql"/>
        WHERE ds_code = #{dsCode} AND field_code = #{fieldCode}
    </select>

    <insert id="insertField" parameterType="com.ruoyi.ems.domain.ReportField" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO adm_report_field (
            ds_code, field_code, field_name, field_alias, field_expr, field_type,
            field_format, decimals, unit, dict_type, is_default, is_required,
            is_filterable, is_sortable, is_aggregatable, aggregate_func, group_name,
            width, min_width, sort_order, status, remark, create_time
        ) VALUES (
                     #{dsCode}, #{fieldCode}, #{fieldName}, #{fieldAlias}, #{fieldExpr}, #{fieldType},
                     #{fieldFormat}, #{decimals}, #{unit}, #{dictType}, #{isDefault}, #{isRequired},
                     #{isFilterable}, #{isSortable}, #{isAggregatable}, #{aggregateFunc}, #{groupName},
                     #{width}, #{minWidth}, #{sortOrder}, #{status}, #{remark}, NOW()
                 )
    </insert>

    <insert id="insertFieldBatch" parameterType="java.util.List">
        INSERT INTO adm_report_field (
        ds_code, field_code, field_name, field_alias, field_expr, field_type,
        field_format, decimals, unit, dict_type, is_default, is_required,
        is_filterable, is_sortable, is_aggregatable, aggregate_func, group_name,
        width, min_width, sort_order, status, remark, create_time
        ) VALUES
        <foreach collection="list" item="item" separator=",">
            (
            #{item.dsCode}, #{item.fieldCode}, #{item.fieldName}, #{item.fieldAlias}, #{item.fieldExpr}, #{item.fieldType},
            #{item.fieldFormat}, #{item.decimals}, #{item.unit}, #{item.dictType}, #{item.isDefault}, #{item.isRequired},
            #{item.isFilterable}, #{item.isSortable}, #{item.isAggregatable}, #{item.aggregateFunc}, #{item.groupName},
            #{item.width}, #{item.minWidth}, #{item.sortOrder}, #{item.status}, #{item.remark}, NOW()
            )
        </foreach>
    </insert>

    <update id="updateField" parameterType="com.ruoyi.ems.domain.ReportField">
        UPDATE adm_report_field
        <set>
            <if test="fieldName != null and fieldName != ''">field_name = #{fieldName},</if>
            <if test="fieldAlias != null">field_alias = #{fieldAlias},</if>
            <if test="fieldExpr != null">field_expr = #{fieldExpr},</if>
            <if test="fieldType != null">field_type = #{fieldType},</if>
            <if test="fieldFormat != null">field_format = #{fieldFormat},</if>
            <if test="decimals != null">decimals = #{decimals},</if>
            <if test="unit != null">unit = #{unit},</if>
            <if test="dictType != null">dict_type = #{dictType},</if>
            <if test="isDefault != null">is_default = #{isDefault},</if>
            <if test="isRequired != null">is_required = #{isRequired},</if>
            <if test="isFilterable != null">is_filterable = #{isFilterable},</if>
            <if test="isSortable != null">is_sortable = #{isSortable},</if>
            <if test="isAggregatable != null">is_aggregatable = #{isAggregatable},</if>
            <if test="aggregateFunc != null">aggregate_func = #{aggregateFunc},</if>
            <if test="groupName != null">group_name = #{groupName},</if>
            <if test="width != null">width = #{width},</if>
            <if test="minWidth != null">min_width = #{minWidth},</if>
            <if test="sortOrder != null">sort_order = #{sortOrder},</if>
            <if test="status != null">status = #{status},</if>
            <if test="remark != null">remark = #{remark},</if>
            update_time = NOW()
        </set>
        WHERE ds_code = #{dsCode} AND field_code = #{fieldCode}
    </update>

    <delete id="deleteField">
        DELETE FROM adm_report_field WHERE ds_code = #{dsCode} AND field_code = #{fieldCode}
    </delete>

    <delete id="deleteFieldsByDsCode">
        DELETE FROM adm_report_field WHERE ds_code = #{dsCode}
    </delete>

    <!-- ==================== 字段条件管理SQL ==================== -->

    <sql id="selectFieldConditionSql">
        SELECT id, ds_code, field_code, condition_type, condition_name, condition_symbol,
               value_count, default_value, is_default, sort_order, status
        FROM adm_report_field_condition
    </sql>

    <select id="selectFieldConditions" resultMap="FieldConditionResult">
        <include refid="selectFieldConditionSql"/>
        WHERE ds_code = #{dsCode} AND field_code = #{fieldCode} AND status = 1
        ORDER BY sort_order ASC
    </select>

    <select id="selectAllFieldConditions" resultMap="FieldConditionResult">
        <include refid="selectFieldConditionSql"/>
        WHERE ds_code = #{dsCode} AND status = 1
        ORDER BY field_code ASC, sort_order ASC
    </select>

    <insert id="insertFieldCondition" parameterType="com.ruoyi.ems.domain.ReportFieldCondition" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO adm_report_field_condition (
            ds_code, field_code, condition_type, condition_name, condition_symbol,
            value_count, default_value, is_default, sort_order, status
        ) VALUES (
                     #{dsCode}, #{fieldCode}, #{conditionType}, #{conditionName}, #{conditionSymbol},
                     #{valueCount}, #{defaultValue}, #{isDefault}, #{sortOrder}, #{status}
                 )
    </insert>

    <insert id="insertFieldConditionBatch" parameterType="java.util.List">
        INSERT INTO adm_report_field_condition (
        ds_code, field_code, condition_type, condition_name, condition_symbol,
        value_count, default_value, is_default, sort_order, status
        ) VALUES
        <foreach collection="list" item="item" separator=",">
            (
            #{item.dsCode}, #{item.fieldCode}, #{item.conditionType}, #{item.conditionName}, #{item.conditionSymbol},
            #{item.valueCount}, #{item.defaultValue}, #{item.isDefault}, #{item.sortOrder}, #{item.status}
            )
        </foreach>
    </insert>

    <delete id="deleteFieldConditions">
        DELETE FROM adm_report_field_condition WHERE ds_code = #{dsCode}
        <if test="fieldCode != null and fieldCode != ''">
            AND field_code = #{fieldCode}
        </if>
    </delete>

    <!-- ==================== 关联管理SQL ==================== -->

    <sql id="selectRelationSql">
        SELECT id, ds_code, relation_code, relation_name, join_type, join_table,
               join_alias, join_condition, is_auto_join, sort_order, status, remark
        FROM adm_report_relation
    </sql>

    <select id="selectRelationsByDsCode" resultMap="RelationResult">
        <include refid="selectRelationSql"/>
        WHERE ds_code = #{dsCode} AND status = 1
        ORDER BY sort_order ASC
    </select>

    <select id="selectRelation" resultMap="RelationResult">
        <include refid="selectRelationSql"/>
        WHERE ds_code = #{dsCode} AND relation_code = #{relationCode}
    </select>

    <insert id="insertRelation" parameterType="com.ruoyi.ems.domain.ReportRelation" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO adm_report_relation (
            ds_code, relation_code, relation_name, join_type, join_table,
            join_alias, join_condition, is_auto_join, sort_order, status, remark
        ) VALUES (
                     #{dsCode}, #{relationCode}, #{relationName}, #{joinType}, #{joinTable},
                     #{joinAlias}, #{joinCondition}, #{isAutoJoin}, #{sortOrder}, #{status}, #{remark}
                 )
    </insert>

    <update id="updateRelation" parameterType="com.ruoyi.ems.domain.ReportRelation">
        UPDATE adm_report_relation
        <set>
            <if test="relationName != null">relation_name = #{relationName},</if>
            <if test="joinType != null">join_type = #{joinType},</if>
            <if test="joinTable != null">join_table = #{joinTable},</if>
            <if test="joinAlias != null">join_alias = #{joinAlias},</if>
            <if test="joinCondition != null">join_condition = #{joinCondition},</if>
            <if test="isAutoJoin != null">is_auto_join = #{isAutoJoin},</if>
            <if test="sortOrder != null">sort_order = #{sortOrder},</if>
            <if test="status != null">status = #{status},</if>
            <if test="remark != null">remark = #{remark},</if>
        </set>
        WHERE ds_code = #{dsCode} AND relation_code = #{relationCode}
    </update>

    <delete id="deleteRelation">
        DELETE FROM adm_report_relation WHERE ds_code = #{dsCode} AND relation_code = #{relationCode}
    </delete>

    <delete id="deleteRelationsByDsCode">
        DELETE FROM adm_report_relation WHERE ds_code = #{dsCode}
    </delete>

    <!-- ==================== 字段关联映射SQL ==================== -->

    <select id="selectFieldRelationCodes" resultType="java.lang.String">
        SELECT relation_code FROM adm_report_field_relation
        WHERE ds_code = #{dsCode} AND field_code = #{fieldCode}
    </select>

    <select id="selectAllFieldRelations" resultType="java.util.Map">
        SELECT field_code AS fieldCode, relation_code AS relationCode
        FROM adm_report_field_relation
        WHERE ds_code = #{dsCode}
    </select>

    <insert id="insertFieldRelation">
        INSERT INTO adm_report_field_relation (ds_code, field_code, relation_code)
        VALUES (#{dsCode}, #{fieldCode}, #{relationCode})
    </insert>

    <delete id="deleteFieldRelations">
        DELETE FROM adm_report_field_relation WHERE ds_code = #{dsCode}
        <if test="fieldCode != null and fieldCode != ''">
            AND field_code = #{fieldCode}
        </if>
    </delete>

    <!-- ==================== 模板管理SQL ==================== -->

    <sql id="selectTemplateSql">
        SELECT t.id, t.template_code, t.template_name, t.template_desc, t.ds_code,
               t.config_json, t.is_public, t.is_system, t.use_count, t.user_id, t.user_name,
               t.dept_id, t.status, t.create_by, t.create_time, t.update_by, t.update_time,
               d.ds_name
        FROM adm_report_template t
                 LEFT JOIN adm_report_datasource d ON t.ds_code = d.ds_code
    </sql>

    <select id="selectTemplateList" parameterType="com.ruoyi.ems.domain.ReportTemplate" resultMap="TemplateResult">
        <include refid="selectTemplateSql"/>
        <where>
            t.status = 1
            <if test="dsCode != null and dsCode != ''">
                AND t.ds_code = #{dsCode}
            </if>
            <if test="templateName != null and templateName != ''">
                AND t.template_name LIKE CONCAT('%', #{templateName}, '%')
            </if>
            <!-- 查询公开模板或自己的私有模板 -->
            <if test="userId != null">
                AND (t.is_public = 1 OR t.user_id = #{userId})
            </if>
            <if test="isSystem != null">
                AND t.is_system = #{isSystem}
            </if>
        </where>
        ORDER BY t.is_system DESC, t.use_count DESC, t.create_time DESC
    </select>

    <select id="selectTemplateByCode" resultMap="TemplateResult">
        <include refid="selectTemplateSql"/>
        WHERE t.template_code = #{templateCode}
    </select>

    <select id="checkTemplateCodeExists" resultType="int">
        SELECT COUNT(1) FROM adm_report_template WHERE template_code = #{templateCode}
    </select>

    <insert id="insertTemplate" parameterType="com.ruoyi.ems.domain.ReportTemplate" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO adm_report_template (
            template_code, template_name, template_desc, ds_code, config_json,
            is_public, is_system, use_count, user_id, user_name, dept_id, status, create_by, create_time
        ) VALUES (
                     #{templateCode}, #{templateName}, #{templateDesc}, #{dsCode}, #{configJson},
                     #{isPublic}, #{isSystem}, 0, #{userId}, #{userName}, #{deptId}, #{status}, #{createBy}, NOW()
                 )
    </insert>

    <update id="updateTemplate" parameterType="com.ruoyi.ems.domain.ReportTemplate">
        UPDATE adm_report_template
        <set>
            <if test="templateName != null and templateName != ''">template_name = #{templateName},</if>
            <if test="templateDesc != null">template_desc = #{templateDesc},</if>
            <if test="configJson != null">config_json = #{configJson},</if>
            <if test="isPublic != null">is_public = #{isPublic},</if>
            <if test="status != null">status = #{status},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
            update_time = NOW()
        </set>
        WHERE template_code = #{templateCode}
    </update>

    <delete id="deleteTemplate">
        DELETE FROM adm_report_template WHERE template_code = #{templateCode}
    </delete>

    <update id="incrementTemplateUseCount">
        UPDATE adm_report_template SET use_count = use_count + 1 WHERE template_code = #{templateCode}
    </update>

    <!-- ==================== 动态查询执行SQL ==================== -->

    <!-- 注意：动态SQL在Service层构建，这里使用${}直接拼接 -->
    <select id="executeDynamicQuery" resultType="java.util.LinkedHashMap">
        ${sql}
        <if test="params != null and params.pageNum != null and params.pageSize != null">
            LIMIT #{params.offset}, #{params.pageSize}
        </if>
    </select>

    <select id="executeDynamicCount" resultType="java.lang.Long">
        SELECT COUNT(*) FROM (${sql}) AS count_table
    </select>

    <select id="executeDynamicSummary" resultType="java.util.LinkedHashMap">
        ${sql}
    </select>

</mapper>