1. 项目概述:奖学金投票评定管理系统的核心价值
这个基于.NET和HTML5的奖学金投票评定管理系统,本质上解决的是高校奖学金评审过程中的三个核心痛点:流程不透明、人工统计易出错、多角色协作困难。我在实际开发中发现,传统Excel表格+纸质材料的评审方式,往往导致一个200人的院系需要3-5个辅导员连续工作一周才能完成初评。
系统采用B/S架构,前端使用HTML5实现跨平台响应式布局,后端基于.NET Framework 4.7.2开发(兼容Windows Server 2012 R2及以上环境),数据库选用SQL Server 2012 Express版。特别值得注意的是,我们通过HTML5的WebSocket实现了实时投票数据可视化,评委在打分时就能看到当前候选人的得分分布曲线。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构解析
2.1 前端技术选型考量
选择HTML5而非传统ASP.NET WebForm,主要基于三点考虑:
- 移动端适配需求:超过35%的评委反馈希望在手机端完成评审
- 数据可视化要求:需要动态展示投票进度和统计图表
- 离线操作支持:使用Service Worker缓存关键页面,解决校园网不稳定的问题
实际开发中遇到的最大坑是Firefox对HTML5视频标签的兼容性问题。我们的解决方案是:
html复制<!-- 候选人展示视频的兼容写法 -->
<video controls poster="default.jpg">
<source src="video.mp4" type="video/mp4">
<source src="video.webm" type="video/webm">
<object data="video.swf" type="application/x-shockwave-flash">
<param name="movie" value="video.swf">
</object>
</video>
2.2 后端框架设计
采用三层架构但做了特殊优化:
- 表现层:ASP.NET MVC 5 + WebAPI
- 业务层:引入策略模式处理不同奖学金类型的评审规则
- 数据层:Entity Framework + Dapper混合使用
关键的业务逻辑代码结构:
csharp复制public interface IScholarshipStrategy
{
decimal CalculateScore(Student student);
}
public class AcademicStrategy : IScholarshipStrategy {...}
public class SportsStrategy : IScholarshipStrategy {...}
// 策略工厂
public class StrategyFactory
{
public static IScholarshipStrategy Create(ScholarshipType type)
{
switch(type)
{
case ScholarshipType.Academic: return new AcademicStrategy();
case ScholarshipType.Sports: return new SportsStrategy();
default: throw new NotImplementedException();
}
}
}
3. 数据库设计要点
3.1 核心表结构
sql复制CREATE TABLE [Student](
[Id] INT PRIMARY KEY IDENTITY,
[StudentId] VARCHAR(20) UNIQUE NOT NULL,
[Name] NVARCHAR(50) NOT NULL,
[GPA] DECIMAL(3,2) CHECK(GPA BETWEEN 0 AND 4)
);
CREATE TABLE [Scholarship](
[Id] INT PRIMARY KEY IDENTITY,
[Name] NVARCHAR(100) NOT NULL,
[Type] TINYINT NOT NULL, -- 0:学业 1:文体 2:公益
[TotalAmount] DECIMAL(10,2) NOT NULL
);
CREATE TABLE [VoteRecord](
[Id] INT PRIMARY KEY IDENTITY,
[StudentId] INT FOREIGN KEY REFERENCES [Student](Id),
[ScholarshipId] INT FOREIGN KEY REFERENCES [Scholarship](Id),
[JudgeId] INT NOT NULL,
[Score] DECIMAL(5,2) NOT NULL,
[VoteTime] DATETIME DEFAULT GETDATE(),
CONSTRAINT UK_Vote UNIQUE([StudentId], [ScholarshipId], [JudgeId])
);
3.2 性能优化实践
在测试阶段发现当并发投票数超过50时会出现死锁,通过以下方案解决:
- 使用NOLOCK提示读取参考数据
- 对投票操作采用队列处理
- 建立覆盖索引:
sql复制CREATE NONCLUSTERED INDEX IX_VoteRecord_Main
ON [VoteRecord]([ScholarshipId], [StudentId])
INCLUDE([Score], [JudgeId]);
4. 关键功能实现细节
4.1 动态评分规则引擎
不同奖学金类型需要不同的计分公式,我们设计了一套规则配置系统:
xml复制<Rule Type="Academic">
<Formula>(GPA*0.7 + Activity*0.3) * BaseAmount</Formula>
<Parameters>
<Param Name="BaseAmount" Value="5000"/>
</Parameters>
</Rule>
对应的解析引擎:
csharp复制public class RuleEngine
{
public decimal Calculate(string formula, Dictionary<string, decimal> parameters)
{
// 使用Roslyn动态编译表达式
var script = CSharpScript.Create<decimal>(formula,
globalsType: typeof(CalculationGlobals));
script.Compile();
return script.RunAsync(new CalculationGlobals {
GPA = parameters["GPA"],
Activity = parameters["Activity"]
}).Result.ReturnValue;
}
}
4.2 实时数据推送
使用SignalR实现投票结果实时更新:
javascript复制// 前端代码
var connection = new signalR.HubConnectionBuilder()
.withUrl("/voteHub")
.configureLogging(signalR.LogLevel.Information)
.build();
connection.on("UpdateVote", (data) => {
updateChart(JSON.parse(data));
});
// 后端Hub
public class VoteHub : Hub
{
public async Task JoinGroup(string scholarshipId)
{
await Groups.AddToGroupAsync(Context.ConnectionId, scholarshipId);
}
}
5. 部署与运维经验
5.1 IIS配置要点
在Windows Server 2016上部署时遇到的两个典型问题及解决方案:
-
WebSocket支持问题:
- 确保安装"WebSocket协议"功能
- 在applicationHost.config中添加:
xml复制<system.webServer> <webSocket enabled="true" receiveBufferLimit="4194304"/> </system.webServer> -
静态文件缓存策略:
xml复制<staticContent> <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" /> </staticContent>
5.2 性能监控方案
我们使用Application Insights收集以下关键指标:
- 投票请求平均响应时间(控制在200ms内)
- 并发用户数峰值(实测支持300+并发)
- SQL查询执行时间(超过500ms的查询需要优化)
配置方法:
csharp复制public static void ConfigureTelemetry()
{
TelemetryConfiguration.Active.InstrumentationKey = "your-key";
TelemetryConfiguration.Active.TelemetryInitializers.Add(
new OperationCorrelationTelemetryInitializer());
}
6. 安全防护措施
6.1 防刷票机制
实现方案:
- 基于IP和用户行为的混合验证
- 投票频率限制(每分钟不超过3次)
- 异常模式检测算法
核心代码:
csharp复制public class VoteValidator
{
public bool Validate(VoteRequest request)
{
var lastHourVotes = _context.VoteRecords
.Count(v => v.JudgeId == request.JudgeId
&& v.VoteTime > DateTime.Now.AddHours(-1));
if(lastHourVotes > 50) return false;
// 更多验证逻辑...
return true;
}
}
6.2 数据加密方案
敏感数据采用双层加密:
- 传输层:强制HTTPS(配置HSTS)
- 存储层:使用SQL Server的Always Encrypted功能
加密配置示例:
sql复制CREATE COLUMN ENCRYPTION KEY [CEK_Auto1]
WITH VALUES (
COLUMN_MASTER_KEY = [CMK_Auto1],
ALGORITHM = 'RSA_OAEP',
ENCRYPTED_VALUE = 0x01700...
);
CREATE TABLE [Student](
[IDCardNumber] NVARCHAR(18)
COLLATE Latin1_General_BIN2
ENCRYPTED WITH (
ENCRYPTION_TYPE = DETERMINISTIC,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',
COLUMN_ENCRYPTION_KEY = [CEK_Auto1]
) NULL
);
7. 项目演进建议
在实际运行一年后,我们总结了三个改进方向:
- 评审流程可视化:使用Workflow Core实现可配置的评审流程
- 智能初筛功能:基于历史数据训练简单模型自动过滤明显不符合条件的申请
- 多租户支持:使系统能够同时服务于多个院系,各院系可自定义评审规则
示例代码结构预想:
code复制/ScholarshipSystem
│── /Features
│ ├── /MultiTenancy
│ ├── /WorkflowEngine
│ └── /AIScreening
└── /Shared
├── TenantProvider.cs
└── WorkflowExtensions.cs
这个项目给我的深刻体会是:教育类管理系统必须平衡技术先进性和操作简便性。我们曾引入过复杂的机器学习算法来自动评分,但最终发现评委们更信任简单透明的规则引擎。技术方案的选择应该始终以解决实际问题为导向,而非单纯追求技术新颖性。
