|
@@ -0,0 +1,111 @@
|
|
|
+<template>
|
|
|
+ <t-select v-model="selected" clearable v-bind="attrs" @change="onChange">
|
|
|
+ <template v-if="filterable" #panelTopContent>
|
|
|
+ <div style="padding: 10px">
|
|
|
+ <t-input
|
|
|
+ v-model="filterVal"
|
|
|
+ placeholder="请输入关键词搜索"
|
|
|
+ @change="onFilter"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <t-option
|
|
|
+ v-for="item in optionList"
|
|
|
+ :key="item.userId"
|
|
|
+ :value="item.userId"
|
|
|
+ :label="`${item.name}_${item.supplierName || ''}_${item.city || ''}`"
|
|
|
+ />
|
|
|
+ </t-select>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup name="SelectFreeEngineer">
|
|
|
+import { onMounted, ref, useAttrs, watch, computed } from 'vue';
|
|
|
+import {
|
|
|
+ personAllocateFreeCoordinatorApi,
|
|
|
+ personAllocateFreeEngineerApi,
|
|
|
+} from '@/api/resource-guard';
|
|
|
+
|
|
|
+let optionList = ref([]);
|
|
|
+let optionFullList = ref([]);
|
|
|
+let selected = ref('');
|
|
|
+let filterVal = ref('');
|
|
|
+
|
|
|
+const attrs = useAttrs();
|
|
|
+
|
|
|
+const emit = defineEmits(['update:modelValue', 'change']);
|
|
|
+const props = defineProps({
|
|
|
+ modelValue: { type: [Number, String, Array], default: '' },
|
|
|
+ filterable: { type: Boolean, default: true },
|
|
|
+ type: { type: String, default: '' },
|
|
|
+ unitId: { type: String, default: '' },
|
|
|
+ crmNo: { type: String, default: '' },
|
|
|
+});
|
|
|
+const isMultiple = computed(() => {
|
|
|
+ const multiple = attrs.multiple;
|
|
|
+ return multiple === '' || multiple;
|
|
|
+});
|
|
|
+
|
|
|
+// bug:第一次复现已选选项时,直接搜索后,选项列表为空时,复现内容展示异常。除非重新选择一个后,在搜索,搜索结果不影响复现内容
|
|
|
+const onFilter = () => {
|
|
|
+ const escapeRegexpString = (value = '') =>
|
|
|
+ String(value).replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
|
|
|
+ const reg = new RegExp(escapeRegexpString(filterVal.value), 'i');
|
|
|
+ optionList.value = optionFullList.value.filter((item) => reg.test(item.name));
|
|
|
+};
|
|
|
+
|
|
|
+const search = async () => {
|
|
|
+ if (!props.type) return;
|
|
|
+ optionFullList.value = [];
|
|
|
+
|
|
|
+ let res = null;
|
|
|
+ if (props.type === 'REGION_COORDINATOR') {
|
|
|
+ res = await personAllocateFreeCoordinatorApi(
|
|
|
+ props.unitId,
|
|
|
+ props.crmNo
|
|
|
+ ).catch(() => {});
|
|
|
+ if (!res) return;
|
|
|
+ } else {
|
|
|
+ res = await personAllocateFreeEngineerApi(props.type, props.crmNo).catch(
|
|
|
+ () => {}
|
|
|
+ );
|
|
|
+ if (!res) return;
|
|
|
+ }
|
|
|
+
|
|
|
+ optionFullList.value = res;
|
|
|
+ onFilter();
|
|
|
+};
|
|
|
+
|
|
|
+const onChange = () => {
|
|
|
+ const selectedData = isMultiple.value
|
|
|
+ ? optionList.value.filter(
|
|
|
+ (item) => selected.value && selected.value.includes(item.userId)
|
|
|
+ )
|
|
|
+ : optionList.value.filter((item) => selected.value === item.userId);
|
|
|
+ emit('update:modelValue', selected.value);
|
|
|
+ emit('change', isMultiple.value ? selectedData : selectedData[0]);
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ search();
|
|
|
+});
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => props.modelValue,
|
|
|
+ (val) => {
|
|
|
+ selected.value = val;
|
|
|
+ },
|
|
|
+ {
|
|
|
+ immediate: true,
|
|
|
+ }
|
|
|
+);
|
|
|
+watch(
|
|
|
+ () => props.type,
|
|
|
+ (val, oldval) => {
|
|
|
+ if (val !== oldval) {
|
|
|
+ search();
|
|
|
+ emit('update:modelValue', null);
|
|
|
+ emit('change', isMultiple.value ? [] : null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+);
|
|
|
+</script>
|