<?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.persagy.dmp.rwd.define.dao.ObjectInfoMapper">
    <!-- 因该对象dataSource字段需要使用自定义Handler处理,
    且在xml自定义sql使用的是MybatisConfiguration类对象,
    无法使用mybatis-plus,所以这里定义了一个ResultMap-->
    <resultMap id="BaseResultMap" type="com.persagy.dmp.define.entity.ObjectInfoDefine">
        <result property="dataSource" column="data_source" jdbcType="OTHER" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
    </resultMap>
    <!-- 类型如果重复则会出现多条，因此这里先用distinct容错.将基础类型的信息点与非基础信息点一起返回，且class_code改为对应的非基础对象类型 -->
    <sql id="SelectColumns">
        distinct
          dt_define_info.id, dt_define_info.code, dt_define_info.name, dt_define_info.alias_code,
          dt_define_info.alias_name, dt_define_type.code as class_code, dt_define_info.group_code,
          dt_define_info.project_id,dt_define_info.category,dt_define_info.first_tag,
          dt_define_info.second_tag, dt_define_info.priority,dt_define_info.input_mode,
          dt_define_info.unit,dt_define_info.data_type,dt_define_info.is_multiple,dt_define_info.is_region,
          dt_define_info.formater,dt_define_info.data_source,
          dt_define_info.remark,dt_define_info.sub_flag,
          dt_define_info.weak_point,dt_define_info.show_order,dt_define_info.version,dt_define_info.creator,
          dt_define_info.creation_time,dt_define_info.modifier,dt_define_info.modified_time,
          dt_define_info.valid,dt_define_info.ts
    </sql>
    <!--
        1. 如果为基础类型、且为平台级，优先级100
        2. 如果为基础类型、且为集团级，优先级200
        3. 如果为基础类型、且为项目级，优先级300
        4. 如果为非基础类型、且为平台级，优先级400
        5. 如果为非基础类型、且为集团级，优先级500
        6. 如果为非基础类型、且为项目级，优先级600
    -->
    <sql id="ShowLevelSQL">
        (case
        when dt_define_info.class_code in ('project','building','floor','space','system','equipment','shaft','component','virtual','tool','material')
          and dt_define_info.project_id = '0' then 100
        when dt_define_info.class_code in ('project','building','floor','space','system','equipment','shaft','component','virtual','tool','material')
          and dt_define_info.project_id = dt_define_info.group_code then 200
        when dt_define_info.class_code in ('project','building','floor','space','system','equipment','shaft','component','virtual','tool','material')
          and dt_define_info.project_id != dt_define_info.group_code then 300
        when dt_define_info.class_code not in ('project','building','floor','space','system','equipment','shaft','component','virtual','tool','material')
          and dt_define_info.project_id = '0' then 400
        when dt_define_info.class_code not in ('project','building','floor','space','system','equipment','shaft','component','virtual','tool','material')
          and dt_define_info.project_id = dt_define_info.group_code then 500
        when dt_define_info.class_code not in ('project','building','floor','space','system','equipment','shaft','component','virtual','tool','material')
          and dt_define_info.project_id != dt_define_info.group_code then 600
        else 0 end)
    </sql>
    <!-- 按项目查询信息点（包含上级信息点） -->
    <sql id="InfoTableSQL">
        select
        <include refid="SelectColumns"/>
        from dt_define_type inner join dt_define_info on dt_define_info.class_code in (dt_define_type.code, dt_define_type.obj_type)
            and dt_define_type.valid = 1 and dt_define_info.valid = 1
        <if test="projectIds!=null and projectIds.size>0">
            <foreach collection="projectIds" item="projectId" separator="," open=" and dt_define_info.project_id IN (" close=")">
                #{projectId}
            </foreach>
        </if>
        <if test="classCodes!=null and classCodes.size>0">
            <foreach collection="classCodes" item="classCode" separator="," open=" and dt_define_type.code IN (" close=")">
                #{classCode}
            </foreach>
        </if>
        where exists(select 1 from (
        select dt_define_type.code class_code, dt_define_info.code code, max(<include refid="ShowLevelSQL"/>) max_show_level
        from dt_define_type inner join dt_define_info on dt_define_info.class_code in (dt_define_type.code, dt_define_type.obj_type)
        and dt_define_type.valid = 1 and dt_define_info.valid = 1
        <if test="projectIds!=null and projectIds.size>0">
            <foreach collection="projectIds" item="projectId" separator="," open="where dt_define_info.project_id IN (" close=")">
                #{projectId}
            </foreach>
        </if>
        <if test="classCodes!=null and classCodes.size>0">
            <foreach collection="classCodes" item="classCode" separator="," open=" and dt_define_type.code IN (" close=")">
                #{classCode}
            </foreach>
        </if>
        group by dt_define_type.code, dt_define_info.code
        ) T
        where T.class_code = dt_define_type.code and T.code = dt_define_info.code and T.max_show_level = <include refid="ShowLevelSQL"/>)
    </sql>
    <select id="queryByClassCodes" resultType="com.persagy.dmp.define.entity.ObjectInfoDefine" resultMap="BaseResultMap">
        select ${ew.sqlSelect}
        from ( <include refid="InfoTableSQL"/> ) dt_define_info
        WHERE 1=1
        <if test="ew.expression.sqlSegment!=null and ew.expression.sqlSegment.length>0">
            AND ${ew.expression.sqlSegment}
        </if>
    </select>
    <select id="queryCollectInfos" resultType="java.util.Map">
        select dt_object.id, dt_object.local_id, dt_object.local_name, dt_define_info.class_code, dt_define_type.name as class_name,
            dt_define_info.code, dt_define_info.name,dt_define_info.first_tag, dt_define_info.data_type,dt_define_info.category,
            json_unquote(json_extract(dt_object.infos, concat('$.', dt_define_info.code))) as info_value
        from ( <include refid="InfoTableSQL"/> ) dt_define_info
        inner join dt_define_type on dt_define_info.class_code = dt_define_type.code and dt_define_type.valid = 1
        inner join dt_object on dt_object.class_code = dt_define_info.class_code and dt_object.valid = 1 and dt_define_info.code not in ('localId','localName')
        WHERE ${ew.expression.sqlSegment}
    </select>
    <select id="queryCollectReport" resultType="java.util.Map">
        select count(1) as all_num, sum(case when category = 'STATIC' then 1 else 0 end) as static_num,
            sum(case when category = 'STATIC' and info_value is not null then 1 else 0 end) as static_value_num,
            sum(case when category != 'STATIC' then 1 else 0 end) as dynamic_num,
            sum(case when category != 'STATIC' and info_value is not null then 1 else 0 end) as dynamic_value_num
        from (
            select dt_object.id, dt_object.local_id, dt_object.local_name, dt_define_info.class_code, dt_define_type.name as class_name,
            dt_define_info.code, dt_define_info.name,dt_define_info.first_tag, dt_define_info.data_type,dt_define_info.category,
            json_unquote(json_extract(dt_object.infos, concat('$.', dt_define_info.code))) as info_value
            from ( <include refid="InfoTableSQL"/> ) dt_define_info
            inner join dt_define_type on dt_define_info.class_code = dt_define_type.code and dt_define_type.valid = 1
            inner join dt_object on dt_object.class_code = dt_define_info.class_code and dt_object.valid = 1 and dt_define_info.code not in ('localId','localName')
            WHERE ${ew.expression.sqlSegment}
        ) R
    </select>

</mapper>
