'use strict'; /** * 竞赛信息模型 - CompetitionInfo * * 表名:competition_info * * 🔴 2026-10-19(R176)修正:原模型声明的是三列结构 * (`competition_uid` / `competition_name` / `competition_code`), * 但**运行库实际是 key-value 结构**: * `id` / `info_key` / `info_value` / `created_at` / `updated_at`(实测 SHOW CREATE TABLE) * 模型与表不一致的后果: * ① `findOne()` 默认按模型声明选列 ⇒ `Unknown column 'competition_uid'` 直接 500; * ② `create()` 会带上 `competition_name`(allowNull:false)⇒ 必然失败。 * 旧代码之所以没暴露,是因为唯一的使用点(导入时取 competition_uid) * 包在 try/catch 里,失败后静默回落到默认值 1 —— 而 `info_key='competition_uid'` * 的值恰好也是 1,所以"看起来一直是对的"。 * * ⚠️ 因此本表**不能按列访问**,必须走 `info_key` 取值。 * 公示表要用的两个键是 `competition_item_name` / `competition_item_code`。 */ module.exports = app => { const { STRING, INTEGER, TEXT, DATE } = app.Sequelize; const CompetitionInfo = app.model.define('competition_info', { // 主键,自增(运行库真实主键是 id,不是 competition_uid) id: { type: INTEGER, primaryKey: true, autoIncrement: true, comment: '自增主键', }, // 配置键名(如 competition_name / competition_code / competition_item_name) // ⚠️ 运行库**没有**给 info_key 建唯一索引 ⇒ 写侧必须"先查再写",不能依赖 upsert info_key: { type: STRING(50), allowNull: false, comment: '配置键', }, // 配置值(统一按字符串存,数字也以文本形式落库) info_value: { type: TEXT, allowNull: true, comment: '配置值', }, created_at: { type: DATE, allowNull: true, comment: '创建时间', }, updated_at: { type: DATE, allowNull: true, comment: '更新时间', }, }, { tableName: 'competition_info', timestamps: false, underscored: true, // 索引仅作 Sequelize 元数据声明(sync 时用);⛔ 本项目的表由 SQL 手工维护, // 不要指望这里加 unique 会同步到运行库 indexes: [ { fields: ['info_key'], }, ], }); return CompetitionInfo; };