smart-admin-web 10.24.0 → 10.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index2.vue.js","sources":["../../../src/components/UserPicker/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, reactive, ref } from 'vue'\nimport {\n NButton,\n NDropdown,\n NEmpty,\n NInput,\n NSpin,\n NTab,\n NTabs,\n NTree,\n NTreeSelect,\n useMessage,\n} from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport { useDebounceFn, useWindowSize } from '@vueuse/core'\nimport AppIcon from '#/components/AppIcon.vue'\nimport FormContainer from '#/components/FormContainer/index.vue'\nimport UserAvatar from './UserAvatar.vue'\nimport { useShellBreakpoint } from '#/composables/useShellBreakpoint'\nimport { orgApi, userApi } from '#/api'\nimport { buildTree } from '#/utils/tree'\nimport { translateError } from '#/utils/error'\nimport type { SysOrg, UserItem } from '#/types/api'\n\nconst props = defineProps<{ excludeIds?: number[] }>()\nconst emit = defineEmits<{ (e: 'confirm', ids: number[]): void }>()\n\nconst { t } = useI18n()\nconst message = useMessage()\n\nconst show = ref(false)\n\n// 屏幕形态:\n// 宽 / 中档 = 居中弹窗里的三栏(机构 | 可选用户 | 已选);\n// 窄档(壳层 < 600)= 底部抽屉,三栏收成「可选用户 / 已选」两页,机构换成页内的树选择;\n// 内容区 < 900 但还不到窄档时仍是弹窗,三栏同样收成两页(920 宽的三栏在这里放不下)。\n// 三栏选择器在抽屉里太局促,所以宽 / 中档固定用弹窗,不跟随「表单形态」全局偏好。\nconst { bp } = useShellBreakpoint()\nconst { width: winW } = useWindowSize()\nconst compact = computed(() => bp.value === 'narrow' || winW.value < 900)\nconst variant = computed(() => (bp.value === 'narrow' ? 'drawer' : 'modal'))\nconst tab = ref<'users' | 'selected'>('users')\n\n// ── 机构(左栏) ──\nconst orgFlat = ref<SysOrg[]>([])\nconst orgTree = computed(() => {\n const all = { id: 0, parentId: -1, name: t('common.all'), children: buildTree(orgFlat.value) }\n return [all]\n})\nconst selectedOrgKey = ref<number | null>(null)\nconst orgId = computed(() =>\n selectedOrgKey.value && selectedOrgKey.value !== 0 ? selectedOrgKey.value : undefined,\n)\n\nonMounted(async () => {\n try {\n orgFlat.value = await orgApi.list()\n } catch {\n /* 静默 */\n }\n})\n\nfunction onOrgSelect(keys: Array<string | number>) {\n selectedOrgKey.value = (keys[0] as number) ?? null\n reload()\n}\n// 两页形态下机构换成树选择:没有「再点一次取消」,选「全部」(id 0)即不限机构。\nfunction onOrgPick(key: number | null) {\n selectedOrgKey.value = key ?? null\n reload()\n}\n\n// ── 可选用户(中栏) ──\n// 一页 20 人;接口只有「姓名 / 账号」两个独立的模糊条件、没有联合检索,所以搜索框带一个范围切换。\nconst PAGE_SIZE = 20\ntype SearchField = 'name' | 'account'\n\nconst field = ref<SearchField>('name')\nconst keyword = ref('')\nconst page = ref(1)\nconst total = ref(0)\nconst rows = ref<UserItem[]>([])\nconst loading = ref(false)\n// 防乱序:输入停顿、翻页、换机构都会发请求,后发的先回来时,先发的结果不能覆盖它。\nlet seq = 0\n\nconst pageCount = computed(() => Math.max(1, Math.ceil(total.value / PAGE_SIZE)))\nconst placeholder = computed(() =>\n field.value === 'name' ? t('userPicker.searchName') : t('userPicker.searchAccount'),\n)\nconst scopeOptions = computed(() => [\n { key: 'name', label: t('user.name') },\n { key: 'account', label: t('user.account') },\n])\n\nasync function load() {\n const mine = ++seq\n loading.value = true\n try {\n const kw = keyword.value.trim() || undefined\n const res = await userApi.page({\n page: page.value,\n pageSize: PAGE_SIZE,\n name: field.value === 'name' ? kw : undefined,\n account: field.value === 'account' ? kw : undefined,\n orgId: orgId.value,\n })\n if (mine !== seq) return\n rows.value = res.items\n total.value = res.total\n } catch (e) {\n if (mine !== seq) return\n rows.value = []\n total.value = 0\n message.error(translateError(e))\n } finally {\n if (mine === seq) loading.value = false\n }\n}\n\n/** 条件变了:回第 1 页重查。 */\nfunction reload() {\n page.value = 1\n void load()\n}\nconst reloadDebounced = useDebounceFn(reload, 300)\n\nfunction onSearchInput(v: string) {\n keyword.value = v\n void reloadDebounced()\n}\nfunction onScope(key: SearchField) {\n field.value = key\n if (keyword.value.trim()) reload()\n}\nfunction goPage(n: number) {\n if (n < 1 || n > pageCount.value || n === page.value) return\n page.value = n\n void load()\n}\n\n// ── 已选用户(右栏) ──\nconst selected = reactive<UserItem[]>([])\nconst selectedSet = computed(() => new Set(selected.map(u => u.id)))\nconst excludeSet = computed(() => new Set(props.excludeIds ?? []))\nconst selectedSearch = ref('')\n// 已选不多时搜索框只是噪音,超过一屏才出现。\nconst SELECTED_SEARCH_MIN = 8\nconst filteredSelected = computed(() => {\n const q = selectedSearch.value.trim().toLowerCase()\n if (!q) return selected\n return selected.filter(\n u => u.name.toLowerCase().includes(q) || u.account.toLowerCase().includes(q),\n )\n})\n\nfunction addUsers(users: UserItem[]) {\n for (const u of users) {\n if (!selectedSet.value.has(u.id) && !excludeSet.value.has(u.id)) selected.push(u)\n }\n}\nfunction removeUser(id: number) {\n const idx = selected.findIndex(u => u.id === id)\n if (idx >= 0) selected.splice(idx, 1)\n}\nfunction toggleUser(u: UserItem) {\n if (excludeSet.value.has(u.id)) return\n if (selectedSet.value.has(u.id)) removeUser(u.id)\n else addUsers([u])\n}\nfunction clearSelected() {\n selected.splice(0, selected.length)\n}\n\n// 「全选本页」:排除名单里的人不算;本页能选的都选上了,再点就是取消本页。\nconst selectable = computed(() => rows.value.filter(u => !excludeSet.value.has(u.id)))\nconst pageAllSelected = computed(\n () => selectable.value.length > 0 && selectable.value.every(u => selectedSet.value.has(u.id)),\n)\nfunction togglePage() {\n if (pageAllSelected.value) {\n for (const u of selectable.value) removeUser(u.id)\n } else {\n addUsers(selectable.value)\n }\n}\n\n/** 次行:账号(与姓名相同就不重复)· 机构。 */\nfunction subline(u: UserItem) {\n return [u.account !== u.name ? u.account : '', u.orgName].filter(Boolean).join(' · ')\n}\n\n// ── 公共 API ──\nasync function open(ids?: number[]) {\n selected.splice(0, selected.length)\n selectedSearch.value = ''\n selectedOrgKey.value = null\n keyword.value = ''\n field.value = 'name'\n page.value = 1\n rows.value = []\n total.value = 0\n tab.value = 'users'\n show.value = true\n\n void load()\n if (!ids?.length) return\n try {\n // ponytail: 拉一页,靠 id 过滤。取 200 是为了在应用把 Api:MaxPageSize 调小时也不会被后端回 48001。\n // 用户超过 200 个时,排在后面的 id 解析不出名字,走下面那条退回显示 id 的分支;\n // 真要支持更大规模的用户名单,再改成分页搜索。\n const { items } = await userApi.page({ page: 1, pageSize: 200 })\n const all = items.filter(u => ids.includes(u.id))\n // 没拉到的 id(翻页之外),退回只显示 id\n const found = new Set(all.map(u => u.id))\n for (const u of all) selected.push(u)\n for (const id of ids) {\n if (!found.has(id)) selected.push({ id, account: String(id), name: String(id) } as UserItem)\n }\n } catch {\n for (const id of ids) selected.push({ id, account: String(id), name: String(id) } as UserItem)\n }\n}\n\nasync function handleConfirm() {\n emit(\n 'confirm',\n selected.map(u => u.id),\n )\n}\n\ndefineExpose({ open })\n</script>\n\n<template>\n <FormContainer\n v-model:show=\"show\"\n :variant=\"variant\"\n :title=\"t('userPicker.title')\"\n :width=\"920\"\n :on-confirm=\"handleConfirm\"\n :confirm-text=\"t('common.confirm')\"\n >\n <n-tabs v-if=\"compact\" v-model:value=\"tab\" type=\"segment\" animated class=\"picker-tabs\">\n <n-tab name=\"users\">{{ t('userPicker.available') }}</n-tab>\n <n-tab name=\"selected\">{{ t('userPicker.selected') }} {{ selected.length }}</n-tab>\n </n-tabs>\n <div class=\"user-picker\" :class=\"{ 'is-compact': compact }\">\n <!-- 左栏:机构(侧栏式列表;两页形态下换成可选用户页顶部的树选择) -->\n <div v-if=\"!compact\" class=\"picker-org\">\n <div class=\"side-title\">{{ t('userPicker.org') }}</div>\n <n-tree\n :data=\"orgTree\"\n key-field=\"id\"\n label-field=\"name\"\n children-field=\"children\"\n selectable\n block-line\n default-expand-all\n :selected-keys=\"[selectedOrgKey ?? 0]\"\n @update:selected-keys=\"onOrgSelect\"\n />\n </div>\n\n <!-- 中栏:搜索 + 用户列表 -->\n <div v-show=\"!compact || tab === 'users'\" class=\"picker-main\">\n <n-tree-select\n v-if=\"compact\"\n :value=\"selectedOrgKey ?? 0\"\n :options=\"orgTree\"\n key-field=\"id\"\n label-field=\"name\"\n children-field=\"children\"\n default-expand-all\n size=\"large\"\n class=\"picker-org-select\"\n @update:value=\"onOrgPick\"\n />\n <div class=\"picker-toolbar\">\n <n-input\n :value=\"keyword\"\n round\n clearable\n :size=\"compact ? 'large' : 'medium'\"\n :placeholder=\"placeholder\"\n class=\"picker-search\"\n @update:value=\"onSearchInput\"\n >\n <template #prefix>\n <n-dropdown trigger=\"click\" :options=\"scopeOptions\" :value=\"field\" @select=\"onScope\">\n <span class=\"scope-trigger\" role=\"button\" tabindex=\"0\">\n <AppIcon icon=\"ph:magnifying-glass\" :size=\"15\" />\n <AppIcon icon=\"ph:caret-down\" :size=\"10\" />\n </span>\n </n-dropdown>\n </template>\n </n-input>\n <n-button\n text\n type=\"primary\"\n class=\"page-toggle\"\n :disabled=\"selectable.length === 0\"\n @click=\"togglePage\"\n >\n {{ pageAllSelected ? t('userPicker.unselectPage') : t('userPicker.selectPage') }}\n </n-button>\n </div>\n\n <n-spin :show=\"loading\" size=\"small\" class=\"picker-spin\">\n <div class=\"user-list\" role=\"group\">\n <div\n v-for=\"u in rows\"\n :key=\"u.id\"\n class=\"user-row\"\n :class=\"{\n 'is-selected': selectedSet.has(u.id),\n 'is-disabled': excludeSet.has(u.id),\n }\"\n role=\"checkbox\"\n :aria-checked=\"selectedSet.has(u.id) ? 'true' : 'false'\"\n :aria-disabled=\"excludeSet.has(u.id) ? 'true' : undefined\"\n :tabindex=\"excludeSet.has(u.id) ? -1 : 0\"\n @click=\"toggleUser(u)\"\n @keydown.enter.prevent=\"toggleUser(u)\"\n @keydown.space.prevent=\"toggleUser(u)\"\n >\n <UserAvatar :name=\"u.name\" :src=\"u.avatar\" :size=\"32\" />\n <span class=\"user-main\">\n <span class=\"user-name\">{{ u.name }}</span>\n <span v-if=\"subline(u)\" class=\"user-sub\">{{ subline(u) }}</span>\n </span>\n <span v-if=\"excludeSet.has(u.id)\" class=\"user-tag\">\n {{ t('userPicker.existing') }}\n </span>\n <span v-else class=\"user-check\"><AppIcon icon=\"ph:check-bold\" :size=\"12\" /></span>\n </div>\n <n-empty\n v-if=\"!loading && rows.length === 0\"\n :description=\"t('common.noData')\"\n class=\"user-empty\"\n />\n </div>\n </n-spin>\n\n <div class=\"picker-foot\">\n <span class=\"picker-total\">{{ t('userPicker.total', { n: total }) }}</span>\n <div v-if=\"pageCount > 1\" class=\"pager\">\n <button\n type=\"button\"\n class=\"pager-btn pager-prev\"\n :disabled=\"page <= 1\"\n :aria-label=\"t('userPicker.prevPage')\"\n @click=\"goPage(page - 1)\"\n >\n <AppIcon icon=\"ph:caret-left\" :size=\"14\" />\n </button>\n <span class=\"pager-num\">{{ page }} / {{ pageCount }}</span>\n <button\n type=\"button\"\n class=\"pager-btn pager-next\"\n :disabled=\"page >= pageCount\"\n :aria-label=\"t('userPicker.nextPage')\"\n @click=\"goPage(page + 1)\"\n >\n <AppIcon icon=\"ph:caret-right\" :size=\"14\" />\n </button>\n </div>\n </div>\n </div>\n\n <!-- 右栏:已选 -->\n <div v-show=\"!compact || tab === 'selected'\" class=\"picker-selected\">\n <div class=\"side-head\">\n <span class=\"side-title\">\n {{ t('userPicker.selected') }}\n <span class=\"side-count\">{{ selected.length }}</span>\n </span>\n <n-button\n text\n type=\"error\"\n class=\"selected-clear\"\n :disabled=\"selected.length === 0\"\n @click=\"clearSelected\"\n >\n {{ t('userPicker.clear') }}\n </n-button>\n </div>\n <n-input\n v-if=\"selected.length > SELECTED_SEARCH_MIN\"\n v-model:value=\"selectedSearch\"\n round\n clearable\n :size=\"compact ? 'large' : 'small'\"\n :placeholder=\"t('common.search')\"\n class=\"selected-search\"\n />\n <div class=\"selected-list\">\n <div v-for=\"u in filteredSelected\" :key=\"u.id\" class=\"selected-item\">\n <UserAvatar :name=\"u.name\" :src=\"u.avatar\" :size=\"28\" />\n <span class=\"user-main\">\n <span class=\"user-name\">{{ u.name }}</span>\n <span v-if=\"subline(u)\" class=\"user-sub\">{{ subline(u) }}</span>\n </span>\n <button\n type=\"button\"\n class=\"item-remove\"\n :aria-label=\"t('userPicker.remove')\"\n @click=\"removeUser(u.id)\"\n >\n <AppIcon icon=\"ph:x\" :size=\"12\" />\n </button>\n </div>\n <n-empty\n v-if=\"selected.length === 0\"\n :description=\"t('userPicker.emptySelected')\"\n class=\"user-empty\"\n />\n </div>\n </div>\n </div>\n </FormContainer>\n</template>\n\n<style scoped>\n/* 三栏:机构(浅底侧栏)| 可选用户 | 已选。整体定高,各栏自己滚,翻页和搜索时弹窗不跳。 */\n.user-picker {\n display: flex;\n gap: 16px;\n height: min(460px, calc(100vh - 260px));\n}\n\n/* ── 左栏:macOS 侧栏式机构列表 ── */\n.picker-org {\n width: 200px;\n flex-shrink: 0;\n overflow: auto;\n padding: 8px;\n border-radius: var(--radius-lg);\n background: var(--fill);\n}\n.side-title {\n font-size: 12px;\n font-weight: 600;\n color: var(--text-3);\n}\n.picker-org .side-title {\n padding: 2px 8px 6px;\n}\n.picker-org :deep(.n-tree-node) {\n min-height: var(--sidebar-row-h);\n border-radius: var(--radius-md);\n}\n.picker-org :deep(.n-tree-node:hover) {\n background: var(--hover);\n}\n/* 灰底面板上 --sel-bg(6% 强调色)几乎看不出来,选中条用更实的 --fill-strong,文字再用强调色加粗。 */\n.picker-org :deep(.n-tree-node.n-tree-node--selected) {\n background: var(--fill-strong);\n}\n.picker-org :deep(.n-tree-node.n-tree-node--selected .n-tree-node-content__text) {\n color: var(--sel-fg);\n font-weight: 600;\n}\n\n/* ── 中栏 ── */\n.picker-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n.picker-org-select {\n margin-bottom: 8px;\n}\n.picker-toolbar {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n.picker-search {\n flex: 1;\n min-width: 0;\n}\n.scope-trigger {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n color: var(--text-3);\n cursor: pointer;\n}\n.page-toggle {\n flex-shrink: 0;\n font-size: 13.5px;\n}\n.picker-spin {\n flex: 1;\n min-height: 0;\n}\n.picker-spin :deep(.n-spin-content) {\n height: 100%;\n}\n.user-list {\n height: 100%;\n overflow: auto;\n margin: 0 -4px;\n padding: 0 4px;\n}\n\n.user-row {\n display: flex;\n align-items: center;\n gap: 12px;\n min-height: 48px;\n padding: 0 10px;\n border-radius: var(--radius-md);\n cursor: pointer;\n transition: background var(--transition-fast);\n outline: none;\n}\n.user-row:hover {\n background: var(--hover);\n}\n.user-row.is-selected {\n background: var(--sel-bg);\n}\n.user-row:focus-visible {\n box-shadow: inset 0 0 0 2px var(--sel-ring);\n}\n.user-row.is-disabled {\n cursor: not-allowed;\n background: none;\n opacity: 0.55;\n}\n\n.user-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n line-height: 1.35;\n}\n.user-name {\n font-size: 14px;\n color: var(--text-1);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.user-sub {\n font-size: 12.5px;\n color: var(--text-3);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.user-tag {\n flex-shrink: 0;\n font-size: 12.5px;\n color: var(--text-3);\n}\n\n/* 圆形勾选标记:空心环 → 选中后实心强调色。整行可点,它只负责告诉人「选了没」。 */\n.user-check {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 999px;\n border: 1.5px solid var(--border);\n color: transparent;\n transition:\n background var(--transition-fast),\n border-color var(--transition-fast);\n}\n.user-row.is-selected .user-check {\n background: var(--acc-solid);\n border-color: var(--acc-solid);\n color: var(--on-acc);\n}\n\n.user-empty {\n padding: 48px 0;\n}\n\n.picker-foot {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 34px;\n padding-top: 8px;\n border-top: 1px solid var(--hairline);\n font-size: 13px;\n color: var(--text-3);\n}\n.pager {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.pager-num {\n min-width: 48px;\n text-align: center;\n font-variant-numeric: tabular-nums;\n color: var(--text-2);\n}\n.pager-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n padding: 0;\n border: none;\n border-radius: var(--radius-sm);\n background: none;\n color: var(--text-2);\n cursor: pointer;\n transition: background var(--transition-fast);\n}\n.pager-btn:hover:not(:disabled) {\n background: var(--hover);\n}\n.pager-btn:disabled {\n color: var(--text-4);\n cursor: not-allowed;\n}\n\n/* ── 右栏 ── */\n.picker-selected {\n width: 232px;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n min-height: 0;\n padding-left: 16px;\n border-left: 1px solid var(--hairline);\n}\n.side-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 30px;\n margin-bottom: 8px;\n}\n.side-head .side-title {\n font-size: 13.5px;\n color: var(--text-1);\n}\n.side-count {\n margin-left: 4px;\n font-weight: 500;\n color: var(--text-3);\n font-variant-numeric: tabular-nums;\n}\n.selected-search {\n margin-bottom: 8px;\n}\n.selected-list {\n flex: 1;\n min-height: 0;\n overflow: auto;\n}\n.selected-item {\n display: flex;\n align-items: center;\n gap: 10px;\n min-height: 44px;\n padding: 0 6px 0 8px;\n border-radius: var(--radius-md);\n}\n.selected-item:hover {\n background: var(--hover);\n}\n.item-remove {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n padding: 0;\n border: none;\n border-radius: 999px;\n background: none;\n color: var(--text-3);\n cursor: pointer;\n opacity: 0;\n transition:\n opacity var(--transition-fast),\n background var(--transition-fast);\n}\n.selected-item:hover .item-remove,\n.item-remove:focus-visible {\n opacity: 1;\n}\n.item-remove:hover {\n background: var(--fill-strong);\n color: var(--err);\n}\n\n/* 两页形态:分段页签在上,当前页占满整行;已选页不再要左侧分隔线,条目放大到可点;触屏没有悬停,移除钮常显 */\n.picker-tabs {\n margin-bottom: 12px;\n}\n.user-picker.is-compact {\n height: min(60vh, 520px);\n}\n.is-compact .picker-selected {\n width: auto;\n flex: 1;\n padding-left: 0;\n border-left: none;\n}\n.is-compact .selected-item {\n min-height: 52px;\n}\n.is-compact .item-remove {\n opacity: 1;\n width: 32px;\n height: 32px;\n}\n.is-compact .user-row {\n min-height: 56px;\n}\n</style>\n"],"names":["PAGE_SIZE","SELECTED_SEARCH_MIN","props","__props","emit","__emit","t","useI18n","message","useMessage","show","ref","bp","useShellBreakpoint","winW","useWindowSize","compact","computed","variant","tab","orgFlat","orgTree","buildTree","selectedOrgKey","orgId","onMounted","orgApi","onOrgSelect","keys","reload","onOrgPick","key","field","keyword","page","total","rows","loading","seq","pageCount","placeholder","scopeOptions","load","mine","kw","res","userApi","e","translateError","reloadDebounced","useDebounceFn","onSearchInput","v","onScope","goPage","n","selected","reactive","selectedSet","u","excludeSet","selectedSearch","filteredSelected","q","addUsers","users","removeUser","id","idx","toggleUser","clearSelected","selectable","pageAllSelected","togglePage","subline","open","ids","items","all","found","handleConfirm","__expose","_createBlock","FormContainer","$event","_unref","NTabs","_createVNode","NTab","_createTextVNode","_toDisplayString","_createElementVNode","_normalizeClass","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","NTree","_withDirectives","_hoisted_3","NTreeSelect","_hoisted_4","NInput","NDropdown","_hoisted_5","AppIcon","NButton","NSpin","_hoisted_6","_Fragment","_renderList","_withKeys","_withModifiers","UserAvatar","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","NEmpty","_hoisted_13","_hoisted_14","_hoisted_15","_cache","_hoisted_17","_vShow","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26"],"mappings":"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"}
1
+ {"version":3,"file":"index2.vue.js","sources":["../../../src/components/UserPicker/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, reactive, ref } from 'vue'\nimport {\n NButton,\n NEmpty,\n NInput,\n NSpin,\n NTab,\n NTabs,\n NTree,\n NTreeSelect,\n useMessage,\n} from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport { useDebounceFn, useWindowSize } from '@vueuse/core'\nimport AppIcon from '#/components/AppIcon.vue'\nimport FormContainer from '#/components/FormContainer/index.vue'\nimport UserAvatar from './UserAvatar.vue'\nimport { useShellBreakpoint } from '#/composables/useShellBreakpoint'\nimport { orgApi, userApi } from '#/api'\nimport { buildTree } from '#/utils/tree'\nimport { translateError } from '#/utils/error'\nimport type { OrgOption, UserOption } from '#/types/api'\n\nconst props = defineProps<{ excludeIds?: number[] }>()\nconst emit = defineEmits<{ (e: 'confirm', ids: number[]): void }>()\n\nconst { t } = useI18n()\nconst message = useMessage()\n\nconst show = ref(false)\n\n// 屏幕形态:\n// 宽 / 中档 = 居中弹窗里的三栏(机构 | 可选用户 | 已选);\n// 窄档(壳层 < 600)= 底部抽屉,三栏收成「可选用户 / 已选」两页,机构换成页内的树选择;\n// 内容区 < 900 但还不到窄档时仍是弹窗,三栏同样收成两页(920 宽的三栏在这里放不下)。\n// 三栏选择器在抽屉里太局促,所以宽 / 中档固定用弹窗,不跟随「表单形态」全局偏好。\nconst { bp } = useShellBreakpoint()\nconst { width: winW } = useWindowSize()\nconst compact = computed(() => bp.value === 'narrow' || winW.value < 900)\nconst variant = computed(() => (bp.value === 'narrow' ? 'drawer' : 'modal'))\nconst tab = ref<'users' | 'selected'>('users')\n\n// ── 机构(左栏) ──\nconst orgFlat = ref<OrgOption[]>([])\nconst orgTree = computed(() => {\n const all = { id: 0, parentId: -1, name: t('common.all'), children: buildTree(orgFlat.value) }\n return [all]\n})\nconst selectedOrgKey = ref<number | null>(null)\nconst orgId = computed(() =>\n selectedOrgKey.value && selectedOrgKey.value !== 0 ? selectedOrgKey.value : undefined,\n)\n\nonMounted(async () => {\n try {\n orgFlat.value = await orgApi.options()\n } catch (e) {\n // 机构只是筛选维度,失败不阻断选人,但要说出来,不能让左栏悄悄只剩「全部」\n message.error(translateError(e))\n }\n})\n\nfunction onOrgSelect(keys: Array<string | number>) {\n selectedOrgKey.value = (keys[0] as number) ?? null\n reload()\n}\n// 两页形态下机构换成树选择:没有「再点一次取消」,选「全部」(id 0)即不限机构。\nfunction onOrgPick(key: number | null) {\n selectedOrgKey.value = key ?? null\n reload()\n}\n\n// ── 可选用户(中栏) ──\n// 一页 20 人;一个搜索框同时匹配姓名与账号。\nconst PAGE_SIZE = 20\n\nconst keyword = ref('')\nconst page = ref(1)\nconst total = ref(0)\nconst rows = ref<UserOption[]>([])\nconst loading = ref(false)\n// 防乱序:输入停顿、翻页、换机构都会发请求,后发的先回来时,先发的结果不能覆盖它。\nlet seq = 0\n\nconst pageCount = computed(() => Math.max(1, Math.ceil(total.value / PAGE_SIZE)))\n\nasync function load() {\n const mine = ++seq\n loading.value = true\n try {\n const kw = keyword.value.trim() || undefined\n const res = await userApi.options({\n page: page.value,\n pageSize: PAGE_SIZE,\n keyword: kw,\n orgId: orgId.value,\n })\n if (mine !== seq) return\n rows.value = res.items\n total.value = res.total\n } catch (e) {\n if (mine !== seq) return\n rows.value = []\n total.value = 0\n message.error(translateError(e))\n } finally {\n if (mine === seq) loading.value = false\n }\n}\n\n/** 条件变了:回第 1 页重查。 */\nfunction reload() {\n page.value = 1\n void load()\n}\nconst reloadDebounced = useDebounceFn(reload, 300)\n\nfunction onSearchInput(v: string) {\n keyword.value = v\n void reloadDebounced()\n}\nfunction goPage(n: number) {\n if (n < 1 || n > pageCount.value || n === page.value) return\n page.value = n\n void load()\n}\n\n// ── 已选用户(右栏) ──\nconst selected = reactive<UserOption[]>([])\nconst selectedSet = computed(() => new Set(selected.map(u => u.id)))\nconst excludeSet = computed(() => new Set(props.excludeIds ?? []))\nconst selectedSearch = ref('')\n// 已选不多时搜索框只是噪音,超过一屏才出现。\nconst SELECTED_SEARCH_MIN = 8\nconst filteredSelected = computed(() => {\n const q = selectedSearch.value.trim().toLowerCase()\n if (!q) return selected\n return selected.filter(\n u => u.name.toLowerCase().includes(q) || u.account.toLowerCase().includes(q),\n )\n})\n\nfunction addUsers(users: UserOption[]) {\n for (const u of users) {\n if (!selectedSet.value.has(u.id) && !excludeSet.value.has(u.id)) selected.push(u)\n }\n}\nfunction removeUser(id: number) {\n const idx = selected.findIndex(u => u.id === id)\n if (idx >= 0) selected.splice(idx, 1)\n}\nfunction toggleUser(u: UserOption) {\n if (excludeSet.value.has(u.id)) return\n if (selectedSet.value.has(u.id)) removeUser(u.id)\n else addUsers([u])\n}\nfunction clearSelected() {\n selected.splice(0, selected.length)\n}\n\n// 「全选本页」:排除名单里的人不算;本页能选的都选上了,再点就是取消本页。\nconst selectable = computed(() => rows.value.filter(u => !excludeSet.value.has(u.id)))\nconst pageAllSelected = computed(\n () => selectable.value.length > 0 && selectable.value.every(u => selectedSet.value.has(u.id)),\n)\nfunction togglePage() {\n if (pageAllSelected.value) {\n for (const u of selectable.value) removeUser(u.id)\n } else {\n addUsers(selectable.value)\n }\n}\n\n/** 次行:账号(与姓名相同就不重复)。 */\nfunction subline(u: UserOption) {\n return u.account !== u.name ? u.account : ''\n}\n\n// ── 公共 API ──\nasync function open(ids?: number[]) {\n selected.splice(0, selected.length)\n selectedSearch.value = ''\n selectedOrgKey.value = null\n keyword.value = ''\n page.value = 1\n rows.value = []\n total.value = 0\n tab.value = 'users'\n show.value = true\n\n void load()\n if (!ids?.length) return\n try {\n // ponytail: 拉一页,靠 id 过滤。取 200 是为了在应用把 Api:MaxPageSize 调小时也不会被后端回 48001。\n // 用户超过 200 个时,排在后面的 id 解析不出名字,走下面那条退回显示 id 的分支;\n // 真要支持更大规模的用户名单,再改成分页搜索。\n const { items } = await userApi.options({ page: 1, pageSize: 200 })\n const all = items.filter(u => ids.includes(u.id))\n // 没拉到的 id(翻页之外),退回只显示 id\n const found = new Set(all.map(u => u.id))\n for (const u of all) selected.push(u)\n for (const id of ids) {\n if (!found.has(id)) selected.push({ id, account: String(id), name: String(id) })\n }\n } catch {\n for (const id of ids) selected.push({ id, account: String(id), name: String(id) })\n }\n}\n\nasync function handleConfirm() {\n emit(\n 'confirm',\n selected.map(u => u.id),\n )\n}\n\ndefineExpose({ open })\n</script>\n\n<template>\n <FormContainer\n v-model:show=\"show\"\n :variant=\"variant\"\n :title=\"t('userPicker.title')\"\n :width=\"920\"\n :on-confirm=\"handleConfirm\"\n :confirm-text=\"t('common.confirm')\"\n >\n <n-tabs v-if=\"compact\" v-model:value=\"tab\" type=\"segment\" animated class=\"picker-tabs\">\n <n-tab name=\"users\">{{ t('userPicker.available') }}</n-tab>\n <n-tab name=\"selected\">{{ t('userPicker.selected') }} {{ selected.length }}</n-tab>\n </n-tabs>\n <div class=\"user-picker\" :class=\"{ 'is-compact': compact }\">\n <!-- 左栏:机构(侧栏式列表;两页形态下换成可选用户页顶部的树选择) -->\n <div v-if=\"!compact\" class=\"picker-org\">\n <div class=\"side-title\">{{ t('userPicker.org') }}</div>\n <n-tree\n :data=\"orgTree\"\n key-field=\"id\"\n label-field=\"name\"\n children-field=\"children\"\n selectable\n block-line\n default-expand-all\n :selected-keys=\"[selectedOrgKey ?? 0]\"\n @update:selected-keys=\"onOrgSelect\"\n />\n </div>\n\n <!-- 中栏:搜索 + 用户列表 -->\n <div v-show=\"!compact || tab === 'users'\" class=\"picker-main\">\n <n-tree-select\n v-if=\"compact\"\n :value=\"selectedOrgKey ?? 0\"\n :options=\"orgTree\"\n key-field=\"id\"\n label-field=\"name\"\n children-field=\"children\"\n default-expand-all\n size=\"large\"\n class=\"picker-org-select\"\n @update:value=\"onOrgPick\"\n />\n <div class=\"picker-toolbar\">\n <n-input\n :value=\"keyword\"\n round\n clearable\n :size=\"compact ? 'large' : 'medium'\"\n :placeholder=\"t('userPicker.search')\"\n class=\"picker-search\"\n @update:value=\"onSearchInput\"\n >\n <template #prefix>\n <AppIcon class=\"search-icon\" icon=\"ph:magnifying-glass\" :size=\"15\" />\n </template>\n </n-input>\n <n-button\n text\n type=\"primary\"\n class=\"page-toggle\"\n :disabled=\"selectable.length === 0\"\n @click=\"togglePage\"\n >\n {{ pageAllSelected ? t('userPicker.unselectPage') : t('userPicker.selectPage') }}\n </n-button>\n </div>\n\n <n-spin :show=\"loading\" size=\"small\" class=\"picker-spin\">\n <div class=\"user-list\" role=\"group\">\n <div\n v-for=\"u in rows\"\n :key=\"u.id\"\n class=\"user-row\"\n :class=\"{\n 'is-selected': selectedSet.has(u.id),\n 'is-disabled': excludeSet.has(u.id),\n }\"\n role=\"checkbox\"\n :aria-checked=\"selectedSet.has(u.id) ? 'true' : 'false'\"\n :aria-disabled=\"excludeSet.has(u.id) ? 'true' : undefined\"\n :tabindex=\"excludeSet.has(u.id) ? -1 : 0\"\n @click=\"toggleUser(u)\"\n @keydown.enter.prevent=\"toggleUser(u)\"\n @keydown.space.prevent=\"toggleUser(u)\"\n >\n <UserAvatar :name=\"u.name\" :size=\"32\" />\n <span class=\"user-main\">\n <span class=\"user-name\">{{ u.name }}</span>\n <span v-if=\"subline(u)\" class=\"user-sub\">{{ subline(u) }}</span>\n </span>\n <span v-if=\"excludeSet.has(u.id)\" class=\"user-tag\">\n {{ t('userPicker.existing') }}\n </span>\n <span v-else class=\"user-check\"><AppIcon icon=\"ph:check-bold\" :size=\"12\" /></span>\n </div>\n <n-empty\n v-if=\"!loading && rows.length === 0\"\n :description=\"t('common.noData')\"\n class=\"user-empty\"\n />\n </div>\n </n-spin>\n\n <div class=\"picker-foot\">\n <span class=\"picker-total\">{{ t('userPicker.total', { n: total }) }}</span>\n <div v-if=\"pageCount > 1\" class=\"pager\">\n <button\n type=\"button\"\n class=\"pager-btn pager-prev\"\n :disabled=\"page <= 1\"\n :aria-label=\"t('userPicker.prevPage')\"\n @click=\"goPage(page - 1)\"\n >\n <AppIcon icon=\"ph:caret-left\" :size=\"14\" />\n </button>\n <span class=\"pager-num\">{{ page }} / {{ pageCount }}</span>\n <button\n type=\"button\"\n class=\"pager-btn pager-next\"\n :disabled=\"page >= pageCount\"\n :aria-label=\"t('userPicker.nextPage')\"\n @click=\"goPage(page + 1)\"\n >\n <AppIcon icon=\"ph:caret-right\" :size=\"14\" />\n </button>\n </div>\n </div>\n </div>\n\n <!-- 右栏:已选 -->\n <div v-show=\"!compact || tab === 'selected'\" class=\"picker-selected\">\n <div class=\"side-head\">\n <span class=\"side-title\">\n {{ t('userPicker.selected') }}\n <span class=\"side-count\">{{ selected.length }}</span>\n </span>\n <n-button\n text\n type=\"error\"\n class=\"selected-clear\"\n :disabled=\"selected.length === 0\"\n @click=\"clearSelected\"\n >\n {{ t('userPicker.clear') }}\n </n-button>\n </div>\n <n-input\n v-if=\"selected.length > SELECTED_SEARCH_MIN\"\n v-model:value=\"selectedSearch\"\n round\n clearable\n :size=\"compact ? 'large' : 'small'\"\n :placeholder=\"t('common.search')\"\n class=\"selected-search\"\n />\n <div class=\"selected-list\">\n <div v-for=\"u in filteredSelected\" :key=\"u.id\" class=\"selected-item\">\n <UserAvatar :name=\"u.name\" :size=\"28\" />\n <span class=\"user-main\">\n <span class=\"user-name\">{{ u.name }}</span>\n <span v-if=\"subline(u)\" class=\"user-sub\">{{ subline(u) }}</span>\n </span>\n <button\n type=\"button\"\n class=\"item-remove\"\n :aria-label=\"t('userPicker.remove')\"\n @click=\"removeUser(u.id)\"\n >\n <AppIcon icon=\"ph:x\" :size=\"12\" />\n </button>\n </div>\n <n-empty\n v-if=\"selected.length === 0\"\n :description=\"t('userPicker.emptySelected')\"\n class=\"user-empty\"\n />\n </div>\n </div>\n </div>\n </FormContainer>\n</template>\n\n<style scoped>\n/* 三栏:机构(浅底侧栏)| 可选用户 | 已选。整体定高,各栏自己滚,翻页和搜索时弹窗不跳。 */\n.user-picker {\n display: flex;\n gap: 16px;\n height: min(460px, calc(100vh - 260px));\n}\n\n/* ── 左栏:macOS 侧栏式机构列表 ── */\n.picker-org {\n width: 200px;\n flex-shrink: 0;\n overflow: auto;\n padding: 8px;\n border-radius: var(--radius-lg);\n background: var(--fill);\n}\n.side-title {\n font-size: 12px;\n font-weight: 600;\n color: var(--text-3);\n}\n.picker-org .side-title {\n padding: 2px 8px 6px;\n}\n.picker-org :deep(.n-tree-node) {\n min-height: var(--sidebar-row-h);\n border-radius: var(--radius-md);\n}\n.picker-org :deep(.n-tree-node:hover) {\n background: var(--hover);\n}\n/* 灰底面板上 --sel-bg(6% 强调色)几乎看不出来,选中条用更实的 --fill-strong,文字再用强调色加粗。 */\n.picker-org :deep(.n-tree-node.n-tree-node--selected) {\n background: var(--fill-strong);\n}\n.picker-org :deep(.n-tree-node.n-tree-node--selected .n-tree-node-content__text) {\n color: var(--sel-fg);\n font-weight: 600;\n}\n\n/* ── 中栏 ── */\n.picker-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n.picker-org-select {\n margin-bottom: 8px;\n}\n.picker-toolbar {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n.picker-search {\n flex: 1;\n min-width: 0;\n}\n.search-icon {\n color: var(--text-3);\n}\n.page-toggle {\n flex-shrink: 0;\n font-size: 13.5px;\n}\n.picker-spin {\n flex: 1;\n min-height: 0;\n}\n.picker-spin :deep(.n-spin-content) {\n height: 100%;\n}\n.user-list {\n height: 100%;\n overflow: auto;\n margin: 0 -4px;\n padding: 0 4px;\n}\n\n.user-row {\n display: flex;\n align-items: center;\n gap: 12px;\n min-height: 48px;\n padding: 0 10px;\n border-radius: var(--radius-md);\n cursor: pointer;\n transition: background var(--transition-fast);\n outline: none;\n}\n.user-row:hover {\n background: var(--hover);\n}\n.user-row.is-selected {\n background: var(--sel-bg);\n}\n.user-row:focus-visible {\n box-shadow: inset 0 0 0 2px var(--sel-ring);\n}\n.user-row.is-disabled {\n cursor: not-allowed;\n background: none;\n opacity: 0.55;\n}\n\n.user-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n line-height: 1.35;\n}\n.user-name {\n font-size: 14px;\n color: var(--text-1);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.user-sub {\n font-size: 12.5px;\n color: var(--text-3);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.user-tag {\n flex-shrink: 0;\n font-size: 12.5px;\n color: var(--text-3);\n}\n\n/* 圆形勾选标记:空心环 → 选中后实心强调色。整行可点,它只负责告诉人「选了没」。 */\n.user-check {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 999px;\n border: 1.5px solid var(--border);\n color: transparent;\n transition:\n background var(--transition-fast),\n border-color var(--transition-fast);\n}\n.user-row.is-selected .user-check {\n background: var(--acc-solid);\n border-color: var(--acc-solid);\n color: var(--on-acc);\n}\n\n.user-empty {\n padding: 48px 0;\n}\n\n.picker-foot {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 34px;\n padding-top: 8px;\n border-top: 1px solid var(--hairline);\n font-size: 13px;\n color: var(--text-3);\n}\n.pager {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.pager-num {\n min-width: 48px;\n text-align: center;\n font-variant-numeric: tabular-nums;\n color: var(--text-2);\n}\n.pager-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n padding: 0;\n border: none;\n border-radius: var(--radius-sm);\n background: none;\n color: var(--text-2);\n cursor: pointer;\n transition: background var(--transition-fast);\n}\n.pager-btn:hover:not(:disabled) {\n background: var(--hover);\n}\n.pager-btn:disabled {\n color: var(--text-4);\n cursor: not-allowed;\n}\n\n/* ── 右栏 ── */\n.picker-selected {\n width: 232px;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n min-height: 0;\n padding-left: 16px;\n border-left: 1px solid var(--hairline);\n}\n.side-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 30px;\n margin-bottom: 8px;\n}\n.side-head .side-title {\n font-size: 13.5px;\n color: var(--text-1);\n}\n.side-count {\n margin-left: 4px;\n font-weight: 500;\n color: var(--text-3);\n font-variant-numeric: tabular-nums;\n}\n.selected-search {\n margin-bottom: 8px;\n}\n.selected-list {\n flex: 1;\n min-height: 0;\n overflow: auto;\n}\n.selected-item {\n display: flex;\n align-items: center;\n gap: 10px;\n min-height: 44px;\n padding: 0 6px 0 8px;\n border-radius: var(--radius-md);\n}\n.selected-item:hover {\n background: var(--hover);\n}\n.item-remove {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n padding: 0;\n border: none;\n border-radius: 999px;\n background: none;\n color: var(--text-3);\n cursor: pointer;\n opacity: 0;\n transition:\n opacity var(--transition-fast),\n background var(--transition-fast);\n}\n.selected-item:hover .item-remove,\n.item-remove:focus-visible {\n opacity: 1;\n}\n.item-remove:hover {\n background: var(--fill-strong);\n color: var(--err);\n}\n\n/* 两页形态:分段页签在上,当前页占满整行;已选页不再要左侧分隔线,条目放大到可点;触屏没有悬停,移除钮常显 */\n.picker-tabs {\n margin-bottom: 12px;\n}\n.user-picker.is-compact {\n height: min(60vh, 520px);\n}\n.is-compact .picker-selected {\n width: auto;\n flex: 1;\n padding-left: 0;\n border-left: none;\n}\n.is-compact .selected-item {\n min-height: 52px;\n}\n.is-compact .item-remove {\n opacity: 1;\n width: 32px;\n height: 32px;\n}\n.is-compact .user-row {\n min-height: 56px;\n}\n</style>\n"],"names":["PAGE_SIZE","SELECTED_SEARCH_MIN","props","__props","emit","__emit","t","useI18n","message","useMessage","show","ref","bp","useShellBreakpoint","winW","useWindowSize","compact","computed","variant","tab","orgFlat","orgTree","buildTree","selectedOrgKey","orgId","onMounted","orgApi","translateError","onOrgSelect","keys","reload","onOrgPick","key","keyword","page","total","rows","loading","seq","pageCount","load","mine","kw","res","userApi","e","reloadDebounced","useDebounceFn","onSearchInput","v","goPage","n","selected","reactive","selectedSet","u","excludeSet","selectedSearch","filteredSelected","q","addUsers","users","removeUser","id","idx","toggleUser","clearSelected","selectable","pageAllSelected","togglePage","subline","open","ids","items","all","found","handleConfirm","__expose","_createBlock","FormContainer","$event","_unref","NTabs","_createVNode","NTab","_createTextVNode","_toDisplayString","_createElementVNode","_normalizeClass","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","NTree","_withDirectives","_hoisted_3","NTreeSelect","_hoisted_4","NInput","AppIcon","NButton","NSpin","_hoisted_5","_Fragment","_renderList","_withKeys","_withModifiers","UserAvatar","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","NEmpty","_hoisted_12","_hoisted_13","_hoisted_14","_cache","_hoisted_16","_vShow","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25"],"mappings":"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"}
@@ -1,28 +1,28 @@
1
- import { defineComponent as i, computed as c, openBlock as s, createBlock as m, mergeProps as d } from "vue";
1
+ import { defineComponent as p, computed as s, openBlock as c, createBlock as d, mergeProps as m } from "vue";
2
2
  import l from "../ApiSelect/index.vue.js";
