fix(bpm): 流程用户任务的选择器支持按用户名称搜索
流程设计器中「指定用户」下拉未开启搜索,用户量大时只能滚动查找,
输入文字无任何反馈,实际不可用。
- 简易流程设计器:用户任务节点「指定用户」开启 show-search,
补 option-filter-prop 与 filterUserOption
- BPMN 设计器:用户任务「指定用户」同样处理
- 用户任务自定义配置:无人处理时指定用户同样处理
- 流程实例管理/报表「发起人」、用户组「成员」的 ApiSelect 补搜索能力
补充说明:原 SelectOption 只写了插槽内容、未设置 label 属性,
而 Ant Design Vue 的搜索按 label 匹配,因此仅加 show-search 仍搜不到,
本次同时补上 :label="item.nickname"。
Co-Authored-By: Claude <noreply@anthropic.com>
| | |
| | | }; |
| | | |
| | | const userOptions = ref<SystemUserApi.User[]>([]); // 用户列表 |
| | | |
| | | /** |
| | | * 用户下拉的搜索过滤:按昵称模糊匹配(忽略大小写)。 |
| | | */ |
| | | function filterUserOption(input: string, option: any) { |
| | | const keyword = (input || '').trim().toLowerCase(); |
| | | if (!keyword) { |
| | | return true; |
| | | } |
| | | const label = String(option?.label ?? option?.nickname ?? ''); |
| | | return label.toLowerCase().includes(keyword); |
| | | } |
| | | |
| | | onMounted(async () => { |
| | | // 获得用户列表 |
| | | userOptions.value = await getSimpleUserList(); |
| | |
| | | v-model:value="assignEmptyUserIds" |
| | | allow-clear |
| | | mode="multiple" |
| | | show-search |
| | | option-filter-prop="label" |
| | | :filter-option="filterUserOption" |
| | | placeholder="请输入用户名称搜索" |
| | | style="width: 100%" |
| | | @change="updateAssignEmptyUserIds" |
| | | > |
| | | <SelectOption |
| | | v-for="item in userOptions" |
| | | :key="item.id" |
| | | :label="item.nickname" |
| | | :value="item.id" |
| | | > |
| | | {{ item.nickname }} |
| | |
| | | // @ts-expect-error: tree ref instance type is provided by the UI library at runtime |
| | | const treeRef = ref<any>(); |
| | | |
| | | /** |
| | | * 用户下拉的搜索过滤:按昵称模糊匹配(忽略大小写)。 |
| | | */ |
| | | function filterUserOption(input: string, option: any) { |
| | | const keyword = (input || '').trim().toLowerCase(); |
| | | if (!keyword) { |
| | | return true; |
| | | } |
| | | const label = String(option?.label ?? option?.nickname ?? ''); |
| | | return label.toLowerCase().includes(keyword); |
| | | } |
| | | |
| | | const { formFieldOptions } = useFormFieldsPermission(FieldPermissionType.READ); |
| | | |
| | | // 定义 TreeSelect 的默认属性映射 |
| | |
| | | v-model:value="userTaskForm.candidateParam" |
| | | allow-clear |
| | | mode="multiple" |
| | | show-search |
| | | option-filter-prop="label" |
| | | :filter-option="filterUserOption" |
| | | placeholder="请输入用户名称搜索" |
| | | style="width: 100%" |
| | | @change="updateElementTask" |
| | | > |
| | | <SelectOption |
| | | v-for="item in userOptions" |
| | | :key="item.id" |
| | | :label="item.nickname" |
| | | :value="item.id" |
| | | > |
| | | {{ item.nickname }} |
| | |
| | | } = useNodeForm(currentNode.value.type); |
| | | const configForm = tempConfigForm as Ref<UserTaskFormType>; |
| | | |
| | | /** |
| | | * 用户下拉的搜索过滤。 |
| | | * |
| | | * 默认的 Select 搜索只在 options 已渲染时按 label 过滤,这里显式实现, |
| | | * 保证输入昵称(含中文)能正确匹配,且不受大小写影响。 |
| | | */ |
| | | function filterUserOption(input: string, option: any) { |
| | | const keyword = (input || '').trim().toLowerCase(); |
| | | if (!keyword) { |
| | | return true; |
| | | } |
| | | const label = String(option?.label ?? option?.nickname ?? ''); |
| | | return label.toLowerCase().includes(keyword); |
| | | } |
| | | |
| | | // 改变审批人设置策略 |
| | | function changeCandidateStrategy() { |
| | | configForm.value.userIds = []; |
| | |
| | | v-model:value="configForm.userIds" |
| | | clearable |
| | | mode="multiple" |
| | | show-search |
| | | option-filter-prop="label" |
| | | :filter-option="filterUserOption" |
| | | placeholder="请输入用户名称搜索" |
| | | > |
| | | <SelectOption |
| | | v-for="item in userOptions" |
| | |
| | | label: '成员', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | showSearch: true, |
| | | optionFilterProp: 'label', |
| | | filterOption: (input: string, option: any) => |
| | | String(option?.label ?? '') |
| | | .toLowerCase() |
| | | .includes((input || '').trim().toLowerCase()), |
| | | placeholder: '请选择成员', |
| | | api: getSimpleUserList, |
| | | labelField: 'nickname', |
| | |
| | | label: '发起人', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | showSearch: true, |
| | | optionFilterProp: 'label', |
| | | filterOption: (input: string, option: any) => |
| | | String(option?.label ?? '') |
| | | .toLowerCase() |
| | | .includes((input || '').trim().toLowerCase()), |
| | | placeholder: '请选择发起人', |
| | | allowClear: true, |
| | | api: getSimpleUserList, |
| | |
| | | label: '发起人', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | showSearch: true, |
| | | optionFilterProp: 'label', |
| | | filterOption: (input: string, option: any) => |
| | | String(option?.label ?? '') |
| | | .toLowerCase() |
| | | .includes((input || '').trim().toLowerCase()), |
| | | placeholder: '请选择发起人', |
| | | allowClear: true, |
| | | api: getSimpleUserList, |