123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- <script lang="ts" setup>
- import { ref, reactive, onMounted, inject, watchEffect, computed } from 'vue';
- import type { CascaderProps, CascaderNode } from 'element-plus'
- import { cloneDeep, debounce } from 'lodash';
- import { post } from "@/utils/request";
- import { useStore } from '@/store/index'
- import { Emits } from '../type';
- import { storeToRefs } from 'pinia';
- import { updateDepTreeData, generateUniqueId } from '@/utils/tools'
- const emit = defineEmits<Emits>();
- const props = defineProps({
- modelValue: { type: [String, Number, Array, Object, Boolean], required: true },
- size: { type: String as () => assemblySize, required: true, default: () => 'small' },
- placeholder: { type: String, required: false, default: () => '请选择' },
- multiple: { type: Boolean, required: false, default: false },
- disabled: { type: Boolean, required: false, default: false },
- clearable: { type: Boolean, required: false, default: true },
- options: { type: Array as () => any, required: false, default: () => [] },
- width: { type: String, required: false, default: () => '100%' },
- isAddChineseCharacters: { type: Boolean, required: false, default: false },
- props: {
- type: Object as () => CascaderProps, required: false, default: () => {
- return {
- value: 'id',
- expandTrigger: 'hover' as const,
- checkStrictly: true
- }
- }
- }
- })
- const { departmentList, userInfo } = storeToRefs(useStore());
- const { setValue } = useStore()
- const departmentVal = ref(props.modelValue); // 响应式绑定 v-model 的值
- const departmentValTwo = ref(props.modelValue);
- const departmentProps = ref<CascaderProps>({})
- const departmantArray = ref<any>([]);
- const visibleFlag = ref<boolean>(false);
- const deptRef = ref<any>(null)
- const deptLabel = computed(() => {
- if (Array.isArray(departmentVal.value)) {
- const deptId = departmentVal.value[departmentVal.value.length - 1]
- return findLabelById(departmantArray.value, deptId)
- }
- return ''
- })
- async function filterMethod(node: CascaderNode, keyword: string) {
- const { userNameNeedTranslate } = userInfo.value
- if(userNameNeedTranslate == 0) {
- return [keyword].includes(node.label)
- }
- const { data = [] } = await post(`/department/listAllMemb`, { keyword, cursor: '2' })
- const keywordList = data.flatMap(extractLabels)
- return [...keywordList].includes(node.label)
- }
- function getDeptList(keyword: string = '') {
- post(`/department/listAllMemb`, { keyword }).then(res => {
- const deptList = updateDepTreeData(res.data, props.isAddChineseCharacters)
- departmantArray.value = deptList
- if (!keyword) {
- setValue((deptList || []), 'departmentList')
- }
- })
- }
- function visibleChange(visible: boolean) { // 下拉框出现/隐藏时触发
- if (!props.multiple) {
- setTimeout(() => {
- departmentVal.value = visible ? [] : cloneDeep(departmentValTwo.value)
- }, 10)
- }
- visibleFlag.value = visible
- }
- function updateValue(val: any) { // 值改变的时候触发
- if (!props.multiple) {
- deptRef.value.$refs.input.value = '';
- deptRef.value.togglePopperVisible()
- }
- departmentValTwo.value = cloneDeep(val)
- emit('update:modelValue', departmentVal.value)
- emit('change', val)
- }
- function findLabelById(tree: any, id: any) {
- for (let node of tree) {
- if (node.id == id) {
- return node.label;
- }
- if (node.children && node.children.length > 0) {
- const result: any = findLabelById(node.children, id);
- if (result) {
- return result;
- }
- }
- }
- return null;
- }
- function extractLabels(node: any) {
- let labels: any[] = [];
- if (node.label) {
- labels.push(node.label);
- }
- if (node.children && Array.isArray(node.children)) {
- node.children.forEach((child: any) => {
- labels = labels.concat(extractLabels(child));
- });
- }
- return labels;
- }
- onMounted(() => {
- departmentProps.value = props.props
- if (departmentList.value.length == 0) {
- if (props.options.length > 0) {
- departmantArray.value = props.options
- } else {
- getDeptList()
- }
- } else {
- departmantArray.value = departmentList.value
- }
- })
- </script>
- <template>
- <div class="departmentSelectionDiv" :style="`width: ${width}`">
- <el-cascader v-model="departmentVal" :ref="'deptRef'" :options="departmantArray" :props="departmentProps"
- :size="size" :clearable="clearable" :placeholder="placeholder" filterable :show-all-levels="false"
- :class="`departmentSelection ${!multiple && !visibleFlag ? 'clearColor' : ''}`" :style="`width: ${width}`"
- :filter-method="filterMethod" @visible-change="visibleChange" @change="updateValue">
- <template #default="{ node, data }">
- <span>
- <TextTranslation translationTypes="departmentName" :translationValue="data.label"></TextTranslation>
- </span>
- </template>
- </el-cascader>
- <!-- 覆盖 -->
- <div class="coverDept" v-if="!visibleFlag">
- <TextTranslation translationTypes="departmentName" :translationValue="deptLabel"></TextTranslation>
- </div>
- </div>
- </template>
- <style>
- .clearColor .el-input .el-input__inner {
- color: transparent !important;
- }
- </style>
- <style lang="scss" scoped>
- .departmentSelectionDiv {
- position: relative;
- display: inline-block;
- .coverDept {
- position: absolute;
- top: 50%;
- transform: translateY(-50%);
- left: 6px;
- background: #fff;
- color: #303133;
- font-size: 12px;
- height: calc(100% - 4px);
- }
- }
- </style>
|