3
3
  import { userApi as f } from "../../api/index.js";
4
- const v = /* @__PURE__ */ i({
4
+ const v = /* @__PURE__ */ p({
5
5
  inheritAttrs: !1,
6
6
  __name: "index",
7
7
  props: {
8
8
  orgId: {},
9
9
  pageSize: { default: 50 }
10
10
  },
11
- setup(t) {
12
- const e = t;
11
+ setup(a) {
12
+ const e = a;
13
13
  async function n(o) {
14
- const { items: a } = await f.page({
14
+ const { items: t } = await f.options({
15
15
  page: 1,
16
16
  pageSize: e.pageSize,
17
- name: o || void 0,
17
+ keyword: o || void 0,
18
18
  orgId: e.orgId ?? void 0
19
19
  });
20
- return a.map((r) => ({ label: `${r.name}(${r.account})`, value: r.id }));
20
+ return t.map((r) => ({ label: `${r.name}(${r.account})`, value: r.id }));
21
21
  }
22
- const p = c(() => e.orgId);
23
- return (o, a) => (s(), m(l, d({
22
+ const i = s(() => e.orgId);
23
+ return (o, t) => (c(), d(l, m({
24
24
  fetch: n,
25
- "reload-on": p.value
25
+ "reload-on": i.value
26
26
  }, o.$attrs), null, 16, ["reload-on"]));
27
27
  }
28
28
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.vue.js","sources":["../../../src/components/UserSelect/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 人员选择器:基于 ApiSelect,fetch=userApi.page(name 搜索 + 可选 orgId 部门过滤)。\n// 选项 label 为「姓名(账号)」,value 为用户 id。单/多选、placeholder 等一切经 $attrs 透传。\nimport { computed } from 'vue'\nimport type { SelectOption } from 'naive-ui'\nimport ApiSelect from '#/components/ApiSelect/index.vue'\nimport { userApi } from '#/api'\n\ndefineOptions({ inheritAttrs: false })\nconst props = withDefaults(defineProps<{ orgId?: number | null; pageSize?: number }>(), {\n pageSize: 50,\n})\n\nasync function fetch(keyword: string): Promise<SelectOption[]> {\n const { items } = await userApi.page({\n page: 1,\n pageSize: props.pageSize,\n name: keyword || undefined,\n orgId: props.orgId ?? undefined,\n })\n return items.map(u => ({ label: `${u.name}(${u.account})`, value: u.id }))\n}\nconst reloadOn = computed(() => props.orgId) // 部门过滤变化 → 重新拉\n</script>\n\n<template>\n <ApiSelect :fetch=\"fetch\" :reload-on=\"reloadOn\" v-bind=\"$attrs\" />\n</template>\n"],"names":["props","__props","fetch","keyword","items","userApi","u","reloadOn","computed","_openBlock","_createBlock","ApiSelect","_mergeProps","$attrs"],"mappings":";;;;;;;;;;;AASA,UAAMA,IAAQC;AAId,mBAAeC,EAAMC,GAA0C;AAC7D,YAAM,EAAE,OAAAC,EAAA,IAAU,MAAMC,EAAQ,KAAK;AAAA,QACnC,MAAM;AAAA,QACN,UAAUL,EAAM;AAAA,QAChB,MAAMG,KAAW;AAAA,QACjB,OAAOH,EAAM,SAAS;AAAA,MAAA,CACvB;AACD,aAAOI,EAAM,IAAI,CAAAE,OAAM,EAAE,OAAO,GAAGA,EAAE,IAAI,IAAIA,EAAE,OAAO,KAAK,OAAOA,EAAE,KAAK;AAAA,IAC3E;AACA,UAAMC,IAAWC,EAAS,MAAMR,EAAM,KAAK;sBAIzCS,EAAA,GAAAC,EAAkEC,GAAlEC,EAAkE;AAAA,MAAtD,OAAAV;AAAA,MAAe,aAAWK,EAAA;AAAA,IAAA,GAAkBM,EAAAA,MAAM,GAAA,MAAA,IAAA,CAAA,WAAA,CAAA;AAAA;;"}
1
+ {"version":3,"file":"index.vue.js","sources":["../../../src/components/UserSelect/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 人员选择器:基于 ApiSelect,fetch=userApi.options(姓名/账号搜索 + 可选 orgId 部门过滤;不占用户页权限码)。\n// 选项 label 为「姓名(账号)」,value 为用户 id。单/多选、placeholder 等一切经 $attrs 透传。\nimport { computed } from 'vue'\nimport type { SelectOption } from 'naive-ui'\nimport ApiSelect from '#/components/ApiSelect/index.vue'\nimport { userApi } from '#/api'\n\ndefineOptions({ inheritAttrs: false })\nconst props = withDefaults(defineProps<{ orgId?: number | null; pageSize?: number }>(), {\n pageSize: 50,\n})\n\nasync function fetch(keyword: string): Promise<SelectOption[]> {\n const { items } = await userApi.options({\n page: 1,\n pageSize: props.pageSize,\n keyword: keyword || undefined,\n orgId: props.orgId ?? undefined,\n })\n return items.map(u => ({ label: `${u.name}(${u.account})`, value: u.id }))\n}\nconst reloadOn = computed(() => props.orgId) // 部门过滤变化 → 重新拉\n</script>\n\n<template>\n <ApiSelect :fetch=\"fetch\" :reload-on=\"reloadOn\" v-bind=\"$attrs\" />\n</template>\n"],"names":["props","__props","fetch","keyword","items","userApi","u","reloadOn","computed","_openBlock","_createBlock","ApiSelect","_mergeProps","$attrs"],"mappings":";;;;;;;;;;;AASA,UAAMA,IAAQC;AAId,mBAAeC,EAAMC,GAA0C;AAC7D,YAAM,EAAE,OAAAC,EAAA,IAAU,MAAMC,EAAQ,QAAQ;AAAA,QACtC,MAAM;AAAA,QACN,UAAUL,EAAM;AAAA,QAChB,SAASG,KAAW;AAAA,QACpB,OAAOH,EAAM,SAAS;AAAA,MAAA,CACvB;AACD,aAAOI,EAAM,IAAI,CAAAE,OAAM,EAAE,OAAO,GAAGA,EAAE,IAAI,IAAIA,EAAE,OAAO,KAAK,OAAOA,EAAE,KAAK;AAAA,IAC3E;AACA,UAAMC,IAAWC,EAAS,MAAMR,EAAM,KAAK;sBAIzCS,EAAA,GAAAC,EAAkEC,GAAlEC,EAAkE;AAAA,MAAtD,OAAAV;AAAA,MAAe,aAAWK,EAAA;AAAA,IAAA,GAAkBM,EAAAA,MAAM,GAAA,MAAA,IAAA,CAAA,WAAA,CAAA;AAAA;;"}
@@ -2,7 +2,7 @@ const e = {
2
2
  /** API 根地址;空串 = 同源(dev 由 Vite 代理,生产由反代或后端托管 dist) */
3
3
  apiBase: "",
4
4
  /** 登录页页脚展示的版本号;默认内核版本,消费方可覆盖为应用版本 */
5
- version: "10.24.0",
5
+ version: "10.25.0",
6
6
  /** 开发态:登录页预填超管账号、设置抽屉显示「复制配置」 */
7
7
  dev: !1,
8
8
  brand: {}
@@ -36,6 +36,7 @@ declare const _default: {
36
36
  batchDeleteConfirm: string;
37
37
  all: string;
38
38
  noData: string;
39
+ loadFailed: string;
39
40
  back: string;
40
41
  detail: string;
41
42
  };
@@ -67,8 +68,7 @@ declare const _default: {
67
68
  org: string;
68
69
  available: string;
69
70
  selected: string;
70
- searchName: string;
71
- searchAccount: string;
71
+ search: string;
72
72
  selectPage: string;
73
73
  unselectPage: string;
74
74
  total: string;
@@ -518,6 +518,7 @@ declare const _default: {
518
518
  org: string;
519
519
  allOrgs: string;
520
520
  orgFilter: string;
521
+ optionsLoadFailed: string;
521
522
  collapseToFirstLevel: string;
522
523
  hideOrgPanel: string;
523
524
  showOrgPanel: string;
@@ -36,6 +36,7 @@ const e = {
36
36
  batchDeleteConfirm: "Delete the {count} selected item(s)? This cannot be undone.",
37
37
  all: "All",
38
38
  noData: "No data",
39
+ loadFailed: "Failed to load",
39
40
  back: "Back",
40
41
  detail: "Detail"
41
42
  },
@@ -69,8 +70,7 @@ const e = {
69
70
  org: "Organizations",
70
71
  available: "Available",
71
72
  selected: "Selected",
72
- searchName: "Search by name",
73
- searchAccount: "Search by account",
73
+ search: "Search by name or account",
74
74
  selectPage: "Select page",
75
75
  unselectPage: "Deselect page",
76
76
  total: "{n} users",
@@ -527,6 +527,8 @@ const e = {
527
527
  allOrgs: "All",
528
528
  // Group name of the org panel; in a narrow content area the tree moves into a drawer, where it is also the toolbar button + drawer title
529
529
  orgFilter: "Organization",
530
+ // Shown once when the position / role / manager options fail to load, without interrupting the list; {names} lists what failed
531
+ optionsLoadFailed: "Failed to load options for {names}. Dropdowns in the add/edit form may be empty; refresh the page to retry",
530
532
  // Panel header button tips: once fully expanded it becomes "collapse to first level"; "hide" slides the whole panel left, after which the toolbar button's tip is "show"
531
533
  collapseToFirstLevel: "Collapse to first level",
532
534
  hideOrgPanel: "Hide organization panel",
@@ -1116,7 +1118,7 @@ const e = {
1116
1118
  // Org management (tree table + parent-org tree select)
1117
1119
  org: {
1118
1120
  title: "Organizations",
1119
- searchPlaceholder: "Search name / code",
1121
+ searchPlaceholder: "Search by name",
1120
1122
  name: "Name",
1121
1123
  code: "Code",
1122
1124
  category: "Category",