Files
fad_oa/ruoyi-oa/src/main/resources/mapper/oa/SysOaProjectMapper.xml

877 lines
34 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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="closureFiles" column="closure_files"/>
<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="closureFiles" column="closure_files"/>
<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.closure_files,
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,
closure_files,
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>