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 ? '项目组' : '项目' }}
查看 - 编辑 - 删除