Files
orange-admin/OrangeFormsOpen-VUE3/src/components/DeptSelect/index.vue
2024-10-11 21:42:49 +08:00

209 lines
5.3 KiB
Vue

<template>
<div class="dept-select">
<el-select
:model-value="modelValue"
style="width: 100%"
:multiple="multiple"
:disabled="disabled"
:size="size"
:clearable="clearable"
:collapse-tags="collapseTags"
:placeholder="placeholder"
:teleported="false"
popper-class="dept-select-popper"
@visible-change="onVisibleChange"
@remove-tag="onRemoveTag"
@clear="onClear"
>
<el-option
v-for="item in selectedItems"
:key="item[pps.value]"
:label="item[pps.label]"
:value="item[pps.value]"
/>
</el-select>
</div>
</template>
<script setup lang="ts">
import { getUUID } from '@/common/utils';
import { ANY_OBJECT } from '@/types/generic';
import { SysCommonBizController } from '@/api/system';
import { Dialog } from '@/components/Dialog';
import DeptSelectDlg from './DeptSelectDlg.vue';
const emit = defineEmits<{
'update:modelValue': [string | number | ANY_OBJECT[]];
change: [string | number | ANY_OBJECT[], string | number | ANY_OBJECT[]];
}>();
const props = withDefaults(
defineProps<{
modelValue: string | number | Array<ANY_OBJECT> | undefined;
size?: '' | 'default' | 'small' | 'large';
placeholder?: string;
props?: ANY_OBJECT;
multiple?: boolean;
disabled?: boolean;
clearable?: boolean;
collapseTags?: boolean;
}>(),
{
props: () => {
return {
label: 'deptName',
value: 'deptId',
};
},
multiple: false,
disabled: false,
clearable: false,
collapseTags: true,
},
);
const widgetId = ref(getUUID());
const selectedItems = ref<ANY_OBJECT[]>([]);
const pps = computed(() => props.props);
const handlerEditOperate = (items: Ref<ANY_OBJECT>) => {
selectedItems.value = [];
if (props.multiple) {
if (Array.isArray(items)) selectedItems.value = items;
} else {
if (items != null) selectedItems.value.push(items);
}
if (!checkSelectChange()) return;
emitChange();
};
const onVisibleChange = (visible: boolean) => {
if (visible) {
Dialog.show<Ref<ANY_OBJECT>>(
'部门选择',
DeptSelectDlg,
{
area: ['900px', '650px'],
offset: '100px',
},
{
value: selectedItems.value,
props: props.props,
path: 'thirdSelectDept/' + widgetId.value,
multiple: props.multiple,
},
{
width: '900px',
height: '650px',
pathName: '/thirdParty/thirdSelectDept',
},
).then(res => {
handlerEditOperate(res);
});
}
};
const onRemoveTag = (val: ANY_OBJECT) => {
selectedItems.value = selectedItems.value.filter(item => {
return item[props.props.value] !== val;
});
emitChange();
};
const onClear = () => {
selectedItems.value = [];
emitChange();
};
const emitChange = () => {
let tempValue: string | number | ANY_OBJECT[];
if (props.multiple) {
tempValue = selectedItems.value.map(item => {
return item[props.props.value];
});
} else {
tempValue = (selectedItems.value[0] || {})[props.props.value];
}
emit('update:modelValue', tempValue);
emit('change', tempValue, selectedItems.value);
};
const checkSelectChange = () => {
let valueIdString =
props.multiple && Array.isArray(props.modelValue)
? (props.modelValue || [])
.sort((val1: ANY_OBJECT, val2: ANY_OBJECT) => {
if (val1 === val2) return 0;
return val1 < val2 ? -1 : 1;
})
.join(',')
: props.modelValue || '';
let selectedItemsString = selectedItems.value
.sort((item1, item2) => {
if (item1[props.props.value] === item2[props.props.value]) return 0;
return item1[props.props.value] < item2[props.props.value] ? -1 : 1;
})
.map(item => item[props.props.value])
.join(',');
return valueIdString !== selectedItemsString;
};
const getSelectDeptList = () => {
let params: ANY_OBJECT = {
widgetType: 'upms_dept',
};
if (
props.modelValue == null ||
props.modelValue === '' ||
(props.modelValue as ANY_OBJECT[]).length <= 0
)
selectedItems.value = [];
if (props.multiple) {
params.fieldValues = Array.isArray(props.modelValue) ? props.modelValue : [];
} else {
params.fieldValues = Array.isArray(props.modelValue) ? props.modelValue[0] : props.modelValue;
params.fieldValues = params.fieldValues == null ? [] : [params.fieldValues];
}
if (Array.isArray(params.fieldValues) && params.fieldValues.length > 0) {
params.fieldValues = params.fieldValues.join(',');
SysCommonBizController.viewByIds(params, {
showMask: false,
})
.then(res => {
if (Array.isArray(res.data)) {
selectedItems.value = res.data;
}
})
.catch(e => {
console.warn(e);
});
}
};
watch(
() => props.modelValue,
() => {
if (props.modelValue) getSelectDeptList();
},
{
immediate: true,
},
);
</script>
<style scoped>
.dept-select :deep(.dept-select-popper) {
display: none;
}
.dept-select :deep(.el-dialog__header) {
height: 42px;
line-height: 42px;
padding: 0 20px;
background-color: #f8f8f8;
}
.dept-select :deep(.el-dialog__title) {
font-size: 14px;
color: #333;
}
.dept-select :deep(.el-dialog__headerbtn) {
top: 12px;
}
.dept-select :deep(.el-dialog__body) {
padding: 25px;
}
</style>