From eb409398f36c4e983283919bd6f5b9a7aa9bf282 Mon Sep 17 00:00:00 2001 From: zhonghua Date: Tue, 7 Apr 2026 14:32:50 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=B7=BB=E5=8A=A0=E8=AF=84=E5=AE=A1?= =?UTF-8?q?=E8=A1=A8=E8=87=AA=E5=8A=A8=E5=88=9B=E5=BB=BA=E5=85=9C=E5=BA=95?= =?UTF-8?q?=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flyway迁移可能未执行,添加ApplicationRunner在启动时自动检测并创建评审相关5张表。 Co-Authored-By: Claude Opus 4.6 --- .../config/ReviewTablesSchemaRepair.java | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 backend-java/src/main/java/com/competition/common/config/ReviewTablesSchemaRepair.java diff --git a/backend-java/src/main/java/com/competition/common/config/ReviewTablesSchemaRepair.java b/backend-java/src/main/java/com/competition/common/config/ReviewTablesSchemaRepair.java new file mode 100644 index 0000000..a307a62 --- /dev/null +++ b/backend-java/src/main/java/com/competition/common/config/ReviewTablesSchemaRepair.java @@ -0,0 +1,157 @@ +package com.competition.common.config; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; + +/** + * 评审模块表结构自动修复: + * 启动时检测评审相关表是否存在,若不存在则自动创建。 + * 兜底策略,确保 Flyway 未执行时系统仍可正常工作。 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class ReviewTablesSchemaRepair implements ApplicationRunner { + + private final JdbcTemplate jdbcTemplate; + + @Override + public void run(ApplicationArguments args) { + createIfNotExists("t_biz_contest_judge", """ + CREATE TABLE IF NOT EXISTS t_biz_contest_judge ( + id BIGINT NOT NULL AUTO_INCREMENT, + contest_id BIGINT NOT NULL COMMENT '赛事ID', + judge_id BIGINT NOT NULL COMMENT '评委用户ID', + specialty VARCHAR(100) DEFAULT NULL COMMENT '专业领域', + weight DECIMAL(3,2) DEFAULT 1.00 COMMENT '评委权重', + description VARCHAR(500) DEFAULT NULL COMMENT '评委描述', + create_by VARCHAR(64) DEFAULT NULL, + update_by VARCHAR(64) DEFAULT NULL, + deleted TINYINT NOT NULL DEFAULT 0, + creator INT DEFAULT NULL, + modifier INT DEFAULT NULL, + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + valid_state TINYINT NOT NULL DEFAULT 1, + PRIMARY KEY (id), + INDEX idx_contest_id (contest_id), + INDEX idx_judge_id (judge_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='赛事评委表' + """); + + createIfNotExists("t_biz_contest_review_rule", """ + CREATE TABLE IF NOT EXISTS t_biz_contest_review_rule ( + id BIGINT NOT NULL AUTO_INCREMENT, + tenant_id BIGINT DEFAULT NULL COMMENT '租户ID', + rule_name VARCHAR(200) NOT NULL COMMENT '规则名称', + rule_description VARCHAR(500) DEFAULT NULL COMMENT '规则描述', + judge_count INT NOT NULL DEFAULT 3 COMMENT '评委数量', + dimensions JSON DEFAULT NULL COMMENT '评分维度', + calculation_rule VARCHAR(50) NOT NULL DEFAULT 'average' COMMENT '计算规则', + create_by VARCHAR(64) DEFAULT NULL, + update_by VARCHAR(64) DEFAULT NULL, + deleted TINYINT NOT NULL DEFAULT 0, + creator INT DEFAULT NULL, + modifier INT DEFAULT NULL, + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + valid_state TINYINT NOT NULL DEFAULT 1, + PRIMARY KEY (id), + INDEX idx_tenant_id (tenant_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='评审规则表' + """); + + createIfNotExists("t_biz_contest_work_judge_assignment", """ + CREATE TABLE IF NOT EXISTS t_biz_contest_work_judge_assignment ( + id BIGINT NOT NULL AUTO_INCREMENT, + contest_id BIGINT NOT NULL COMMENT '赛事ID', + work_id BIGINT NOT NULL COMMENT '作品ID', + judge_id BIGINT NOT NULL COMMENT '评委用户ID', + assignment_time DATETIME DEFAULT NULL COMMENT '分配时间', + status VARCHAR(20) NOT NULL DEFAULT 'assigned' COMMENT '状态', + creator INT DEFAULT NULL, + modifier INT DEFAULT NULL, + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id), + INDEX idx_contest_work (contest_id, work_id), + INDEX idx_judge_status (judge_id, status), + UNIQUE INDEX uk_contest_work_judge (contest_id, work_id, judge_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='作品评委分配表' + """); + + createIfNotExists("t_biz_contest_work_score", """ + CREATE TABLE IF NOT EXISTS t_biz_contest_work_score ( + id BIGINT NOT NULL AUTO_INCREMENT, + tenant_id BIGINT DEFAULT NULL COMMENT '租户ID', + contest_id BIGINT NOT NULL COMMENT '赛事ID', + work_id BIGINT NOT NULL COMMENT '作品ID', + assignment_id BIGINT DEFAULT NULL COMMENT '分配记录ID', + judge_id BIGINT NOT NULL COMMENT '评委用户ID', + judge_name VARCHAR(100) DEFAULT NULL COMMENT '评委姓名', + dimension_scores JSON DEFAULT NULL COMMENT '维度评分', + total_score DECIMAL(10,2) DEFAULT NULL COMMENT '总分', + comments TEXT DEFAULT NULL COMMENT '评语', + score_time DATETIME DEFAULT NULL COMMENT '评分时间', + create_by VARCHAR(64) DEFAULT NULL, + update_by VARCHAR(64) DEFAULT NULL, + deleted TINYINT NOT NULL DEFAULT 0, + creator INT DEFAULT NULL, + modifier INT DEFAULT NULL, + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + valid_state TINYINT NOT NULL DEFAULT 1, + PRIMARY KEY (id), + INDEX idx_work_id (work_id), + INDEX idx_contest_id (contest_id), + INDEX idx_judge_id (judge_id), + INDEX idx_assignment_id (assignment_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='作品评分表' + """); + + createIfNotExists("t_biz_preset_comment", """ + CREATE TABLE IF NOT EXISTS t_biz_preset_comment ( + id BIGINT NOT NULL AUTO_INCREMENT, + contest_id BIGINT DEFAULT NULL COMMENT '赛事ID', + judge_id BIGINT DEFAULT NULL COMMENT '评委ID', + content VARCHAR(1000) NOT NULL COMMENT '评语文本', + category VARCHAR(50) DEFAULT NULL COMMENT '评语分类', + score DECIMAL(10,2) DEFAULT NULL COMMENT '关联分数', + sort_order INT DEFAULT 0 COMMENT '排序', + use_count INT NOT NULL DEFAULT 0 COMMENT '使用次数', + create_by VARCHAR(64) DEFAULT NULL, + update_by VARCHAR(64) DEFAULT NULL, + deleted TINYINT NOT NULL DEFAULT 0, + creator INT DEFAULT NULL, + modifier INT DEFAULT NULL, + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + valid_state TINYINT NOT NULL DEFAULT 1, + PRIMARY KEY (id), + INDEX idx_contest_id (contest_id), + INDEX idx_judge_id (judge_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='预设评语表' + """); + } + + private void createIfNotExists(String tableName, String createSql) { + try { + Integer cnt = jdbcTemplate.queryForObject( + "SELECT COUNT(*) FROM information_schema.tables " + + "WHERE table_schema = DATABASE() AND table_name = '" + tableName + "'", + Integer.class); + + if (cnt == null || cnt == 0) { + log.warn("表 `{}` 不存在,自动创建...", tableName); + jdbcTemplate.execute(createSql); + log.info("表 `{}` 创建成功", tableName); + } + } catch (Exception e) { + log.warn("表 `{}` 创建失败:{}", tableName, e.getMessage()); + } + } +}