Merge remote-tracking branch 'origin/master'

This commit is contained in:
zjf committed 2026-06-22 17:35:54 +08:00
commit f2d8863ec2
19 files changed
+630 -241

No files matched your search

+92 -16
View File
@@ -1,7 +1,7 @@
<template>
<el-select style="width: 100%" v-model="selectId" :placeholder="props.placeholder" clearable remote-show-suffix
filterable remote :disabled="props.disabled" :remote-method="remoteSearch" :loading="state.loading"
@visible-change="(e: boolean) => e && getOptions()" @clear="clear" :multiple="props.multiple">
@visible-change="handleVisibleChange" @clear="clear" :multiple="props.multiple">
<el-option v-for="v in state.options" :key="v.id" :label="`${v.name}`" :value="v.id">
<div class="flex items-center">
<div class="color-primary">{{ v.name }}</div>
@@ -57,27 +57,75 @@ const state = reactive<any>({
options: [],
})
async function getOptions() {
try {
let parentDeptId = null
if (props.deptMch) {
const currentUser = userInfos.value.user
if (userInfos.value.roleCodes.includes("DEPT_ADMIN")) {
parentDeptId = currentUser?.deptId
}
let requestSeq = 0
let lastRequestKey = ""
let inflightKey = ""
let inflightPromise: Promise<void> | null = null
let refreshScheduled = false
function stableStringify(value: any): string {
if (value == null) return ""
if (typeof value !== "object") return String(value)
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`
const keys = Object.keys(value).sort()
return `{${keys.map((k) => `${k}:${stableStringify(value[k])}`).join(",")}}`
}
function buildRequestKey(parentDeptId: any) {
return [
parentDeptId ?? "",
queryForm.name ?? "",
queryForm.current ?? "",
queryForm.size ?? "",
stableStringify(props.apiParams),
props.deptMch ? "1" : "0",
].join("|")
}
async function getOptions(force = false) {
const seq = ++requestSeq
let parentDeptId = null
if (props.deptMch) {
const currentUser = userInfos.value.user
if (userInfos.value.roleCodes.includes("DEPT_ADMIN")) {
parentDeptId = currentUser?.deptId
}
state.loading = true
}
const requestKey = buildRequestKey(parentDeptId)
if (!force) {
if (inflightPromise && inflightKey === requestKey) return inflightPromise
if (lastRequestKey === requestKey) return
}
state.loading = true
inflightKey = requestKey
try {
const _pa = {
parentDeptId,
...queryForm,
...props.apiParams,
}
const { data } = await mchApi.select(_pa)
state.options = data.records ?? []
if (props.autoFirst && !selectId.value && state.options.length !== 0) {
selectId.value = state.options[0].id
}
inflightPromise = mchApi
.select(_pa)
.then(({ data }) => {
if (seq !== requestSeq) return
state.options = data.records ?? []
lastRequestKey = requestKey
const isEmptySelection = Array.isArray(selectId.value) ? selectId.value.length === 0 : !selectId.value
const isSelectionInOptions = Array.isArray(selectId.value)
? selectId.value.every((id: any) => state.options.some((item: any) => item?.id === id))
: state.options.some((item: any) => item?.id === selectId.value)
if (props.autoFirst && (isEmptySelection || !isSelectionInOptions) && state.options.length !== 0) {
selectId.value = state.options[0].id
}
})
return inflightPromise
} finally {
if (inflightKey === requestKey) {
inflightPromise = null
}
setTimeout(() => (state.loading = false), 500)
}
}
@@ -90,10 +138,38 @@ function remoteSearch(params: string) {
}
function clear() {
selectId.value = null
selectId.value = props.multiple ? [] : null
getOptions()
}
function handleVisibleChange(visible: boolean) {
if (!visible) return
if (!state.options.length) {
getOptions()
}
}
function scheduleRefreshOptions() {
if (refreshScheduled) return
refreshScheduled = true
Promise.resolve().then(() => {
refreshScheduled = false
lastRequestKey = ""
getOptions()
})
}
watch(
() => [stableStringify(props.apiParams), props.deptMch],
(newVal, oldVal) => {
if (oldVal && newVal[0] === oldVal[0] && newVal[1] === oldVal[1]) return
if (props.autoFirst) {
scheduleRefreshOptions()
}
},
{ flush: "post" },
)
onMounted(() => {
props.autoFirst && getOptions()
})
+4 -14
View File
@@ -1,17 +1,7 @@
<template>
<el-select
style="width: 100%"
v-model="state.selectId"
:placeholder="props.placeholder"
clearable
remote-show-suffix
filterable
remote
:remote-method="remoteSearch"
:loading="state.loading"
@visible-change="(e: boolean) => e && getOptions()"
@change="change"
>
<el-select style="width: 100%" v-model="state.selectId" :placeholder="props.placeholder" clearable
remote-show-suffix filterable remote :remote-method="remoteSearch" :loading="state.loading"
@visible-change="(e: boolean) => e && getOptions()" @change="change">
<el-option v-for="v in state.options" :key="v.userId" :label="`${v.name}-${v.phone}`" :value="v.userId">
<div class="flex items-center">
<div class="color-primary">{{ v.name }}</div>
@@ -64,7 +54,7 @@ async function getOptions() {
userId: selectId.value,
...queryForm,
}
const { data } = await userApi.pageList(_pa)
const { data } = await userApi.pageSelect(_pa)
state.options = data.records ?? []
} finally {
setTimeout(() => (state.loading = false), 500)