<?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.ccdi.project.mapper.CcdiRelationGraphMapper">

    <resultMap id="RelationGraphNodeResultMap" type="com.ruoyi.ccdi.project.domain.vo.CcdiRelationGraphNodeVO">
        <id property="objectKey" column="objectKey"/>
        <result property="nodeKey" column="nodeKey"/>
        <result property="nodeName" column="nodeName"/>
        <result property="idNumber" column="idNumber"/>
        <result property="subjectType" column="subjectType"/>
        <result property="sourceType" column="sourceType"/>
        <result property="createdTime" column="createdTime"/>
        <result property="updatedTime" column="updatedTime"/>
        <result property="canExpand" column="canExpand"/>
        <result property="depth" column="depth"/>
    </resultMap>

    <resultMap id="RelationGraphEdgeResultMap" type="com.ruoyi.ccdi.project.domain.vo.CcdiRelationGraphEdgeVO">
        <id property="objectKey" column="objectKey"/>
        <result property="fromKey" column="fromKey"/>
        <result property="toKey" column="toKey"/>
        <result property="edgeTable" column="edgeTable"/>
        <result property="relationType" column="relationType"/>
        <result property="companyName" column="companyName"/>
        <result property="stockName" column="stockName"/>
        <result property="stockType" column="stockType"/>
        <result property="stockPercent" column="stockPercent"/>
        <result property="shouldCapi" column="shouldCapi"/>
        <result property="shouldCapiValue" column="shouldCapiValue"/>
        <result property="shouldCapiUnit" column="shouldCapiUnit"/>
        <result property="shoudDate" column="shoudDate"/>
        <result property="pKeyNo" column="pKeyNo"/>
        <result property="operName" column="operName"/>
        <result property="operKeyNo" column="operKeyNo"/>
        <result property="personId" column="personId"/>
        <result property="relationName" column="relationName"/>
        <result property="relationCertNo" column="relationCertNo"/>
        <result property="gender" column="gender"/>
        <result property="birthDate" column="birthDate"/>
        <result property="relationCertType" column="relationCertType"/>
        <result property="mobilePhone1" column="mobilePhone1"/>
        <result property="mobilePhone2" column="mobilePhone2"/>
        <result property="wechatNo1" column="wechatNo1"/>
        <result property="wechatNo2" column="wechatNo2"/>
        <result property="wechatNo3" column="wechatNo3"/>
        <result property="contactAddress" column="contactAddress"/>
        <result property="annualIncome" column="annualIncome"/>
        <result property="relationDesc" column="relationDesc"/>
        <result property="status" column="status"/>
        <result property="effectiveDate" column="effectiveDate"/>
        <result property="invalidDate" column="invalidDate"/>
        <result property="remark" column="remark"/>
        <result property="dataSource" column="dataSource"/>
    </resultMap>

    <resultMap id="SuspectedEnterpriseResultMap" type="com.ruoyi.ccdi.project.domain.vo.CcdiRelationGraphSuspectedEnterpriseItemVO">
        <result property="candidateKeyNo" column="candidateKeyNo"/>
        <result property="personName" column="personName"/>
        <result property="companyId" column="companyId"/>
        <result property="companyName" column="companyName"/>
        <result property="creditCode" column="creditCode"/>
        <result property="enterpriseStatus" column="enterpriseStatus"/>
        <result property="industryName" column="industryName"/>
        <result property="relationType" column="relationType"/>
        <result property="stockPercent" column="stockPercent"/>
        <result property="establishDate" column="establishDate"/>
    </resultMap>

    <sql id="nodeColumns">
        n.object_key AS objectKey,
        CONCAT('rel_node/', n.object_key) AS nodeKey,
        n.node_name AS nodeName,
        n.id_number AS idNumber,
        n.subject_type AS subjectType,
        n.source_type AS sourceType,
        DATE_FORMAT(n.created_time, '%Y-%m-%d %H:%i:%s') AS createdTime,
        DATE_FORMAT(n.updated_time, '%Y-%m-%d %H:%i:%s') AS updatedTime,
        1 AS canExpand,
        0 AS depth
    </sql>

    <select id="selectRelationGraphSubjects" resultMap="RelationGraphNodeResultMap">
        SELECT
            <include refid="nodeColumns"/>
        FROM lx_rel_node n
        WHERE 1 = 1
        <if test="query.objectKey != null and query.objectKey != ''">
            AND n.object_key = (#{query.objectKey} COLLATE utf8mb4_general_ci)
        </if>
        <if test="query.objectKey == null or query.objectKey == ''">
            <if test="query.keyword != null and query.keyword != ''">
                AND (
                    n.object_key = (TRIM(#{query.keyword}) COLLATE utf8mb4_general_ci)
                    OR n.id_number = (TRIM(#{query.keyword}) COLLATE utf8mb4_general_ci)
                    OR n.node_name LIKE (CONCAT('%', TRIM(#{query.keyword}), '%') COLLATE utf8mb4_general_ci)
                )
            </if>
        </if>
        ORDER BY
            CASE
                WHEN n.object_key = (TRIM(IFNULL(#{query.keyword}, '')) COLLATE utf8mb4_general_ci) THEN 0
                WHEN n.id_number = (TRIM(IFNULL(#{query.keyword}, '')) COLLATE utf8mb4_general_ci) THEN 1
                ELSE 2
            END,
            n.node_name
        LIMIT 20
    </select>

    <select id="selectRelationGraphNodesByKeys" resultMap="RelationGraphNodeResultMap">
        SELECT
            <include refid="nodeColumns"/>
        FROM lx_rel_node n
        WHERE n.object_key IN
        <foreach collection="objectKeys" item="objectKey" open="(" separator="," close=")">
            #{objectKey}
        </foreach>
    </select>

    <select id="selectRelationGraphEdges" resultMap="RelationGraphEdgeResultMap">
        SELECT *
        FROM (
            SELECT
                e.object_key AS objectKey,
                e.from_key AS fromKey,
                e.to_key AS toKey,
                'lx_rel_family_edge' AS edgeTable,
                e.relation_type AS relationType,
                NULL AS companyName,
                NULL AS stockName,
                NULL AS stockType,
                NULL AS stockPercent,
                NULL AS shouldCapi,
                NULL AS shouldCapiValue,
                NULL AS shouldCapiUnit,
                NULL AS shoudDate,
                NULL AS pKeyNo,
                NULL AS operName,
                NULL AS operKeyNo,
                e.person_id AS personId,
                e.relation_name AS relationName,
                e.relation_cert_no AS relationCertNo,
                NULL AS gender,
                NULL AS birthDate,
                NULL AS relationCertType,
                NULL AS mobilePhone1,
                NULL AS mobilePhone2,
                NULL AS wechatNo1,
                NULL AS wechatNo2,
                NULL AS wechatNo3,
                NULL AS contactAddress,
                NULL AS annualIncome,
                e.relation_desc AS relationDesc,
                NULL AS status,
                NULL AS effectiveDate,
                NULL AS invalidDate,
                NULL AS remark,
                NULL AS dataSource
            FROM lx_rel_family_edge e
            WHERE e.from_key = CONCAT('rel_node/', #{query.objectKey})
               OR e.to_key = CONCAT('rel_node/', #{query.objectKey})

            UNION ALL

            SELECT
                e.object_key AS objectKey,
                e.from_key AS fromKey,
                e.to_key AS toKey,
                'lx_rel_stock_edge' AS edgeTable,
                e.stock_type AS relationType,
                e.company_name AS companyName,
                e.stock_name AS stockName,
                e.stock_type AS stockType,
                e.stock_percent AS stockPercent,
                e.should_capi AS shouldCapi,
                e.should_capi_value AS shouldCapiValue,
                e.should_capi_unit AS shouldCapiUnit,
                e.shoud_date AS shoudDate,
                e.p_key_no AS pKeyNo,
                NULL AS operName,
                NULL AS operKeyNo,
                NULL AS personId,
                NULL AS relationName,
                NULL AS relationCertNo,
                NULL AS gender,
                NULL AS birthDate,
                NULL AS relationCertType,
                NULL AS mobilePhone1,
                NULL AS mobilePhone2,
                NULL AS wechatNo1,
                NULL AS wechatNo2,
                NULL AS wechatNo3,
                NULL AS contactAddress,
                NULL AS annualIncome,
                NULL AS relationDesc,
                NULL AS status,
                NULL AS effectiveDate,
                NULL AS invalidDate,
                NULL AS remark,
                NULL AS dataSource
            FROM lx_rel_stock_edge e
            WHERE e.from_key = CONCAT('rel_node/', #{query.objectKey})
               OR e.to_key = CONCAT('rel_node/', #{query.objectKey})

            UNION ALL

            SELECT
                e.object_key AS objectKey,
                e.from_key AS fromKey,
                e.to_key AS toKey,
                'lx_rel_represent_edge' AS edgeTable,
                '法定代表人' AS relationType,
                NULL AS companyName,
                NULL AS stockName,
                NULL AS stockType,
                NULL AS stockPercent,
                NULL AS shouldCapi,
                NULL AS shouldCapiValue,
                NULL AS shouldCapiUnit,
                NULL AS shoudDate,
                NULL AS pKeyNo,
                e.oper_name AS operName,
                e.oper_key_no AS operKeyNo,
                NULL AS personId,
                NULL AS relationName,
                NULL AS relationCertNo,
                NULL AS gender,
                NULL AS birthDate,
                NULL AS relationCertType,
                NULL AS mobilePhone1,
                NULL AS mobilePhone2,
                NULL AS wechatNo1,
                NULL AS wechatNo2,
                NULL AS wechatNo3,
                NULL AS contactAddress,
                NULL AS annualIncome,
                NULL AS relationDesc,
                NULL AS status,
                NULL AS effectiveDate,
                NULL AS invalidDate,
                NULL AS remark,
                NULL AS dataSource
            FROM lx_rel_represent_edge e
            WHERE e.from_key = CONCAT('rel_node/', #{query.objectKey})
               OR e.to_key = CONCAT('rel_node/', #{query.objectKey})
        ) graph_edges
        ORDER BY
            CASE edgeTable
                WHEN 'lx_rel_family_edge' THEN 0
                WHEN 'lx_rel_stock_edge' THEN 1
                ELSE 2
            END,
            relationType,
            objectKey
        LIMIT #{query.limit}
    </select>

    <select id="countSuspectedEnterpriseKeyNos" resultType="int">
        SELECT COUNT(DISTINCT candidate_key_no)
        FROM (
            SELECT e.oper_key_no AS candidate_key_no
            FROM lx_rel_represent_edge e
            WHERE e.oper_name = (#{personName} COLLATE utf8mb4_general_ci)
              AND e.oper_key_no IS NOT NULL
              AND e.oper_key_no != ''

            UNION ALL

            SELECT e.p_key_no AS candidate_key_no
            FROM lx_rel_stock_edge e
            WHERE e.stock_name = (#{personName} COLLATE utf8mb4_general_ci)
              AND e.stock_type = '自然人股东'
              AND e.p_key_no IS NOT NULL
              AND e.p_key_no != ''
        ) same_name_candidates
    </select>

    <select id="selectSuspectedEnterprises" resultMap="SuspectedEnterpriseResultMap">
        SELECT *
        FROM (
            SELECT
                e.oper_key_no AS candidateKeyNo,
                e.oper_name AS personName,
                REPLACE(e.to_key, 'rel_node/', '') AS companyId,
                COALESCE(ent.enterprise_name, company_node.node_name) AS companyName,
                COALESCE(ent.social_credit_code, company_node.id_number) AS creditCode,
                ent.status AS enterpriseStatus,
                ent.industry_name AS industryName,
                '法定代表人' AS relationType,
                NULL AS stockPercent,
                DATE_FORMAT(ent.establish_date, '%Y-%m-%d') AS establishDate,
                0 AS relationSort
            FROM lx_rel_represent_edge e
            LEFT JOIN lx_rel_node company_node
                ON company_node.object_key = REPLACE(e.to_key, 'rel_node/', '')
            LEFT JOIN ccdi_enterprise_base_info ent
                ON ent.social_credit_code = company_node.id_number
            WHERE e.oper_name = (#{personName} COLLATE utf8mb4_general_ci)
              AND e.oper_key_no IS NOT NULL
              AND e.oper_key_no != ''

            UNION ALL

            SELECT
                e.p_key_no AS candidateKeyNo,
                e.stock_name AS personName,
                REPLACE(e.to_key, 'rel_node/', '') AS companyId,
                COALESCE(ent.enterprise_name, e.company_name, company_node.node_name) AS companyName,
                COALESCE(ent.social_credit_code, company_node.id_number) AS creditCode,
                ent.status AS enterpriseStatus,
                ent.industry_name AS industryName,
                e.stock_type AS relationType,
                e.stock_percent AS stockPercent,
                COALESCE(DATE_FORMAT(ent.establish_date, '%Y-%m-%d'), e.shoud_date) AS establishDate,
                1 AS relationSort
            FROM lx_rel_stock_edge e
            LEFT JOIN lx_rel_node company_node
                ON company_node.object_key = REPLACE(e.to_key, 'rel_node/', '')
            LEFT JOIN ccdi_enterprise_base_info ent
                ON ent.social_credit_code = company_node.id_number
            WHERE e.stock_name = (#{personName} COLLATE utf8mb4_general_ci)
              AND e.stock_type = '自然人股东'
              AND e.p_key_no IS NOT NULL
              AND e.p_key_no != ''
        ) suspected_enterprises
        ORDER BY relationSort, companyName, companyId
        LIMIT #{limit}
    </select>
</mapper>
