UserSelect
人员选择组件,基于FSelect封装。
- 内置公共人员部门数据源
- 可自定义key,若能识别唯一用户不推荐自定义(比如始终以员工号做关联)
业务场景
- 符合UI规范的人员选择场景,多与
SearchForm
,AdvancedForm
组件组合使用,也可将Modal单独使用。
如何使用
vue
<script setup lang="ts">
import { ref } from 'vue'
const modelValue = ref()
</script>
<template>
<div class="test">
v-model:value => {{ modelValue }}
<UserSelect style="width: 240px" v-model:value="modelValue" pressLine="创建人" />
</div>
</template>
代码演示
基本使用
v-model:value =>
<script setup lang="ts">
import { ref } from 'vue'
const modelValue = ref()
</script>
<template>
<div class="test">
v-model:value => {{ modelValue }}
<br />
<br />
<UserSelect style="width: 240px" v-model:value="modelValue" pressLine="选人组件" />
</div>
</template>
简单模式使用 simple
v-model:value =>
<script setup lang="ts">
import { ref } from 'vue'
const modelValue = ref()
</script>
<template>
<div class="test">
v-model:value => {{ modelValue }}
<br />
<br />
<UserSelect style="width: 240px" v-model:value="modelValue" pressLine="选人组件" simple />
</div>
</template>
单独触发Modal(如在权限管理平台选审批人的业务场景)
发送给后端的数据:
v-model:
详细的数据(比如后端既要id也要name的情况):
<script setup lang="ts">
import { ref } from 'vue'
import { FIcon, FButton } from '@fs/smart-design'
import { UserModal } from '@fs/fui'
const visible = ref(false)
const model = ref()
const modelDetail = ref()
function handleChange(v, ...rest) {
console.log('change', v, ...rest)
const [value] = rest
modelDetail.value = value
}
</script>
<script lang="ts">
export default {
name: 'FDemo',
}
</script>
<template>
<div>
<f-button type="primary" @click="visible = true">
<template #icon>
<f-icon type="icon-tianjia2" />
</template>
选人
</f-button>
<br />
<br />
发送给后端的数据:
<br />
v-model: {{ model }}
<br />
<br />
详细的数据(比如后端既要id也要name的情况):
<br />
<dl v-if="modelDetail" v-for="k in Object.keys(modelDetail)" :key="k">
<dt>{{ k }}:</dt>
<dd v-for="v in modelDetail[k]" :key="v.id">{{ v?.userName ?? v?.deptName }}({{ v.id }}) 、</dd>
</dl>
<UserModal v-model:visible="visible" v-model:value="model" @change="handleChange" />
</div>
</template>
更多场景是与SearchForm
,AdvancedForm
组合使用
与SearchForm
组合使用
<script setup lang="ts">
import { useCommonPage, IFieldType } from '@fs/lib'
const { searchForm, searchModel } = useCommonPage()
// 查询字段配置
const config = {
fields: [
{
type: IFieldType.Input,
label: '仓库',
name: 'warehouse',
},
{
type: IFieldType.UserSelect,
label: '选人',
name: 'user',
props: {
mode: 'user',
simple: true,
},
},
{
type: IFieldType.UserSelect,
label: '选部门',
name: 'dept',
props: {
mode: 'dept',
simple: true,
},
},
{
type: IFieldType.Input,
label: '快速搜索',
name: 'search',
placeholder: '转移单号/库存ID',
},
],
}
const search = (modelValue: any) => {
console.log('查询参数:回调=>', modelValue)
console.log('查询参数:v-model=>', searchModel.value)
}
</script>
<template>
<SearchForm ref="searchForm" v-model="searchModel" :config="config" @query="search" @reset="search" />
</template>
与AdvancedForm
组合使用
<script setup lang="ts">
import { onMounted } from 'vue'
import { IFieldType, useForm } from '@fs/lib'
const { advForm, model } = useForm()
const config = {
column: 2,
groups: [
{
label: '基础信息',
fields: [
{
type: IFieldType.Input,
label: '仓库名',
name: 'name',
required: true,
span: [24, 12],
},
],
},
{
label: '用户信息',
fields: [
{
type: IFieldType.UserSelect,
label: '用户(默认)',
name: 'user0',
required: true,
},
{
type: IFieldType.UserSelect,
label: '用户(排除管理员)',
name: 'user000',
required: true,
props: {
isAllowUserAdmin: false,
},
},
{
type: IFieldType.UserSelect,
label: '用户(排除部门)',
desc: '由于部门下人员不定,交由limit控制',
name: 'user1',
required: true,
props: {
limit: 3,
isAllowUserDept: false,
},
},
{
type: IFieldType.UserSelect,
label: '用户(简单模式单选)',
name: 'user2',
required: true,
props: {
simple: true,
},
},
{
type: IFieldType.UserSelect,
label: '用户(简单模式多选)',
name: 'user3',
required: true,
props: {
simple: true,
multiple: true,
},
},
{
type: IFieldType.UserSelect,
label: '用户(简单模式重写fieldNames)',
desc: '适用简单落库为用户名,而非用户ID',
name: 'user4',
required: true,
props: {
simple: true,
multiple: false,
mode: 'user',
fieldNames: {
label: 'userName',
value: 'userName',
options: 'options',
},
},
},
{
type: IFieldType.UserSelect,
label: '用户(北森)',
desc: '假如业务场景要与北森产生数据关联',
name: 'user5',
required: true,
props: {
simple: true,
multiple: false,
mode: 'user',
fieldNames: {
value: 'italentId',
},
},
},
{
type: IFieldType.UserSelect,
label: '用户(员工号)',
desc: '假如业务场景要使用员工号在各个系统索引用户唯一',
name: 'user6',
required: true,
props: {
simple: true,
multiple: false,
mode: 'user',
fieldNames: {
value: 'fsNo',
},
},
},
{
type: IFieldType.UserSelect,
label: '管理员',
name: 'userRoles2',
required: true,
props: {
mode: 'admin',
appCode: 'DocumentSystem',
},
},
{
type: IFieldType.UserSelect,
label: '管理员(简单模式)',
name: 'userRoles3',
required: true,
props: {
mode: 'admin',
simple: true,
},
},
],
},
{
label: '部门信息',
desc: '考虑选部门场景与此相关,增加mode用以支持部门选择',
fields: [
{
type: IFieldType.UserSelect,
label: '部门(默认)',
name: 'dept0',
required: true,
props: {
mode: 'dept',
},
},
{
type: IFieldType.UserSelect,
label: '部门(限制数量)',
name: 'dept1',
required: true,
props: {
mode: 'dept',
limit: 2,
},
},
{
type: IFieldType.UserSelect,
label: '部门(简单模式)',
name: 'dept2',
required: true,
props: {
mode: 'dept',
simple: true,
},
},
{
type: IFieldType.UserSelect,
label: '部门(简单模式可多选)',
name: 'dept3',
required: true,
props: {
mode: 'dept',
simple: true,
multiple: true,
},
},
{
type: IFieldType.UserSelect,
label: '部门(简单模式fieldNames)',
name: 'dept4',
required: true,
props: {
mode: 'dept',
simple: true,
multiple: false,
fieldNames: {
value: 'deptName',
},
},
},
{
type: IFieldType.UserSelect,
label: '部门(支持北森)',
name: 'dept5',
required: true,
props: {
mode: 'dept',
simple: true,
multiple: false,
fieldNames: {
value: 'italentDeptId',
},
},
},
],
},
{
label: '附加信息',
fields: [
{
type: IFieldType.TextArea,
label: '备注',
name: 'remark',
span: 24,
props: {
autosize: { minRows: 2, maxRows: 6 },
showCount: true,
maxlength: 200,
},
},
],
},
],
}
function onChange(k, v, ...rest) {
console.log(k, v, '=>', ...rest)
}
function onReset(v) {
console.log('onReset=>', v)
}
function reset() {
advForm.value?.reset()
}
function submit() {
console.log('model=>', model.value)
advForm.value
?.validate()
.then((res) => {
console.log('validate=>success', res)
})
.catch((e) => {
console.log('validate=>error', e)
})
}
// 模拟编辑时数据反显
const fetchDetail = () => {
return new Promise((resolve) => {
setTimeout(() => {
model.value.user0 = {
users: [71649],
depts: [117],
}
resolve(true)
}, 1000)
})
}
onMounted(() => {
fetchDetail()
})
</script>
<template>
<!-- 全局注册引用 亦可 按需引用 -->
<AdvancedForm ref="advForm" v-model="model" :config="config" @reset="onReset" @change="onChange" />
<f-space style="padding: 0 24px">
<f-button type="primary" @click="submit">提交</f-button>
<f-button @click="reset">重置</f-button>
</f-space>
</template>
业务场景举例
一般情况下,只需携带id
给后端即可,后端需要时可关联查询或缓存中取,但有些情况不考虑数据严谨可能会由前端一次传入多个字段,如userId
,userName
等一块传给后端,此时可通过监听change
事件取得详细数据。
问题
- 目前UI设计支持
SearchForm
用户体验可能不友好,所以一般在查询场景使用simple
模式。