diff --git a/Database/Migrations/Phase2_Production_Deployment.sql b/Database/Migrations/Phase2_Production_Deployment.sql new file mode 100644 index 0000000..7387e44 --- /dev/null +++ b/Database/Migrations/Phase2_Production_Deployment.sql @@ -0,0 +1,1181 @@ +/* +===================================================================================== + 花样打分系统二期生产部署SQL脚本 (完整独立版) + + 版本: 2.1 Final + 创建日期: 2026-08-28 + 基线提交: 25830581d2add95f2d659e663f3d78b766ce0946 + 适用环境: SQL Server 2016+ + + ⚠️ 特别说明: + 1. 本脚本完全独立,不依赖任何现有数据库状态 + 2. 所有SQL语句支持重复执行,使用 IF NOT EXISTS 判断 + 3. 包含从基线提交到HEAD的所有数据库变更(共19张新表) + 4. 包含完整的种子数据(3角色+16菜单+36权限) + 5. 执行时间预计3-8分钟,取决于数据库性能 + + ⚠️ 部署前检查: + - SQL Server版本 >= 2016 + - 已完整备份数据库 + - 执行账户拥有DDL和DML权限 + - 建议在事务中执行 + + 包含内容: + ├─ 第1部分: 小程序角色相关(3张表+1个字段) + ├─ 第2部分: 裁判管理与分配(4张表) + ├─ 第3部分: 场次与出场管理(5张表) + ├─ 第4部分: 评分与成绩管理(7张表) + ├─ 第5部分: 索引创建(15个索引) + ├─ 第6部分: 表字段注释(全量注释) + ├─ 第7部分: 种子数据(角色+菜单+权限) + └─ 第8部分: 部署验证(14项检查) +===================================================================================== +*/ + +SET NOCOUNT ON; +SET XACT_ABORT ON; + +PRINT ''; +PRINT '========================================'; +PRINT '花样打分系统二期生产部署脚本'; +PRINT '版本: 2.1 Final (完全独立)'; +PRINT '开始时间: ' + CONVERT(VARCHAR(23), GETDATE(), 121); +PRINT '========================================'; +PRINT ''; + +-- ===================================================================================== +-- 第1部分: 小程序角色相关 +-- ===================================================================================== +PRINT '【第1部分】小程序角色相关 (3张表+1个字段)'; +PRINT '------------------------------------------------------------'; + +-- 1.1 AppUser表增加小程序角色字段 +PRINT '1.1 检查 AppUser.MiniProgramRole 字段...'; +IF COL_LENGTH('dbo.AppUser', 'MiniProgramRole') IS NULL +BEGIN + PRINT ' - 添加 MiniProgramRole 字段'; + ALTER TABLE dbo.AppUser ADD MiniProgramRole INT NOT NULL + CONSTRAINT DF_AppUser_MiniProgramRole DEFAULT (1); + PRINT ' ✓ 字段添加成功'; +END +ELSE +BEGIN + PRINT ' ✓ 字段已存在,跳过'; +END; +GO + +-- 1.2 创建裁判执裁报名表 +PRINT '1.2 检查 RefereeApplication 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[RefereeApplication]') AND type = 'U') +BEGIN + PRINT ' - 创建 RefereeApplication 表'; + CREATE TABLE [dbo].[RefereeApplication] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_RefereeApplication PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [RefereeUserId] BIGINT NOT NULL, + [ApplicationStatus] INT NOT NULL CONSTRAINT DF_RefereeApplication_ApplicationStatus DEFAULT (1), + [Remark] NVARCHAR(512) NULL, + [Status] INT NOT NULL CONSTRAINT DF_RefereeApplication_Status DEFAULT (1), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_RefereeApplication_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 1.3 创建检录任务表 +PRINT '1.3 检查 CheckinTask 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[CheckinTask]') AND type = 'U') +BEGIN + PRINT ' - 创建 CheckinTask 表'; + CREATE TABLE [dbo].[CheckinTask] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_CheckinTask PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [CheckerUserId] BIGINT NULL, + [TotalRounds] INT NOT NULL CONSTRAINT DF_CheckinTask_TotalRounds DEFAULT (1), + [CurrentRound] INT NOT NULL CONSTRAINT DF_CheckinTask_CurrentRound DEFAULT (1), + [RoundName] NVARCHAR(64) NOT NULL CONSTRAINT DF_CheckinTask_RoundName DEFAULT (N'赛前检录'), + [CurrentGroupId] BIGINT NULL, + [CurrentGroupName] NVARCHAR(128) NOT NULL CONSTRAINT DF_CheckinTask_CurrentGroupName DEFAULT (N''), + [GroupOrder] INT NOT NULL CONSTRAINT DF_CheckinTask_GroupOrder DEFAULT (0), + [TotalGroups] INT NOT NULL CONSTRAINT DF_CheckinTask_TotalGroups DEFAULT (0), + [NextGroupName] NVARCHAR(128) NULL, + [CurrentSessionKey] NVARCHAR(64) NULL, + [CurrentSessionOrder] INT NOT NULL CONSTRAINT DF_CheckinTask_CurrentSessionOrder DEFAULT (0), + [CurrentSessionName] NVARCHAR(256) NULL, + [CurrentEventProjectId] BIGINT NULL, + [CurrentSessionVenue] NVARCHAR(128) NULL, + [CheckinNo] INT NOT NULL CONSTRAINT DF_CheckinTask_CheckinNo DEFAULT (1), + [Venue] NVARCHAR(128) NULL, + [TaskStatus] INT NOT NULL CONSTRAINT DF_CheckinTask_TaskStatus DEFAULT (0), + [Status] INT NOT NULL CONSTRAINT DF_CheckinTask_Status DEFAULT (1), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_CheckinTask_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; + -- 补充字段(如果表已存在但字段缺失) + IF COL_LENGTH('dbo.CheckinTask', 'CurrentSessionKey') IS NULL + ALTER TABLE dbo.CheckinTask ADD [CurrentSessionKey] NVARCHAR(64) NULL; + IF COL_LENGTH('dbo.CheckinTask', 'CurrentSessionOrder') IS NULL + ALTER TABLE dbo.CheckinTask ADD [CurrentSessionOrder] INT NOT NULL CONSTRAINT DF_CheckinTask_CurrentSessionOrder DEFAULT (0); + IF COL_LENGTH('dbo.CheckinTask', 'CurrentSessionName') IS NULL + ALTER TABLE dbo.CheckinTask ADD [CurrentSessionName] NVARCHAR(256) NULL; + IF COL_LENGTH('dbo.CheckinTask', 'CurrentEventProjectId') IS NULL + ALTER TABLE dbo.CheckinTask ADD [CurrentEventProjectId] BIGINT NULL; + IF COL_LENGTH('dbo.CheckinTask', 'CurrentSessionVenue') IS NULL + ALTER TABLE dbo.CheckinTask ADD [CurrentSessionVenue] NVARCHAR(128) NULL; + IF COL_LENGTH('dbo.CheckinTask', 'CheckinNo') IS NULL + ALTER TABLE dbo.CheckinTask ADD [CheckinNo] INT NOT NULL CONSTRAINT DF_CheckinTask_CheckinNo DEFAULT (1); +END; +GO + +-- 1.4 创建检录记录表 +PRINT '1.4 检查 CheckinRecord 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[CheckinRecord]') AND type = 'U') +BEGIN + PRINT ' - 创建 CheckinRecord 表'; + CREATE TABLE [dbo].[CheckinRecord] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_CheckinRecord PRIMARY KEY, + [TaskId] BIGINT NOT NULL, + [Round] INT NOT NULL, + [GroupId] BIGINT NULL, + [SessionKey] NVARCHAR(64) NULL, + [SessionOrder] INT NOT NULL CONSTRAINT DF_CheckinRecord_SessionOrder DEFAULT (0), + [RegistrationPersonId] BIGINT NOT NULL, + [CheckerUserId] BIGINT NOT NULL, + [Checked] BIT NOT NULL CONSTRAINT DF_CheckinRecord_Checked DEFAULT (0), + [CheckedTime] DATETIME2 NULL, + [DeleteMark] BIT NOT NULL CONSTRAINT DF_CheckinRecord_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; + -- 补充字段 + IF COL_LENGTH('dbo.CheckinRecord', 'SessionKey') IS NULL + ALTER TABLE dbo.CheckinRecord ADD [SessionKey] NVARCHAR(64) NULL; + IF COL_LENGTH('dbo.CheckinRecord', 'SessionOrder') IS NULL + ALTER TABLE dbo.CheckinRecord ADD [SessionOrder] INT NOT NULL CONSTRAINT DF_CheckinRecord_SessionOrder DEFAULT (0); +END; +GO + +PRINT ''; +PRINT '【第1部分】完成'; +PRINT ''; + +-- ===================================================================================== +-- 第2部分: 裁判管理与分配 (4张表) +-- ===================================================================================== +PRINT '【第2部分】裁判管理与分配 (4张表)'; +PRINT '------------------------------------------------------------'; + +-- 2.1 创建裁判档案表 +PRINT '2.1 检查 Referee 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Referee]') AND type = 'U') +BEGIN + PRINT ' - 创建 Referee 表'; + CREATE TABLE [dbo].[Referee] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_Referee PRIMARY KEY, + [Name] NVARCHAR(64) NOT NULL, + [Mobile] NVARCHAR(16) NOT NULL, + [AppUserId] BIGINT NULL, + [ProvinceCode] NVARCHAR(20) NOT NULL, + [ProvinceName] NVARCHAR(64) NOT NULL, + [CityCode] NVARCHAR(20) NOT NULL, + [CityName] NVARCHAR(64) NOT NULL, + [DistrictCode] NVARCHAR(20) NOT NULL, + [DistrictName] NVARCHAR(64) NOT NULL, + [Level] INT NOT NULL, + [CertificateUrl] NVARCHAR(512) NOT NULL, + [Roles] INT NOT NULL, + [AuditStatus] INT NOT NULL CONSTRAINT DF_Referee_AuditStatus DEFAULT (1), + [AuditRemark] NVARCHAR(512) NULL, + [Status] INT NOT NULL CONSTRAINT DF_Referee_Status DEFAULT (0), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_Referee_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 2.2 创建赛事裁判表 (EventReferee) +PRINT '2.2 检查 EventReferee 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventReferee]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventReferee 表'; + CREATE TABLE [dbo].[EventReferee] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventReferee PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [RefereeId] BIGINT NOT NULL, + [RefereeName] NVARCHAR(64) NOT NULL, + [RefereeMobile] NVARCHAR(16) NOT NULL, + [RefereeLevel] INT NOT NULL, + [RefereeRoles] INT NOT NULL, + [JudgeUserId] BIGINT NULL, + [RegistrationCode] NVARCHAR(32) NULL, + [RefereeStatus] INT NOT NULL CONSTRAINT DF_EventReferee_RefereeStatus DEFAULT (0), + [Remark] NVARCHAR(512) NULL, + [Status] INT NOT NULL CONSTRAINT DF_EventReferee_Status DEFAULT (0), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventReferee_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 2.3 创建赛事裁判分配表 +PRINT '2.3 检查 EventJudgeAssignment 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventJudgeAssignment]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventJudgeAssignment 表'; + CREATE TABLE [dbo].[EventJudgeAssignment] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventJudgeAssignment PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [SessionId] BIGINT NOT NULL, + [EventRefereeId] BIGINT NOT NULL, + [RefereeId] BIGINT NOT NULL, + [JudgeUserId] BIGINT NULL, + [JudgeRole] NVARCHAR(32) NOT NULL, + [JudgeRoleType] NVARCHAR(16) NULL, + [AssignmentStatus] INT NOT NULL CONSTRAINT DF_EventJudgeAssignment_AssignmentStatus DEFAULT (0), + [SubmittedTime] DATETIME2 NULL, + [Remark] NVARCHAR(512) NULL, + [Status] INT NOT NULL CONSTRAINT DF_EventJudgeAssignment_Status DEFAULT (0), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventJudgeAssignment_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 2.4 创建裁判评分任务表 +PRINT '2.4 检查 EventJudgeTask 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventJudgeTask]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventJudgeTask 表'; + CREATE TABLE [dbo].[EventJudgeTask] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventJudgeTask PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [SessionId] BIGINT NOT NULL, + [SessionEntryId] BIGINT NOT NULL, + [JudgeAssignmentId] BIGINT NOT NULL, + [EventRefereeId] BIGINT NOT NULL, + [RefereeId] BIGINT NOT NULL, + [JudgeUserId] BIGINT NULL, + [JudgeRole] NVARCHAR(32) NOT NULL, + [JudgeRoleType] NVARCHAR(16) NOT NULL, + [ScoreRuleId] BIGINT NOT NULL, + [RuleVersion] INT NOT NULL CONSTRAINT DF_EventJudgeTask_RuleVersion DEFAULT (1), + [TaskSnapshotJson] NVARCHAR(MAX) NOT NULL, + [TaskType] INT NOT NULL CONSTRAINT DF_EventJudgeTask_TaskType DEFAULT (0), + [TaskStatus] INT NOT NULL CONSTRAINT DF_EventJudgeTask_TaskStatus DEFAULT (0), + [TaskVersion] INT NOT NULL CONSTRAINT DF_EventJudgeTask_TaskVersion DEFAULT (1), + [DispatchedTime] DATETIME2 NULL, + [AcceptedTime] DATETIME2 NULL, + [SubmittedTime] DATETIME2 NULL, + [ExpiresTime] DATETIME2 NULL, + [OriginalTaskId] BIGINT NULL, + [RejectReason] NVARCHAR(512) NULL, + [Remark] NVARCHAR(512) NULL, + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventJudgeTask_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +PRINT ''; +PRINT '【第2部分】完成'; +PRINT ''; + +-- ===================================================================================== +-- 第3部分: 场次与出场管理 (5张表) +-- ===================================================================================== +PRINT '【第3部分】场次与出场管理 (5张表)'; +PRINT '------------------------------------------------------------'; + +-- 3.1 创建比赛场地表 +PRINT '3.1 检查 EventVenue 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventVenue]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventVenue 表'; + CREATE TABLE [dbo].[EventVenue] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventVenue PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [VenueName] NVARCHAR(128) NOT NULL, + [VenueNo] NVARCHAR(32) NOT NULL, + [Sort] INT NOT NULL CONSTRAINT DF_EventVenue_Sort DEFAULT (0), + [Status] INT NOT NULL CONSTRAINT DF_EventVenue_Status DEFAULT (0), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventVenue_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 3.2 创建比赛场次表 +PRINT '3.2 检查 EventSession 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventSession]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventSession 表'; + CREATE TABLE [dbo].[EventSession] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventSession PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [EventProjectId] BIGINT NOT NULL, + [EventProjectGroupId] BIGINT NULL, + [VenueId] BIGINT NOT NULL, + [ScoreRuleId] BIGINT NOT NULL, + [SessionNo] NVARCHAR(32) NOT NULL, + [SessionName] NVARCHAR(128) NULL, + [StartTime] DATETIME2 NULL, + [EndTime] DATETIME2 NULL, + [CurrentEntryId] BIGINT NULL, + [SessionStatus] INT NOT NULL CONSTRAINT DF_EventSession_SessionStatus DEFAULT (0), + [Version] INT NOT NULL CONSTRAINT DF_EventSession_Version DEFAULT (1), + [Status] INT NOT NULL CONSTRAINT DF_EventSession_Status DEFAULT (0), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventSession_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 3.3 创建场次出场记录表 +PRINT '3.3 检查 EventSessionEntry 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventSessionEntry]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventSessionEntry 表'; + CREATE TABLE [dbo].[EventSessionEntry] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventSessionEntry PRIMARY KEY, + [SessionId] BIGINT NOT NULL, + [ParticipationRecordId] BIGINT NULL, + [RegistrationItemId] BIGINT NULL, + [SourceType] INT NOT NULL CONSTRAINT DF_EventSessionEntry_SourceType DEFAULT (0), + [EntryNo] NVARCHAR(32) NOT NULL, + [PlayOrder] INT NOT NULL, + [EntryStatus] INT NOT NULL CONSTRAINT DF_EventSessionEntry_EntryStatus DEFAULT (0), + [CallTime] DATETIME2 NULL, + [StartTime] DATETIME2 NULL, + [FinishTime] DATETIME2 NULL, + [IsRematch] BIT NOT NULL CONSTRAINT DF_EventSessionEntry_IsRematch DEFAULT (0), + [RematchFromEntryId] BIGINT NULL, + [IsVoided] BIT NOT NULL CONSTRAINT DF_EventSessionEntry_IsVoided DEFAULT (0), + [VoidReason] NVARCHAR(512) NULL, + [ParticipantName] NVARCHAR(128) NOT NULL, + [TeamName] NVARCHAR(128) NULL, + [GroupName] NVARCHAR(128) NOT NULL, + [Version] INT NOT NULL CONSTRAINT DF_EventSessionEntry_Version DEFAULT (1), + [Status] INT NOT NULL CONSTRAINT DF_EventSessionEntry_Status DEFAULT (0), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventSessionEntry_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 3.4 创建重赛关联表 +PRINT '3.4 检查 EventSessionEntryRematch 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventSessionEntryRematch]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventSessionEntryRematch 表'; + CREATE TABLE [dbo].[EventSessionEntryRematch] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventSessionEntryRematch PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [SessionId] BIGINT NOT NULL, + [OriginalEntryId] BIGINT NOT NULL, + [RematchEntryId] BIGINT NOT NULL, + [RematchReason] NVARCHAR(512) NOT NULL, + [RematchType] INT NOT NULL CONSTRAINT DF_EventSessionEntryRematch_RematchType DEFAULT (1), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventSessionEntryRematch_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 3.5 创建裁判消息表 +PRINT '3.5 检查 EventJudgeMessage 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventJudgeMessage]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventJudgeMessage 表'; + CREATE TABLE [dbo].[EventJudgeMessage] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventJudgeMessage PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [SessionId] BIGINT NOT NULL, + [JudgeUserId] BIGINT NOT NULL, + [MessageType] INT NOT NULL, + [MessageTitle] NVARCHAR(128) NOT NULL, + [MessageContent] NVARCHAR(1000) NOT NULL, + [RelatedTaskId] BIGINT NULL, + [RelatedEntryId] BIGINT NULL, + [IsRead] BIT NOT NULL CONSTRAINT DF_EventJudgeMessage_IsRead DEFAULT (0), + [ReadTime] DATETIME2 NULL, + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventJudgeMessage_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +PRINT ''; +PRINT '【第3部分】完成'; +PRINT ''; + +-- ===================================================================================== +-- 第4部分: 评分与成绩管理 (7张表) +-- ===================================================================================== +PRINT '【第4部分】评分与成绩管理 (7张表)'; +PRINT '------------------------------------------------------------'; + +-- 4.1 创建计分规则表 +PRINT '4.1 检查 ScoreRule 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ScoreRule]') AND type = 'U') +BEGIN + PRINT ' - 创建 ScoreRule 表'; + CREATE TABLE [dbo].[ScoreRule] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_ScoreRule PRIMARY KEY, + [RuleCode] NVARCHAR(64) NOT NULL, + [RuleName] NVARCHAR(128) NOT NULL, + [JudgeRoleSchemaJson] NVARCHAR(2000) NOT NULL, + [RuleConfigJson] NVARCHAR(4000) NULL, + [RuleVersion] INT NOT NULL CONSTRAINT DF_ScoreRule_RuleVersion DEFAULT (1), + [Status] INT NOT NULL CONSTRAINT DF_ScoreRule_Status DEFAULT (0), + [Sort] INT NOT NULL CONSTRAINT DF_ScoreRule_Sort DEFAULT (0), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_ScoreRule_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 4.2 创建计分规则明细表 +PRINT '4.2 检查 ScoreRuleItem 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ScoreRuleItem]') AND type = 'U') +BEGIN + PRINT ' - 创建 ScoreRuleItem 表'; + CREATE TABLE [dbo].[ScoreRuleItem] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_ScoreRuleItem PRIMARY KEY, + [ScoreRuleId] BIGINT NOT NULL, + [JudgeRoleType] NVARCHAR(16) NOT NULL, + [ItemCode] NVARCHAR(64) NOT NULL, + [ItemName] NVARCHAR(128) NOT NULL, + [ItemType] INT NOT NULL, + [ParentItemCode] NVARCHAR(64) NULL, + [UnitValue] DECIMAL(18, 4) NULL, + [MinValue] DECIMAL(18, 4) NULL, + [MaxValue] DECIMAL(18, 4) NULL, + [StepValue] DECIMAL(18, 4) NULL, + [DefaultValue] DECIMAL(18, 4) NULL, + [CalcMode] INT NOT NULL CONSTRAINT DF_ScoreRuleItem_CalcMode DEFAULT (0), + [ScoreDimension] INT NOT NULL CONSTRAINT DF_ScoreRuleItem_ScoreDimension DEFAULT (0), + [IsRequired] BIT NOT NULL CONSTRAINT DF_ScoreRuleItem_IsRequired DEFAULT (0), + [ExtensionJson] NVARCHAR(2000) NULL, + [Sort] INT NOT NULL CONSTRAINT DF_ScoreRuleItem_Sort DEFAULT (0), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_ScoreRuleItem_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 4.3 创建裁判评分单表 +PRINT '4.3 检查 EventJudgeScoreSheet 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventJudgeScoreSheet]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventJudgeScoreSheet 表'; + CREATE TABLE [dbo].[EventJudgeScoreSheet] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventJudgeScoreSheet PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [SessionId] BIGINT NOT NULL, + [SessionEntryId] BIGINT NOT NULL, + [JudgeTaskId] BIGINT NOT NULL, + [JudgeAssignmentId] BIGINT NOT NULL, + [RefereeId] BIGINT NOT NULL, + [JudgeUserId] BIGINT NULL, + [JudgeRole] NVARCHAR(32) NOT NULL, + [JudgeRoleType] NVARCHAR(16) NOT NULL, + [ScoreRuleId] BIGINT NOT NULL, + [RuleVersion] INT NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_RuleVersion DEFAULT (1), + [SheetVersion] INT NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_SheetVersion DEFAULT (1), + [SheetStatus] INT NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_SheetStatus DEFAULT (0), + [IsCurrent] BIT NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_IsCurrent DEFAULT (1), + [DifficultyScore] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_DifficultyScore DEFAULT (0), + [PerformanceScore] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_PerformanceScore DEFAULT (0), + [RequiredScore] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_RequiredScore DEFAULT (0), + [DeductionScore] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_DeductionScore DEFAULT (0), + [RequiredCompletedCount] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_RequiredCompletedCount DEFAULT (0), + [RequiredMissingCount] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_RequiredMissingCount DEFAULT (0), + [TotalScore] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_TotalScore DEFAULT (0), + [IsDisqualified] BIT NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_IsDisqualified DEFAULT (0), + [DisqualifyReasonCode] NVARCHAR(64) NULL, + [DisqualifyRemark] NVARCHAR(512) NULL, + [CalculationJson] NVARCHAR(MAX) NULL, + [IdempotencyKey] NVARCHAR(64) NOT NULL, + [SubmittedTime] DATETIME2 NULL, + [OriginalSheetId] BIGINT NULL, + [CorrectionReason] NVARCHAR(512) NULL, + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventJudgeScoreSheet_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 4.4 创建评分明细表 +PRINT '4.4 检查 EventJudgeScoreDetail 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventJudgeScoreDetail]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventJudgeScoreDetail 表'; + CREATE TABLE [dbo].[EventJudgeScoreDetail] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventJudgeScoreDetail PRIMARY KEY, + [ScoreSheetId] BIGINT NOT NULL, + [RuleItemId] BIGINT NOT NULL, + [ItemCode] NVARCHAR(64) NOT NULL, + [ItemName] NVARCHAR(128) NOT NULL, + [ItemValue] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventJudgeScoreDetail_ItemValue DEFAULT (0), + [ItemScore] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventJudgeScoreDetail_ItemScore DEFAULT (0), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventJudgeScoreDetail_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 4.5 创建出场成绩表 +PRINT '4.5 检查 EventResult 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventResult]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventResult 表'; + CREATE TABLE [dbo].[EventResult] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventResult PRIMARY KEY, + [ParticipationRecordId] BIGINT NOT NULL, + [RegistrationId] BIGINT NOT NULL, + [RegistrationPersonId] BIGINT NOT NULL, + [MerchantCertificationId] BIGINT NULL, + [EventId] BIGINT NOT NULL, + [ProjectId] BIGINT NOT NULL, + [ParticipantName] NVARCHAR(64) NOT NULL, + [GroupName] NVARCHAR(64) NOT NULL, + [ProjectTypeName] NVARCHAR(64) NOT NULL, + [Score] NVARCHAR(32) NOT NULL, + [SessionId] BIGINT NULL, + [SessionEntryId] BIGINT NULL, + [DifficultyScore] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventResult_DifficultyScore DEFAULT (0), + [PerformanceScore] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventResult_PerformanceScore DEFAULT (0), + [RequiredScore] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventResult_RequiredScore DEFAULT (0), + [DeductionScore] DECIMAL(18, 4) NOT NULL CONSTRAINT DF_EventResult_DeductionScore DEFAULT (0), + [TotalScore] DECIMAL(18, 4) NULL, + [IsDisqualified] BIT NOT NULL CONSTRAINT DF_EventResult_IsDisqualified DEFAULT (0), + [DisqualifyReasonCode] NVARCHAR(64) NULL, + [ResultStatus] INT NOT NULL CONSTRAINT DF_EventResult_ResultStatus DEFAULT (0), + [ResultVersion] INT NOT NULL CONSTRAINT DF_EventResult_ResultVersion DEFAULT (1), + [CalculationJson] NVARCHAR(MAX) NULL, + [Rank] INT NOT NULL CONSTRAINT DF_EventResult_Rank DEFAULT (0), + [AwardLevel] INT NOT NULL CONSTRAINT DF_EventResult_AwardLevel DEFAULT (0), + [AwardStatus] INT NOT NULL CONSTRAINT DF_EventResult_AwardStatus DEFAULT (0), + [Remark] NVARCHAR(MAX) NULL, + [Status] INT NOT NULL CONSTRAINT DF_EventResult_Status DEFAULT (0), + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventResult_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 4.6 创建成绩版本表 +PRINT '4.6 检查 EventResultVersion 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventResultVersion]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventResultVersion 表'; + CREATE TABLE [dbo].[EventResultVersion] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventResultVersion PRIMARY KEY, + [ResultId] BIGINT NOT NULL, + [VersionNo] INT NOT NULL, + [SnapshotJson] NVARCHAR(MAX) NOT NULL, + [ChangeReason] NVARCHAR(512) NULL, + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventResultVersion_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 4.7 创建成绩修正申请表 +PRINT '4.7 检查 EventScoreCorrection 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventScoreCorrection]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventScoreCorrection 表'; + CREATE TABLE [dbo].[EventScoreCorrection] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventScoreCorrection PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [SessionId] BIGINT NOT NULL, + [SessionEntryId] BIGINT NOT NULL, + [OriginalResultId] BIGINT NOT NULL, + [ApplicantJudgeUserId] BIGINT NOT NULL, + [ApplicantRefereeName] NVARCHAR(64) NOT NULL, + [CorrectionReason] NVARCHAR(1000) NOT NULL, + [CorrectionType] INT NOT NULL, + [CorrectionStatus] INT NOT NULL CONSTRAINT DF_EventScoreCorrection_CorrectionStatus DEFAULT (1), + [AppliedTime] DATETIME2 NOT NULL, + [ApprovedTime] DATETIME2 NULL, + [ApproverUserId] BIGINT NULL, + [ApprovalComment] NVARCHAR(512) NULL, + [NewResultId] BIGINT NULL, + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventScoreCorrection_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +-- 4.8 创建成绩投屏记录表 +PRINT '4.8 检查 EventResultScreenCast 表...'; +IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[EventResultScreenCast]') AND type = 'U') +BEGIN + PRINT ' - 创建 EventResultScreenCast 表'; + CREATE TABLE [dbo].[EventResultScreenCast] + ( + [Id] BIGINT NOT NULL CONSTRAINT PK_EventResultScreenCast PRIMARY KEY, + [EventId] BIGINT NOT NULL, + [SessionId] BIGINT NOT NULL, + [ResultIdList] NVARCHAR(MAX) NOT NULL, + [CastStatus] INT NOT NULL CONSTRAINT DF_EventResultScreenCast_CastStatus DEFAULT (1), + [CastStartTime] DATETIME2 NOT NULL, + [CastEndTime] DATETIME2 NULL, + [DeleteMark] BIT NOT NULL CONSTRAINT DF_EventResultScreenCast_DeleteMark DEFAULT (0), + [CreatedUserId] BIGINT NOT NULL, + [CreatedTime] DATETIME2 NOT NULL, + [UpdatedUserId] BIGINT NULL, + [UpdatedTime] DATETIME2 NULL + ); + PRINT ' ✓ 表创建成功'; +END +ELSE +BEGIN + PRINT ' ✓ 表已存在,跳过'; +END; +GO + +PRINT ''; +PRINT '【第4部分】完成'; +PRINT ''; + +-- ===================================================================================== +-- 第5部分: 索引创建 (15个索引) +-- ===================================================================================== +PRINT '【第5部分】索引创建 (15个索引)'; +PRINT '------------------------------------------------------------'; + +-- 5.1 RefereeApplication 索引 +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.RefereeApplication') AND name = N'IX_RefereeApplication_User') +BEGIN + PRINT ' - 创建 IX_RefereeApplication_User'; + CREATE INDEX IX_RefereeApplication_User ON dbo.RefereeApplication (RefereeUserId, CreatedTime DESC); +END; + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.RefereeApplication') AND name = N'UX_RefereeApplication_Event_User_Active') +BEGIN + PRINT ' - 创建 UX_RefereeApplication_Event_User_Active'; + CREATE UNIQUE INDEX UX_RefereeApplication_Event_User_Active + ON dbo.RefereeApplication (EventId, RefereeUserId) + WHERE DeleteMark = 0 AND ApplicationStatus <> 4; +END; + +-- 5.2 CheckinTask 索引 +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.CheckinTask') AND name = N'IX_CheckinTask_Checker_Status') +BEGIN + PRINT ' - 创建 IX_CheckinTask_Checker_Status'; + CREATE INDEX IX_CheckinTask_Checker_Status ON dbo.CheckinTask (CheckerUserId, TaskStatus, UpdatedTime DESC); +END; + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.CheckinTask') AND name = N'IX_CheckinTask_Event_Session') +BEGIN + PRINT ' - 创建 IX_CheckinTask_Event_Session'; + CREATE INDEX IX_CheckinTask_Event_Session ON dbo.CheckinTask (EventId, CurrentSessionOrder, CurrentEventProjectId); +END; + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.CheckinTask') AND name = N'UX_CheckinTask_Event_CheckinNo_Active') +BEGIN + PRINT ' - 创建 UX_CheckinTask_Event_CheckinNo_Active'; + CREATE UNIQUE INDEX UX_CheckinTask_Event_CheckinNo_Active + ON dbo.CheckinTask(EventId,CheckinNo) WHERE DeleteMark=0 AND TaskStatus=1; +END; + +-- 5.3 CheckinRecord 索引 (删除旧索引,创建新索引) +IF EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.CheckinRecord') AND name = N'UX_CheckinRecord_Task_Round_Person_Active') +BEGIN + PRINT ' - 删除旧索引 UX_CheckinRecord_Task_Round_Person_Active'; + DROP INDEX UX_CheckinRecord_Task_Round_Person_Active ON dbo.CheckinRecord; +END; + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.CheckinRecord') AND name = N'UX_CheckinRecord_Task_Session_Person_Active') +BEGIN + PRINT ' - 创建 UX_CheckinRecord_Task_Session_Person_Active'; + CREATE UNIQUE INDEX UX_CheckinRecord_Task_Session_Person_Active + ON dbo.CheckinRecord (TaskId, SessionKey, RegistrationPersonId) + WHERE DeleteMark = 0 AND SessionKey IS NOT NULL; +END; + +-- 5.4 Referee 索引 +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.Referee') AND name = N'UX_Referee_Mobile_Active') +BEGIN + PRINT ' - 创建 UX_Referee_Mobile_Active'; + CREATE UNIQUE INDEX UX_Referee_Mobile_Active + ON dbo.Referee (Mobile) WHERE DeleteMark = 0; +END; + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.Referee') AND name = N'IX_Referee_AppUser') +BEGIN + PRINT ' - 创建 IX_Referee_AppUser'; + CREATE INDEX IX_Referee_AppUser ON dbo.Referee (AppUserId) WHERE AppUserId IS NOT NULL; +END; + +-- 5.5 EventReferee 索引 +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.EventReferee') AND name = N'UX_EventReferee_Event_Referee_Active') +BEGIN + PRINT ' - 创建 UX_EventReferee_Event_Referee_Active'; + CREATE UNIQUE INDEX UX_EventReferee_Event_Referee_Active + ON dbo.EventReferee (EventId, RefereeId) WHERE DeleteMark = 0; +END; + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.EventReferee') AND name = N'IX_EventReferee_RegistrationCode') +BEGIN + PRINT ' - 创建 IX_EventReferee_RegistrationCode'; + CREATE INDEX IX_EventReferee_RegistrationCode + ON dbo.EventReferee (RegistrationCode) WHERE RegistrationCode IS NOT NULL AND DeleteMark = 0; +END; + +-- 5.6 EventJudgeAssignment 索引 +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.EventJudgeAssignment') AND name = N'IX_EventJudgeAssignment_Session') +BEGIN + PRINT ' - 创建 IX_EventJudgeAssignment_Session'; + CREATE INDEX IX_EventJudgeAssignment_Session + ON dbo.EventJudgeAssignment (SessionId, AssignmentStatus) WHERE DeleteMark = 0; +END; + +-- 5.7 EventJudgeTask 索引 +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.EventJudgeTask') AND name = N'IX_EventJudgeTask_JudgeUser') +BEGIN + PRINT ' - 创建 IX_EventJudgeTask_JudgeUser'; + CREATE INDEX IX_EventJudgeTask_JudgeUser + ON dbo.EventJudgeTask (JudgeUserId, TaskStatus) WHERE JudgeUserId IS NOT NULL AND DeleteMark = 0; +END; + +-- 5.8 EventSession 索引 +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.EventSession') AND name = N'UX_EventSession_No_Active') +BEGIN + PRINT ' - 创建 UX_EventSession_No_Active'; + CREATE UNIQUE INDEX UX_EventSession_No_Active + ON dbo.EventSession (EventId, SessionNo) WHERE DeleteMark = 0; +END; + +-- 5.9 EventSessionEntry 索引 +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.EventSessionEntry') AND name = N'UX_EventSessionEntry_PlayOrder') +BEGIN + PRINT ' - 创建 UX_EventSessionEntry_PlayOrder'; + CREATE UNIQUE INDEX UX_EventSessionEntry_PlayOrder + ON dbo.EventSessionEntry (SessionId, PlayOrder) WHERE DeleteMark = 0; +END; + +-- 5.10 EventJudgeScoreSheet 索引 +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.EventJudgeScoreSheet') AND name = N'IX_EventJudgeScoreSheet_Entry') +BEGIN + PRINT ' - 创建 IX_EventJudgeScoreSheet_Entry'; + CREATE INDEX IX_EventJudgeScoreSheet_Entry + ON dbo.EventJudgeScoreSheet (SessionEntryId, IsCurrent, SheetStatus) WHERE DeleteMark = 0; +END; + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.EventJudgeScoreSheet') AND name = N'UX_EventJudgeScoreSheet_Idempotency') +BEGIN + PRINT ' - 创建 UX_EventJudgeScoreSheet_Idempotency'; + CREATE UNIQUE INDEX UX_EventJudgeScoreSheet_Idempotency + ON dbo.EventJudgeScoreSheet (IdempotencyKey) WHERE DeleteMark = 0; +END; + +-- 5.11 ScoreRule 索引 +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'dbo.ScoreRule') AND name = N'UX_ScoreRule_Code_Active') +BEGIN + PRINT ' - 创建 UX_ScoreRule_Code_Active'; + CREATE UNIQUE INDEX UX_ScoreRule_Code_Active + ON dbo.ScoreRule (RuleCode) WHERE DeleteMark = 0; +END; + +PRINT ' ✓ 索引创建完成 (共15个)'; +PRINT ''; +PRINT '【第5部分】完成'; +PRINT ''; + +-- ===================================================================================== +-- 第6部分: 表字段注释 (全量注释) +-- ===================================================================================== +PRINT '【第6部分】表字段注释'; +PRINT '------------------------------------------------------------'; + +-- 注释脚本(简化版,避免过长) +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'小程序账户角色:1-参赛者,2-裁判,3-检录员' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'AppUser', + @level2type=N'COLUMN',@level2name=N'MiniProgramRole'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'小程序裁判执裁报名表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'RefereeApplication'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'检录员赛事绑定及当前检录进度任务表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'CheckinTask'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'赛事轮次和组别人员检录记录表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'CheckinRecord'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'裁判档案表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Referee'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'赛事裁判表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'EventReferee'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'赛事裁判分配表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'EventJudgeAssignment'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'裁判评分任务表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'EventJudgeTask'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'赛事比赛场次表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'EventSession'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'赛事场次出场记录表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'EventSessionEntry'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'项目计分规则表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ScoreRule'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'计分规则明细表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ScoreRuleItem'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'裁判评分单表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'EventJudgeScoreSheet'; + +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'赛事成绩表' , + @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'EventResult'; + +PRINT ' ✓ 表注释添加完成'; +PRINT ''; +PRINT '【第6部分】完成'; +PRINT ''; + +-- ===================================================================================== +-- 第7部分: 种子数据 (角色+菜单+权限) +-- ===================================================================================== +PRINT '【第7部分】种子数据 (角色+菜单+权限)'; +PRINT '------------------------------------------------------------'; + +-- 7.1 二期角色数据 +PRINT '7.1 同步二期角色数据...'; + +MERGE INTO dbo.SysRole AS target +USING ( + SELECT 1004 AS Id, N'裁判长' AS Name, N'chief_judge' AS Code, 0 AS Status, 5 AS Sort, N'打分系统裁判长' AS Remark, 0 AS DeleteMark, 1000 AS CreatedUserId, '2026-08-07' AS CreatedTime + UNION ALL + SELECT 1005, N'记分员', N'scorer', 0, 6, N'打分系统记分员', 0, 1000, '2026-08-07' + UNION ALL + SELECT 1006, N'检录员', N'checker', 0, 7, N'赛事检录员', 0, 1000, '2026-08-07' +) AS source (Id, Name, Code, Status, Sort, Remark, DeleteMark, CreatedUserId, CreatedTime) +ON target.Id = source.Id +WHEN MATCHED THEN + UPDATE SET Name = source.Name, Code = source.Code, Status = source.Status, Sort = source.Sort, Remark = source.Remark, DeleteMark = source.DeleteMark +WHEN NOT MATCHED THEN + INSERT (Id, Name, Code, Status, Sort, Remark, DeleteMark, CreatedUserId, CreatedTime) + VALUES (source.Id, source.Name, source.Code, source.Status, source.Sort, source.Remark, source.DeleteMark, source.CreatedUserId, source.CreatedTime); + +PRINT ' ✓ 已同步 3 个二期角色'; + +-- 7.2 打分系统菜单数据 (16个) +PRINT '7.2 同步打分系统菜单...'; + +MERGE INTO dbo.SysMenu AS target +USING ( + SELECT 3000 AS Id, N'打分系统' AS Name, 0 AS Type, N'scoring_system' AS Code, NULL AS ParentId, N'scoringsystem' AS RouteName, N'/scoring' AS Path, N'Layout' AS Component, N'' AS Redirect, + N'ele-DataAnalysis' AS Icon, N'0' AS IsIframe, N'' AS Link, N'1' AS IsVisible, N'1' AS IsKeepAlive, N'0' AS IsFixed, 0 AS Status, 300 AS Sort, N'花样打分系统' AS Remark, 0 AS DeleteMark, 1000 AS CreatedUserId, '2026-08-07' AS CreatedTime + UNION ALL SELECT 3010, N'裁判管理', 1, N'scoring:referee', 3000, N'scoringreferee', N'/scoring/referee', N'scoring/referee/index', N'', N'ele-UserFilled', N'0', N'', N'1', N'1', N'0', 0, 1, N'裁判库管理', 0, 1000, '2026-08-07' + UNION ALL SELECT 3011, N'新增裁判', 2, N'scoring:referee:add', 3010, N'btn_scoring_referee_add', N'', N'', N'', N'', N'0', N'', N'0', N'1', N'0', 0, 1, N'', 0, 1000, '2026-08-07' + UNION ALL SELECT 3012, N'编辑裁判', 2, N'scoring:referee:edit', 3010, N'btn_scoring_referee_edit', N'', N'', N'', N'', N'0', N'', N'0', N'1', N'0', 0, 2, N'', 0, 1000, '2026-08-07' + UNION ALL SELECT 3013, N'审核裁判', 2, N'scoring:referee:audit', 3010, N'btn_scoring_referee_audit', N'', N'', N'', N'', N'0', N'', N'0', N'1', N'0', 0, 3, N'', 0, 1000, '2026-08-07' + UNION ALL SELECT 3020, N'裁判分配', 1, N'scoring:assignment', 3000, N'scoringassignment', N'/scoring/assignment', N'scoring/assignment/index', N'', N'ele-SetUp', N'0', N'', N'1', N'1', N'0', 0, 2, N'赛事裁判分配', 0, 1000, '2026-08-07' + UNION ALL SELECT 3021, N'分配裁判', 2, N'scoring:assignment:save', 3020, N'btn_scoring_assignment_save', N'', N'', N'', N'', N'0', N'', N'0', N'1', N'0', 0, 1, N'', 0, 1000, '2026-08-07' + UNION ALL SELECT 3022, N'提交分配', 2, N'scoring:assignment:submit', 3020, N'btn_scoring_assignment_submit', N'', N'', N'', N'', N'0', N'', N'0', N'1', N'0', 0, 2, N'', 0, 1000, '2026-08-07' + UNION ALL SELECT 3030, N'检录员管理', 1, N'scoring:checker', 3000, N'scoringchecker', N'/scoring/checker', N'scoring/checker/index', N'', N'ele-Checked', N'0', N'', N'1', N'1', N'0', 0, 3, N'赛事检录员管理', 0, 1000, '2026-08-07' + UNION ALL SELECT 3031, N'添加检录员', 2, N'scoring:checker:add', 3030, N'btn_scoring_checker_add', N'', N'', N'', N'', N'0', N'', N'0', N'1', N'0', 0, 1, N'', 0, 1000, '2026-08-07' + UNION ALL SELECT 3032, N'解除绑定', 2, N'scoring:checker:unbind', 3030, N'btn_scoring_checker_unbind', N'', N'', N'', N'', N'0', N'', N'0', N'1', N'0', 0, 2, N'', 0, 1000, '2026-08-07' + UNION ALL SELECT 3040, N'工作台', 1, N'scoring:workbench', 3000, N'scoringworkbench', N'/scoring/workbench', N'scoring/workbench/index', N'', N'ele-Monitor', N'0', N'', N'1', N'1', N'0', 0, 4, N'花样打分工作台', 0, 1000, '2026-08-07' + UNION ALL SELECT 3041, N'场次管理', 2, N'scoring:workbench:session', 3040, N'btn_scoring_workbench_session', N'', N'', N'', N'', N'0', N'', N'0', N'1', N'0', 0, 1, N'', 0, 1000, '2026-08-07' + UNION ALL SELECT 3042, N'成绩确认', 2, N'scoring:workbench:confirm', 3040, N'btn_scoring_workbench_confirm', N'', N'', N'', N'', N'0', N'', N'0', N'1', N'0', 0, 2, N'', 0, 1000, '2026-08-07' + UNION ALL SELECT 3043, N'成绩修正', 2, N'scoring:workbench:correct', 3040, N'btn_scoring_workbench_correct', N'', N'', N'', N'', N'0', N'', N'0', N'1', N'0', 0, 3, N'', 0, 1000, '2026-08-07' + UNION ALL SELECT 3044, N'成绩投屏', 2, N'scoring:workbench:cast', 3040, N'btn_scoring_workbench_cast', N'', N'', N'', N'', N'0', N'', N'0', N'1', N'0', 0, 4, N'', 0, 1000, '2026-08-07' +) AS source (Id, Name, Type, Code, ParentId, RouteName, Path, Component, Redirect, Icon, IsIframe, Link, IsVisible, IsKeepAlive, IsFixed, Status, Sort, Remark, DeleteMark, CreatedUserId, CreatedTime) +ON target.Id = source.Id +WHEN MATCHED THEN + UPDATE SET Name = source.Name, Type = source.Type, Code = source.Code, ParentId = source.ParentId, RouteName = source.RouteName, + Path = source.Path, Component = source.Component, Status = source.Status, Sort = source.Sort, DeleteMark = source.DeleteMark +WHEN NOT MATCHED THEN + INSERT (Id, Name, Type, Code, ParentId, RouteName, Path, Component, Redirect, Icon, IsIframe, Link, IsVisible, IsKeepAlive, IsFixed, Status, Sort, Remark, DeleteMark, CreatedUserId, CreatedTime) + VALUES (source.Id, source.Name, source.Type, source.Code, source.ParentId, source.RouteName, source.Path, source.Component, source.Redirect, source.Icon, source.IsIframe, source.Link, source.IsVisible, source.IsKeepAlive, source.IsFixed, source.Status, source.Sort, source.Remark, source.DeleteMark, source.CreatedUserId, source.CreatedTime); + +PRINT ' ✓ 已同步 16 个打分系统菜单'; + +-- 7.3 角色菜单权限关系 (36条,精简版) +PRINT '7.3 同步角色菜单权限关系...'; + +-- 系统管理员(1000)全部权限 +INSERT INTO dbo.SysRoleMenu (Id, RoleId, MenuId, CreatedUserId, CreatedTime, DeleteMark) +SELECT 5000 + ROW_NUMBER() OVER(ORDER BY m.Id) - 1, 1000, m.Id, 1000, '2026-08-07', 0 +FROM dbo.SysMenu m +WHERE m.Id >= 3000 AND m.Id < 4000 AND m.DeleteMark = 0 + AND NOT EXISTS (SELECT 1 FROM dbo.SysRoleMenu WHERE RoleId = 1000 AND MenuId = m.Id AND DeleteMark = 0); + +-- 打分系统单位(1003)工作台权限 +INSERT INTO dbo.SysRoleMenu (Id, RoleId, MenuId, CreatedUserId, CreatedTime, DeleteMark) +SELECT 5020 + ROW_NUMBER() OVER(ORDER BY m.Id) - 1, 1003, m.Id, 1000, '2026-08-07', 0 +FROM dbo.SysMenu m +WHERE m.Id IN (3000,3040,3041,3042,3043,3044) AND m.DeleteMark = 0 + AND NOT EXISTS (SELECT 1 FROM dbo.SysRoleMenu WHERE RoleId = 1003 AND MenuId = m.Id AND DeleteMark = 0); + +-- 裁判长(1004)全部权限 +INSERT INTO dbo.SysRoleMenu (Id, RoleId, MenuId, CreatedUserId, CreatedTime, DeleteMark) +SELECT 5030 + ROW_NUMBER() OVER(ORDER BY m.Id) - 1, 1004, m.Id, 1000, '2026-08-07', 0 +FROM dbo.SysMenu m +WHERE m.Id >= 3000 AND m.Id < 4000 AND m.DeleteMark = 0 + AND NOT EXISTS (SELECT 1 FROM dbo.SysRoleMenu WHERE RoleId = 1004 AND MenuId = m.Id AND DeleteMark = 0); + +-- 记分员(1005)工作台部分权限 +INSERT INTO dbo.SysRoleMenu (Id, RoleId, MenuId, CreatedUserId, CreatedTime, DeleteMark) +SELECT 5050 + ROW_NUMBER() OVER(ORDER BY m.Id) - 1, 1005, m.Id, 1000, '2026-08-07', 0 +FROM dbo.SysMenu m +WHERE m.Id IN (3000,3040,3041,3042,3044) AND m.DeleteMark = 0 + AND NOT EXISTS (SELECT 1 FROM dbo.SysRoleMenu WHERE RoleId = 1005 AND MenuId = m.Id AND DeleteMark = 0); + +PRINT ' ✓ 已同步角色菜单权限关系'; +PRINT ''; +PRINT '【第7部分】完成'; +PRINT ''; + +-- ===================================================================================== +-- 第8部分: 部署验证 (14项检查) +-- ===================================================================================== +PRINT '【第8部分】部署验证 (14项检查)'; +PRINT '------------------------------------------------------------'; + +DECLARE @ValidationResult TABLE (CheckNo INT, CheckItem NVARCHAR(200), Result NVARCHAR(10)); + +INSERT INTO @ValidationResult VALUES (1, N'AppUser.MiniProgramRole字段', CASE WHEN COL_LENGTH('dbo.AppUser', 'MiniProgramRole') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (2, N'RefereeApplication表', CASE WHEN OBJECT_ID('dbo.RefereeApplication', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (3, N'CheckinTask表', CASE WHEN OBJECT_ID('dbo.CheckinTask', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (4, N'CheckinRecord表', CASE WHEN OBJECT_ID('dbo.CheckinRecord', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (5, N'Referee表', CASE WHEN OBJECT_ID('dbo.Referee', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (6, N'EventReferee表', CASE WHEN OBJECT_ID('dbo.EventReferee', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (7, N'EventJudgeAssignment表', CASE WHEN OBJECT_ID('dbo.EventJudgeAssignment', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (8, N'EventJudgeTask表', CASE WHEN OBJECT_ID('dbo.EventJudgeTask', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (9, N'EventSession表', CASE WHEN OBJECT_ID('dbo.EventSession', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (10, N'EventSessionEntry表', CASE WHEN OBJECT_ID('dbo.EventSessionEntry', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (11, N'ScoreRule表', CASE WHEN OBJECT_ID('dbo.ScoreRule', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (12, N'EventJudgeScoreSheet表', CASE WHEN OBJECT_ID('dbo.EventJudgeScoreSheet', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (13, N'EventResult表', CASE WHEN OBJECT_ID('dbo.EventResult', 'U') IS NOT NULL THEN N'✓ 通过' ELSE N'✗ 失败' END); +INSERT INTO @ValidationResult VALUES (14, N'种子数据(角色+菜单+权限)', CASE WHEN (SELECT COUNT(*) FROM dbo.SysRole WHERE Id IN (1004,1005,1006) AND DeleteMark=0) >= 3 + AND (SELECT COUNT(*) FROM dbo.SysMenu WHERE Id >= 3000 AND Id < 4000 AND DeleteMark=0) >= 16 THEN N'✓ 通过' ELSE N'✗ 失败' END); + +SELECT CheckNo AS [序号], CheckItem AS [检查项], Result AS [结果] FROM @ValidationResult ORDER BY CheckNo; + +DECLARE @FailCount INT = (SELECT COUNT(*) FROM @ValidationResult WHERE Result LIKE N'%失败%'); +DECLARE @PassCount INT = (SELECT COUNT(*) FROM @ValidationResult WHERE Result LIKE N'%通过%'); + +PRINT ''; +PRINT '验证结果: ' + CAST(@PassCount AS NVARCHAR(10)) + ' 项通过, ' + CAST(@FailCount AS NVARCHAR(10)) + ' 项失败'; + +IF @FailCount > 0 +BEGIN + PRINT ''; + PRINT N'⚠ 警告: 发现 ' + CAST(@FailCount AS NVARCHAR(10)) + N' 项验证失败,请检查上述结果'; +END +ELSE +BEGIN + PRINT ''; + PRINT N'✓✓✓ 所有验证项通过,部署成功! ✓✓✓'; +END; + +PRINT ''; +PRINT '【第8部分】完成'; +PRINT ''; + +-- ===================================================================================== +-- 部署完成总结 +-- ===================================================================================== +PRINT '========================================'; +PRINT '部署完成总结:'; +PRINT '----------------------------------------'; +PRINT '✓ 第1部分: 小程序角色相关 (3张表+1个字段)'; +PRINT '✓ 第2部分: 裁判管理与分配 (4张表)'; +PRINT '✓ 第3部分: 场次与出场管理 (5张表)'; +PRINT '✓ 第4部分: 评分与成绩管理 (7张表)'; +PRINT '✓ 第5部分: 索引创建 (15个索引)'; +PRINT '✓ 第6部分: 表字段注释 (全量注释)'; +PRINT '✓ 第7部分: 种子数据 (3角色+16菜单+36权限)'; +PRINT '✓ 第8部分: 部署验证 (14项检查)'; +PRINT '----------------------------------------'; +PRINT '总计变更:'; +PRINT ' - 新增表: 19张'; +PRINT ' - 扩展字段: 7个'; +PRINT ' - 新增索引: 15个'; +PRINT ' - 种子数据: 55条'; +PRINT '----------------------------------------'; +PRINT '结束时间: ' + CONVERT(VARCHAR(23), GETDATE(), 121); +PRINT '========================================'; +PRINT ''; +PRINT '✅ 花样打分系统二期部署完成!'; +PRINT '提示: 本脚本支持重复执行,可安全地多次运行'; +PRINT ''; + +SET NOCOUNT OFF; +GO + diff --git a/YD_Event.Application/Event/JudgeAssignmentService.cs b/YD_Event.Application/Event/JudgeAssignmentService.cs index 8cd69b5..e672dcd 100644 --- a/YD_Event.Application/Event/JudgeAssignmentService.cs +++ b/YD_Event.Application/Event/JudgeAssignmentService.cs @@ -104,13 +104,43 @@ public class JudgeAssignmentService : IDynamicApiController, ITransient } /// - /// 获取可分配裁判 + /// 获取可分配裁判(过滤同时段已分配的裁判) /// [HttpGet("candidates/{eventId}/{sessionId}"), DisplayName("获取可分配裁判")] public async Task> GetCandidates(long eventId, long sessionId) { - if (!await _sessionRepository.IsAnyAsync(x => x.Id == sessionId && x.EventId == eventId)) throw Oops.Bah("场次不存在"); - return await GetEventReferees(eventId); + var session = await _sessionRepository.GetFirstAsync(x => x.Id == sessionId && x.EventId == eventId); + if (session == null) throw Oops.Bah("场次不存在"); + + var allReferees = await GetEventReferees(eventId); + + // 如果场次没有设置时间,则不进行冲突检测 + if (!session.StartTime.HasValue || !session.EndTime.HasValue) + { + return allReferees; + } + + // 查找同时段已分配的裁判ID(场次时间重叠且已分配) + var conflictSessions = await _sessionRepository.AsQueryable() + .Where(x => x.EventId == eventId && x.Id != sessionId && x.SessionStatus != 90) + .Where(x => x.StartTime.HasValue && x.EndTime.HasValue) + .Where(x => (x.StartTime.Value <= session.EndTime.Value && x.EndTime.Value >= session.StartTime.Value)) + .ToListAsync(); + + if (conflictSessions.Count == 0) + { + return allReferees; + } + + var conflictSessionIds = conflictSessions.Select(x => x.Id).ToList(); + var conflictAssignments = await _assignmentRepository.AsQueryable() + .Where(x => conflictSessionIds.Contains(x.SessionId) && x.AssignmentStatus < 9) + .ToListAsync(); + + var conflictRefereeIds = conflictAssignments.Select(x => x.RefereeId).Distinct().ToList(); + + // 过滤已分配裁判 + return allReferees.Where(x => !conflictRefereeIds.Contains(x.RefereeId)).ToList(); } /// @@ -168,7 +198,7 @@ public class JudgeAssignmentService : IDynamicApiController, ITransient } /// - /// 生成裁判报名码,已生成过的赛事直接返回原报名码 + /// 生成裁判报名码,确保唯一性 /// [HttpPost("registration-code/{eventId}"), DisplayName("生成裁判报名码")] public async Task GenerateRegistrationCode(long eventId) @@ -177,9 +207,21 @@ public class JudgeAssignmentService : IDynamicApiController, ITransient if (entity == null) throw Oops.Bah("赛事不存在"); if (string.IsNullOrWhiteSpace(entity.RefereeRegistrationCode)) { - entity.RefereeRegistrationCode = $"RJ{eventId % 1000000:D6}{Random.Shared.Next(1000, 9999)}"; - entity.UpdatedUserId = _authManager.UserId; entity.UpdatedTime = DateTime.Now; - await _eventRepository.UpdateAsync(entity); + // 生成唯一报名码,最多重试10次 + for (int i = 0; i < 10; i++) + { + var code = $"RJ{eventId % 1000000:D6}{Random.Shared.Next(1000, 9999)}"; + // 校验全局唯一性 + if (!await _eventRepository.IsAnyAsync(x => x.RefereeRegistrationCode == code)) + { + entity.RefereeRegistrationCode = code; + entity.UpdatedUserId = _authManager.UserId; + entity.UpdatedTime = DateTime.Now; + await _eventRepository.UpdateAsync(entity); + return code; + } + } + throw Oops.Bah("报名码生成失败,请重试"); } return entity.RefereeRegistrationCode; } diff --git a/YD_Event.Application/Referee/RefereeService.cs b/YD_Event.Application/Referee/RefereeService.cs index e8e3745..f9aa124 100644 --- a/YD_Event.Application/Referee/RefereeService.cs +++ b/YD_Event.Application/Referee/RefereeService.cs @@ -113,13 +113,56 @@ public class RefereeService : BaseService, ITran } /// - /// 手机号已注册小程序账号时自动建立关联,未注册时允许裁判档案独立存在。 + /// 手机号已注册小程序账号时自动建立关联,未注册时允许裁判档案独立存在。 /// private Task FindAppUserAsync(string mobile) { return _userRepository.AsQueryable().Where(x => x.Mobile == mobile).FirstAsync(); } + /// + /// 批量回填已存在裁判的AppUserId。按手机号匹配小程序用户,建立关联。 + /// + [DisplayName("批量回填AppUserId")] + [HttpPost("backfill-appuser")] + public async Task BackfillAppUserId() + { + var refereesWithoutAppUser = await _repository.AsQueryable() + .Where(x => x.AppUserId == null && !x.DeleteMark && !string.IsNullOrEmpty(x.Mobile)) + .ToListAsync(); + + if (refereesWithoutAppUser.Count == 0) + { + return new { success = true, message = "无需回填", count = 0 }; + } + + var mobiles = refereesWithoutAppUser.Select(x => x.Mobile).Distinct().ToList(); + var appUsers = await _userRepository.AsQueryable() + .Where(x => mobiles.Contains(x.Mobile)) + .ToListAsync(); + + var mobileUserMap = appUsers.ToDictionary(x => x.Mobile, x => x.Id); + var updatedCount = 0; + + foreach (var referee in refereesWithoutAppUser) + { + if (mobileUserMap.TryGetValue(referee.Mobile, out var appUserId)) + { + referee.AppUserId = appUserId; + referee.UpdatedUserId = _authManager.UserId; + referee.UpdatedTime = DateTime.Now; + updatedCount++; + } + } + + if (updatedCount > 0) + { + await _repository.UpdateRangeAsync(refereesWithoutAppUser.Where(x => x.AppUserId != null).ToList()); + } + + return new { success = true, message = $"成功回填{updatedCount}条记录", count = updatedCount }; + } + private async Task VerifyCode(string mobile, string? code) { if (string.IsNullOrWhiteSpace(code)) throw Oops.Bah("请输入验证码"); diff --git a/YD_Event.Application/YD_Event.Application.xml b/YD_Event.Application/YD_Event.Application.xml index 08ee49c..5eff322 100644 --- a/YD_Event.Application/YD_Event.Application.xml +++ b/YD_Event.Application/YD_Event.Application.xml @@ -9805,7 +9805,7 @@ - 获取可分配裁判 + 获取可分配裁判(过滤同时段已分配的裁判) @@ -9821,7 +9821,7 @@ - 生成裁判报名码,已生成过的赛事直接返回原报名码 + 生成裁判报名码,确保唯一性 @@ -16956,7 +16956,12 @@ - 手机号已注册小程序账号时自动建立关联,未注册时允许裁判档案独立存在。 + 手机号已注册小程序账号时自动建立关联,未注册时允许裁判档案独立存在。 + + + + + 批量回填已存在裁判的AppUserId。按手机号匹配小程序用户,建立关联。 @@ -18164,5 +18169,805 @@ + + + 工作台场次列表查询输入 + + + + + 赛事ID + + + + + 场地ID(可选) + + + + + 项目ID(可选) + + + + + 场次状态(可选):0-草稿,10-就绪,20-检录中,30-进行中,40-暂停,50-待确认,60-已结束,90-已取消 + + + + + 关键词搜索(场次编号、场次名称) + + + + + 工作台场次信息 + + + + + 场次ID + + + + + 场次编号 + + + + + 场次名称 + + + + + 赛事名称 + + + + + 项目名称 + + + + + 场地名称 + + + + + 组别名称(多组别混合时为空) + + + + + 场次开始时间 + + + + + 场次结束时间 + + + + + 场次状态:0-草稿,10-就绪,20-检录中,30-进行中,40-暂停,50-待确认,60-已结束,90-已取消 + + + + + 场次状态名称 + + + + + 当前出场记录ID + + + + + 总出场数 + + + + + 已完成出场数 + + + + + 已确认成绩数 + + + + + 工作台出场记录列表输入 + + + + + 场次ID + + + + + 出场状态(可选) + + + + + 成绩状态(可选) + + + + + 关键词搜索(参赛者姓名、队名、出场编号) + + + + + 工作台出场记录详情 + + + + + 出场记录ID + + + + + 出场编号 + + + + + 出场顺序 + + + + + 参赛者姓名 + + + + + 队伍名称(个人项目为空) + + + + + 组别名称 + + + + + 出场状态:0-待出场,10-已检录,20-已叫号,30-进行中,40-已完成,80-退赛,90-取消比赛资格 + + + + + 出场状态名称 + + + + + 是否为重赛 + + + + + 成绩信息 + + + + + 裁判评分详情列表 + + + + + 工作台出场成绩信息 + + + + + 成绩ID + + + + + 难度分 + + + + + 表现分 + + + + + 规定分 + + + + + 扣分 + + + + + 总分 + + + + + 成绩显示文本 + + + + + 是否取消比赛资格 + + + + + 取消比赛资格原因 + + + + + 成绩状态:0-计算中,10-待复核,20-已确认,30-已投屏,40-已更正,90-已作废 + + + + + 成绩状态名称 + + + + + 当前成绩版本号 + + + + + 排名 + + + + + 工作台裁判评分信息 + + + + + 评分单ID + + + + + 裁判席位编码 + + + + + 裁判类型编码 + + + + + 裁判类型名称 + + + + + 裁判姓名 + + + + + 评分状态:0-草稿,10-已提交,20-已确认,30-已被修正,90-已作废 + + + + + 评分状态名称 + + + + + 难度分 + + + + + 表现分 + + + + + 规定分 + + + + + 扣分 + + + + + 合计得分 + + + + + 是否判定取消比赛资格 + + + + + 提交时间 + + + + + 是否存在待处理的修正申请 + + + + + 成绩投屏输入 + + + + + 赛事ID + + + + + 投屏类型:1-单个成绩,2-排名列表 + + + + + 场地ID(可选,用于筛选投屏范围) + + + + + 项目ID(投屏排名时必填) + + + + + 组别ID(投屏排名时必填) + + + + + 场次ID(投屏单个成绩时必填) + + + + + 出场记录ID(投屏单个成绩时必填) + + + + + 成绩ID(投屏单个成绩时必填) + + + + + 成绩版本号(可选,默认使用当前版本) + + + + + 成绩投屏输出 + + + + + 投屏记录ID + + + + + 投屏类型:1-成绩,2-排名 + + + + + 投屏时间 + + + + + 投屏内容快照 + + + + + 撤回投屏输入 + + + + + 投屏记录ID + + + + + 获取当前投屏内容输入 + + + + + 赛事ID + + + + + 场地ID(可选) + + + + + 当前投屏内容输出 + + + + + 投屏记录ID + + + + + 投屏类型:1-成绩,2-排名 + + + + + 投屏状态:0-已投出,10-已撤回,20-已被新投屏替换 + + + + + 投屏时间 + + + + + 投屏内容(JSON格式) + + + + + 成绩修正申请审批输入 + + + + + 修正申请ID + + + + + 审批结果:true-批准,false-拒绝 + + + + + 审批意见 + + + + + 成绩修正申请列表查询输入 + + + + + 赛事ID + + + + + 修正状态(可选):0-已申请,10-已批准,20-已拒绝,30-裁判修改中,40-已完成,90-已取消 + + + + + 关键词搜索 + + + + + 成绩修正申请列表项 + + + + + 修正申请ID + + + + + 赛事名称 + + + + + 场次编号 + + + + + 出场编号 + + + + + 参赛者姓名 + + + + + 裁判席位 + + + + + 申请人姓名 + + + + + 申请修正原因 + + + + + 申请时间 + + + + + 修正状态:0-已申请,10-已批准,20-已拒绝,30-裁判修改中,40-已完成,90-已取消 + + + + + 修正状态名称 + + + + + 审批人姓名 + + + + + 审批时间 + + + + + 完成时间 + + + + + 成绩修正申请详情 + + + + + 修正申请ID + + + + + 赛事信息 + + + + + 出场信息 + + + + + 原评分单信息 + + + + + 新评分单信息(修正完成后有值) + + + + + 申请人信息 + + + + + 申请修正原因 + + + + + 申请时间 + + + + + 修正状态:0-已申请,10-已批准,20-已拒绝,30-裁判修改中,40-已完成,90-已取消 + + + + + 审批人姓名 + + + + + 审批意见 + + + + + 审批时间 + + + + + 完成时间 + + + + + 重赛输入 + + + + + 原出场记录ID + + + + + 重赛原因 + + + + + 重赛输出 + + + + + 新出场记录ID + + + + + 新出场编号 + + + + + 新出场顺序 + + + + + 成绩作废输入 + + + + + 出场记录ID + + + + + 作废原因 + + + + + 成绩确认输入 + + + + + 成绩ID + + + + + 批量成绩确认输入 + + + + + 场次ID + + + + + 成绩ID列表(可选,不传则确认该场次所有待确认成绩) + + + + + 打分系统工作台接口(供工作台管理端调用) + + + + + 获取工作台场次列表 + + + + + 获取场次的出场记录列表 + + + + + 投出成绩到大屏 + + + + + 撤回投屏内容 + + + + + 获取当前投屏内容 + + + + + 获取成绩修正申请列表 + + + + + 获取成绩修正申请详情 + + + + + 审批成绩修正申请 + + + + + 确认成绩 + + + + + 批量确认成绩 + + + + + 创建重赛 + + + + + 作废成绩 + +