修复:工作人员列表切换后自动加载数据
监听工作人员类型变化,切换安装、配送和运维菜单时自动重置搜索及页码并重新查询;补充资源、搜索和人员关联回归检查,同时更新中文需求说明与操作日志。
This commit is contained in:
@@ -142,6 +142,8 @@
|
|||||||
|
|
||||||
工作人员支持安装人员 `installer`、配送人员 `delivery`、运维人员 `operations` 三种角色,可关联气站或配送点,并记录在岗/离岗状态。前端按角色提供独立列表和新增入口;后端按菜单和人员实际角色校验详情、修改及资质访问。
|
工作人员支持安装人员 `installer`、配送人员 `delivery`、运维人员 `operations` 三种角色,可关联气站或配送点,并记录在岗/离岗状态。前端按角色提供独立列表和新增入口;后端按菜单和人员实际角色校验详情、修改及资质访问。
|
||||||
|
|
||||||
|
安装人员、配送人员和运维人员列表在首次进入及角色菜单相互切换时主动加载对应角色数据;切换时清空上一列表的模糊搜索条件并回到第 1 页,手动刷新入口继续保留。
|
||||||
|
|
||||||
工作人员的新建、详情和编辑均使用独立页面。账户页面顶部展示头像、用户名、唯一标识和创建时间,下方维护现有基本信息与钱包摘要;头像仅支持 JPG/PNG、本地预览和保存时上传,读取继续受平台 JWT、菜单及人员角色权限保护。工作人员列表使用现有受控头像接口懒加载 32px 圆形缩略图,无头像时显示默认头像;通用列表响应仍不得返回头像 URI。用户名和密码仅用于创建,编辑时用户名只读且密码不回填。
|
工作人员的新建、详情和编辑均使用独立页面。账户页面顶部展示头像、用户名、唯一标识和创建时间,下方维护现有基本信息与钱包摘要;头像仅支持 JPG/PNG、本地预览和保存时上传,读取继续受平台 JWT、菜单及人员角色权限保护。工作人员列表使用现有受控头像接口懒加载 32px 圆形缩略图,无头像时显示默认头像;通用列表响应仍不得返回头像 URI。用户名和密码仅用于创建,编辑时用户名只读且密码不回填。
|
||||||
|
|
||||||
### 6.3 用户管理
|
### 6.3 用户管理
|
||||||
|
|||||||
51
docs/操作日志_工作人员列表自动加载修复_20260811.md
Normal file
51
docs/操作日志_工作人员列表自动加载修复_20260811.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# 工作人员列表自动加载修复操作日志
|
||||||
|
|
||||||
|
操作时间:2026-08-11 22:34:45
|
||||||
|
操作类型:修改
|
||||||
|
影响模块:平台总后台工作人员列表
|
||||||
|
|
||||||
|
## 操作前状态
|
||||||
|
|
||||||
|
安装人员、配送人员和运维人员共用 `/staff_account` 列表资源,只通过路由中的 `staffType` 区分角色。共享列表仅监听资源路径变化;三个菜单之间切换时资源路径不变,因此在组件被复用的场景下不会主动重新查询,必须点击刷新按钮才显示已有数据。
|
||||||
|
|
||||||
|
## 具体操作
|
||||||
|
|
||||||
|
1. 将共享列表的变更监听范围从单一资源路径扩展为资源路径与工作人员类型。
|
||||||
|
2. 工作人员类型变化后,清空原列表的模糊搜索条件、回到第 1 页,并重新预加载关联项和查询当前角色数据。
|
||||||
|
3. 在资源页面静态检查中增加工作人员角色菜单切换的回归门禁。
|
||||||
|
4. 补全列表搜索状态重置条件,同时清理 URL 中遗留的关键字和页码。
|
||||||
|
5. 修正工作人员关联检查脚本的扫描位置,使其继续验证已拆分的列表查询参数同步逻辑。
|
||||||
|
6. 更新平台总后台现状基线,记录首次进入、菜单切换与手动刷新的交互规则。
|
||||||
|
|
||||||
|
## 操作后状态
|
||||||
|
|
||||||
|
首次进入安装人员、配送人员或运维人员列表时继续自动加载;三个角色菜单相互切换时也会主动查询当前角色数据,无需额外点击刷新。刷新按钮和其他标准资源列表行为保持不变。
|
||||||
|
|
||||||
|
## 代码变更
|
||||||
|
|
||||||
|
- `frontend/platform_admin/src/views/shared/CrudListPage.vue`:扩展列表变更监听条件并补充中文业务注释。
|
||||||
|
- `frontend/platform_admin/scripts/check-resource-pages.mjs`:新增角色切换自动加载静态回归检查。
|
||||||
|
- `frontend/platform_admin/scripts/check-staff-relation-policy.mjs`:修正列表查询参数同步逻辑的检查位置。
|
||||||
|
- `frontend/platform_admin/src/views/shared/use-resource-list-search.ts`:切换列表时同步清理遗留页码。
|
||||||
|
- `frontend/platform_admin/scripts/check-resource-search.mjs`:增加列表切换页码清理回归检查。
|
||||||
|
- `docs/05-平台总后台需求.md`:补充工作人员列表加载规则。
|
||||||
|
- `docs/操作日志_工作人员列表自动加载修复_20260811.md`:记录本次修复及验证情况。
|
||||||
|
|
||||||
|
## 验证结果
|
||||||
|
|
||||||
|
- `pnpm.cmd resource-pages:check`:通过,角色菜单切换自动加载回归门禁生效。
|
||||||
|
- `pnpm.cmd staff-relations:check`:通过,工作人员关联与资质上下文契约正常。
|
||||||
|
- `pnpm.cmd resource-search:check`:通过,搜索状态清理与 URL 同步规则正常。
|
||||||
|
- `pnpm.cmd type:check`:通过。
|
||||||
|
- `pnpm.cmd contract:check`:通过,共 48 个资源。
|
||||||
|
- `pnpm.cmd build`:通过,Vite 完成生产构建。
|
||||||
|
- 定向 Biome 检查:本次修改的 Vue 文件无错误;存在模板符号识别产生的既有告警。
|
||||||
|
- 全仓 `pnpm.cmd lint`:未通过,仓库基线中未修改的 Vite 配置和旧组件仍有 2 个错误、158 个告警及 12 个提示;本次未扩大范围处理。
|
||||||
|
- 浏览器手动验证:当前本机没有前端 `5173` 或后端 `12426` 服务监听,无法在现有数据环境执行点击验收。
|
||||||
|
|
||||||
|
## 风险评估
|
||||||
|
|
||||||
|
- 影响范围仅限共享列表在资源路径或工作人员类型变化时的重载逻辑。
|
||||||
|
- 同一资源的普通分页、搜索、手动刷新和记录操作接口保持兼容。
|
||||||
|
- 当前源码已有按路由名称重建列表组件的保护;新增监听属于防御性补强,可避免外层缓存或组件复用策略变化后问题复发。
|
||||||
|
- 截图环境若仍加载旧静态资源,需要部署本次生产构建并清理浏览器或代理缓存后再验收。
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* 功能:静态检查平台总后台全部标准资源是否具备独立记录页配置。
|
* 功能:静态检查平台总后台全部标准资源是否具备独立记录页配置。
|
||||||
* 版本:v1.0.0
|
* 版本:v1.1.0
|
||||||
*/
|
*/
|
||||||
import { readFileSync, existsSync } from 'node:fs';
|
import { readFileSync, existsSync } from 'node:fs';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
@@ -39,6 +39,13 @@ for (const marker of ["makeRecordRoute('create'", "makeRecordRoute('detail'", "m
|
|||||||
if (!routeBuilderSource.includes(marker)) fail(`通用路由生成器缺少 ${marker}`);
|
if (!routeBuilderSource.includes(marker)) fail(`通用路由生成器缺少 ${marker}`);
|
||||||
}
|
}
|
||||||
if (listSource.includes('<a-drawer')) fail('列表组件仍包含 CRUD Drawer');
|
if (listSource.includes('<a-drawer')) fail('列表组件仍包含 CRUD Drawer');
|
||||||
|
if (
|
||||||
|
!listSource.includes(
|
||||||
|
'[() => props.definition.resource, () => staffType.value]',
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
fail('工作人员角色菜单切换未触发列表重新加载');
|
||||||
|
}
|
||||||
if (existsSync(resolve(root, 'src/views/account/AccountProfilePage.vue'))) {
|
if (existsSync(resolve(root, 'src/views/account/AccountProfilePage.vue'))) {
|
||||||
fail('旧账户资料组件仍存在,未统一到共享记录页');
|
fail('旧账户资料组件仍存在,未统一到共享记录页');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* 功能:校验标准资源列表仅在具备真实搜索能力时显示动态中文提示。
|
* 功能:校验标准资源列表仅在具备真实搜索能力时显示动态中文提示。
|
||||||
* 版本:v1.0.0
|
* 版本:v1.1.0
|
||||||
*/
|
*/
|
||||||
import { readFileSync } from 'node:fs';
|
import { readFileSync } from 'node:fs';
|
||||||
import { dirname, resolve } from 'node:path';
|
import { dirname, resolve } from 'node:path';
|
||||||
@@ -24,6 +24,7 @@ const expectations = [
|
|||||||
[searchState, 'definition.value.searchFields', '读取后端搜索契约'],
|
[searchState, 'definition.value.searchFields', '读取后端搜索契约'],
|
||||||
[searchState, 'resourceListDisplayFields', '搜索字段与实际列表列求交集'],
|
[searchState, 'resourceListDisplayFields', '搜索字段与实际列表列求交集'],
|
||||||
[searchState, 'if (searchEnabled.value || !route.query.keyword) return;', '清理不支持页面的陈旧关键字'],
|
[searchState, 'if (searchEnabled.value || !route.query.keyword) return;', '清理不支持页面的陈旧关键字'],
|
||||||
|
[searchState, 'if (route.query.keyword || route.query.page) await syncQuery();', '切换列表时清理陈旧关键字和页码'],
|
||||||
[searchState, '`可搜索:${searchableFields.value', '明确列出可搜索中文字段'],
|
[searchState, '`可搜索:${searchableFields.value', '明确列出可搜索中文字段'],
|
||||||
[resources, 'searchFields: resourceSearchFields(name)', '资源定义消费后端搜索契约'],
|
[resources, 'searchFields: resourceSearchFields(name)', '资源定义消费后端搜索契约'],
|
||||||
[resources, "resourceSearchEnumOptions('staff_account', 'role_code')", '工作人员中文角色与搜索契约同源'],
|
[resources, "resourceSearchEnumOptions('staff_account', 'role_code')", '工作人员中文角色与搜索契约同源'],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* 功能:验证工作人员关联字段过滤、资质来源校验和路由上下文传递契约。
|
* 功能:验证工作人员关联字段过滤、资质来源校验和路由上下文传递契约。
|
||||||
* 版本:v1.0.0
|
* 版本:v1.1.0
|
||||||
*/
|
*/
|
||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import { readFile } from 'node:fs/promises';
|
import { readFile } from 'node:fs/promises';
|
||||||
@@ -117,6 +117,10 @@ const listSource = await readFile(
|
|||||||
'utf8',
|
'utf8',
|
||||||
);
|
);
|
||||||
assert.match(listSource, /staff_type: staffType\.value/);
|
assert.match(listSource, /staff_type: staffType\.value/);
|
||||||
assert.match(listSource, /'staff_type'/);
|
const listSearchSource = await readFile(
|
||||||
|
new URL('../src/views/shared/use-resource-list-search.ts', import.meta.url),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
assert.match(listSearchSource, /'staff_type'/);
|
||||||
|
|
||||||
console.log('工作人员关联与资质上下文检查通过');
|
console.log('工作人员关联与资质上下文检查通过');
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
功能:展示标准资源列表,并将新建、详情和编辑入口导航到独立页面。
|
功能:展示标准资源列表,并将新建、详情和编辑入口导航到独立页面。
|
||||||
版本:v2.2.0
|
版本:v2.2.1
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-card :title="listTitle" :bordered="false">
|
<a-card :title="listTitle" :bordered="false">
|
||||||
@@ -470,8 +470,9 @@ onMounted(async () => {
|
|||||||
});
|
});
|
||||||
onBeforeUnmount(avatarLoader.reset);
|
onBeforeUnmount(avatarLoader.reset);
|
||||||
watch(
|
watch(
|
||||||
() => props.definition.resource,
|
[() => props.definition.resource, () => staffType.value],
|
||||||
async () => {
|
async () => {
|
||||||
|
// 同一工作人员资源切换角色菜单时,复位旧查询并主动加载当前角色数据。
|
||||||
await resetSearchState();
|
await resetSearchState();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
relations.preload(displayFields.value),
|
relations.preload(displayFields.value),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* 功能描述:管理标准资源列表的可搜索字段、关键字状态和 URL 查询参数。
|
* 功能描述:管理标准资源列表的可搜索字段、关键字状态和 URL 查询参数。
|
||||||
* 版本:v1.0.0
|
* 版本:v1.0.1
|
||||||
*/
|
*/
|
||||||
import { computed, reactive, type Ref } from 'vue';
|
import { computed, reactive, type Ref } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
@@ -73,7 +73,7 @@ export function useResourceListSearch(
|
|||||||
async function resetSearchState() {
|
async function resetSearchState() {
|
||||||
page.value = 1;
|
page.value = 1;
|
||||||
filters.keyword = '';
|
filters.keyword = '';
|
||||||
if (route.query.keyword) await syncQuery();
|
if (route.query.keyword || route.query.page) await syncQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user