<?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.oa.mapper.SysOaProjectMapper">

    <resultMap type="com.ruoyi.oa.domain.SysOaProject" id="SysOaProjectResult">
        <result property="projectId" column="project_id"/>
        <result property="projectName" column="project_name"/>
        <result property="projectNum" column="project_num"/>
        <result property="projectType" column="project_type"/>
        <result property="address" column="address"/>
        <result property="funds" column="funds"/>
        <result property="functionary" column="functionary"/>
        <result property="beginTime" column="begin_time"/>
        <result property="finishTime" column="finish_time"/>
        <result property="delivery" column="delivery"/>
        <result property="guarantee" column="guarantee"/>
        <result property="introduction" column="introduction"/>
        <result property="projectGrade" column="project_grade"/>
        <result property="projectStatus" column="project_status"/>
        <result property="contractId" column="contract_id"/>
        <result property="invoiceName" column="invoice_name"/>
        <result property="invoiceNumber" column="invoice_number"/>
        <result property="invoiceAddress" column="invoice_address"/>
        <result property="invoiceBank" column="invoice_bank"/>
        <result property="accessory" column="accessory"/>
        <result property="bail" column="bail"/>
        <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.oa.domain.vo.SysOaProjectVo" id="SysOaProjectVoResult">
        <result property="projectId" column="project_id"/>
        <result property="projectName" column="project_name"/>
        <result property="projectNum" column="project_num"/>
        <result property="projectType" column="project_type"/>
        <result property="address" column="address"/>
        <result property="funds" column="funds"/>
        <result property="functionary" column="functionary"/>
        <result property="beginTime" column="begin_time"/>
        <result property="finishTime" column="finish_time"/>
        <result property="delivery" column="delivery"/>
        <result property="guarantee" column="guarantee"/>
        <result property="introduction" column="introduction"/>
        <result property="projectGrade" column="project_grade"/>
        <result property="projectStatus" column="project_status"/>
        <result property="contractId" column="contract_id"/>
        <result property="invoiceName" column="invoice_name"/>
        <result property="invoiceNumber" column="invoice_number"/>
        <result property="invoiceAddress" column="invoice_address"/>
        <result property="invoiceBank" column="invoice_bank"/>
        <result property="accessory" column="accessory"/>
        <result property="bail" column="bail"/>
        <result property="remark" column="remark"/>
        <result property="createBy" column="create_by"/>
        <result property="createTime" column="create_time"/>
        <result property="count" column="count"/>
        <result property="laborCost" column="labor_cost"/>
        <result property="projectCode" column="project_code"/>

    </resultMap>


    <resultMap type="com.ruoyi.oa.domain.vo.SysOaOutWarehouseListVo" id="SysOaOutWarehouseListVoResult">
        <result property="projectId" column="project_id"/>
        <result property="projectName" column="project_name"/>
        <result property="projectName" column="create_time"/>
        <association property="outWarehouseVoList" javaType="java.util.List" resultMap="outWarehouseResult"/>
    </resultMap>


    <resultMap type="com.ruoyi.oa.domain.vo.SysOaWarehouseDetailVo" id="outWarehouseResult">
        <result property="id" column="soow_id"/>
        <result property="amount" column="amount"/>
        <result property="warehouseId" column="warehouse_id"/>
        <result property="warehouseName" column="name"/>
        <result property="createTime" column="out_create_time"/>
    </resultMap>


    <select id="selectPageOutList" resultMap="SysOaOutWarehouseListVoResult">
        select sop.project_id,
               project_name,
               sop.project_code,
               soow.warehouse_id,
               soow.id          as soow_id,
               soow.amount,
               soow.create_time as out_create_time,
               sow.name
        from sys_oa_project sop
                 left join sys_oa_warehouse_detail soow on soow.project_id = sop.project_id
                 left join sys_oa_warehouse sow on sow.id = soow.warehouse_id
            ${ew.getCustomSqlSegment}
    </select>

    <select id="getProjectDataByMonth" resultType="com.ruoyi.oa.domain.vo.SysOaProjectVo">
        SELECT
            p.project_id,
            p.project_name,
            p.project_code,
            p.color,
            -- 子查询里已经聚合完 labor_cost
            a.labor_cost,
            -- 同理财务部分
            f.total_price
        FROM sys_oa_project AS p
                 LEFT JOIN (
            SELECT
                project_id,
                ROUND(SUM(day_length + hour / 9), 2) AS labor_cost
            FROM sys_oa_attendance
            WHERE create_time BETWEEN #{firstDay} AND #{lastDay}
              AND del_flag = '0'
            GROUP BY project_id
        ) AS a ON p.project_id = a.project_id
                 LEFT JOIN (
            SELECT
                sof.project_id,
                SUM(
                        CASE WHEN sof.finance_type = 0 THEN sod.price ELSE 0 END
                ) AS total_price
            FROM sys_oa_finance sof
                     JOIN sys_oa_detail sod ON sof.finance_id = sod.finance_id
                AND sod.create_time BETWEEN #{firstDay} AND #{lastDay}
            WHERE sof.create_time BETWEEN #{firstDay} AND #{lastDay}
            GROUP BY sof.project_id
        ) AS f ON p.project_id = f.project_id

