This commit is contained in:
owenchen committed 2026-10-15 16:31:09 +08:00
1 parent f6f3735ab3
commit 95b38a7e4d
34 files changed
+6166 -329

No files matched your search

@@ -9,10 +9,11 @@
* 页面只组数据与路由,列表/筛选/分页的机制全在 admin-list + useAdminList 里。
*/
import type { AdminColumn, AdminQuery, AdminRow } from "@/admin/admin-types";
import { onLoad } from "@dcloudio/uni-app";
import { useLocale } from "uview-pro";
import { computed, nextTick, reactive, ref, watch } from "vue";
import { fillCriteria, makeFilterOption } from "@/admin/admin-filter";
import { useAdminList, useAuthGuard } from "@/composables";
import { useAdminList, useAdminPickTarget, useAuthGuard } from "@/composables";
import { SecurityUserEntity } from "@/data/auto/securityUserEntity";
import { SecurityUserSearchCriteria } from "@/data/auto/securityUserSearchCriteria";
import { SearchFilterOperatorPolicy } from "@/data/custom/searchFilterOperatorPolicy";
@@ -23,6 +24,10 @@ import securityUserService from "@/service/security/securityUserService";
const { t, currentLocale } = useLocale();
const perm = usePagePermission("userEnquiry");
const pickTarget = useAdminPickTarget();
/** 选择器模式:带 channel 进来(如 actor-operation 选用户)时点行回传而非跳详情 */
const isPick = ref(false);
/** 列名 -> i18n key:抽屉标签、卡片行标签都靠它,切换语言时就地刷新而不重建条件 */
const LABEL_KEYS: Record<string, string> = {
@@ -102,6 +107,13 @@ function onSearch(): void {
}
function onRowTap(row: AdminRow): void {
if (isPick.value) {
if (pickTarget.multiple.value) {
return;
}
pickTarget.deliverOne(row);
return;
}
// 与旧页面一致:id 用 UserName,mode 决定详情页是只读还是编辑
// 不做 encodeURIComponent:见 composables/useAdminPick 的说明(H5 二次编码坑)
uni.navigateTo({
@@ -109,6 +121,14 @@ function onRowTap(row: AdminRow): void {
});
}
function onConfirm(rows: AdminRow[]): void {
if (!rows.length) {
uni.showToast({ title: t("AdminPage.pickNoneTip"), icon: "none" });
return;
}
pickTarget.deliver(rows);
}
function onCreate(): void {
uni.navigateTo({ url: `${pageUrl("userOperation")}?mode=create` });
}
@@ -145,33 +165,37 @@ watch(currentLocale, () => {
}
});
onLoad((options) => {
pickTarget.readOptions(options);
isPick.value = String(options?.channel ?? "").trim().length > 0;
});
// 取数排在登录守卫之后:admin-list 的 auto 默认 false,首屏由这里手动触发一次
let booted = false;
useAuthGuard(() => {
if (booted) {
return;
}
booted = true;
// 每次显示都重拉第一页:增/改/删后从详情返回能看到最新数据(navigateBack 不重新挂页面)
nextTick(() => listRef.value?.refresh());
});
</script>
<template>
<view class="page">
<admin-list ref="listRef" v-model:keyword="keyword" :nav-title="t('UserPage.title')" :show-nav-back="false"
<admin-list ref="listRef" v-model:keyword="keyword" :nav-title="t('UserPage.title')" :show-nav-back="isPick"
:columns="columns" :loader="state.query" :row-key="SecurityUserEntity.USER_NAME" title-key="UserLocalName"
:selectable="Boolean(perm.canDelete.value)" :filter-count="filterCount" :filter-visible="filterVisible"
:filter-items="draft" :search-token="searchToken" @search="onSearch" @open-filter="state.openFilter()"
:selectable="isPick ? pickTarget.multiple.value : Boolean(perm.canDelete.value)" :filter-count="filterCount"
:filter-visible="filterVisible" :filter-items="draft" :search-token="searchToken"
:keep-selection-on-reload="isPick" @search="onSearch" @open-filter="state.openFilter()"
@close-filter="state.closeFilter()" @apply-filter="state.applyFilter($event)"
@clear-filter="state.clearFiltersAndSearch()" @row-tap="onRowTap">
<template #toolbar-actions>
<view v-if="perm.canCreate.value" class="create-entry" @click="onCreate">
<template v-if="!isPick && perm.canCreate.value" #toolbar-actions>
<view class="create-entry" @click="onCreate">
<u-icon name="plus" size="40" />
</view>
</template>
<template #actions="{ rows }">
<u-button v-if="perm.canDelete.value" type="error" shape="circle" size="mini"
<u-button v-if="isPick" type="primary" shape="circle" size="mini" :text="t('AdminPage.pickDoneBut')"
@click="onConfirm(rows)" />
<u-button v-else-if="perm.canDelete.value" type="error" shape="circle" size="mini"
:text="t('AdminPage.deleteBut')" @click="onDelete(rows)" />
</template>
</admin-list>