feat: 会议提交剩余时间+解冻 + 会务/劳务材料批量下载 + 多角色人员/账号模块完善

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
郭庆泰
2026-08-25 06:53:18 +08:00
co-authored by Claude
parent 0c882ae846
commit 591a43fe61
126 changed files with 3789 additions and 1334 deletions
@@ -154,6 +154,7 @@
<select id="selectByMeetingId" resultMap="BizMeetingAttendeeResult" parameterType="Long">
select id, meeting_id, user_id, name, phone, work_unit, department, title, id_card, bank_card, bank_name, bank_branch, bank_region, bank_address, account_name, id_card_attachments, labor_form, fee_pre_tax, tax, fee, vat_and_surcharge, summary, on_site_photos, signed_at, signed_ip, handsign, labor_protocol, labor_protocol_masked, create_by, create_time, is_deleted, is_esigned, is_invited
from biz_meeting_attendee where meeting_id = #{meetingId} and is_deleted = 0
order by id
</select>
<select id="selectByUserId" resultMap="BizMeetingAttendeeResult" parameterType="Long">
select id, meeting_id, user_id, name, phone, work_unit, department, title, id_card, bank_card, bank_name, bank_branch, bank_region, bank_address, account_name, id_card_attachments, labor_form, fee_pre_tax, tax, fee, vat_and_surcharge, summary, on_site_photos, signed_at, signed_ip, handsign, labor_protocol, create_by, create_time, is_deleted, is_esigned, is_invited
@@ -5,14 +5,15 @@
<resultMap type="BizMeetingExecutor" id="BizMeetingExecutorResult">
<id property="id" column="id" />
<result property="meetingId" column="meeting_id" />
<result property="userId" column="user_id" />
<result property="executorOrgId" column="executor_org_id" />
<result property="orgName" column="org_name" />
<result property="assignedBy" column="assigned_by" />
<result property="createTime" column="create_time" />
<result property="isDeleted" column="is_deleted" />
</resultMap>
<sql id="selectFields">
select id, meeting_id, user_id, assigned_by, create_time, is_deleted
select id, meeting_id, executor_org_id, assigned_by, create_time, is_deleted
from biz_meeting_executor
</sql>
@@ -22,15 +23,12 @@
</select>
<select id="selectByMeetingId" resultMap="BizMeetingExecutorResult" parameterType="Long">
<include refid="selectFields"/>
where meeting_id = #{meetingId} and is_deleted = 0
order by id asc
</select>
<select id="selectByUserId" resultMap="BizMeetingExecutorResult" parameterType="Long">
<include refid="selectFields"/>
where user_id = #{userId} and is_deleted = 0
order by id desc
select e.id, e.meeting_id, e.executor_org_id, e.assigned_by, e.create_time, e.is_deleted,
o.org_name
from biz_meeting_executor e
left join biz_org o on o.org_id = e.executor_org_id
where e.meeting_id = #{meetingId} and e.is_deleted = 0
order by e.id asc
</select>
<select id="selectList" resultMap="BizMeetingExecutorResult" parameterType="BizMeetingExecutor">
@@ -38,7 +36,7 @@
<where>
is_deleted = 0
<if test="meetingId != null">and meeting_id = #{meetingId}</if>
<if test="userId != null">and user_id = #{userId}</if>
<if test="executorOrgId != null">and executor_org_id = #{executorOrgId}</if>
</where>
order by id asc
</select>
@@ -47,30 +45,30 @@
insert into biz_meeting_executor
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="meetingId != null">meeting_id,</if>
<if test="userId != null">user_id,</if>
<if test="executorOrgId != null">executor_org_id,</if>
<if test="assignedBy != null">assigned_by,</if>
<if test="createTime != null">create_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="meetingId != null">#{meetingId},</if>
<if test="userId != null">#{userId},</if>
<if test="executorOrgId != null">#{executorOrgId},</if>
<if test="assignedBy != null">#{assignedBy},</if>
<if test="createTime != null">#{createTime},</if>
</trim>
</insert>
<insert id="insertBatch" parameterType="java.util.List">
insert into biz_meeting_executor (meeting_id, user_id, assigned_by, create_time)
insert into biz_meeting_executor (meeting_id, executor_org_id, assigned_by, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.meetingId}, #{item.userId}, #{item.assignedBy}, #{item.createTime})
(#{item.meetingId}, #{item.executorOrgId}, #{item.assignedBy}, #{item.createTime})
</foreach>
</insert>
<update id="updateByPrimaryKey" parameterType="BizMeetingExecutor">
update biz_meeting_executor
<trim prefix="SET" suffixOverrides=",">
<if test="userId != null">user_id = #{userId},</if>
<if test="executorOrgId != null">executor_org_id = #{executorOrgId},</if>
<if test="assignedBy != null">assigned_by = #{assignedBy},</if>
</trim>
where id = #{id}
@@ -20,7 +20,6 @@
<result property="supervisionBy" column="supervision_by" />
<result property="supervisionTime" column="supervision_time" />
<result property="materialAuditStage" column="material_audit_stage" />
<result property="voucherAuditStage" column="voucher_audit_stage" />
<result property="isExecuted" column="is_executed" />
<result property="executeTime" column="execute_time" />
<result property="isSettled" column="is_settled" />
@@ -30,10 +29,10 @@
<result property="isFrozen" column="is_frozen" />
<result property="freezeTime" column="freeze_time" />
<result property="materialAuditTime" column="material_audit_time" />
<result property="voucherAuditTime" column="voucher_audit_time" />
<result property="materialComplianceApproved" column="material_compliance_approved" />
<result property="voucherComplianceApproved" column="voucher_compliance_approved" />
<result property="submitDeadline" column="submit_deadline" />
<result property="invitationUrl" column="invitation_url" />
<result property="projectInvitationUrl" column="project_invitation_url" />
<result property="scheduleUrl" column="schedule_url" />
<result property="posterUrl" column="poster_url" />
<result property="laborSigned" column="labor_signed" />
@@ -50,10 +49,12 @@
<result property="isDeleted" column="is_deleted" />
</resultMap>
<sql id="selectFields">
meeting_id, business_id, project_id, project_no, project_name, meeting_name, period_no, total_periods, project_form, start_time, end_time, org_name, address, current_stage, supervision_opinion, supervision_by, supervision_time, material_audit_stage, voucher_audit_stage, is_executed, execute_time, is_settled, settle_time, is_finished, finish_time, is_frozen, freeze_time, material_audit_time, voucher_audit_time, material_compliance_approved, voucher_compliance_approved, invitation_url, schedule_url, poster_url, labor_signed, labor_fee, meeting_fee, total_fee, fee_calc_status, create_by, create_time, update_by, update_time, is_deleted
meeting_id, business_id, project_id, project_no, project_name, meeting_name, period_no, total_periods, project_form, start_time, end_time, address, current_stage, supervision_opinion, supervision_by, supervision_time, material_audit_stage, is_executed, execute_time, is_settled, settle_time, is_finished, finish_time, is_frozen, freeze_time, material_audit_time, material_compliance_approved, submit_deadline, invitation_url, schedule_url, poster_url, labor_signed, labor_fee, meeting_fee, total_fee, fee_calc_status, create_by, create_time, update_by, update_time, is_deleted
</sql>
<select id="selectByPrimaryKey" resultMap="BizMeetingResult" parameterType="Long">
select <include refid="selectFields"/>
select
(select o.org_name from biz_project p join biz_org o on o.org_id = p.sponsor_org_id where p.project_id = biz_meeting.project_id limit 1) as org_name,
<include refid="selectFields"/>
from biz_meeting
where meeting_id = #{meetingId} and is_deleted = 0
</select>
@@ -61,6 +62,8 @@
select
<if test="userId != null">(select a.id from biz_meeting_attendee a where a.meeting_id = biz_meeting.meeting_id and a.user_id = #{userId} and a.is_deleted = 0 limit 1) as attendee_id,</if>
<if test="userId != null">(select a.labor_protocol from biz_meeting_attendee a where a.meeting_id = biz_meeting.meeting_id and a.user_id = #{userId} and a.is_deleted = 0 limit 1) as attendee_labor_protocol,</if>
(select o.org_name from biz_project p join biz_org o on o.org_id = p.sponsor_org_id where p.project_id = biz_meeting.project_id limit 1) as org_name,
(select p.invitation_url from biz_project p where p.project_id = biz_meeting.project_id limit 1) as project_invitation_url,
<include refid="selectFields"/>
from biz_meeting
<where>
@@ -75,16 +78,24 @@
<if test="endTime != null">and end_time &lt;= #{endTime}</if>
<!-- doctor 角色按 user_id 过滤 (走 biz_meeting_attendee 中间表, 同时 attendee 也需 is_deleted=0) -->
<if test="userId != null">and exists (select 1 from biz_meeting_attendee a where a.meeting_id = biz_meeting.meeting_id and a.user_id = #{userId} and a.is_deleted = 0)</if>
<!-- sponsor 数据权限: 只看"我的项目"下的会议 (project_id ∈ 我的项目). MAIN 走 sponsor_admin_user_id, SUB 走 sponsor_assign.monitor_user_id.
<!-- sponsor 数据权限: 只看"我的项目"下的会议 (project_id ∈ 我的项目). MAIN 走 sponsor_org_id (经 user_id 反查 org_id), SUB 走 sponsor_assign.monitor_user_id.
刻意不带 biz_publicity_support_intent 关联 (与项目列表 selectSponsorList 的区别点) -->
<if test="params.sponsorAdminUserId != null">and project_id in (select project_id from biz_project where sponsor_admin_user_id = #{params.sponsorAdminUserId} and is_deleted = 0)</if>
<if test="params.sponsorAdminUserId != null">and project_id in (select project_id from biz_project where sponsor_org_id = (select org_id from biz_org where user_id = #{params.sponsorAdminUserId} and org_type = 'sponsor') and is_deleted = 0)</if>
<if test="params.monitorUserId != null">and project_id in (select distinct project_id from biz_project_sponsor_assign where monitor_user_id = #{params.monitorUserId} and is_deleted = 0)</if>
<!-- executor 数据权限: 只看"我的项目"下的会议. MAIN 走 biz_project_assign (exec_user_id / execution_unit_id), SUB(执行人) 走 biz_project_executor_assign.staff_user_id -->
<!-- 结题且未开通的项目, sponsor 会议不可见 (与项目列表 selectSponsorList 同口径) -->
<if test="params.sponsorAdminUserId != null or params.monitorUserId != null">
and not exists (
select 1 from biz_project p2
where p2.project_id = biz_meeting.project_id
and p2.is_deleted = 0
and p2.is_finished = '1' and p2.open_status = 'N'
)
</if>
<!-- executor 数据权限: 只看"我的项目"下的会议. MAIN 走 biz_project_assign (execution_unit_id), SUB(执行人) 走 biz_project_executor_assign.staff_user_id -->
<if test="params.executorUserId != null">and project_id in (
select distinct a.project_id from biz_project_assign a
where a.is_deleted = 0
and (a.exec_user_id = #{params.executorUserId}
or a.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor'))
and a.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor')
)</if>
<if test="params.executorStaffUserId != null">and project_id in (
select distinct a.project_id from biz_project_executor_assign a
@@ -107,14 +118,13 @@
<if test="projectForm != null and projectForm != ''">project_form,</if>
<if test="startTime != null">start_time,</if>
<if test="endTime != null">end_time,</if>
<if test="orgName != null and orgName != ''">org_name,</if>
<if test="address != null and address != ''">address,</if>
<if test="currentStage != null and currentStage != ''">current_stage,</if>
<if test="supervisionOpinion != null and supervisionOpinion != ''">supervision_opinion,</if>
<if test="supervisionBy != null and supervisionBy != ''">supervision_by,</if>
<if test="supervisionTime != null">supervision_time,</if>
<if test="materialAuditStage != null and materialAuditStage != ''">material_audit_stage,</if>
<if test="voucherAuditStage != null and voucherAuditStage != ''">voucher_audit_stage,</if>
<if test="submitDeadline != null">submit_deadline,</if>
<if test="invitationUrl != null and invitationUrl != ''">invitation_url,</if>
<if test="scheduleUrl != null and scheduleUrl != ''">schedule_url,</if>
<if test="posterUrl != null and posterUrl != ''">poster_url,</if>
@@ -136,14 +146,13 @@
<if test="projectForm != null and projectForm != ''">#{projectForm},</if>
<if test="startTime != null">#{startTime},</if>
<if test="endTime != null">#{endTime},</if>
<if test="orgName != null and orgName != ''">#{orgName},</if>
<if test="address != null and address != ''">#{address},</if>
<if test="currentStage != null and currentStage != ''">#{currentStage},</if>
<if test="supervisionOpinion != null and supervisionOpinion != ''">#{supervisionOpinion},</if>
<if test="supervisionBy != null and supervisionBy != ''">#{supervisionBy},</if>
<if test="supervisionTime != null">#{supervisionTime},</if>
<if test="materialAuditStage != null and materialAuditStage != ''">#{materialAuditStage},</if>
<if test="voucherAuditStage != null and voucherAuditStage != ''">#{voucherAuditStage},</if>
<if test="submitDeadline != null">#{submitDeadline},</if>
<if test="invitationUrl != null and invitationUrl != ''">#{invitationUrl},</if>
<if test="scheduleUrl != null and scheduleUrl != ''">#{scheduleUrl},</if>
<if test="posterUrl != null and posterUrl != ''">#{posterUrl},</if>
@@ -168,14 +177,12 @@
<!-- Date/Long 字段不能用 != '' (OGNL 会把 Date 和 String 做非法比较), 只判 null -->
<if test="startTime != null">start_time = #{startTime},</if>
<if test="endTime != null">end_time = #{endTime},</if>
<if test="orgName != null and orgName != ''">org_name = #{orgName},</if>
<if test="address != null and address != ''">address = #{address},</if>
<if test="currentStage != null and currentStage != ''">current_stage = #{currentStage},</if>
<if test="supervisionOpinion != null and supervisionOpinion != ''">supervision_opinion = #{supervisionOpinion},</if>
<if test="supervisionBy != null and supervisionBy != ''">supervision_by = #{supervisionBy},</if>
<if test="supervisionTime != null">supervision_time = #{supervisionTime},</if>
<if test="materialAuditStage != null and materialAuditStage != ''">material_audit_stage = #{materialAuditStage},</if>
<if test="voucherAuditStage != null and voucherAuditStage != ''">voucher_audit_stage = #{voucherAuditStage},</if>
<if test="isExecuted != null">is_executed = #{isExecuted},</if>
<if test="executeTime != null">execute_time = #{executeTime},</if>
<if test="isSettled != null">is_settled = #{isSettled},</if>
@@ -185,9 +192,8 @@
<if test="isFrozen != null">is_frozen = #{isFrozen},</if>
<if test="freezeTime != null">freeze_time = #{freezeTime},</if>
<if test="materialAuditTime != null">material_audit_time = #{materialAuditTime},</if>
<if test="voucherAuditTime != null">voucher_audit_time = #{voucherAuditTime},</if>
<if test="materialComplianceApproved != null">material_compliance_approved = #{materialComplianceApproved},</if>
<if test="voucherComplianceApproved != null">voucher_compliance_approved = #{voucherComplianceApproved},</if>
<if test="submitDeadline != null">submit_deadline = #{submitDeadline},</if>
<if test="invitationUrl != null and invitationUrl != ''">invitation_url = #{invitationUrl},</if>
<if test="scheduleUrl != null and scheduleUrl != ''">schedule_url = #{scheduleUrl},</if>
<if test="posterUrl != null and posterUrl != ''">poster_url = #{posterUrl},</if>
@@ -231,21 +237,20 @@
and start_time &lt;= NOW()
and material_audit_stage = 'NOT_SUBMITTED'
</update>
<!-- 自动流转 (MeetingStageScheduler 每分钟调): material 未提交 且 end_time + submit_deadline_days 已过 → 冻结 -->
<!-- 自动流转 (MeetingStageScheduler 每分钟调): material 未提交/已退回 且 submit_deadline 已过 → 冻结.
submit_deadline 由建会/退回/解冻 时写入 (end_time 或 now + 项目 submit_deadline_days 天), null = 项目未设天数 → 永不冻结. -->
<update id="markFrozen">
update biz_meeting m
join biz_project p on p.project_id = m.project_id and p.is_deleted = 0
set m.is_frozen = 1,
m.freeze_time = NOW(),
m.current_stage = 'FROZEN'
where m.is_deleted = 0
and m.is_frozen = 0
and m.material_audit_stage = 'NOT_SUBMITTED'
and m.end_time is not null
and p.submit_deadline_days is not null
and date_add(m.end_time, interval p.submit_deadline_days day) &lt;= NOW()
update biz_meeting
set is_frozen = 1,
freeze_time = NOW(),
current_stage = 'FROZEN'
where is_deleted = 0
and is_frozen = 0
and material_audit_stage in ('NOT_SUBMITTED', 'REJECTED')
and submit_deadline is not null
and submit_deadline &lt;= NOW()
</update>
<!-- 自动流转 (MeetingStageScheduler 每分钟调): material+voucher 都 APPROVED 且 最晚审核时间已过 1 自然日 → AWAITING_SETTLEMENT (待结算 24h 慢路径) -->
<!-- 自动流转 (MeetingStageScheduler 每分钟调): 材料 APPROVED 且 材料审核时间已过 1 自然日 → AWAITING_SETTLEMENT (待结算 24h 慢路径) -->
<update id="markSettlementReady">
update biz_meeting
set current_stage = 'AWAITING_SETTLEMENT'
@@ -254,10 +259,9 @@
and is_settled = 0
and is_finished = 0
and material_audit_stage = 'APPROVED'
and voucher_audit_stage = 'APPROVED'
and current_stage = 'SUPERVISION_APPROVED'
and greatest(material_audit_time, voucher_audit_time) is not null
and greatest(material_audit_time, voucher_audit_time) &lt;= (NOW() - INTERVAL 1 DAY)
and material_audit_time is not null
and material_audit_time &lt;= (NOW() - INTERVAL 1 DAY)
</update>
<!-- 费用汇总调度器: 查 fee_calc_status=0 且未软删的会议 id -->
<select id="selectPendingFeeCalcIds" resultType="Long">
@@ -33,6 +33,12 @@
order by id asc
</select>
<select id="selectByMeetingAndSubType" resultMap="BizMeetingMaterialResult">
<include refid="selectFields"/>
where meeting_id = #{meetingId} and sub_type = #{subType} and is_deleted = 0
limit 1
</select>
<insert id="insert" parameterType="BizMeetingMaterial" useGeneratedKeys="true" keyProperty="id">
insert into biz_meeting_material
<trim prefix="(" suffix=")" suffixOverrides=",">
@@ -89,6 +95,13 @@
update biz_meeting_material set fee_status = #{feeStatus} where id = #{id}
</update>
<!-- 会务材料"打包上传"回填: 替换文件 URL/文件名, 清空金额(待重 OCR) + 置 fee_status -->
<update id="updateFile">
update biz_meeting_material
set oss_url = #{ossUrl}, file_name = #{fileName}, amount = null, fee_status = #{feeStatus}
where id = #{id}
</update>
<delete id="deleteByPrimaryKey" parameterType="Long">
delete from biz_meeting_material where id = #{id}
</delete>
@@ -5,14 +5,15 @@
<resultMap type="BizMeetingSupervisor" id="BizMeetingSupervisorResult">
<id property="id" column="id" />
<result property="meetingId" column="meeting_id" />
<result property="userId" column="user_id" />
<result property="sponsorOrgId" column="sponsor_org_id" />
<result property="orgName" column="org_name" />
<result property="assignedBy" column="assigned_by" />
<result property="createTime" column="create_time" />
<result property="isDeleted" column="is_deleted" />
</resultMap>
<sql id="selectFields">
select id, meeting_id, user_id, assigned_by, create_time, is_deleted
select id, meeting_id, sponsor_org_id, assigned_by, create_time, is_deleted
from biz_meeting_supervisor
</sql>
@@ -22,15 +23,12 @@
</select>
<select id="selectByMeetingId" resultMap="BizMeetingSupervisorResult" parameterType="Long">
<include refid="selectFields"/>
where meeting_id = #{meetingId} and is_deleted = 0
order by id asc
</select>
<select id="selectByUserId" resultMap="BizMeetingSupervisorResult" parameterType="Long">
<include refid="selectFields"/>
where user_id = #{userId} and is_deleted = 0
order by id desc
select s.id, s.meeting_id, s.sponsor_org_id, s.assigned_by, s.create_time, s.is_deleted,
o.org_name
from biz_meeting_supervisor s
left join biz_org o on o.org_id = s.sponsor_org_id
where s.meeting_id = #{meetingId} and s.is_deleted = 0
order by s.id asc
</select>
<select id="selectList" resultMap="BizMeetingSupervisorResult" parameterType="BizMeetingSupervisor">
@@ -38,7 +36,7 @@
<where>
is_deleted = 0
<if test="meetingId != null">and meeting_id = #{meetingId}</if>
<if test="userId != null">and user_id = #{userId}</if>
<if test="sponsorOrgId != null">and sponsor_org_id = #{sponsorOrgId}</if>
</where>
order by id asc
</select>
@@ -47,30 +45,30 @@
insert into biz_meeting_supervisor
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="meetingId != null">meeting_id,</if>
<if test="userId != null">user_id,</if>
<if test="sponsorOrgId != null">sponsor_org_id,</if>
<if test="assignedBy != null">assigned_by,</if>
<if test="createTime != null">create_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="meetingId != null">#{meetingId},</if>
<if test="userId != null">#{userId},</if>
<if test="sponsorOrgId != null">#{sponsorOrgId},</if>
<if test="assignedBy != null">#{assignedBy},</if>
<if test="createTime != null">#{createTime},</if>
</trim>
</insert>
<insert id="insertBatch" parameterType="java.util.List">
insert into biz_meeting_supervisor (meeting_id, user_id, assigned_by, create_time)
insert into biz_meeting_supervisor (meeting_id, sponsor_org_id, assigned_by, create_time)
values
<foreach collection="list" item="item" separator=",">
(#{item.meetingId}, #{item.userId}, #{item.assignedBy}, #{item.createTime})
(#{item.meetingId}, #{item.sponsorOrgId}, #{item.assignedBy}, #{item.createTime})
</foreach>
</insert>
<update id="updateByPrimaryKey" parameterType="BizMeetingSupervisor">
update biz_meeting_supervisor
<trim prefix="SET" suffixOverrides=",">
<if test="userId != null">user_id = #{userId},</if>
<if test="sponsorOrgId != null">sponsor_org_id = #{sponsorOrgId},</if>
<if test="assignedBy != null">assigned_by = #{assignedBy},</if>
</trim>
where id = #{id}
@@ -103,20 +103,20 @@
<!--
支持方下拉选项: JOIN sys_user 取主账号 user_name (供分配弹窗缓存 biz_project.sponsor_admin_user_name 用)
返回 Map: userId / orgName / userName
返回 Map: orgId / orgName / userName
EXPLAIN 实际命中: idx_org_type_status (org_type,status) (优化器在数据量小时倾向小索引),
org_name LIKE 走 Using where 二次过滤, ORDER BY org_id DESC 走 filesort
过滤条件: orgName 模糊匹配 (主用) / userId 精确匹配 (拉回已选项)
过滤条件: orgName 模糊匹配 (主用) / orgId 精确匹配 (拉回已选项)
-->
<select id="selectSponsorOrgOptions" parameterType="BizOrg" resultType="java.util.LinkedHashMap">
select o.user_id as userId,
select o.org_id as orgId,
o.org_name as orgName,
u.user_name as userName
from biz_org o
join sys_user u on u.user_id = o.user_id
where o.org_type = 'sponsor'
and u.del_flag = '0'
<if test="userId != null">and o.user_id = #{userId}</if>
<if test="orgId != null">and o.org_id = #{orgId}</if>
<if test="orgName != null and orgName != ''">and o.org_name like concat('%', #{orgName}, '%')</if>
order by o.org_id desc
LIMIT 5
@@ -124,16 +124,16 @@
<!--
执行方下拉选项: JOIN sys_user 取 MAIN 账号 user_name (parent_user_id IS NULL 限定主账号)
返回 Map: userId / orgName / userName
返回 Map: orgId / orgName / userName
EXPLAIN 实际命中: idx_org_type_status (org_type,status) (优化器在数据量小时倾向小索引),
sys_user 走 PRIMARY eq_ref, parent_user_id IS NULL 走 Using where
关键: 只查 MAIN 账号 (parent_user_id IS NULL), 过滤掉同一公司下的普通员工子账号
value=userId (MAIN 账号 sys_user.user_id, 直接写 biz_project_assign.exec_user_id)
value=orgId (biz_org.org_id, 直接写 biz_project_assign.execution_unit_id)
label=orgName (执行单位名称, 不带 user_name 避免人名/昵称混淆)
过滤条件: orgName 模糊匹配 (主用) / userId 精确匹配 (拉回已选项)
过滤条件: orgName 模糊匹配 (主用) / orgId 精确匹配 (拉回已选项)
-->
<select id="selectExecutorOrgOptions" parameterType="BizOrg" resultType="java.util.LinkedHashMap">
select o.user_id as userId,
select o.org_id as orgId,
o.org_name as orgName,
u.user_name as userName
from biz_org o
@@ -141,12 +141,30 @@
where o.org_type = 'executor'
and u.del_flag = '0'
and u.parent_user_id is null
<if test="userId != null">and o.user_id = #{userId}</if>
<if test="orgId != null">and o.org_id = #{orgId}</if>
<if test="orgName != null and orgName != ''">and o.org_name like concat('%', #{orgName}, '%')</if>
order by o.org_id desc
LIMIT 5
</select>
<!--
支持方注册下拉选项 (匿名公开, register-sponsor 选企业注册 SUB 子账号)
与 selectSponsorOrgOptions 的区别: 不 JOIN sys_user → 无主账号 (user_id IS NULL) 的 org 也能被选到
返回 Map: orgId / orgName / mainUserId (= biz_org.user_id, 可为 null)
mainUserId 用于 registerSponsor 判断: 有主账号 → SUB 绑 parent_user_id; 无主账号 → parent_user_id 留空待 admin/manager 分配
-->
<select id="selectSponsorRegisterOptions" parameterType="BizOrg" resultType="java.util.LinkedHashMap">
select o.org_id as orgId,
o.org_name as orgName,
o.user_id as mainUserId
from biz_org o
where o.org_type = 'sponsor'
and o.status = '0'
<if test="orgName != null and orgName != ''">and o.org_name like concat('%', #{orgName}, '%')</if>
order by o.org_id desc
limit 20
</select>
<!--
当前登录 sponsor 的所属公司 (供 /sponsor/account 页面回显 + 主账号改名)
主账号 (sys_user.parent_user_id IS NULL): 用 own (biz_org.user_id = #{userId})
@@ -165,4 +183,17 @@
where u.user_id = #{userId}
limit 1
</select>
<!--
user_id → org_id 单一可信源反查:
MAIN 主账号: biz_org.user_id = #{userId} (企业表直接关联主账号)
SUB 子账号: biz_person.org_id (person 表 user_id = #{userId} 反查企业)
COALESCE 二选一, 都没有返回 NULL
-->
<select id="selectOrgIdByUserId" parameterType="Long" resultType="Long">
select coalesce(
(select org_id from biz_org where user_id = #{userId} limit 1),
(select org_id from biz_person where user_id = #{userId} limit 1)
)
</select>
</mapper>
@@ -10,12 +10,12 @@
<result property="orgType" column="org_type" />
<result property="department" column="department" />
<result property="position" column="position" />
<result property="role" column="role" />
<result property="userId" column="user_id" />
<result property="unitType" column="unit_type" />
<result property="accountType" column="account_type" />
<result property="parentUserId" column="parent_user_id" />
<result property="account" column="user_name" />
<result property="email" column="email" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
@@ -23,17 +23,18 @@
</resultMap>
<sql id="selectFields">
select person_id, name, phone, org_id, department, position, role, unit_type, user_id, create_by, create_time, update_by, update_time
select person_id, name, phone, org_id, department, position, unit_type, user_id, create_by, create_time, update_by, update_time
from biz_person
</sql>
<!-- 通用列表: LEFT JOIN biz_org 取公司名/类型, LEFT JOIN sys_user 取账号状态/类型 -->
<sql id="selectFieldsWithAccount">
select p.person_id, p.name, p.phone, p.org_id, o.org_name, o.org_type,
p.department, p.position, p.role, p.unit_type, p.user_id,
p.department, p.position, p.unit_type, p.user_id,
p.create_by, p.create_time, p.update_by, p.update_time,
u.account_type, u.parent_user_id, u.status, u.del_flag as user_del_flag,
u.user_name as user_name
u.user_name as user_name,
u.email as email
from biz_person p
left join biz_org o on p.org_id = o.org_id
left join sys_user u on p.user_id = u.user_id
@@ -51,12 +52,12 @@
<if test="unitType != null and unitType != ''"> and p.unit_type = #{unitType}</if>
<if test="name != null and name != ''"> and p.name like concat('%', #{name}, '%')</if>
<if test="phone != null and phone != ''"> and p.phone = #{phone}</if>
<if test="email != null and email != ''"> and u.email = #{email}</if>
<if test="orgId != null"> and p.org_id = #{orgId}</if>
<if test="orgName != null and orgName != ''"> and o.org_name like concat('%', #{orgName}, '%')</if>
<if test="orgType != null and orgType != ''"> and o.org_type = #{orgType}</if>
<if test="department != null and department != ''"> and p.department = #{department}</if>
<if test="position != null and position != ''"> and p.position = #{position}</if>
<if test="role != null and role != ''"> and p.role = #{role}</if>
<if test="status != null and status != ''"> and u.status = #{status}</if>
<if test="parentUserId != null"> and u.parent_user_id = #{parentUserId}</if>
<if test="userId != null"> and p.user_id = #{userId}</if>
@@ -80,7 +81,6 @@
<if test="orgId != null">org_id,</if>
<if test="department != null">department,</if>
<if test="position != null">position,</if>
<if test="role != null">role,</if>
<if test="unitType != null">unit_type,</if>
<if test="userId != null">user_id,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
@@ -95,7 +95,6 @@
<if test="orgId != null">#{orgId},</if>
<if test="department != null">#{department},</if>
<if test="position != null">#{position},</if>
<if test="role != null">#{role},</if>
<if test="unitType != null">#{unitType},</if>
<if test="userId != null">#{userId},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
@@ -115,7 +114,6 @@
<if test="phone != null">phone = #{phone},</if>
<if test="department != null">department = #{department},</if>
<if test="position != null">position = #{position},</if>
<if test="role != null">role = #{role},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
update_time = sysdate(),
</trim>
@@ -162,7 +160,6 @@
<if test="orgName != null and orgName != ''"> and o.org_name like concat('%', #{orgName}, '%')</if>
<if test="department != null and department != ''"> and p.department = #{department}</if>
<if test="position != null and position != ''"> and p.position = #{position}</if>
<if test="role != null and role != ''"> and p.role = #{role}</if>
<if test="status != null and status != ''"> and u.status = #{status}</if>
</where>
order by p.person_id desc
@@ -183,16 +180,9 @@
<if test="orgName != null and orgName != ''"> and o.org_name like concat('%', #{orgName}, '%')</if>
<if test="department != null and department != ''"> and p.department = #{department}</if>
<if test="position != null and position != ''"> and p.position = #{position}</if>
<if test="role != null and role != ''"> and p.role = #{role}</if>
<if test="status != null and status != ''"> and u.status = #{status}</if>
</where>
order by p.person_id desc
</select>
<!-- 校验某 org 下是否已有 admin 角色 (主账号自带 biz_person.role='admin', 每公司唯一) -->
<select id="countAdminByOrgId" resultType="int">
select count(*) from biz_person p
left join sys_user u on p.user_id = u.user_id
where p.org_id = #{orgId} and p.role = 'admin' and u.del_flag = '0'
</select>
</mapper>
@@ -5,7 +5,6 @@
<id property="assignId" column="assign_id" />
<result property="projectId" column="project_id" />
<result property="executionUnitId" column="execution_unit_id" />
<result property="execUserId" column="exec_user_id" />
<result property="sessions" column="sessions" />
<result property="amount" column="amount" />
<result property="remark" column="remark" />
@@ -18,7 +17,7 @@
</resultMap>
<sql id="selectFields">
select assign_id, project_id, execution_unit_id, exec_user_id,
select assign_id, project_id, execution_unit_id,
sessions, amount, remark, status,
create_by, create_time, update_by, update_time, is_deleted
from biz_project_assign
@@ -41,7 +40,6 @@
is_deleted = 0
<if test="projectId != null"> and project_id = #{projectId}</if>
<if test="executionUnitId != null"> and execution_unit_id = #{executionUnitId}</if>
<if test="execUserId != null"> and exec_user_id = #{execUserId}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
</where>
order by assign_id desc
@@ -57,7 +55,6 @@
<if test="assignId != null and assignId != ''">assign_id,</if>
<if test="projectId != null">project_id,</if>
<if test="executionUnitId != null">execution_unit_id,</if>
<if test="execUserId != null">exec_user_id,</if>
<if test="sessions != null">sessions,</if>
<if test="amount != null">amount,</if>
<if test="remark != null and remark != ''">remark,</if>
@@ -71,7 +68,6 @@
<if test="assignId != null and assignId != ''">#{assignId},</if>
<if test="projectId != null">#{projectId},</if>
<if test="executionUnitId != null">#{executionUnitId},</if>
<if test="execUserId != null">#{execUserId},</if>
<if test="sessions != null">#{sessions},</if>
<if test="amount != null">#{amount},</if>
<if test="remark != null and remark != ''">#{remark},</if>
@@ -87,7 +83,6 @@
update biz_project_assign
<trim prefix="SET" suffixOverrides=",">
<if test="executionUnitId != null">execution_unit_id = #{executionUnitId},</if>
<if test="execUserId != null">exec_user_id = #{execUserId},</if>
<if test="sessions != null">sessions = #{sessions},</if>
<if test="amount != null">amount = #{amount},</if>
<if test="remark != null">remark = #{remark},</if>
@@ -5,7 +5,7 @@
<resultMap id="BaseResultMap" type="BizProjectExecutorAssign">
<id property="id" column="id" />
<result property="projectId" column="project_id" />
<result property="executorUserId" column="executor_user_id" />
<result property="executorOrgId" column="executor_org_id" />
<result property="staffUserId" column="staff_user_id" />
<result property="assignDesc" column="assign_desc" />
<result property="assignPoints" column="assign_points" />
@@ -18,9 +18,9 @@
<insert id="insertAssign" parameterType="BizProjectExecutorAssign" useGeneratedKeys="true" keyProperty="id">
INSERT INTO biz_project_executor_assign
(project_id, executor_user_id, staff_user_id, assign_desc, assign_points, create_by, create_time)
(project_id, executor_org_id, staff_user_id, assign_desc, assign_points, create_by, create_time)
VALUES
(#{projectId}, #{executorUserId}, #{staffUserId}, #{assignDesc}, #{assignPoints}, #{createBy}, sysdate())
(#{projectId}, #{executorOrgId}, #{staffUserId}, #{assignDesc}, #{assignPoints}, #{createBy}, sysdate())
</insert>
<!-- 按 project_id 全删 (执行方分配策略: 先删后插) -->
@@ -38,7 +38,8 @@
e.user_name AS executor_user_name,
s.user_name AS staff_user_name
FROM biz_project_executor_assign a
LEFT JOIN sys_user e ON a.executor_user_id = e.user_id
LEFT JOIN biz_org o ON o.org_id = a.executor_org_id
LEFT JOIN sys_user e ON e.user_id = o.user_id
LEFT JOIN sys_user s ON a.staff_user_id = s.user_id
WHERE a.project_id = #{projectId} and a.is_deleted = 0
ORDER BY a.create_time DESC
@@ -18,7 +18,7 @@
<result property="managerScore" column="manager_score" />
<result property="sponsorScore" column="sponsor_score" />
<result property="sponsorAdminUserName" column="sponsor_admin_user_name" />
<result property="sponsorAdminUserId" column="sponsor_admin_user_id" />
<result property="sponsorOrgId" column="sponsor_org_id" />
<result property="leadUserId" column="lead_user_id" />
<result property="leadUserName" column="lead_user_name" />
<result property="isBidProject" column="is_bid_project" />
@@ -43,11 +43,15 @@
<result property="invitationUrl" column="invitation_url" />
<result property="supportLetterUrl" column="support_letter_url" />
<result property="publishUrl" column="publish_url" />
<result property="scheduleUrl" column="schedule_url" />
<result property="openDeadline" column="open_deadline" />
<result property="openStatus" column="open_status" />
<result property="isDeleted" column="is_deleted" />
</resultMap>
<sql id="selectFields">
select p.project_id, p.project_no, p.project_name, p.total_sessions, p.done_sessions, p.todo_sessions, p.total_amount, p.available_amount, p.paid_labor_amount, p.paid_meeting_amount, p.manager_score, p.sponsor_score, p.sponsor_admin_user_name, p.project_form, p.is_finished, p.is_settled, p.sponsor_admin_user_id, p.lead_user_id, p.is_bid_project, p.create_by, p.create_user_id, p.create_time, p.update_by, p.update_time, p.manage_fee, p.role_labor, p.start_time, p.end_time, p.submit_deadline_days, p.support_contract_url, p.execute_contract_url, p.invitation_url, p.support_letter_url, p.publish_url, p.is_deleted,
select p.project_id, p.project_no, p.project_name, p.total_sessions, p.done_sessions, p.todo_sessions, p.total_amount, p.available_amount, p.paid_labor_amount, p.paid_meeting_amount, p.manager_score, p.sponsor_score, p.project_form, p.is_finished, p.is_settled, p.sponsor_org_id, p.lead_user_id, p.is_bid_project, p.create_by, p.create_user_id, p.create_time, p.update_by, p.update_time, p.manage_fee, p.role_labor, p.start_time, p.end_time, p.submit_deadline_days, p.support_contract_url, p.execute_contract_url, p.invitation_url, p.support_letter_url, p.publish_url, p.schedule_url, p.open_deadline, p.open_status, p.is_deleted,
o.org_name as sponsor_org_name,
su.user_name as sponsor_admin_user_name,
lu.user_name as lead_user_name,
bp.name as create_user_name,
(select group_concat(distinct o2.org_name separator ',')
@@ -55,7 +59,8 @@
join biz_org o2 on o2.org_id = bpa.execution_unit_id and o2.org_type = 'executor'
where bpa.project_id = p.project_id and bpa.is_deleted = 0) as exec_org_names
from biz_project p
left join biz_org o on o.user_id = p.sponsor_admin_user_id and o.org_type = 'sponsor'
left join biz_org o on o.org_id = p.sponsor_org_id and o.org_type = 'sponsor'
left join sys_user su on su.user_id = o.user_id
left join sys_user lu on lu.user_id = p.lead_user_id
left join biz_person bp on bp.user_id = p.create_user_id
</sql>
@@ -64,13 +69,14 @@
<sql id="selectFieldsForSponsor">
select p.project_id, p.project_no, p.project_name, p.total_sessions, p.done_sessions, p.todo_sessions,
p.total_amount, p.available_amount, p.paid_labor_amount, p.paid_meeting_amount,
p.manager_score, p.sponsor_score, p.sponsor_admin_user_name, p.project_form, p.is_finished, p.is_settled,
p.sponsor_admin_user_id, p.lead_user_id, p.is_bid_project,
p.manager_score, p.sponsor_score, p.project_form, p.is_finished, p.is_settled,
p.sponsor_org_id, p.lead_user_id, p.is_bid_project,
p.create_by, p.create_user_id, p.create_time, p.update_by, p.update_time, p.manage_fee, p.role_labor,
p.start_time, p.end_time, p.submit_deadline_days,
p.support_contract_url, p.execute_contract_url, p.invitation_url, p.support_letter_url,
p.publish_url, p.is_deleted,
p.publish_url, p.schedule_url, p.open_deadline, p.open_status, p.is_deleted,
o.org_name as sponsor_org_name,
su.user_name as sponsor_admin_user_name,
lu.user_name as lead_user_name,
bp.name as create_user_name,
(select group_concat(distinct o2.org_name separator ',')
@@ -78,7 +84,8 @@
join biz_org o2 on o2.org_id = bpa.execution_unit_id and o2.org_type = 'executor'
where bpa.project_id = p.project_id and bpa.is_deleted = 0) as exec_org_names
from biz_project p
left join biz_org o on o.user_id = p.sponsor_admin_user_id and o.org_type = 'sponsor'
left join biz_org o on o.org_id = p.sponsor_org_id and o.org_type = 'sponsor'
left join sys_user su on su.user_id = o.user_id
left join sys_user lu on lu.user_id = p.lead_user_id
left join biz_person bp on bp.user_id = p.create_user_id
</sql>
@@ -91,6 +98,8 @@
<include refid="selectFieldsForSponsor"/>
<where>
p.is_deleted = 0
<!-- 结题(is_finished=1)且未开通(open_status=N)的项目, sponsor 不可见 -->
and not (p.is_finished = '1' and p.open_status = 'N')
<if test="params.projectIds != null and params.projectIds.size() > 0">
and p.project_id in
<foreach collection="params.projectIds" item="id" open="(" separator="," close=")">
@@ -98,12 +107,12 @@
</foreach>
</if>
<!--
sponsor 视角: 可见项目 = MAIN/ADMIN 默认 (sponsor_admin_user_id) OR SUB/监察员 (sponsor_assign.monitor_user_id), 任一路径同时 UNION biz_publicity_support_intent
sponsor 视角: 可见项目 = MAIN/ADMIN 默认 (sponsor_org_id, 经 user_id 反查 org_id) OR SUB/监察员 (sponsor_assign.monitor_user_id), 任一路径同时 UNION biz_publicity_support_intent
业务: sponsor (无论 MAIN/SUB) 提交过支持意向的项目, 同样要在 /sponsor/my-projects 看到, 跟被分配监察员同等地位
分页: PageHelper 加 LIMIT 到外层, 自动生成 COUNT(*) FROM biz_project WHERE ... — 子查询内 DISTINCT 避免重复 count
-->
<if test="params.sponsorAdminUserId != null">and (
p.sponsor_admin_user_id = #{params.sponsorAdminUserId}
p.sponsor_org_id = (select org_id from biz_org where user_id = #{params.sponsorAdminUserId} and org_type = 'sponsor')
or p.project_id in (
select distinct i.project_id
from biz_publicity_support_intent i
@@ -140,8 +149,9 @@
注: executor 角色无评分/聚合分需求, 复用 selectFields (含 sponsor_score / manager_score)
-->
<select id="selectExecutorList" resultMap="BizProjectResult" parameterType="BizProject">
select distinct p.project_id, p.project_no, p.project_name, p.total_sessions, p.done_sessions, p.todo_sessions, p.total_amount, p.available_amount, p.paid_labor_amount, p.paid_meeting_amount, p.manager_score, p.sponsor_score, p.sponsor_admin_user_name, p.project_form, p.is_finished, p.is_settled, p.sponsor_admin_user_id, p.lead_user_id, p.is_bid_project, p.create_by, p.create_user_id, p.create_time, p.update_by, p.update_time, p.manage_fee, p.role_labor, p.start_time, p.end_time, p.submit_deadline_days, p.support_contract_url, p.execute_contract_url, p.invitation_url, p.support_letter_url, p.publish_url,
select distinct p.project_id, p.project_no, p.project_name, p.total_sessions, p.done_sessions, p.todo_sessions, p.total_amount, p.available_amount, p.paid_labor_amount, p.paid_meeting_amount, p.manager_score, p.sponsor_score, p.project_form, p.is_finished, p.is_settled, p.sponsor_org_id, p.lead_user_id, p.is_bid_project, p.create_by, p.create_user_id, p.create_time, p.update_by, p.update_time, p.manage_fee, p.role_labor, p.start_time, p.end_time, p.submit_deadline_days, p.support_contract_url, p.execute_contract_url, p.invitation_url, p.support_letter_url, p.publish_url,
o.org_name as sponsor_org_name,
su.user_name as sponsor_admin_user_name,
lu.user_name as lead_user_name,
bp.name as create_user_name,
(select group_concat(distinct o2.org_name separator ',')
@@ -152,22 +162,20 @@
from biz_project_assign bpa3
where bpa3.project_id = p.project_id
and bpa3.is_deleted = 0
and (bpa3.exec_user_id = #{params.executorUserId}
or bpa3.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor'))) as assigned_sessions,
and bpa3.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor')) as assigned_sessions,
(select coalesce(sum(bpa4.amount), 0)
from biz_project_assign bpa4
where bpa4.project_id = p.project_id
and bpa4.is_deleted = 0
and (bpa4.exec_user_id = #{params.executorUserId}
or bpa4.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor'))) as assigned_amount,
and bpa4.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor')) as assigned_amount,
(select count(*) from biz_meeting m where m.project_id = p.project_id and m.is_deleted = 0) as meeting_count
from biz_project p
<!-- 执行方专属 join: 把 executor 限定条件放进 ON (而不是 WHERE), 这样 join 只命中分给当前执行方的 assignment, 1 行/项目. SELECT DISTINCT 保留以防 LEFT JOIN 副作用 -->
join biz_project_assign a on a.project_id = p.project_id
and a.is_deleted = 0
and (a.exec_user_id = #{params.executorUserId}
or a.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor'))
left join biz_org o on o.user_id = p.sponsor_admin_user_id and o.org_type = 'sponsor'
and a.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor')
left join biz_org o on o.org_id = p.sponsor_org_id and o.org_type = 'sponsor'
left join sys_user su on su.user_id = o.user_id
left join sys_user lu on lu.user_id = p.lead_user_id
left join biz_person bp on bp.user_id = p.create_user_id
<where>
@@ -188,8 +196,9 @@
场次/金额列 assigned_sessions/assigned_amount 按 params.executorUserId (主账号/本公司) 聚合 — 执行人看到的是公司数据, 不是个人数据
-->
<select id="selectExecutorStaffList" resultMap="BizProjectResult" parameterType="BizProject">
select p.project_id, p.project_no, p.project_name, p.total_sessions, p.done_sessions, p.todo_sessions, p.total_amount, p.available_amount, p.paid_labor_amount, p.paid_meeting_amount, p.manager_score, p.sponsor_score, p.sponsor_admin_user_name, p.project_form, p.is_finished, p.is_settled, p.sponsor_admin_user_id, p.lead_user_id, p.is_bid_project, p.create_by, p.create_user_id, p.create_time, p.update_by, p.update_time, p.manage_fee, p.role_labor, p.start_time, p.end_time, p.submit_deadline_days, p.support_contract_url, p.execute_contract_url, p.invitation_url, p.support_letter_url, p.publish_url,
select p.project_id, p.project_no, p.project_name, p.total_sessions, p.done_sessions, p.todo_sessions, p.total_amount, p.available_amount, p.paid_labor_amount, p.paid_meeting_amount, p.manager_score, p.sponsor_score, p.project_form, p.is_finished, p.is_settled, p.sponsor_org_id, p.lead_user_id, p.is_bid_project, p.create_by, p.create_user_id, p.create_time, p.update_by, p.update_time, p.manage_fee, p.role_labor, p.start_time, p.end_time, p.submit_deadline_days, p.support_contract_url, p.execute_contract_url, p.invitation_url, p.support_letter_url, p.publish_url,
o.org_name as sponsor_org_name,
su.user_name as sponsor_admin_user_name,
lu.user_name as lead_user_name,
bp.name as create_user_name,
(select group_concat(distinct o2.org_name separator ',')
@@ -200,17 +209,16 @@
from biz_project_assign bpa3
where bpa3.project_id = p.project_id
and bpa3.is_deleted = 0
and (bpa3.exec_user_id = #{params.executorUserId}
or bpa3.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor'))) as assigned_sessions,
and bpa3.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor')) as assigned_sessions,
(select coalesce(sum(bpa4.amount), 0)
from biz_project_assign bpa4
where bpa4.project_id = p.project_id
and bpa4.is_deleted = 0
and (bpa4.exec_user_id = #{params.executorUserId}
or bpa4.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor'))) as assigned_amount,
and bpa4.execution_unit_id = (select org_id from biz_org where user_id = #{params.executorUserId} and org_type = 'executor')) as assigned_amount,
(select count(*) from biz_meeting m where m.project_id = p.project_id and m.is_deleted = 0) as meeting_count
from biz_project p
left join biz_org o on o.user_id = p.sponsor_admin_user_id and o.org_type = 'sponsor'
left join biz_org o on o.org_id = p.sponsor_org_id and o.org_type = 'sponsor'
left join sys_user su on su.user_id = o.user_id
left join sys_user lu on lu.user_id = p.lead_user_id
left join biz_person bp on bp.user_id = p.create_user_id
<where>
@@ -248,25 +256,26 @@
<if test="projectNo != null and projectNo != ''">and project_no like concat('%', #{projectNo}, '%')</if>
<if test="projectName != null and projectName != ''">and project_name like concat('%', #{projectName}, '%')</if>
<if test="projectForm != null and projectForm != ''">and project_form = #{projectForm}</if>
<if test="sponsorAdminUserIds != null and sponsorAdminUserIds.size() > 0">
and sponsor_admin_user_id in
<foreach collection="sponsorAdminUserIds" item="id" open="(" separator="," close=")">
<if test="sponsorOrgIds != null and sponsorOrgIds.size() > 0">
and sponsor_org_id in
<foreach collection="sponsorOrgIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
<if test="execAdminUserIds != null and execAdminUserIds.size() > 0">
<if test="execOrgIds != null and execOrgIds.size() > 0">
and exists (
select 1 from biz_project_assign bpa
where bpa.project_id = project_id
and bpa.exec_user_id in
<foreach collection="execAdminUserIds" item="id" open="(" separator="," close=")">
where bpa.project_id = p.project_id
and bpa.execution_unit_id in
<foreach collection="execOrgIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
)
</if>
<if test="isFinished != null and isFinished != ''">and is_finished = #{isFinished}</if>
<if test="isSettled != null and isSettled != ''">and is_settled = #{isSettled}</if>
<if test="managerScore != null">and manager_score = #{managerScore}</if>
<if test="startTime != null">and start_time &gt;= #{startTime}</if>
<if test="endTime != null">and end_time &lt;= #{endTime}</if>
</where>
order by project_id desc
</select>
@@ -285,11 +294,10 @@
<if test="paidMeetingAmount != null">paid_meeting_amount,</if>
<if test="managerScore != null">manager_score,</if>
<if test="sponsorScore != null">sponsor_score,</if>
<if test="sponsorAdminUserName != null and sponsorAdminUserName != ''">sponsor_admin_user_name,</if>
<if test="projectForm != null and projectForm != ''">project_form,</if>
<if test="isFinished != null and isFinished != ''">is_finished,</if>
<if test="isSettled != null and isSettled != ''">is_settled,</if>
<if test="sponsorAdminUserId != null">sponsor_admin_user_id,</if>
<if test="sponsorOrgId != null">sponsor_org_id,</if>
<if test="leadUserId != null">lead_user_id,</if>
<if test="isBidProject != null and isBidProject != ''">is_bid_project,</if>
<if test="createBy != null">create_by,</if>
@@ -307,6 +315,9 @@
<if test="invitationUrl != null and invitationUrl != ''">invitation_url,</if>
<if test="supportLetterUrl != null and supportLetterUrl != ''">support_letter_url,</if>
<if test="publishUrl != null and publishUrl != ''">publish_url,</if>
<if test="scheduleUrl != null and scheduleUrl != ''">schedule_url,</if>
<if test="openDeadline != null">open_deadline,</if>
<if test="openStatus != null and openStatus != ''">open_status,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="projectId != null and projectId != ''">#{projectId},</if>
@@ -321,11 +332,10 @@
<if test="paidMeetingAmount != null">#{paidMeetingAmount},</if>
<if test="managerScore != null">#{managerScore},</if>
<if test="sponsorScore != null">#{sponsorScore},</if>
<if test="sponsorAdminUserName != null and sponsorAdminUserName != ''">#{sponsorAdminUserName},</if>
<if test="projectForm != null and projectForm != ''">#{projectForm},</if>
<if test="isFinished != null and isFinished != ''">#{isFinished},</if>
<if test="isSettled != null and isSettled != ''">#{isSettled},</if>
<if test="sponsorAdminUserId != null">#{sponsorAdminUserId},</if>
<if test="sponsorOrgId != null">#{sponsorOrgId},</if>
<if test="leadUserId != null">#{leadUserId},</if>
<if test="isBidProject != null and isBidProject != ''">#{isBidProject},</if>
<if test="createBy != null">#{createBy},</if>
@@ -343,6 +353,9 @@
<if test="invitationUrl != null and invitationUrl != ''">#{invitationUrl},</if>
<if test="supportLetterUrl != null and supportLetterUrl != ''">#{supportLetterUrl},</if>
<if test="publishUrl != null and publishUrl != ''">#{publishUrl},</if>
<if test="scheduleUrl != null and scheduleUrl != ''">#{scheduleUrl},</if>
<if test="openDeadline != null">#{openDeadline},</if>
<if test="openStatus != null and openStatus != ''">#{openStatus},</if>
</trim>
</insert>
<update id="updateByPrimaryKey" parameterType="BizProject">
@@ -358,6 +371,9 @@
<if test="invitationUrl != null and invitationUrl != ''">invitation_url = #{invitationUrl},</if>
<if test="supportLetterUrl != null and supportLetterUrl != ''">support_letter_url = #{supportLetterUrl},</if>
<if test="publishUrl != null and publishUrl != ''">publish_url = #{publishUrl},</if>
<if test="scheduleUrl != null and scheduleUrl != ''">schedule_url = #{scheduleUrl},</if>
<if test="openDeadline != null">open_deadline = #{openDeadline},</if>
<if test="openStatus != null and openStatus != ''">open_status = #{openStatus},</if>
<if test="projectNo != null and projectNo != ''">project_no = #{projectNo},</if>
<if test="projectName != null and projectName != ''">project_name = #{projectName},</if>
<if test="totalSessions != null">total_sessions = #{totalSessions},</if>
@@ -369,11 +385,10 @@
<if test="paidMeetingAmount != null">paid_meeting_amount = #{paidMeetingAmount},</if>
<if test="managerScore != null">manager_score = #{managerScore},</if>
<if test="sponsorScore != null">sponsor_score = #{sponsorScore},</if>
<if test="sponsorAdminUserName != null and sponsorAdminUserName != ''">sponsor_admin_user_name = #{sponsorAdminUserName},</if>
<if test="projectForm != null and projectForm != ''">project_form = #{projectForm},</if>
<if test="isFinished != null and isFinished != ''">is_finished = #{isFinished},</if>
<if test="isSettled != null and isSettled != ''">is_settled = #{isSettled},</if>
<if test="sponsorAdminUserId != null">sponsor_admin_user_id = #{sponsorAdminUserId},</if>
<if test="sponsorOrgId != null">sponsor_org_id = #{sponsorOrgId},</if>
<if test="leadUserId != null">lead_user_id = #{leadUserId},</if>
<if test="isBidProject != null and isBidProject != ''">is_bid_project = #{isBidProject},</if>
<if test="createBy != null">create_by = #{createBy},</if>
@@ -384,6 +399,24 @@
</trim>
where project_id = #{projectId}
</update>
<!-- 删除公告: 将 4 个公示 URL 字段全部置 NULL (未发布态由 URL 是否为空判定, 表里无独立 is_published 列) -->
<update id="clearAnnouncement" parameterType="Long">
update biz_project
set invitation_url = null,
support_letter_url = null,
publish_url = null,
schedule_url = null
where project_id = #{projectId}
</update>
<!-- 开通到期回收: 每天 00:05 由 OpenStatusScheduler 调用, 到期(open_deadline <= 今天)的 Y 置回 N -->
<update id="closeExpiredOpenStatus">
update biz_project
set open_status = 'N'
where open_status = 'Y'
and open_deadline is not null
and open_deadline &lt;= CURDATE()
and is_deleted = 0
</update>
<delete id="deleteByPrimaryKey" parameterType="Long">
delete from biz_project where project_id = #{projectId}
</delete>
@@ -407,8 +440,7 @@
from biz_project_assign a
where a.project_id = #{projectId}
and a.is_deleted = 0
and (a.exec_user_id = #{executorUserId}
or a.execution_unit_id = (select org_id from biz_org where user_id = #{executorUserId} and org_type = 'executor'))
and a.execution_unit_id = (select org_id from biz_org where user_id = #{executorUserId} and org_type = 'executor')
</select>
<!-- 提交权限用: 判断 user 是否该项目的执行方.
MAIN: biz_project_assign (exec_user_id 或 其执行单位 org); SUB(执行人): biz_project_executor_assign.staff_user_id.
@@ -420,8 +452,7 @@
from biz_project_assign a
where a.project_id = #{projectId}
and a.is_deleted = 0
and (a.exec_user_id = #{userId}
or a.execution_unit_id = (select org_id from biz_org where user_id = #{userId} and org_type = 'executor'))
and a.execution_unit_id = (select org_id from biz_org where user_id = #{userId} and org_type = 'executor')
union
select 1
from biz_project_executor_assign b
@@ -10,6 +10,7 @@
<result property="planCategory" column="plan_category" />
<result property="projectForm" column="project_form" />
<result property="designFileUrl" column="design_file_url" />
<result property="subjectDirection" column="subject_direction" />
<result property="status" column="status" />
<result property="isSettled" column="is_settled" />
<result property="projectNo" column="project_no" />
@@ -29,7 +30,7 @@
<sql id="selectFields">
select p.plan_id, p.plan_name, p.plan_direction, p.plan_direction_id,
s.title as plan_direction_title,
p.plan_category, p.project_form, p.design_file_url, p.status, p.is_settled,
p.plan_category, p.project_form, p.design_file_url, p.subject_direction, p.status, p.is_settled,
p.project_no, p.remark, p.audit_opinion, p.audit_by, p.audit_time, p.submitter_id,
COALESCE(bp.name, u.user_name) as submitter_name,
proj.project_name as project_name,
@@ -70,6 +71,7 @@
<if test="planCategory != null and planCategory != ''">plan_category,</if>
<if test="projectForm != null and projectForm != ''">project_form,</if>
<if test="designFileUrl != null and designFileUrl != ''">design_file_url,</if>
<if test="subjectDirection != null and subjectDirection != ''">subject_direction,</if>
<if test="status != null">status,</if>
<if test="isSettled != null and isSettled != ''">is_settled,</if>
<if test="projectNo != null and projectNo != ''">project_no,</if>
@@ -84,6 +86,7 @@
<if test="planCategory != null and planCategory != ''">#{planCategory},</if>
<if test="projectForm != null and projectForm != ''">#{projectForm},</if>
<if test="designFileUrl != null and designFileUrl != ''">#{designFileUrl},</if>
<if test="subjectDirection != null and subjectDirection != ''">#{subjectDirection},</if>
<if test="status != null">#{status},</if>
<if test="isSettled != null and isSettled != ''">#{isSettled},</if>
<if test="projectNo != null and projectNo != ''">#{projectNo},</if>
@@ -100,6 +103,7 @@
<if test="planCategory != null and planCategory != ''">plan_category = #{planCategory},</if>
<if test="projectForm != null and projectForm != ''">project_form = #{projectForm},</if>
<if test="designFileUrl != null and designFileUrl != ''">design_file_url = #{designFileUrl},</if>
<if test="subjectDirection != null and subjectDirection != ''">subject_direction = #{subjectDirection},</if>
<if test="isSettled != null and isSettled != ''">is_settled = #{isSettled},</if>
<if test="projectNo != null and projectNo != ''">project_no = #{projectNo},</if>
<if test="auditOpinion != null and auditOpinion != ''">audit_opinion = #{auditOpinion},</if>
@@ -5,7 +5,7 @@
<resultMap id="BaseResultMap" type="BizProjectSponsorAssign">
<id property="id" column="id" />
<result property="projectId" column="project_id" />
<result property="sponsorUserId" column="sponsor_user_id" />
<result property="sponsorOrgId" column="sponsor_org_id" />
<result property="monitorUserId" column="monitor_user_id" />
<result property="assignDesc" column="assign_desc" />
<result property="assignPoints" column="assign_points" />
@@ -18,9 +18,9 @@
<insert id="insertAssign" parameterType="BizProjectSponsorAssign" useGeneratedKeys="true" keyProperty="id">
INSERT INTO biz_project_sponsor_assign
(project_id, sponsor_user_id, monitor_user_id, assign_desc, assign_points, create_by, create_time)
(project_id, sponsor_org_id, monitor_user_id, assign_desc, assign_points, create_by, create_time)
VALUES
(#{projectId}, #{sponsorUserId}, #{monitorUserId}, #{assignDesc}, #{assignPoints}, #{createBy}, sysdate())
(#{projectId}, #{sponsorOrgId}, #{monitorUserId}, #{assignDesc}, #{assignPoints}, #{createBy}, sysdate())
</insert>
<!-- 按 project_id 全删 (支持方分配策略: 一个项目只分配一个 sponsor, 先删后插) -->
@@ -38,7 +38,8 @@
s.user_name AS sponsor_user_name,
m.user_name AS monitor_user_name
FROM biz_project_sponsor_assign a
LEFT JOIN sys_user s ON a.sponsor_user_id = s.user_id
LEFT JOIN biz_org o ON o.org_id = a.sponsor_org_id
LEFT JOIN sys_user s ON s.user_id = o.user_id
LEFT JOIN sys_user m ON a.monitor_user_id = m.user_id
WHERE a.project_id = #{projectId} and a.is_deleted = 0
ORDER BY a.create_time DESC