diff --git a/backend/api/internal/logic/platform/menu.go b/backend/api/internal/logic/platform/menu.go
index 7d3f25d..d8b2e8e 100644
--- a/backend/api/internal/logic/platform/menu.go
+++ b/backend/api/internal/logic/platform/menu.go
@@ -32,8 +32,10 @@ var PlatformMenus = [][]Menu{
},
{
{Identity: "staff", GroupCode: "staff", Name: "工作人员管理", Icon: "icon-user-group", Path: "/staff", SortNo: 40, Status: common.StatusEnable},
- {Identity: "staff_account", ParentIdentity: "staff", GroupCode: "staff", Name: "工作人员", Path: "/staff/staff-account", SortNo: 1, Status: common.StatusEnable},
- {Identity: "staff_credential", ParentIdentity: "staff", GroupCode: "staff", Name: "人员资质", Path: "/staff/staff-credential", SortNo: 2, Status: common.StatusEnable},
+ {Identity: "staff_add", ParentIdentity: "staff", GroupCode: "staff", Name: "新增工作人员", Path: "/staff/add", SortNo: 1, Status: common.StatusEnable},
+ {Identity: "staff_installer", ParentIdentity: "staff", GroupCode: "staff", Name: "安装人员管理", Path: "/staff/installers", SortNo: 2, Status: common.StatusEnable},
+ {Identity: "staff_delivery", ParentIdentity: "staff", GroupCode: "staff", Name: "配送人员管理", Path: "/staff/delivery", SortNo: 3, Status: common.StatusEnable},
+ {Identity: "staff_operations", ParentIdentity: "staff", GroupCode: "staff", Name: "运维人员管理", Path: "/staff/operations", SortNo: 4, Status: common.StatusEnable},
},
{
{Identity: "user", GroupCode: "user", Name: "用户管理", Icon: "icon-user", Path: "/user", SortNo: 50, Status: common.StatusEnable},
diff --git a/backend/api/internal/logic/platform/platform/access.go b/backend/api/internal/logic/platform/platform/access.go
index a6aa7ee..e8a07e1 100644
--- a/backend/api/internal/logic/platform/platform/access.go
+++ b/backend/api/internal/logic/platform/platform/access.go
@@ -36,6 +36,8 @@ func platformRouteMenuIdentity(resource string) string {
return "gas_basic"
case resource == "delivery_account":
return "delivery_basic"
+ case resource == "staff_account" || resource == "staff_credential":
+ return "staff"
case strings.HasPrefix(resource, "gasorder_contract"):
return "gasorder_contract"
case resource == "gasorder_track" || resource == "gasorder_track_point":
diff --git a/frontend/platform_admin/src/api/resources.ts b/frontend/platform_admin/src/api/resources.ts
index 421ca36..7e8d30c 100644
--- a/frontend/platform_admin/src/api/resources.ts
+++ b/frontend/platform_admin/src/api/resources.ts
@@ -285,7 +285,7 @@ export const resources: ResourceUiDefinition[] = [
define('gas_account', '气站账户', 'writable', [f('username', { required: true }), f('password', { required: true }), f('display_name'), f('role_code'), relation('gas_basic_identity', '/gas_basic', true)]),
{ ...define('delivery_basic', '配送点管理', 'writable', [f('delivery_code', { required: true }), f('name', { required: true }), relation('gas_basic_identity', '/gas_basic'), f('principal'), f('address')]), accountManagement: { resource: '/delivery_account', relationKey: 'delivery_basic_identity', title: '配送点账户' } },
define('delivery_account', '配送站账户', 'writable', [f('username', { required: true }), f('password', { required: true }), f('display_name'), f('role_code'), relation('delivery_basic_identity', '/delivery_basic', true)]),
- define('staff_account', '工作人员', 'writable', [f('username', { required: true }), f('password', { required: true }), f('name', { required: true }), f('phone'), f('avatar'), f('role_code'), relation('gas_basic_identity', '/gas_basic'), relation('delivery_basic_identity', '/delivery_basic'), f('work_status')]),
+ define('staff_account', '工作人员', 'writable', [f('username', { required: true }), f('password', { required: true }), f('name', { required: true }), f('phone'), f('avatar'), f('role_code', { required: true, type: 'select', options: [{ label: '安装人员', value: 'installer' }, { label: '配送人员', value: 'delivery' }, { label: '运维人员', value: 'operations' }] }), relation('gas_basic_identity', '/gas_basic'), relation('delivery_basic_identity', '/delivery_basic'), f('work_status', { type: 'select', options: [{ label: '在岗', value: 'on_duty' }, { label: '离岗', value: 'off_duty' }] })]),
define('staff_credential', '工作人员资质', 'writable', [relation('staff_account_identity', '/staff_account', true), f('credential_type', { required: true }), f('credential_no'), f('expired_at')]),
define('user_account', '用户账户', 'writable', [f('username', { required: true }), f('password', { required: true }), f('name', { required: true }), f('phone'), f('avatar'), f('real_name')]),
define('user_address', '用户地址', 'writable', [relation('user_account_identity', '/user_account', true), f('address', { required: true }), f('longitude'), f('latitude'), f('is_default')]),
diff --git a/frontend/platform_admin/src/router/routes/modules/platform.ts b/frontend/platform_admin/src/router/routes/modules/platform.ts
index c552d0b..db86d8e 100644
--- a/frontend/platform_admin/src/router/routes/modules/platform.ts
+++ b/frontend/platform_admin/src/router/routes/modules/platform.ts
@@ -66,8 +66,11 @@ const routes: AppRouteRecordRaw[] = [
child('organization', 'delivery-account', 'delivery-account', '配送点账户', '/delivery_account', 'delivery_basic', true, 'delivery-basic'),
]),
group('staff', 'staff', '工作人员管理', 'icon-user-group', 30, [
- child('staff', 'staff-account', 'account', '工作人员', '/staff_account', 'staff_account'),
- child('staff', 'staff-credential', 'credential', '人员资质', '/staff_credential', 'staff_credential'),
+ { ...child('staff', 'add', 'add', '新增工作人员', '/staff_account', 'staff_add'), meta: { title: '新增工作人员', resource: '/staff_account', requiresAuth: true, menuCode: 'staff_add', createMode: true } },
+ { ...child('staff', 'installers', 'installers', '安装人员管理', '/staff_account', 'staff_installer'), meta: { title: '安装人员管理', resource: '/staff_account', requiresAuth: true, menuCode: 'staff_installer', staffType: 'installer' } },
+ { ...child('staff', 'delivery', 'delivery', '配送人员管理', '/staff_account', 'staff_delivery'), meta: { title: '配送人员管理', resource: '/staff_account', requiresAuth: true, menuCode: 'staff_delivery', staffType: 'delivery' } },
+ { ...child('staff', 'operations', 'operations', '运维人员管理', '/staff_account', 'staff_operations'), meta: { title: '运维人员管理', resource: '/staff_account', requiresAuth: true, menuCode: 'staff_operations', staffType: 'operations' } },
+ child('staff', 'credential', 'credential', '人员资质', '/staff_credential', 'staff', true, 'staff-installers'),
]),
group('user', 'user', '用户管理', 'icon-user', 40, [
child('user', 'user-account', 'account', '用户账户', '/user_account', 'user_account'),
diff --git a/frontend/platform_admin/src/router/typings.d.ts b/frontend/platform_admin/src/router/typings.d.ts
index c95eed3..1f85192 100644
--- a/frontend/platform_admin/src/router/typings.d.ts
+++ b/frontend/platform_admin/src/router/typings.d.ts
@@ -4,6 +4,8 @@ declare module 'vue-router' {
interface RouteMeta {
roles?: string[]; // Controls roles that have access to the page
menuCode?: string; // Server-assigned menu domain required by this route
+ staffType?: 'installer' | 'delivery' | 'operations';
+ createMode?: boolean;
requiresAuth: boolean; // Whether login is required to access the current page (every route must declare)
icon?: string; // The icon show in the side menu
locale?: string; // The locale name show in side menu and breadcrumb
diff --git a/frontend/platform_admin/src/views/shared/CrudListPage.vue b/frontend/platform_admin/src/views/shared/CrudListPage.vue
index 1cde6a2..fc272a8 100644
--- a/frontend/platform_admin/src/views/shared/CrudListPage.vue
+++ b/frontend/platform_admin/src/views/shared/CrudListPage.vue
@@ -38,10 +38,18 @@
{{ accountCounts[String(record.identity)] ?? 0 }}
+
+
+
+ {{ Number(record.status) === 1 ? '已通过' : Number(record.status) === 2 ? '已禁用' : '待审批' }}
+
+
+
账户管理
+ 查看资质
详情
编辑
审核
@@ -175,6 +183,9 @@ const managedOwnerIdentity = computed(() =>
const managedRelationKey = computed(() =>
typeof route.query.relation_key === 'string' ? route.query.relation_key : '',
);
+const staffType = computed(() =>
+ typeof route.meta.staffType === 'string' ? route.meta.staffType : '',
+);
const platformRootWriteResources = new Set([
'platform_account',
'platform_role',
@@ -275,7 +286,20 @@ function resetForm(data?: Row) {
async function load() {
loading.value = true;
try {
- if (managedOwnerIdentity.value && managedRelationKey.value) {
+ if (staffType.value) {
+ const staff = await loadAllRows(props.definition.resource);
+ const keyword = filters.keyword.trim().toLowerCase();
+ const filtered = staff.filter(
+ (row) =>
+ String(row.role_code ?? '') === staffType.value &&
+ (!keyword ||
+ ['username', 'name', 'phone'].some((key) =>
+ String(row[key] ?? '').toLowerCase().includes(keyword),
+ )),
+ );
+ list.value = filtered.slice((page.value - 1) * pageSize, page.value * pageSize);
+ total.value = filtered.length;
+ } else if (managedOwnerIdentity.value && managedRelationKey.value) {
const accounts = await loadAllRows(props.definition.resource);
const keyword = filters.keyword.trim().toLowerCase();
const filtered = accounts.filter(
@@ -345,6 +369,16 @@ function manageAccounts(row: Row) {
});
}
+function viewCredentials(row: Row) {
+ router.push({
+ name: 'staff-credential',
+ query: {
+ owner_identity: String(row.identity ?? ''),
+ relation_key: 'staff_account_identity',
+ },
+ });
+}
+
async function syncQuery() {
const query: Record = {};
if (managedOwnerIdentity.value) query.owner_identity = managedOwnerIdentity.value;
@@ -371,6 +405,7 @@ function openCreate() {
if (managedOwnerIdentity.value && managedRelationKey.value) {
form[managedRelationKey.value] = managedOwnerIdentity.value;
}
+ if (staffType.value) form.role_code = staffType.value;
formVisible.value = true;
}
@@ -680,6 +715,7 @@ onMounted(async () => {
(role) => !role.is_system && role.status === 1,
);
}
+ if (route.meta.createMode) openCreate();
});
watch(
diff --git a/frontend/platform_admin/src/views/shared/ResourcePage.vue b/frontend/platform_admin/src/views/shared/ResourcePage.vue
index 89be553..d6d761d 100644
--- a/frontend/platform_admin/src/views/shared/ResourcePage.vue
+++ b/frontend/platform_admin/src/views/shared/ResourcePage.vue
@@ -1,12 +1,12 @@