|
|
@@ -57,6 +57,65 @@ const handleCreate = () => {
|
|
|
name: 'Create Report Template'
|
|
|
})
|
|
|
}
|
|
|
+
|
|
|
+import { debounce } from 'lodash'
|
|
|
+import axios from 'axios'
|
|
|
+
|
|
|
+const emit = defineEmits(['changeData'])
|
|
|
+const changeData = (val: string[]) => {
|
|
|
+ // 同步选中状态
|
|
|
+ emit('changeData', val)
|
|
|
+}
|
|
|
+
|
|
|
+interface ListItem {
|
|
|
+ label: string
|
|
|
+ id: string
|
|
|
+}
|
|
|
+
|
|
|
+const options = ref<ListItem[]>([])
|
|
|
+const loading = ref(false)
|
|
|
+const currentController = ref<AbortController | null>(null)
|
|
|
+
|
|
|
+const handleVisibleChange = (visible) => {
|
|
|
+ !visible && (options.value = [])
|
|
|
+}
|
|
|
+const remoteMethod = (query: string) => {
|
|
|
+ currentController.value?.abort()
|
|
|
+
|
|
|
+ const newController = new AbortController()
|
|
|
+ currentController.value = newController
|
|
|
+ loading.value = true
|
|
|
+
|
|
|
+ $api
|
|
|
+ .getSpecificRolesPartyID({ term: query }, { signal: newController.signal })
|
|
|
+ .then((res) => {
|
|
|
+ if (!newController.signal.aborted && res.code === 200) {
|
|
|
+ options.value = (res.data || []).map((item) => ({
|
|
|
+ id: item.id,
|
|
|
+ label: item.label
|
|
|
+ }))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ options.value = []
|
|
|
+ if (!axios.isCancel(err) && !newController.signal.aborted) {
|
|
|
+ ElMessage.error('Failed to load options')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ // 仅当这是最新请求时,才关闭 loading
|
|
|
+ if (currentController.value === newController) {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 防抖版本(可选)
|
|
|
+const debouncedRemoteMethod = debounce(remoteMethod, 200)
|
|
|
+
|
|
|
+onUnmounted(() => {
|
|
|
+ currentController.value?.abort()
|
|
|
+})
|
|
|
</script>
|
|
|
<template>
|
|
|
<div class="dashboard">
|
|
|
@@ -108,14 +167,34 @@ const handleCreate = () => {
|
|
|
/>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
- <div class="tips_filter">
|
|
|
- <el-select v-model="queryData.party_id" clearable placeholder="Party ID">
|
|
|
+ <div class="party-id-tips-filter">
|
|
|
+ <el-select
|
|
|
+ v-model="queryData.party_id"
|
|
|
+ multiple
|
|
|
+ filterable
|
|
|
+ reserve-keyword
|
|
|
+ placeholder="Party IDs"
|
|
|
+ :loading="loading"
|
|
|
+ collapse-tags
|
|
|
+ collapse-tags-tooltip
|
|
|
+ :max-collapse-tags="1"
|
|
|
+ popper-class="part-id-select-popper"
|
|
|
+ :filter-method="debouncedRemoteMethod"
|
|
|
+ @change="changeData"
|
|
|
+ @visible-change="handleVisibleChange"
|
|
|
+ >
|
|
|
<el-option
|
|
|
- v-for="item in aiModelList"
|
|
|
- :key="item.value"
|
|
|
- :label="item.label"
|
|
|
- :value="item.value"
|
|
|
- />
|
|
|
+ v-for="item in options"
|
|
|
+ :key="item.id + item.label"
|
|
|
+ :label="item.id"
|
|
|
+ :value="item.id"
|
|
|
+ >
|
|
|
+ <div class="select-option">
|
|
|
+ <el-checkbox :model-value="queryData.party_id.includes(item.id)">
|
|
|
+ <span class="text-ellipsis" style="width: 260px">{{ item.id }}</span>
|
|
|
+ </el-checkbox>
|
|
|
+ </div>
|
|
|
+ </el-option>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
|
|
|
@@ -156,6 +235,16 @@ const handleCreate = () => {
|
|
|
max-width: 190px;
|
|
|
margin-right: 8px;
|
|
|
}
|
|
|
+.party-id-tips-filter {
|
|
|
+ flex: 1;
|
|
|
+ height: 30px;
|
|
|
+ width: 320px;
|
|
|
+ max-width: 320px;
|
|
|
+ margin-right: 8px;
|
|
|
+ :deep(.el-tag) {
|
|
|
+ max-width: 220px !important;
|
|
|
+ }
|
|
|
+}
|
|
|
.input-tips_filter {
|
|
|
flex: 1;
|
|
|
max-width: 320px;
|
|
|
@@ -183,4 +272,15 @@ const handleCreate = () => {
|
|
|
position: relative;
|
|
|
background-color: var(--color-mode);
|
|
|
}
|
|
|
+.text-ellipsis {
|
|
|
+ display: inline-block;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style lang="scss">
|
|
|
+.el-select__selection {
|
|
|
+ max-width: 450px;
|
|
|
+}
|
|
|
</style>
|