2026-05-27 17:19:14 +08:00

465 lines
20 KiB
C#

using System;
using Dapper;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Business.IRepositories.ShangWaiMao;
using VOL.Core.DBManager;
using VOL.Core.Dapper;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
using VOL.Model;
using VOL.Model.ShangWaiMao.Request;
using VOL.Model.ShangWaiMao.Response;
namespace VOL.Business.Repositories.ShangWaiMao
{
/// <summary>
/// 上外贸体测成绩临时表仓储
/// </summary>
public class TempTccjRepository : ITempTccjRepository
{
private const string TableName = "temp_tccj";
private ISqlDapper Dapper => DBServerProvider.SqlDapperSwmMySql;
public static ITempTccjRepository Instance
{
get { return AutofacContainerModule.GetService<ITempTccjRepository>(); }
}
public async Task<ShangWaiMaoTempTccjFilterOptions> GetFilterOptionsAsync()
{
const string sql = @"
select distinct
case sex
when '1' then '男'
when '2' then '女'
else sex
end as Label,
sex as Value
from temp_tccj
where ifnull(sex, '') <> ''
order by sex;
select distinct college_name as Label, college_name as Value
from temp_tccj
where ifnull(college_name, '') <> ''
order by college_name;
select distinct grade_no as Label, grade_no as Value
from temp_tccj
where ifnull(grade_no, '') <> ''
order by grade_no;
select distinct class_name as Label, class_name as Value
from temp_tccj
where ifnull(class_name, '') <> ''
order by class_name;
select distinct conclusion as Label, conclusion as Value
from temp_tccj
where ifnull(conclusion, '') <> ''
order by conclusion;";
var (sexList, collegeList, gradeList, administrativeClassList, conclusionList) =
await Dapper.QueryMultipleAsync<ShangWaiMaoOptionItem, ShangWaiMaoOptionItem, ShangWaiMaoOptionItem, ShangWaiMaoOptionItem, ShangWaiMaoOptionItem>(sql, null);
return new ShangWaiMaoTempTccjFilterOptions
{
SexList = sexList.ToList(),
CollegeList = collegeList.ToList(),
GradeList = gradeList.ToList(),
AdministrativeClassList = administrativeClassList.ToList(),
SportsClassList = new List<ShangWaiMaoOptionItem>(),
ConclusionList = conclusionList.ToList()
};
}
public async Task<PageDataDto<ShangWaiMaoTempTccjListItem>> GetPageListAsync(ShangWaiMaoTempTccjPageParam param)
{
param ??= new ShangWaiMaoTempTccjPageParam();
param.PageIndex = param.PageIndex <= 0 ? 1 : param.PageIndex;
param.PageSize = param.PageSize <= 0 ? 20 : param.PageSize;
var whereBuilder = new StringBuilder(" where 1=1 ");
var dbParams = new DynamicParameters();
if (!string.IsNullOrWhiteSpace(param.StudentNo))
{
whereBuilder.Append(" and student_no like concat('%', @StudentNo, '%') ");
dbParams.Add("StudentNo", param.StudentNo.Trim());
}
if (!string.IsNullOrWhiteSpace(param.Name))
{
whereBuilder.Append(" and name like concat('%', @Name, '%') ");
dbParams.Add("Name", param.Name.Trim());
}
if (!string.IsNullOrWhiteSpace(param.Sex))
{
whereBuilder.Append(" and sex = @Sex ");
dbParams.Add("Sex", NormalizeSex(param.Sex));
}
if (!string.IsNullOrWhiteSpace(param.CollegeName))
{
whereBuilder.Append(" and college_name = @CollegeName ");
dbParams.Add("CollegeName", param.CollegeName.Trim());
}
if (!string.IsNullOrWhiteSpace(param.GradeNo))
{
whereBuilder.Append(" and grade_no = @GradeNo ");
dbParams.Add("GradeNo", param.GradeNo.Trim());
}
if (!string.IsNullOrWhiteSpace(param.AdministrativeClass))
{
whereBuilder.Append(" and class_name = @AdministrativeClass ");
dbParams.Add("AdministrativeClass", param.AdministrativeClass.Trim());
}
if (!string.IsNullOrWhiteSpace(param.Conclusion))
{
whereBuilder.Append(" and conclusion = @Conclusion ");
dbParams.Add("Conclusion", param.Conclusion.Trim());
}
var countSql = $"select count(1) from {TableName} {whereBuilder}";
var totalObj = await Dapper.ExecuteScalarAsync(countSql, dbParams);
var total = int.TryParse(totalObj?.ToString(), out var parsedTotal) ? parsedTotal : 0;
dbParams.Add("Offset", (param.PageIndex - 1) * param.PageSize);
dbParams.Add("PageSize", param.PageSize);
var listSql = $@"
select
student_no as StudentNo,
name as Name,
case sex
when '1' then '男'
when '2' then '女'
else sex
end as Sex,
grade_no as GradeNo,
class_name as AdministrativeClass,
'' as SportsClass,
case test_state
when 0 then '未测试'
when 1 then '已测试'
when 2 then '缺项'
else ''
end as TestState,
case exempt
when 0 then '测试'
when 1 then '免试'
else ''
end as Exempt,
add_score as AddScore,
health_score as HealthScore,
score as Score,
conclusion as Conclusion,
'' as Remark,
college_name as CollegeName
from {TableName}
{whereBuilder}
order by student_no
limit @Offset, @PageSize";
var datas = (await Dapper.QueryListAsync<ShangWaiMaoTempTccjListItem>(listSql, dbParams)).ToList();
return new PageDataDto<ShangWaiMaoTempTccjListItem>
{
Total = total,
TotalPages = total == 0 ? 0 : (total + param.PageSize - 1) / param.PageSize,
PageIndex = param.PageIndex,
PageSize = param.PageSize,
Datas = datas
};
}
public async Task<ShangWaiMaoTempTccjDetailDto> GetDetailAsync(ShangWaiMaoTempTccjDetailParam param)
{
if (string.IsNullOrWhiteSpace(param?.StudentNo))
{
throw new Exception("学号不能为空");
}
var whereBuilder = new StringBuilder(" where student_no = @StudentNo ");
var dbParams = new DynamicParameters();
dbParams.Add("StudentNo", param.StudentNo.Trim());
if (!string.IsNullOrWhiteSpace(param.SchoolYear))
{
whereBuilder.Append(" and school_year = @SchoolYear ");
dbParams.Add("SchoolYear", param.SchoolYear.Trim());
}
if (!string.IsNullOrWhiteSpace(param.SchoolTerm))
{
whereBuilder.Append(" and school_term = @SchoolTerm ");
dbParams.Add("SchoolTerm", param.SchoolTerm.Trim());
}
var sql = $@"
select *
from {TableName}
{whereBuilder}
order by school_year desc, school_term desc
limit 1;
select
avg(lungs_score) as LungsScore,
avg(meter50_score) as Meter50Score,
avg(standing_long_jump_score) as StandingLongJumpScore,
avg(sit_and_reach_score) as SitAndReachScore,
avg(case when sex = '1' then meter1000_score when sex = '2' then meter800_score else null end) as EnduranceScore,
avg(case when sex = '1' then pull_up_score when sex = '2' then sit_up_score else null end) as StrengthScore
from {TableName};";
var (studentList, averageList) = await Dapper.QueryMultipleAsync<TempTccj, TempTccjPortraitAverageData>(sql, dbParams);
var student = studentList.FirstOrDefault();
if (student == null)
{
throw new Exception("未找到该学生体测详情");
}
var averages = averageList.FirstOrDefault() ?? new TempTccjPortraitAverageData();
return new ShangWaiMaoTempTccjDetailDto
{
BasicInfo = BuildBasicInfo(student),
DetailItems = BuildDetailItems(student),
PortraitItems = BuildPortraitItems(student, averages)
};
}
private static string NormalizeSex(string sex)
{
var normalized = sex?.Trim();
return normalized switch
{
"男" => "1",
"女" => "2",
_ => normalized
};
}
private static ShangWaiMaoTempTccjBasicInfo BuildBasicInfo(TempTccj student)
{
return new ShangWaiMaoTempTccjBasicInfo
{
CollegeName = student.college_name,
GradeName = GetGradeDisplayName(student.grade_no),
AdministrativeClass = student.class_name,
StudentNo = student.student_no,
Name = student.name,
Sex = GetSexDisplayName(student.sex),
HealthScore = FormatDisplayValue(student.health_score),
AddScore = FormatDisplayValue(student.add_score),
TotalScore = FormatDisplayValue(student.score),
Conclusion = student.conclusion,
Remark = string.Empty
};
}
private static List<ShangWaiMaoTempTccjDetailItem> BuildDetailItems(TempTccj student)
{
var isMale = student.sex == "1";
return new List<ShangWaiMaoTempTccjDetailItem>
{
CreateDetailItem("身高", student.height, "厘米"),
CreateDetailItem("体重", student.weight, "公斤"),
CreateDetailItem("肺活量", student.lungs, "毫升", null, student.lungs_score, student.lungs_leve),
CreateDetailItem("50米跑", student.meter50, "秒", null, student.meter50_score, student.meter50_leve),
CreateDetailItem("立定跳远", student.standing_long_jump, "厘米", null, student.standing_long_jump_score, student.standing_long_jump_leve),
CreateDetailItem("坐位体前屈", student.sit_and_reach, "厘米", null, student.sit_and_reach_score, student.sit_and_reach_leve),
CreateDetailItem(isMale ? "1000米跑" : "800米跑", isMale ? student.meter1000 : student.meter800, "分/秒", student.bonus2_df, isMale ? student.meter1000_score : student.meter800_score, isMale ? student.meter1000_leve : student.meter800_leve),
CreateDetailItem(isMale ? "引体向上" : "1分钟仰卧起坐", isMale ? student.pull_up : student.sit_up, isMale ? "次" : "次/分钟", student.bonus1_df, isMale ? student.pull_up_score : student.sit_up_score, isMale ? student.pull_up_leve : student.sit_up_leve),
CreateDetailItem("左眼裸眼视力", student.leftVision),
CreateDetailItem("右眼裸眼视力", student.rightVision),
CreateDetailItem("左眼球镜", student.left_sphere),
CreateDetailItem("右眼球镜", student.right_sphere),
CreateDetailItem("左眼柱镜", student.left_cytdnder),
CreateDetailItem("右眼柱镜", student.right_cytdnder)
};
}
private static List<ShangWaiMaoTempTccjPortraitItem> BuildPortraitItems(TempTccj student, TempTccjPortraitAverageData averages)
{
var isMale = student.sex == "1";
return new List<ShangWaiMaoTempTccjPortraitItem>
{
CreatePortraitItem("肺活量", student.lungs_score, averages.LungsScore),
CreatePortraitItem("中长跑", isMale ? student.meter1000_score : student.meter800_score, averages.EnduranceScore),
CreatePortraitItem("引体/仰卧", isMale ? student.pull_up_score : student.sit_up_score, averages.StrengthScore),
CreatePortraitItem("立定跳远", student.standing_long_jump_score, averages.StandingLongJumpScore),
CreatePortraitItem("坐位体前屈", student.sit_and_reach_score, averages.SitAndReachScore),
CreatePortraitItem("50米跑", student.meter50_score, averages.Meter50Score)
};
}
private static ShangWaiMaoTempTccjDetailItem CreateDetailItem(string itemName, decimal? achievement, string unit = "", decimal? addScore = null, decimal? score = null, string level = "")
{
return new ShangWaiMaoTempTccjDetailItem
{
ItemName = itemName,
Achievement = FormatDisplayValue(achievement),
Unit = unit,
AddScore = FormatDisplayValue(addScore),
Score = FormatDisplayValue(score),
Level = level ?? string.Empty
};
}
private static ShangWaiMaoTempTccjDetailItem CreateDetailItem(string itemName, string achievement, string unit = "", string addScore = "", string score = "", string level = "")
{
return new ShangWaiMaoTempTccjDetailItem
{
ItemName = itemName,
Achievement = achievement ?? string.Empty,
Unit = unit,
AddScore = addScore ?? string.Empty,
Score = score ?? string.Empty,
Level = level ?? string.Empty
};
}
private static ShangWaiMaoTempTccjPortraitItem CreatePortraitItem(string itemName, decimal? personalScore, decimal? schoolAverageScore)
{
return new ShangWaiMaoTempTccjPortraitItem
{
ItemName = itemName,
PersonalScore = personalScore,
SchoolAverageScore = schoolAverageScore
};
}
private static string GetSexDisplayName(string sex)
{
return sex switch
{
"1" => "男",
"2" => "女",
_ => sex ?? string.Empty
};
}
private static string GetGradeDisplayName(string gradeNo)
{
var normalized = gradeNo?.Trim();
return normalized switch
{
"41" => "大一",
"42" => "大二",
"43" => "大三",
"44" => "大四",
_ => normalized ?? string.Empty
};
}
private static string FormatDisplayValue(decimal? value)
{
return value.HasValue ? value.Value.ToString("0.##") : string.Empty;
}
private sealed class TempTccjPortraitAverageData
{
public decimal? LungsScore { get; set; }
public decimal? Meter50Score { get; set; }
public decimal? StandingLongJumpScore { get; set; }
public decimal? SitAndReachScore { get; set; }
public decimal? EnduranceScore { get; set; }
public decimal? StrengthScore { get; set; }
}
public async Task<List<TempTccj>> GetAllAsync()
{
var result = await Dapper.QueryListAsync<TempTccj>($"select * from {TableName}", null);
return result.ToList();
}
public Task<int> InsertAsync(TempTccj entity)
{
const string sql = @"
insert into temp_tccj
(
school_year, school_term, student_no, name, sex, class_no, grade_no, class_name, college_name,
test_state, exempt, add_score, health_score, score, conclusion, height, weight, bmi, bmi_df,
bmi_score, bmi_leve, lungs, lungs_df, lungs_score, lungs_leve, meter50, meter50_df, meter50_score,
meter50_leve, standing_long_jump, standing_long_jump_df, standing_long_jump_score, standing_long_jump_leve,
sit_and_reach, sit_and_reach_df, sit_and_reach_score, sit_and_reach_leve, meter800, meter800_df,
meter800_score, meter800_leve, meter1000, meter1000_df, meter1000_score, meter1000_leve, sit_up,
sit_up_df, sit_up_score, sit_up_leve, pull_up, pull_up_df, pull_up_score, pull_up_leve, skip, skip_df,
skip_score, skip_leve, shuttle_run, shuttle_run_df, shuttle_run_score, shuttle_run_leve, leftVision,
rightVision, leftMirror, rightMirror, leftAmetropia, rightAmetropia, left_sphere, right_sphere,
left_cytdnder, right_cytdnder, left_axial, right_axial, is_ok_mirror, bonus1, bonus1_df, bonus2, bonus2_df
)
values
(
@school_year, @school_term, @student_no, @name, @sex, @class_no, @grade_no, @class_name, @college_name,
@test_state, @exempt, @add_score, @health_score, @score, @conclusion, @height, @weight, @bmi, @bmi_df,
@bmi_score, @bmi_leve, @lungs, @lungs_df, @lungs_score, @lungs_leve, @meter50, @meter50_df, @meter50_score,
@meter50_leve, @standing_long_jump, @standing_long_jump_df, @standing_long_jump_score, @standing_long_jump_leve,
@sit_and_reach, @sit_and_reach_df, @sit_and_reach_score, @sit_and_reach_leve, @meter800, @meter800_df,
@meter800_score, @meter800_leve, @meter1000, @meter1000_df, @meter1000_score, @meter1000_leve, @sit_up,
@sit_up_df, @sit_up_score, @sit_up_leve, @pull_up, @pull_up_df, @pull_up_score, @pull_up_leve, @skip, @skip_df,
@skip_score, @skip_leve, @shuttle_run, @shuttle_run_df, @shuttle_run_score, @shuttle_run_leve, @leftVision,
@rightVision, @leftMirror, @rightMirror, @leftAmetropia, @rightAmetropia, @left_sphere, @right_sphere,
@left_cytdnder, @right_cytdnder, @left_axial, @right_axial, @is_ok_mirror, @bonus1, @bonus1_df, @bonus2, @bonus2_df
);";
return Dapper.ExcuteNonQueryAsync(sql, entity);
}
public Task<int> InsertRangeAsync(IEnumerable<TempTccj> entities)
{
var entityList = entities?.ToList() ?? new List<TempTccj>();
if (entityList.Count == 0)
{
return Task.FromResult(0);
}
const string sql = @"
insert into temp_tccj
(
school_year, school_term, student_no, name, sex, class_no, grade_no, class_name, college_name,
test_state, exempt, add_score, health_score, score, conclusion, height, weight, bmi, bmi_df,
bmi_score, bmi_leve, lungs, lungs_df, lungs_score, lungs_leve, meter50, meter50_df, meter50_score,
meter50_leve, standing_long_jump, standing_long_jump_df, standing_long_jump_score, standing_long_jump_leve,
sit_and_reach, sit_and_reach_df, sit_and_reach_score, sit_and_reach_leve, meter800, meter800_df,
meter800_score, meter800_leve, meter1000, meter1000_df, meter1000_score, meter1000_leve, sit_up,
sit_up_df, sit_up_score, sit_up_leve, pull_up, pull_up_df, pull_up_score, pull_up_leve, skip, skip_df,
skip_score, skip_leve, shuttle_run, shuttle_run_df, shuttle_run_score, shuttle_run_leve, leftVision,
rightVision, leftMirror, rightMirror, leftAmetropia, rightAmetropia, left_sphere, right_sphere,
left_cytdnder, right_cytdnder, left_axial, right_axial, is_ok_mirror, bonus1, bonus1_df, bonus2, bonus2_df
)
values
(
@school_year, @school_term, @student_no, @name, @sex, @class_no, @grade_no, @class_name, @college_name,
@test_state, @exempt, @add_score, @health_score, @score, @conclusion, @height, @weight, @bmi, @bmi_df,
@bmi_score, @bmi_leve, @lungs, @lungs_df, @lungs_score, @lungs_leve, @meter50, @meter50_df, @meter50_score,
@meter50_leve, @standing_long_jump, @standing_long_jump_df, @standing_long_jump_score, @standing_long_jump_leve,
@sit_and_reach, @sit_and_reach_df, @sit_and_reach_score, @sit_and_reach_leve, @meter800, @meter800_df,
@meter800_score, @meter800_leve, @meter1000, @meter1000_df, @meter1000_score, @meter1000_leve, @sit_up,
@sit_up_df, @sit_up_score, @sit_up_leve, @pull_up, @pull_up_df, @pull_up_score, @pull_up_leve, @skip, @skip_df,
@skip_score, @skip_leve, @shuttle_run, @shuttle_run_df, @shuttle_run_score, @shuttle_run_leve, @leftVision,
@rightVision, @leftMirror, @rightMirror, @leftAmetropia, @rightAmetropia, @left_sphere, @right_sphere,
@left_cytdnder, @right_cytdnder, @left_axial, @right_axial, @is_ok_mirror, @bonus1, @bonus1_df, @bonus2, @bonus2_df
);";
return Dapper.ExcuteNonQueryAsync(sql, entityList);
}
}
}