'use strict'; /** * 作品提交模型 - WorkSubmission * * 存储选手上传的作品文件信息,包括文件类型、名称、路径等。 * 支持 plan(计划书)和 ppt(演示文稿)两种文件类型。 * 表名:work_submissions */ module.exports = app => { const { STRING, INTEGER, DATE } = app.Sequelize; const WorkSubmission = app.model.define('work_submission', { // 主键 ID,自增 id: { type: INTEGER, primaryKey: true, autoIncrement: true, comment: '作品提交唯一标识', }, // 选手 ID,外键关联 contestants 表 contestant_id: { type: INTEGER, allowNull: false, comment: '选手 ID', references: { model: 'contestants', key: 'id', }, }, // 文件类型:plan(计划书)/ ppt(演示文稿) file_type: { type: STRING(20), allowNull: false, comment: '文件类型', validate: { isIn: [['plan', 'ppt']], }, }, // 文件名(原始文件名) file_name: { type: STRING(200), allowNull: false, comment: '原始文件名', }, // 文件存储路径(服务器上的相对路径) file_path: { type: STRING(500), allowNull: false, comment: '文件存储路径', }, // 文件大小(字节) file_size: { type: INTEGER, allowNull: false, comment: '文件大小(字节)', }, // 提交时间 submit_time: { type: DATE, allowNull: false, comment: '提交时间', }, // 得分(管理员评分后更新,NULL 表示尚未评分) score: { type: INTEGER, allowNull: true, defaultValue: null, comment: '作品得分', }, // 创建时间 created_at: { type: DATE, allowNull: false, defaultValue: app.Sequelize.literal('CURRENT_TIMESTAMP'), comment: '创建时间', }, // 更新时间 updated_at: { type: DATE, allowNull: false, defaultValue: app.Sequelize.literal('CURRENT_TIMESTAMP'), comment: '更新时间', }, }, { tableName: 'work_submissions', timestamps: false, underscored: true, indexes: [ { fields: ['contestant_id'], }, { fields: ['file_type'], }, ], }); // 关联关系:一条作品提交记录属于一名选手 WorkSubmission.associate = () => { app.model.WorkSubmission.belongsTo(app.model.Contestant, { foreignKey: 'contestant_id', as: 'contestant', }); }; return WorkSubmission; };