# 人员选择器组件使用说明
## 概述
为满足其他页面(如面试不通过原因登记、重点关注人员管理、岗位推荐等)需要选择人员的场景,基于人员信息列表的查询表单和数据表格,封装了一套可复用的**人员选择器组件**,支持单选/多选,并通过 `v-model` 将选中的完整人员记录返回给父组件。
## 涉及文件
| 文件路径(相对于项目根目录 `zjrs-jeecgBoot`) | 操作 | 说明 |
|---|---|---|
| `jeecgboot-vue3/src/views/recruitment/personal/components/PersonalInfoSelectorModal.vue` | 新建 | 选择器弹窗组件,包含查询表单和 BasicTable 表格,支持单/多选行,通过 `@select` 事件返回选中记录 |
| `jeecgboot-vue3/src/views/recruitment/personal/components/PersonalInfoSelector.vue` | 新建 | 带输入框载体的组合组件,封装了触发输入框 + 弹窗的完整交互,通过 `v-model` 双向绑定选中数据 |
## 组件层级
```
PersonalInfoSelector.vue ← 对外暴露的入口组件
└─ 输入框(只读,点击触发弹窗)
└─ PersonalInfoSelectorModal.vue ← 内部弹窗
├─ 查询表单(姓名、性别、学历、户口所在地、现居住地、年龄范围、求职人员类别、求职状态、数据来源)
└─ BasicTable(含字典渲染、行选择、分页)
```
## 快速使用
在任意父页面引入 `PersonalInfoSelector.vue` 即可:
```vue
```
## 实际使用示例
以下为面试不通过原因登记表单中的使用方式(单选模式,选择人员后自动填充关联字段):
```vue
```
> 完整实现参见 `jeecgboot-vue3/src/views/interviewfail/reason/components/InterviewFailReasonForm.vue`
## PersonalInfoSelector.vue(推荐使用者用)
带触发输入框的完整选择器,直接用于表单中。
### Props
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| `modelValue` | `any` | — | v-model 绑定值(标准写法)。单选传对象 `{ id, fullName, ... }`,多选传数组 |
| `value` | `any` | — | v-model:value 绑定值(兼容命名写法),与 `modelValue` 二选一 |
| `selectionType` | `'single' \| 'multiple'` | `'multiple'` | 选择模式 |
| `placeholder` | `string` | `'请选择人员'` | 输入框占位文本 |
| `width` | `string \| number` | — | 输入框宽度(如 `'300px'` 或 `300`) |
| `allowClear` | `boolean` | `true` | 是否允许输入框右侧一键清除已选项 |
### Events
| 事件 | 参数 | 说明 |
|---|---|---|
| `update:modelValue` | `value: any` | v-model 更新事件 |
| `update:value` | `value: any` | v-model:value 更新事件(兼容写法) |
| `change` | `records: any[]` | 选中记录变化时触发,始终返回数组 |
### 交互流程
1. 点击输入框 → 打开选择弹窗
2. 弹窗中可通过查询条件筛选人员
3. 勾选行后点"确认选择"
4. 弹窗关闭,输入框中显示选中人员的姓名(多选以中文逗号分隔)
5. 点输入框右侧清除图标可清空已选
6. 再次打开弹窗时,已选人员会自动回显为选中状态(通过传入 `selectedKeys` 和 `selectedRecords` 实现)
## PersonalInfoSelectorModal.vue(低层弹窗)
仅供 `PersonalInfoSelector.vue` 内部使用,也可单独引用以自定义触发方式。
### 暴露方法
| 方法 | 参数 | 说明 |
|---|---|---|
| `open(config)` | `{ selectionType?: 'single' \| 'multiple', selectedKeys?: (string \| number)[], selectedRecords?: any[] }` | 打开弹窗。`selectionType` 默认 `'multiple'`;`selectedKeys` 用于回显勾选状态;`selectedRecords` 用于回显勾选并提供完整的选中数据 |
### Events
| 事件 | 参数 | 说明 |
|---|---|---|
| `select` | `records: any[]` | 确认选择时触发,返回选中行的完整记录数组 |
### 单独使用示例
```vue
选择人员
```
## 设计要点
- **查询表单**完整复用了人员信息列表的字段,包含姓名、性别、学历、户口所在地(行政区划树)、年龄范围等。
- **字典渲染**通过 `useDict` 预加载,表格中性别、学历、民族、求职状态等字段自动转为中文显示。
- **行选择**通过 `computed` 动态计算 `rowSelection`,根据 `selectionType` 切换为 `checkbox`(多选)或 `radio`(单选)。
- **自定义选择列兼容**:项目使用 `useCustomSelection` 自封装选择列(非 ant-design-vue 原生 `rowSelection`),弹窗打开时通过 `useTable` 返回的 `setSelectedRowKeys` API 程序化设置选中行,确保自定义选择列正确回显。
- **onChange 合并处理**:行选择变更时保留不在当前页的已选记录,替换当前页的选中记录,支持跨页选择场景。
- **已选回显**:再次打开弹窗时,将已选记录的 `selectedKeys` 和 `selectedRecords` 一并传入,确保勾选状态和确认数据完整。
- **年龄查询**在 `beforeFetch` 钩子中自动将输入的年龄范围转换为出生日期范围传给后端。
- **输入框清除**在 `allowClear` 为 `true` 时,清除按钮将 `v-model` 重置为空值(单选为 `null`,多选为 `[]`)。
- **弹窗渲染时序**:`open()` 中先设置 `visible = true`,再通过 `nextTick` 等待弹窗 DOM 渲染完成后执行 `reload()` 和 `setSelectedRowKeys()`,避免表格实例未就绪导致报错。