From a4c402814496cbe707a15da1ab534d7faf45a62f Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Mon, 2 Nov 2026 16:04:31 +0800 Subject: [PATCH] fix(projects): resolve runtime permissions and migration compatibility Use existing menu permissions for management actions, preserve shared list styles in teleported detail dialogs, and align project attribution column collations with the project primary key. Record isolated MySQL and browser validation while retaining the real-device acceptance gate. --- backend/tests/test_project_management.py | 5 +- .../2026-11-02-project_management.sql | 32 +++-- .../project-business-statistics/design.md | 2 +- .../project-business-statistics/tasks.md | 4 +- .../project-management/ManagementPage.vue | 12 +- .../views/project-management/RecordList.vue | 112 +++++++++--------- 6 files changed, 98 insertions(+), 69 deletions(-) diff --git a/backend/tests/test_project_management.py b/backend/tests/test_project_management.py index 007ff91d..bfd4b092 100644 --- a/backend/tests/test_project_management.py +++ b/backend/tests/test_project_management.py @@ -173,10 +173,13 @@ class ProjectManagementTest(unittest.TestCase): root = Path(__file__).resolve().parents[2] migration = (root / 'docs/sql/migrations/2026-11-02-project_management.sql').read_text() self.assertEqual(migration.count('CREATE TABLE IF NOT EXISTS'), 6) - self.assertEqual(migration.count('information_schema.columns'), 4) + self.assertEqual(migration.count('information_schema.columns'), 9) self.assertEqual(migration.count('information_schema.statistics'), 4) self.assertNotIn(' BEFORE ', migration) self.assertNotIn('JSON_TABLE', migration) + self.assertIn('INTO @project_charset, @project_collation', migration) + self.assertEqual(migration.count('ADD COLUMN project_id VARCHAR(64) CHARACTER SET'), 4) + self.assertEqual(migration.count('MODIFY COLUMN project_id VARCHAR(64) CHARACTER SET'), 4) menus = (root / 'docs/sql/migrations/2026-11-02-project_management_menu_seed.sql').read_text() self.assertEqual(menus.count('AND NOT EXISTS'), 6) self.assertEqual(menus.count("parent.perms='menu:market'"), 4) diff --git a/docs/sql/migrations/2026-11-02-project_management.sql b/docs/sql/migrations/2026-11-02-project_management.sql index 600f604a..701e0fcf 100644 --- a/docs/sql/migrations/2026-11-02-project_management.sql +++ b/docs/sql/migrations/2026-11-02-project_management.sql @@ -1,4 +1,4 @@ --- Issue #13: MySQL 5.7 增量迁移。未在真实数据库执行;先备份并在隔离副本验证。 +-- Issue #13: MySQL 5.7 增量迁移。已在隔离 MySQL 5.7 验证;上线前仍须备份并在目标副本验证。 -- DDL 隐式提交;该脚本不作为自动应用启动步骤。 CREATE TABLE IF NOT EXISTS biz_project_team ( @@ -122,10 +122,18 @@ CREATE TABLE IF NOT EXISTS biz_project_assignment_audit ( KEY ix_business (tenant_no, biz_type, biz_id, create_time) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +-- 原业务表可能使用不同的默认排序规则;关联列必须与实际项目主键一致。 +-- 同时修复已执行旧版迁移的列,不更改原表其他业务列或整库排序规则。 +SELECT character_set_name, collation_name INTO @project_charset, @project_collation +FROM information_schema.columns +WHERE table_schema=DATABASE() AND table_name='biz_project' AND column_name='id'; + SET @project_ddl = IF( (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='biz_presign_order' AND column_name='project_id')=0, - 'ALTER TABLE biz_presign_order ADD COLUMN project_id VARCHAR(64) NULL', - 'SELECT 1'); + CONCAT('ALTER TABLE biz_presign_order ADD COLUMN project_id VARCHAR(64) CHARACTER SET ', @project_charset, ' COLLATE ', @project_collation, ' NULL'), + IF((SELECT collation_name FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='biz_presign_order' AND column_name='project_id') <> @project_collation, + CONCAT('ALTER TABLE biz_presign_order MODIFY COLUMN project_id VARCHAR(64) CHARACTER SET ', @project_charset, ' COLLATE ', @project_collation, ' NULL'), + 'SELECT 1')); PREPARE project_stmt FROM @project_ddl; EXECUTE project_stmt; DEALLOCATE PREPARE project_stmt; @@ -139,8 +147,10 @@ DEALLOCATE PREPARE project_stmt; SET @project_ddl = IF( (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='biz_collection_protocol' AND column_name='project_id')=0, - 'ALTER TABLE biz_collection_protocol ADD COLUMN project_id VARCHAR(64) NULL', - 'SELECT 1'); + CONCAT('ALTER TABLE biz_collection_protocol ADD COLUMN project_id VARCHAR(64) CHARACTER SET ', @project_charset, ' COLLATE ', @project_collation, ' NULL'), + IF((SELECT collation_name FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='biz_collection_protocol' AND column_name='project_id') <> @project_collation, + CONCAT('ALTER TABLE biz_collection_protocol MODIFY COLUMN project_id VARCHAR(64) CHARACTER SET ', @project_charset, ' COLLATE ', @project_collation, ' NULL'), + 'SELECT 1')); PREPARE project_stmt FROM @project_ddl; EXECUTE project_stmt; DEALLOCATE PREPARE project_stmt; @@ -154,8 +164,10 @@ DEALLOCATE PREPARE project_stmt; SET @project_ddl = IF( (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='biz_research_donation' AND column_name='project_id')=0, - 'ALTER TABLE biz_research_donation ADD COLUMN project_id VARCHAR(64) NULL', - 'SELECT 1'); + CONCAT('ALTER TABLE biz_research_donation ADD COLUMN project_id VARCHAR(64) CHARACTER SET ', @project_charset, ' COLLATE ', @project_collation, ' NULL'), + IF((SELECT collation_name FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='biz_research_donation' AND column_name='project_id') <> @project_collation, + CONCAT('ALTER TABLE biz_research_donation MODIFY COLUMN project_id VARCHAR(64) CHARACTER SET ', @project_charset, ' COLLATE ', @project_collation, ' NULL'), + 'SELECT 1')); PREPARE project_stmt FROM @project_ddl; EXECUTE project_stmt; DEALLOCATE PREPARE project_stmt; @@ -169,8 +181,10 @@ DEALLOCATE PREPARE project_stmt; SET @project_ddl = IF( (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='biz_pilot_application' AND column_name='project_id')=0, - 'ALTER TABLE biz_pilot_application ADD COLUMN project_id VARCHAR(64) NULL', - 'SELECT 1'); + CONCAT('ALTER TABLE biz_pilot_application ADD COLUMN project_id VARCHAR(64) CHARACTER SET ', @project_charset, ' COLLATE ', @project_collation, ' NULL'), + IF((SELECT collation_name FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='biz_pilot_application' AND column_name='project_id') <> @project_collation, + CONCAT('ALTER TABLE biz_pilot_application MODIFY COLUMN project_id VARCHAR(64) CHARACTER SET ', @project_charset, ' COLLATE ', @project_collation, ' NULL'), + 'SELECT 1')); PREPARE project_stmt FROM @project_ddl; EXECUTE project_stmt; DEALLOCATE PREPARE project_stmt; diff --git a/openspec/changes/project-business-statistics/design.md b/openspec/changes/project-business-statistics/design.md index 7c376ad5..b4b9948a 100644 --- a/openspec/changes/project-business-statistics/design.md +++ b/openspec/changes/project-business-statistics/design.md @@ -47,7 +47,7 @@ project_brief(db, tenant_no, project_id) -> dict # projectId/projectName/teamId Web P01/P02/P09,参考 system/unit/index.vue、cell-storage/protocol/ProtocolFormDialog.vue,复用 panel-top/list-table/list-wrap/list-pager-bar/dialog-form-layout 等。移动复用 src/market 契约与既有选择器,保留 Token,不借任务全局换色。 -测试用隔离 SQLite 内存数据库与合成数据;不连接真实业务库,不启停 backend/web-admin。迁移为 MySQL 5.7 兼容的增量脚本,尚未实库验证前明确标记。最终服务/真机环境不可用时报告验证缺口,不标记完成合并。 +自动化测试使用隔离 SQLite 内存数据库,运行验收使用独立 MySQL 5.7 合成库;不连接或修改真实业务库。用户已明确授权本任务自行切换 backend/web-admin 服务,需保留原配置和运行来源记录。迁移验证覆盖首次新增、排序规则兼容修正及重复执行。最终服务/真机环境不可用时报告验证缺口,不标记完成合并。 ### 查询筛选与新建选择的区别 diff --git a/openspec/changes/project-business-statistics/tasks.md b/openspec/changes/project-business-statistics/tasks.md index 5170e45e..7720d7e0 100644 --- a/openspec/changes/project-business-statistics/tasks.md +++ b/openspec/changes/project-business-statistics/tasks.md @@ -21,4 +21,6 @@ 较大范围后端回归 357 通过、3 个既有失败(缺失历史迁移、运费子行软删除、旧测试 SimpleNamespace refresh);原 HEAD 已复现后两项,缺文件与仓库现状一致。 Web 类型检查基线和改动版均 413 条诊断,无新增文件/错误码组合;字段一致性检查为 5 项既有警告。以上不代表全仓测试通过。 独立源码审查已修复并复核来源链保护、并发引用检查、统计聚合、历史候选及空筛选条件,无剩余 P1/P2。 -尚未执行真实 MySQL 迁移/并发测试、待验收版本浏览器视觉检查、375/414 WebView 联动与集成环境冒烟;当前服务仍运行主目录旧版本,依工程禁令未启停。 +用户于 2026-11-02 明确授权自行切换服务,任务版本已在独立 MySQL 5.7.24 合成库运行,原业务数据库未修改。真实 HTTP/MySQL 62 项断言通过,覆盖五类主单新增、三种转换继承、四业务统计、租户/权限、并发归属冲突及审计;结构与菜单迁移重复执行通过,另验证首次 ADD 与旧迁移修正。 +浏览器已验收项目组/项目创建、Web/移动预签约关联保存、统计钻取及归属维护;375/414 宽度移动 H5 操作通过。验收中修复前端按钮权限机制、明细弹窗全局样式作用域及 MySQL 关联列排序规则。独立复审无 P1/P2。 +仍缺微信真机 WebView 联动、集成候选环境验证及合并后运行环境恢复;不能以移动浏览器模拟尺寸代替真机验收,当前不标记完成或合并。 diff --git a/web-admin/src/views/project-management/ManagementPage.vue b/web-admin/src/views/project-management/ManagementPage.vue index d7ff0764..842d3d0e 100644 --- a/web-admin/src/views/project-management/ManagementPage.vue +++ b/web-admin/src/views/project-management/ManagementPage.vue @@ -51,7 +51,7 @@ >
新增{{ isTeam ? '项目组' : '项目' }}
查看 - 编辑 - 删除