feat: 多处页面改造 + 新增劳务协议模板配置

主要改动:
- biz_meeting_attendee 中间表 + doctor/expert 角色数据隔离
- biz_meeting_attendee 加 handsign/labor_protocol 字段 (劳务协议改造)
- biz_labor_protocol_template 配置表 + admin 页面 (从 HeguiConstants 迁移)
- biz_expert.expertId 改 Long + IdGenerator 生成 (去自增)
- Login.vue / PublicityDetail.vue / Home.vue 等多处 bug 修复 + UI 改进
- 新增 page-tech-review 报告 3 篇 (_self/*.md)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
郭庆泰
2026-08-19 21:06:49 +08:00
co-authored by Claude
parent ec4a8aa8f0
commit e496f34393
44 changed files with 2143 additions and 130 deletions
@@ -36,7 +36,7 @@
<include refid="selectFields"/>
where user_id = #{userId} limit 1
</select>
<select id="selectByPrimaryKey" resultMap="BizExpertResult" parameterType="String">
<select id="selectByPrimaryKey" resultMap="BizExpertResult" parameterType="Long">
<include refid="selectFields"/>
where expert_id = #{expertId}
</select>
@@ -53,7 +53,7 @@
<insert id="insert" parameterType="BizExpert">
insert into biz_expert
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="expertId != null and expertId != ''">expert_id,</if>
<if test="expertId != null">expert_id,</if>
<if test="userId != null">user_id,</if>
<if test="name != null">name,</if>
<if test="phone != null">phone,</if>
@@ -81,7 +81,7 @@
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="expertId != null and expertId != ''">#{expertId},</if>
<if test="expertId != null">#{expertId},</if>
<if test="userId != null">#{userId},</if>
<if test="name != null">#{name},</if>
<if test="phone != null">#{phone},</if>
@@ -206,13 +206,13 @@
</trim>
where expert_id = #{expertId}
</update>
<delete id="deleteByPrimaryKey" parameterType="String">
<delete id="deleteByPrimaryKey" parameterType="Long">
delete from biz_expert where expert_id = #{expertId}
</delete>
<delete id="deleteByPrimaryKeys" parameterType="String">
<delete id="deleteByPrimaryKeys" parameterType="Long">
delete from biz_expert where expert_id in
<foreach collection="expertIds" item="expertId" open="(" separator="," close=")">
#{expertId}
<foreach collection="expertId" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>
@@ -0,0 +1,75 @@
<?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.business.mapper.BizLaborProtocolTemplateMapper">
<resultMap type="BizLaborProtocolTemplate" id="BizLaborProtocolTemplateResult">
<id property="id" column="id" />
<result property="templateName" column="template_name" />
<result property="templateContent" column="template_content" />
<result property="defaultFlag" column="default_flag" />
<result property="sortOrder" column="sort_order" />
<result property="status" column="status" />
<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>
<sql id="selectFields">
select id, template_name, template_content, default_flag, sort_order, status, remark,
create_by, create_time, update_by, update_time
from biz_labor_protocol_template
</sql>
<select id="selectByPrimaryKey" resultMap="BizLaborProtocolTemplateResult" parameterType="Long">
<include refid="selectFields"/>
where id = #{id}
</select>
<select id="selectList" resultMap="BizLaborProtocolTemplateResult" parameterType="BizLaborProtocolTemplate">
<include refid="selectFields"/>
<where>
<if test="templateName != null and templateName != ''">and template_name like concat('%', #{templateName}, '%')</if>
<if test="status != null and status != ''">and status = #{status}</if>
<if test="defaultFlag != null and defaultFlag != ''">and default_flag = #{defaultFlag}</if>
</where>
order by sort_order asc, id asc
</select>
<select id="selectDefault" resultMap="BizLaborProtocolTemplateResult">
<include refid="selectFields"/>
where default_flag = 'Y' and status = 'Y'
limit 1
</select>
<select id="selectAllEnabled" resultMap="BizLaborProtocolTemplateResult">
<include refid="selectFields"/>
where status = 'Y'
order by sort_order asc, id asc
</select>
<insert id="insert" parameterType="BizLaborProtocolTemplate">
insert into biz_labor_protocol_template(template_name, template_content, default_flag, sort_order, status, remark, create_by, create_time)
values(#{templateName}, #{templateContent}, #{defaultFlag}, #{sortOrder}, #{status}, #{remark}, #{createBy}, sysdate())
</insert>
<update id="updateByPrimaryKey" parameterType="BizLaborProtocolTemplate">
update biz_labor_protocol_template
<set>
<if test="templateName != null and templateName != ''">template_name = #{templateName},</if>
template_content = #{templateContent},
<if test="defaultFlag != null and defaultFlag != ''">default_flag = #{defaultFlag},</if>
<if test="sortOrder != null">sort_order = #{sortOrder},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="remark != null">remark = #{remark},</if>
update_by = #{updateBy},
update_time = sysdate()
</set>
where id = #{id}
</update>
<update id="clearAllDefault">
update biz_labor_protocol_template set default_flag = 'N', update_time = sysdate()
</update>
<delete id="deleteByPrimaryKey" parameterType="Long">
delete from biz_labor_protocol_template where id = #{id}
</delete>
<delete id="deleteByPrimaryKeys" parameterType="Long">
delete from biz_labor_protocol_template where id in
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>
@@ -0,0 +1,66 @@
<?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.business.mapper.BizMeetingAttendeeMapper">
<resultMap type="BizMeetingAttendee" id="BizMeetingAttendeeResult">
<id property="id" column="id" />
<result property="meetingId" column="meeting_id" />
<result property="userId" column="user_id" />
<result property="handsign" column="handsign" />
<result property="laborProtocol" column="labor_protocol" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<!-- 联表字段 (非持久化, entity transient 字段接收) -->
<result property="meetingName" column="meeting_name" />
<result property="startTime" column="start_time" />
<result property="endTime" column="end_time" />
<result property="projectName" column="project_name" />
<result property="projectNo" column="project_no" />
</resultMap>
<insert id="insert" parameterType="BizMeetingAttendee">
insert into biz_meeting_attendee(meeting_id, user_id, create_by, create_time)
values(#{meetingId}, #{userId}, #{createBy}, sysdate())
</insert>
<update id="updateHandsign" parameterType="BizMeetingAttendee">
update biz_meeting_attendee
set handsign = #{handsign},
update_by = #{updateBy},
update_time = sysdate()
where id = #{id}
</update>
<update id="updateLaborProtocol" parameterType="BizMeetingAttendee">
update biz_meeting_attendee
set labor_protocol = #{laborProtocol},
update_by = #{updateBy},
update_time = sysdate()
where id = #{id}
</update>
<delete id="deleteByMeetingId" parameterType="Long">
delete from biz_meeting_attendee where meeting_id = #{meetingId}
</delete>
<delete id="deleteByMeetingIdAndUserId" parameterType="BizMeetingAttendee">
delete from biz_meeting_attendee where meeting_id = #{meetingId} and user_id = #{userId}
</delete>
<select id="selectByMeetingId" resultMap="BizMeetingAttendeeResult" parameterType="Long">
select id, meeting_id, user_id, handsign, labor_protocol, create_by, create_time
from biz_meeting_attendee where meeting_id = #{meetingId}
</select>
<select id="selectByUserId" resultMap="BizMeetingAttendeeResult" parameterType="Long">
select id, meeting_id, user_id, handsign, labor_protocol, create_by, create_time
from biz_meeting_attendee where user_id = #{userId}
</select>
<!--
当前用户的"待签署"会议列表 (任一未签: handsign 或 labor_protocol 为 NULL)
INNER JOIN biz_meeting 取会议名/时间/项目名, 用于 /doctor/home 工作台
字段别名 + resultMap 上面的 transient property 接收
-->
<select id="selectUnsignedByUserId" resultType="BizMeetingAttendee" parameterType="Long">
select a.id, a.meeting_id, a.user_id, a.handsign, a.labor_protocol, a.create_by, a.create_time,
m.meeting_name as meetingName, m.start_time as startTime,
m.end_time as endTime, m.project_name as projectName, m.project_no as projectNo
from biz_meeting_attendee a
inner join biz_meeting m on m.meeting_id = a.meeting_id
where a.user_id = #{userId}
and (a.handsign is null or a.handsign = '' or a.labor_protocol is null or a.labor_protocol = '')
order by m.start_time asc
</select>
</mapper>
@@ -45,6 +45,8 @@
<if test="currentStage != null and currentStage != ''">and current_stage = #{currentStage}</if>
<if test="startTime != null">and start_time &gt;= #{startTime}</if>
<if test="endTime != null">and end_time &lt;= #{endTime}</if>
<!-- doctor 角色按 user_id 过滤 (走 biz_meeting_attendee 中间表) -->
<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})</if>
</where>
order by meeting_id desc
</select>
@@ -57,6 +57,7 @@
<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>
<!-- 业务主账号隔离: biz_person.user_id IN (我的子账号 user_ids) -->
<if test="params.subUserIds != null and params.subUserIds.size() > 0">
and p.user_id in