-- 最后只要在这里加一个 WHERE 条件，过滤掉 labor_cost=0 或者为空
        WHERE a.labor_cost > 0


    </select>

    <select id="getProjectDataByMonthAndDate" resultType="com.ruoyi.oa.domain.vo.SysOaProjectVo">
        select sum(soa.day_length + soa.hour / 8)       as labor_cost,
               color,
               sop.project_code,
               sop.project_name,
               date_format(soa.create_time, '%Y-%m-%d') as create_time
        from sys_oa_project sop
                 left join sys_oa_attendance soa on sop.project_id = soa.project_id
        where soa.create_time between #{firstDay} and #{lastDay}
          and soa.del_flag = '0'
        group by sop.project_id,create_time
    </select>
    <select id="selectListToCost" resultType="com.ruoyi.oa.domain.vo.SysOaCostAllVo">
        SELECT
            sop.project_name,sop.project_num,sop.project_id,sop.funds,
            sop.project_code,

            (
                SELECT COALESCE(SUM(soc.cost),0)
                FROM sys_oa_claim soc
                WHERE soc.project_id = sop.project_id
            ) AS claimCost,

            (
                SELECT COALESCE(SUM(sod.price), 0)
                FROM sys_oa_finance sof
                         JOIN sys_oa_detail sod ON sof.finance_id = sod.finance_id
                WHERE sof.project_id = sop.project_id
                  AND sof.finance_type = 0
            ) AS materialCost,

            (
                SELECT COALESCE(ROUND(SUM((soa.day_length * 9 + soa.hour) / 9),1), 0)
                FROM sys_oa_attendance soa
                WHERE soa.project_id = sop.project_id
            ) AS peopleDay,

            (
                SELECT COALESCE(SUM(ROUND((soa.day_length * 9 + soa.hour) / 9, 1) * su.labor_cost),0)
                FROM sys_oa_attendance soa
                         JOIN sys_user su ON soa.user_id = su.user_id
                WHERE soa.project_id = sop.project_id
            ) AS userCost
        FROM sys_oa_project sop
            ${ew.getCustomSqlSegment}

    </select>


    <select id="selectProjectDetails" parameterType="Long" resultType="java.util.Map">
        SELECT JSON_OBJECT(
                       'userCostList',
                       COALESCE(
                               (SELECT JSON_ARRAYAGG(
                                               JSON_OBJECT(
                                                       'userId', CAST(uc.userId AS CHAR),
                                                       'nickName', COALESCE(uc.nickName, ''),
                                                       'laborCost', ROUND(COALESCE(uc.laborCost, 0), 1),
                                                       'attendenceNum', ROUND(COALESCE(uc.attendenceNum, 0), 1)
                                               )
                                       )
                                FROM (SELECT a.user_id   AS userId,
                                             u.nick_name AS nickName,
                                             COALESCE(
                                                     SUM(
                                                             ROUND((a.day_length * 9 + a.hour) / 9, 1) * u.labor_cost
                                                     ),
                                                     0
                                             )           AS laborCost,
                                             COALESCE(
                                                     ROUND(
                                                             SUM((a.day_length * 9 + a.hour) / 9), 1
                                                     ),
                                                     0
                                             )           AS attendenceNum
                                      FROM sys_oa_attendance a
                                               INNER JOIN sys_user u
                                                          ON a.user_id = u.user_id
                                      WHERE a.project_id = #{projectId}
                                        AND a.del_flag = 0
                                      GROUP BY a.user_id) uc),
                               JSON_ARRAY()
                       ),
                       'materialList',
                       COALESCE(
                               (SELECT JSON_ARRAYAGG(
                                               JSON_OBJECT(
                                                       'detailId', CAST(d.detail_id AS CHAR),
                                                       'detailTitle', COALESCE(d.detail_title, ''),
                                                       'price', COALESCE(d.price, 0),
                                                       'financeParties', COALESCE(f.finance_parties, ''),
                                                       'remark', COALESCE(f.remark, '')
                                               )
                                       )
                                FROM sys_oa_finance f
                                         INNER JOIN sys_oa_detail d
                                                    ON f.finance_id = d.finance_id
                                WHERE f.project_id = #{projectId}
                                  AND f.finance_type = 0),
                               JSON_ARRAY()
                       ),
                       'claimList',
                       COALESCE(
                               (SELECT JSON_ARRAYAGG(
                                               JSON_OBJECT(
                                                       'claimId', CAST(cl.claimId AS CHAR),
                                                       'nickName', COALESCE(cl.nickName, ''),
                                                       'cost', COALESCE(cl.cost, 0),
                                                       'remark', COALESCE(cl.remark, '')
                                               )
                                       )
                                FROM (SELECT c.claim_id                AS claimId,
                                             COALESCE(u.nick_name, '') AS nickName,
                                             COALESCE(c.cost, 0)       AS cost,
                                             COALESCE(c.remark, '')    AS remark
                                      FROM sys_oa_claim c
                                               INNER JOIN sys_user u
                                                          ON c.user_id = u.user_id
                                      WHERE c.project_id = #{projectId}
                                        AND c.del_flag = 0) cl),
                               JSON_ARRAY()
                       )
               ) AS data
        FROM sys_oa_project p
        WHERE p.project_id = #{projectId}

    </select>
    <select id="selectVoPlus" resultType="com.ruoyi.oa.domain.vo.SysOaProjectVo">
        SELECT
            p.pre_pay,
            p.trade_type,
            p.project_id,
            p.project_name,
            p.project_code,
            p.project_num,
            p.project_type,
            p.address,
            p.funds,
            p.functionary,
            p.begin_time,
            p.finish_time,
            p.delivery,
            p.guarantee,
            p.introduction,
            p.project_grade,
            p.project_status,
            p.contract_id,
            p.invoice_name,
            p.invoice_number,
            p.invoice_address,
            p.invoice_bank,
            p.accessory,
            p.bail,
            p.remark,
            p.create_by,
            p.create_time,
            p.update_by,
            p.update_time,
            p.is_postpone,
            p.postpone_reason,
            p.postpone_time,
            p.color,
            TIMESTAMPDIFF(DAY, NOW(), p.postpone_time) AS remainTime
        FROM sys_oa_project p

            ${ew.getCustomSqlSegment}
    </select>



    <!-- 最内层 TaskItem -->
    <resultMap id="TaskItemResultMap" type="com.ruoyi.oa.domain.vo.SysOaTaskItemVo">
        <id property="itemId" column="item_id"/>
        <result property="files" column="file_urls"/>
        <result property="nickName" column="nick_name"/>
        <result property="signTime" column="sign_time"/>
    </resultMap>

    <!-- Task, 包含 List<TaskItem> -->
    <resultMap id="TaskResultMap" type="com.ruoyi.oa.domain.vo.SysOaTaskVo">
        <id property="taskId" column="task_id"/>
        <result property="taskType" column="task_type"/>
        <result property="status" column="task_status"/>

        <collection property="taskItemVoList"
                    resultMap="TaskItemResultMap"
                    column="item_id"
                    javaType="ArrayList" />
    </resultMap>

    <!-- Project, 包含 List<Task> -->
    <resultMap id="ProjectResultMap" type="com.ruoyi.oa.domain.vo.SysOaProjectVo">
        <id property="projectId" column="p_id"/>
        <result property="projectName" column="project_name"/>
        <result property="updateTime" column="update_time"/>

        <collection property="taskList"
                    resultMap="TaskResultMap"
                    column="task_id"
                    javaType="ArrayList" />
    </resultMap>



    <select id="selectFileVoList" resultMap="ProjectResultMap">
        SELECT
            sop.project_id             AS p_id,
            sop.project_name           AS project_name,
            sop.update_time,
            sop.project_code,
            t.task_id                AS task_id,
            t.task_type              AS task_type,
            t.status                 AS task_status,

            CASE
                WHEN t.status = 0 THEN u0.nick_name
                WHEN t.status = 1 THEN u1.nick_name
                ELSE ''
                END                      AS nick_name,

            ti.item_id               AS item_id,
            case
                when ti.sign_time is not null then ti.sign_time
                else t.finish_time
                end  AS sign_time,

            GROUP_CONCAT(
                    so.url
                    SEPARATOR ','
            ) AS file_urls

        FROM sys_oa_project sop
            LEFT JOIN sys_oa_task t
                      ON sop.project_id = t.project_id

                 LEFT JOIN sys_user u0
                           ON t.create_user_id = u0.user_id

                 LEFT JOIN sys_user u1
                           ON t.worker_id = u1.user_id

                 LEFT JOIN sys_oa_task_item ti
                           ON t.task_id = ti.task_id

                 LEFT JOIN sys_oss so
                           ON (
                               (t.status = 0 AND FIND_IN_SET(CONCAT(so.oss_id, ''), t.files) > 0)
                                   OR
                               (t.status = 1 AND FIND_IN_SET(CONCAT(so.oss_id, ''), ti.files) > 0)
                               )
            ${ew.getCustomSqlSegment}
    </select>


    <!-- 项目与进度关联的结果映射 -->
    <resultMap type="com.ruoyi.oa.domain.vo.SysOaProjectVo" id="ProjectProgressResult">
        <id property="projectId" column="project_id"/>
        <result property="projectName" column="project_name"/>
        <result property="projectNum" column="project_num"/>
        <result property="projectType" column="project_type"/>
        <result property="projectCode" column="project_code,"/>
        <result property="remainTime" column="remainTime"/>
        <!-- 根据项目 ID 查询顶级进度（parent_id 为 0 或 NULL） -->
        <collection property="progressList"
                    ofType="com.ruoyi.oa.domain.vo.OaProgressVo"
                    select="selectProgressByProjectId"
                    column="project_id"/>
    </resultMap>

    <!-- 进度项的结果映射 -->
    <resultMap type="com.ruoyi.oa.domain.vo.OaProgressVo" id="OaProgressResult">
        <id property="progressId" column="progress_id"/>
        <result property="projectId" column="project_id"/>
        <result property="type" column="type"/>
        <result property="progressName" column="progress_name"/>
        <result property="parentId" column="parent_id"/>
        <result property="sort" column="sort"/>
        <result property="remark" column="remark"/>
        <result property="status" column="status"/>
        <!-- 新增字段映射 -->
        <result property="progressSize" column="progress_size"/>
        <result property="finishCount" column="finish_count"/>
        <result property="completionPercent" column="completionPercent"/>

        <!-- 嵌套查询孩子节点（如果需要展示孩子节点明细，可保留） -->
        <collection property="children"
                    ofType="com.ruoyi.oa.domain.vo.OaProgressVo"
                    select="selectChildProgress"
                    column="progress_id"/>
    </resultMap>

    <!-- 根据项目 ID 查询顶级进度 -->
    <select id="selectProgressByProjectId" resultMap="OaProgressResult">
        SELECT
            p.progress_id,
            p.project_id,
            p.type,
            p.progress_name,
            p.parent_id,
            p.sort,

            p.remark,
            p.status,
            -- 孩子节点总数：如果没有匹配则返回 0
            IFNULL(child.totalCount, 0) AS progress_size,
            -- 孩子节点中 status 为1的数量
            IFNULL(child.finishedCount, 0) AS finish_count,
            -- 计算完成比例：避免除以0的情况
            CASE WHEN child.totalCount > 0
                     THEN ROUND(child.finishedCount / child.totalCount, 2) *100
                 ELSE 0
                END AS completionPercent
        FROM oa_progress p
                 LEFT JOIN (
            SELECT
                parent_id,
                COUNT(*) AS totalCount,
                SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) AS finishedCount
            FROM oa_progress
            GROUP BY parent_id
        ) child ON p.progress_id = child.parent_id
        WHERE p.project_id = #{projectId}
          AND p.parent_id = 0
    </select>

    <!-- 根据进度 ID 查询子进度 -->
    <select id="selectChildProgress" resultMap="OaProgressResult">
        SELECT
            progress_id,
            project_id,
            type,
            progress_name,
            parent_id,
            sort,
            remark,
            status
        FROM oa_progress
        WHERE parent_id = #{progressId}
    </select>

    <!-- 主项目查询，同时获取项目的一些计算字段 -->
    <select id="selectVoAndProgress" resultMap="ProjectProgressResult">
        SELECT
            p.project_id,
            p.project_name,
            p.project_num,
            p.project_type,
            p.project_code,
            p.funds,
            TIMESTAMPDIFF(DAY, NOW(), p.postpone_time) AS remainTime
        FROM sys_oa_project p
            ${ew.getCustomSqlSegment}
    </select>

    <select id="selectVoListPage" resultType="com.ruoyi.oa.domain.vo.SysOaProjectVo">

        SELECT
            sop.project_id,
            sop.project_name,
            sop.project_num,
            sop.begin_time,
            sop.finish_time,
            sop.project_code,
            sop.functionary,
            IFNULL(
                    SUM(CASE WHEN d.detail_status = 1 THEN 1 ELSE 0 END) * 100
                        / NULLIF(COUNT(d.detail_id), 0)
                , 0) AS progress
        FROM sys_oa_project sop
                 LEFT JOIN oa_progress pr
                           ON pr.project_id = sop.project_id
                               AND pr.del_flag = 0
                 LEFT JOIN oa_progress_detail d
                           ON d.progress_id = pr.progress_id
                               AND d.del_flag = 0
        ${ ew.getCustomSqlSegment}
    </select>
    <select id="listWareProject" resultType="com.ruoyi.oa.domain.vo.SysOaProjectVo">
        SELECT distinct sop.project_id,
                        project_name,
                        project_num,
                        project_type,
                        address,
                        funds,
                        functionary,
                        begin_time,
                        finish_time,
                        delivery,
                        guarantee,
                        introduction,
                        project_grade,
                        project_status,
                        contract_id,
                        invoice_name,
                        invoice_number,
                        invoice_address,
                        invoice_bank,
                        accessory,
                        bail,
                        is_postpone,
                        postpone_reason,
                        postpone_time,
                        color,
                        trade_type,
                        sop.project_code,
                        pre_pay
        FROM sys_oa_project sop
                 INNER JOIN sys_oa_warehouse_master sown
                            ON sown.project_id = sop.project_id
            ${ ew.getCustomSqlSegment}
    </select>
    <select id="selectVoByIdPlus" resultMap="SysOaProjectVoResult">
        select sop.project_id,
               project_name,
               project_num,
               project_type,
               address,
               funds,
               functionary,
               begin_time,
               finish_time,
               delivery,
               guarantee,
               introduction,
               project_grade,
               project_status,
               contract_id,
               invoice_name,
               invoice_number,
               invoice_address,
               invoice_bank,
               bail,
               remark,
               accessory,
               sop.create_by,
               sop.create_time,
               sop.update_by,
               sop.update_time,
               sop.project_code,
               is_postpone,
               postpone_reason,
               postpone_time,
               color,
               trade_type,
               pre_pay

        from sys_oa_project sop
        where sop.project_id = #{projectId}
    </select>
    <!-- 本月合同总额 -->
    <select id="selectTotalFunds" resultType="java.math.BigDecimal">
        SELECT IFNULL(SUM(funds),0)
        FROM sys_oa_project
        <where>
            AND begin_time BETWEEN #{start} AND #{end}
            <if test="tradeType !=null and tradeType !=''">
                and trade_type   =  #{tradeType}
            </if>
        </where>

    </select>
    <!-- 当月／指定月份各项目支出占比 -->
    <select id="getProjectData"
            parameterType="string"
            resultType="com.ruoyi.oa.domain.dto.ProjectDataDTO">
        SELECT
        p.project_id    AS projectId,
        p.project_name  AS projectName,
        p.color         AS color,
        IFNULL(
        SUM(
        CASE WHEN f.finance_type = '0' THEN d.price ELSE 0 END
        ),
        0
        ) AS totalPrice
        FROM sys_oa_project p
        LEFT JOIN sys_oa_finance f
        ON f.project_id = p.project_id
        LEFT JOIN sys_oa_detail d
        ON d.finance_id = f.finance_id
        <where>
            <choose>
                <when test="month != null and month != ''">
                    AND DATE_FORMAT(f.finance_time, '%Y-%m') = #{month}
                </when>
                <otherwise>
                    AND DATE_FORMAT(f.finance_time, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
                </otherwise>
            </choose>
        </where>
        GROUP BY p.project_id, p.project_name, p.color
    </select>

    <!-- 项目活跃度（明细） -->
    <select id="getProjectActivities" resultType="com.ruoyi.oa.domain.dto.ProjectActivityDTO">
        SELECT
            p.project_name AS projectName,
            f.finance_time AS createTime,
            d.price        AS laborCost,
            p.color        AS color
        FROM sys_oa_project p
                 JOIN sys_oa_finance f ON f.project_id = p.project_id
                 JOIN sys_oa_detail d  ON d.finance_id = f.finance_id
        ORDER BY f.finance_time
    </select>

    <!-- 历史（月度）平均合同总额 -->
    <select id="selectPrevAvgTotalFunds" resultType="java.math.BigDecimal">
        SELECT IFNULL(AVG(monthly_sum),0)
        FROM (
                 SELECT SUM(funds) AS monthly_sum
                 FROM sys_oa_project
        <where>
            AND begin_time &lt; #{start}
            <if test="tradeType !=null and tradeType !=''">
                and trade_type   =  #{tradeType}
            </if>
        </where>
                 GROUP BY YEAR(begin_time), MONTH(begin_time)
             ) t
    </select>

    <!-- 本月合同数量 -->
    <select id="selectContractCount" resultType="java.lang.Integer">
        SELECT COUNT(*)
        FROM sys_oa_project
        <where>
            AND begin_time BETWEEN #{start} AND #{end}
            <if test="tradeType !=null and tradeType !=''">
                and trade_type   =  #{tradeType}
            </if>
        </where>

    </select>

    <!-- 历史（月度）平均合同数量 -->
    <select id="selectPrevAvgContractCount" resultType="java.math.BigDecimal">
        SELECT IFNULL(AVG(monthly_cnt),0)
        FROM (
                 SELECT COUNT(*) AS monthly_cnt
                 FROM sys_oa_project
        <where>
            AND begin_time &lt; #{start}
            <if test="tradeType !=null and tradeType !=''">
                and trade_type   =  #{tradeType}
            </if>
        </where>
                 GROUP BY YEAR(begin_time), MONTH(begin_time)
             ) t
    </select>

    <!-- 本月临期项目数（仅未完成） -->
    <select id="selectExpiringCount" resultType="java.lang.Integer">
        SELECT COUNT(*)
        FROM sys_oa_project
        <where>
            AND project_status = '0'
            AND finish_time BETWEEN #{start} AND #{end}
            <if test="tradeType !=null and tradeType !=''">
                and trade_type   =  #{tradeType}
            </if>
        </where>

    </select>

    <!-- 历史（月度）平均临期项目数 -->
    <select id="selectPrevAvgExpiringCount" resultType="java.math.BigDecimal">
        SELECT IFNULL(AVG(monthly_expiring),0)
        FROM (
                 SELECT COUNT(*) AS monthly_expiring
                 FROM sys_oa_project
        <where>
            AND project_status = '0'
            AND finish_time &lt; #{start}
            <if test="tradeType !=null and tradeType !=''">
                and trade_type   =  #{tradeType}
            </if>
        </where>

                 GROUP BY YEAR(finish_time), MONTH(finish_time)
             ) t
    </select>
    <select id="selectContractAmountTrend" resultType="com.ruoyi.oa.domain.vo.TrendPointVo">
        SELECT
            CONCAT(t.mth, '月') AS month,
            t.value
        FROM (
                 SELECT
                     YEAR(begin_time)  AS yr,
                     MONTH(begin_time) AS mth,
                     IFNULL(SUM(funds),0) AS value
                 FROM sys_oa_project

        <where>
            AND begin_time BETWEEN #{start} AND #{end}
            <if test="tradeType !=null and tradeType !=''">
                and trade_type   =  #{tradeType}
            </if>
        </where>
                 GROUP BY
                     YEAR(begin_time),
                     MONTH(begin_time)
             ) AS t
        ORDER BY
            t.yr,
            t.mth
    </select>
    <select id="selectProjectStatusDistribution" resultType="com.ruoyi.oa.domain.vo.StatusCountVo">
        SELECT status, COUNT(*) AS count FROM (
        SELECT
        CASE
        WHEN   NOW() > finish_time                       THEN '已逾期'
        WHEN finish_time BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 7 DAY) THEN '即将到期'
        WHEN project_status = '0'                        THEN '进行中'
        ELSE '正常'
        END AS status
        FROM sys_oa_project
        <where>

            <if test="tradeType !=null and tradeType !=''">
                and trade_type   =  #{tradeType}
            </if>
        </where>
        ) t
        GROUP BY status
    </select>
    <select id="selectMonthlyContractComparison" resultType="com.ruoyi.oa.domain.vo.TrendPointVo">
        SELECT
            CONCAT(t.mth, '月') AS month,
            t.value
        FROM (
                 SELECT
                     YEAR(begin_time)  AS yr,
                     MONTH(begin_time) AS mth,
                     COUNT(*)           AS value
                 FROM sys_oa_project
        <where>
            AND begin_time BETWEEN #{start} AND #{end}
            <if test="tradeType !=null and tradeType !=''">
                and trade_type   =  #{tradeType}
            </if>
        </where>
                 GROUP BY
                     YEAR(begin_time),
                     MONTH(begin_time)
             ) AS t
        ORDER BY
            t.yr,
            t.mth
    </select>
    <select id="selectExpiringForeignProjects" resultType="com.ruoyi.oa.domain.vo.SysOaProjectVo">
        SELECT
        p.project_id    AS projectId,
        p.project_name  AS projectName,
        p.funds         AS funds,
        p.finish_time   AS finishTime,
        CASE
        WHEN   NOW() > p.finish_time THEN '已逾期'
        WHEN p.finish_time BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL #{expireDays} DAY) THEN '即将到期'
        ELSE '进行中'
        END              AS status,
        TIMESTAMPDIFF(
        DAY,
        NOW(),
        p.finish_time
        )                AS remainTime
        FROM sys_oa_project p
        <where>
            AND TIMESTAMPDIFF(DAY, NOW(), p.finish_time) &lt; #{expireDays}
            AND p.project_status = '0'
            <if test="tradeType !=null and tradeType !=''">
                and p.trade_type   =  #{tradeType}
            </if>
        </where>
        ORDER BY
        TIMESTAMPDIFF(DAY, NOW(), p.finish_time) ASC
    </select>
    <!-- SysOaProjectMapper.xml -->

    <!-- SysOaProjectMapper.xml -->
    <select id="selectProfitLossPage" resultType="com.ruoyi.oa.domain.vo.ProjectProfitLossVO">
        SELECT
            p.project_id,
            p.project_name,
            p.project_num,
            p.project_code,
            p.trade_type,
            p.begin_time,
            p.project_status,
            p.funds AS original_funds,
            p.remark AS project_remark,
            COALESCE(finance_details.total_income, 0) AS detail_income,
            COALESCE(finance_details.total_expenditure, 0) AS total_expenditure,
            CASE
                WHEN p.remark LIKE '%美元%' OR p.remark LIKE '%美金%' THEN 1
                ELSE 0
                END AS is_usd,
            -- 核心盈亏计算逻辑
            (
                -- 首先计算总收入
                CASE
                    -- 场景1: 如果项目有合同额, 则总收入为合同额 (需考虑汇率)
                    WHEN p.funds IS NOT NULL AND p.funds > 0
                        THEN
                        CASE
                            WHEN p.remark LIKE '%美元%' OR p.remark LIKE '%美金%'
                                THEN p.funds * #{exchangeRate}
                            ELSE p.funds
                            END
                    -- 场景2: 如果项目没有合同额, 则总收入为财务明细中的入账总和
                    ELSE COALESCE(finance_details.total_income, 0)
                    END
                    -- 减去总支出
                    - COALESCE(finance_details.total_expenditure, 0)
                ) AS profit_loss
        FROM
            sys_oa_project p
                LEFT JOIN (
                -- 将财务主表和明细表关联，一次性计算出每个项目的总收入和总支出
                SELECT
                    f.project_id,
                    SUM(CASE WHEN f.finance_type = '1' THEN d.price ELSE 0 END) AS total_income,
                    SUM(CASE WHEN f.finance_type = '0' THEN d.price ELSE 0 END) AS total_expenditure
                FROM
                    sys_oa_finance f
                        JOIN
                    sys_oa_detail d ON f.finance_id = d.finance_id
                WHERE f.project_id > 0
                GROUP BY
                    f.project_id
            ) AS finance_details ON p.project_id = finance_details.project_id
            ${ew.customSqlSegment}
    </select>
</mapper>
