refactor(executor): 对齐 sponsor 人员管理模式 + 修 3 个 bug

后端:
- BizAuthController.registerExecutor step 6 同步建 biz_person (主账号自己=管理员, name=unitName, role='admin', unit_type='executor'), 让"人员管理"能看见自己 (跟 registerSponsor 同模式, 走 BizPersonMapper 直插, 绕过 SUB 子账号逻辑)
- BizPersonMapper.xml selectExecutorList 加 OR u.user_id=主账号 (主账号自己能查到), + countAdminByOrgId (校验公司唯一管理员)
- SysUserMapper.xml 手机号正则 1[3-9] → 1[0-9] (允许 10 开头测试号段, 跟 sponsor 一致)

前端 executor/NewPerson.vue 1:1 对齐 sponsor/NewPerson.vue:
- el-card form-card 包裹 + el-row :gutter=12 两列布局
- 用户名/初始密码 行 (v-if=!isEdit)
- 状态改用 el-radio-group, 值 0=正常 1=禁用
- 修了状态值反向 bug: 原 executor 正常→"1" 禁用→"0" 跟 DB/UserStatus enum 相反, 编辑时反向生效 (BizPersonServiceImpl.insert 硬编码 status='0' 掩盖了 bug)
- role 统一 el-select + admin 选项 :disabled=true (管理员只能注册时建)
- 编辑模式 el-select :disabled=true (不能改角色)
- phone 正则 /^1[0-9]\d{9}$/, userName 3-30 模式, password 6-30, department maxlength=100
- 新建成功 ElMessageBox.alert 展示子账号+密码
- 重复手机号走 warning 黄 (isDuplicateError)
- confirmCancel 取消确认
- loadMyOrg 自动带出主账号公司

前端 executor/People.vue:
- 状态列对齐 sponsor: row.status === '0' ? '正常' : '禁用' (修原 || '正常' fallback bug 导致显示原始 '0' + 颜色永远红的两个 bug)
- 批量导入 完整实装 (原 downloadTemplate/submitImport 都是 stub, 只弹提示):
  - downloadTemplate GET /business/person/executorImportTemplate + blob 下载 + 解析 Content-Disposition 文件名
  - submitImport POST /business/person/executorImport + FormData + 导入结果 dialog (行号/姓名/手机号/成功+错误信息)
  - el-upload 加 :on-change=:on-remove 自管 file, footer 改 "关闭/开始导入" 带 loading/disabled
  - 新增 onImport 先 clearFiles 再开 dialog
This commit is contained in:
郭庆泰
2026-08-18 21:32:10 +08:00
parent 6716074eee
commit 40f296b59d
5 changed files with 348 additions and 155 deletions
@@ -228,6 +228,22 @@ public class BizAuthController extends BaseController {
bizOrgService.insert(org);
Long orgId = org.getOrgId();
// 6. 同步建 biz_person (主账号自己 = 管理员, 让"人员管理"能看到自己)
// 跟 registerSponsor 同样的 5 字段: 走 BizPersonMapper 直插, 绕过 SUB 子账号逻辑
BizPerson self = new BizPerson();
SnowflakeId.injectIfEmpty(self, "personId");
self.setName(unitName);
self.setPhone(phone);
self.setOrgId(orgId);
self.setDepartment("管理部");
self.setPosition("总负责人");
self.setRole("admin"); // 主账号 = 管理员 (与子账号的会议执行区分)
self.setUnitType("executor");
self.setUserId(userId);
self.setCreateBy(username);
self.setUpdateBy(username);
bizPersonMapper.insert(self);
return success("注册成功, 请等待审核").put("userId", userId).put("orgId", orgId);
}
@@ -166,12 +166,14 @@
</select>
<!-- executor 专属: 同 sponsor, SQL 硬编码 unit_type='executor' + parent_user_id=当前主账号 (前端绕不开) -->
<!-- 主账号自己 (parent_user_id=NULL) 也通过 OR u.user_id=#{executorOwnerUid} 一并带上 (否则主账号看不到自己) -->
<select id="selectExecutorList" resultMap="BizPersonResult" parameterType="BizPerson">
<include refid="selectFieldsWithAccount"/>
<where>
u.del_flag = '0'
and p.unit_type = 'executor'
and u.parent_user_id = #{params.executorOwnerUid}
and (u.parent_user_id = #{params.executorOwnerUid}
or u.user_id = #{params.executorOwnerUid})
<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="orgId != null"> and p.org_id = #{orgId}</if>
@@ -205,6 +205,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="pwdUpdateDate != null">pwd_update_date,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="remark != null and remark != ''">remark,</if>
<if test="roleType != null and roleType != ''">role_type,</if>
create_time
)values(
<if test="userId != null and userId != ''">#{userId},</if>
@@ -222,6 +223,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="pwdUpdateDate != null">#{pwdUpdateDate},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="remark != null and remark != ''">#{remark},</if>
<if test="roleType != null and roleType != ''">#{roleType},</if>
sysdate()
)
</insert>
@@ -242,6 +244,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="loginDate != null">login_date = #{loginDate},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="roleType != null and roleType != ''">role_type = #{roleType},</if>
update_time = sysdate()
</set>
where user_id = #{userId}