Skip to content

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给后端即可,后端需要时可关联查询或缓存中取,但有些情况不考虑数据严谨可能会由前端一次传入多个字段,如userIduserName等一块传给后端,此时可通过监听change事件取得详细数据。

问题

  • 目前UI设计支持SearchForm用户体验可能不友好,所以一般在查询场景使用simple模式。