|
|
@ -123,10 +123,36 @@ func (s *sQuestionBank) QuestionDel(ctx context.Context, req *v1.QuestionDelReq) |
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
// UserScoreOutput 获取用户成绩列表
|
|
|
// UserScoreOutput 获取用户成绩列表
|
|
|
func (s *sQuestionBank) UserScoreOutput(ctx context.Context, req *v1.UserScoreOutputReq) (res []*v1.UserScoreOutput, total int, err error) { |
|
|
|
|
|
|
|
|
func (s *sQuestionBank) UserScoreOutput(ctx context.Context, req *v1.UserScoreOutputReq) (res []*v1.UserScoreOutputRes, total int, err error) { |
|
|
db := g.Model("user a"). |
|
|
db := g.Model("user a"). |
|
|
RightJoin("total_score b", "a.jwcode=b.jwcode"). |
|
|
|
|
|
|
|
|
RightJoin("total_score b", "a.jwcode = b.jwcode"). |
|
|
Fields("a.id", "a.user_name", "a.user_identity", "a.jwcode", "b.created_at", "b.score") |
|
|
Fields("a.id", "a.user_name", "a.user_identity", "a.jwcode", "b.created_at", "b.score") |
|
|
|
|
|
|
|
|
|
|
|
// 添加查询条件
|
|
|
|
|
|
if req.UserName != "" { |
|
|
|
|
|
db = db.Where("a.user_name = ?", req.UserName) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if req.UserIdentity != "" { |
|
|
|
|
|
db = db.Where("a.user_identity = ?", req.UserIdentity) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if req.Jwcode != 0 { |
|
|
|
|
|
db = db.Where("a.jwcode = ?", req.Jwcode) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 时间范围查询
|
|
|
|
|
|
if req.StartTime != "" && req.EndTime != "" { |
|
|
|
|
|
db = db.Where("b.created_at BETWEEN ? AND ?", req.StartTime, req.EndTime) |
|
|
|
|
|
} else if req.StartTime != "" { |
|
|
|
|
|
db = db.Where("b.created_at >= ?", req.StartTime) |
|
|
|
|
|
} else if req.EndTime != "" { |
|
|
|
|
|
db = db.Where("b.created_at <= ?", req.EndTime) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 添加排序,默认按创建时间倒序
|
|
|
|
|
|
db = db.OrderDesc("b.created_at") |
|
|
|
|
|
|
|
|
err = db.Page(req.Page, req.PageSize).ScanAndCount(&res, &total, false) |
|
|
err = db.Page(req.Page, req.PageSize).ScanAndCount(&res, &total, false) |
|
|
return |
|
|
return |
|
|
} |
|
|
} |
|
|
@ -200,7 +226,7 @@ func (s *sQuestionBank) ExportQuestion(r *ghttp.Request, ctx context.Context, re |
|
|
fileName := "题目数据导出.xlsx" |
|
|
fileName := "题目数据导出.xlsx" |
|
|
|
|
|
|
|
|
// === 4. 设置表头 ===
|
|
|
// === 4. 设置表头 ===
|
|
|
headers := []string{"ID", "题干", "选项A", "选项B", "选项C", "选项D", "正确答案", "题目类型", "推荐课程", "引用次数", "错误次数", "错误率"} |
|
|
|
|
|
|
|
|
headers := []string{"序号", "ID", "题干", "选项A", "选项B", "选项C", "选项D", "正确答案", "题目类型", "推荐课程", "引用次数", "错误次数", "错误率"} |
|
|
for i, header := range headers { |
|
|
for i, header := range headers { |
|
|
col := string('A' + i) |
|
|
col := string('A' + i) |
|
|
excelFile.SetCellValue(sheetName, col+"1", header) |
|
|
excelFile.SetCellValue(sheetName, col+"1", header) |
|
|
@ -245,13 +271,119 @@ func (s *sQuestionBank) ExportQuestion(r *ghttp.Request, ctx context.Context, re |
|
|
excelFile.SetCellStyle(sheetName, "A1", "L"+strconv.Itoa(lastRow), style) |
|
|
excelFile.SetCellStyle(sheetName, "A1", "L"+strconv.Itoa(lastRow), style) |
|
|
|
|
|
|
|
|
// 设置列宽
|
|
|
// 设置列宽
|
|
|
excelFile.SetColWidth(sheetName, "A", "A", 10) // ID
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "B", "B", 40) // 题干
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "C", "F", 20) // 选项A-D
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "G", "G", 12) // 正确答案
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "H", "H", 15) // 题目类型
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "I", "I", 20) // 推荐课程
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "J", "L", 12) // 统计信息
|
|
|
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "B", "B", 10) // ID
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "C", "C", 40) // 题干
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "D", "G", 20) // 选项A-D
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "H", "H", 12) // 正确答案
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "I", "I", 15) // 题目类型
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "J", "J", 20) // 推荐课程
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "K", "M", 12) // 统计信息
|
|
|
|
|
|
|
|
|
|
|
|
// === 7. 输出 Excel 文件 ===
|
|
|
|
|
|
buffer, err := excelFile.WriteToBuffer() |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
response.JsonExit(r, 400, "生成Excel文件失败", err.Error()) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 设置响应头
|
|
|
|
|
|
r.Response.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") |
|
|
|
|
|
r.Response.Header().Set("Content-Disposition", "attachment; filename="+fileName) |
|
|
|
|
|
r.Response.Write(buffer.Bytes()) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
// ExportUserScore 导出用户成绩数据到 Excel
|
|
|
|
|
|
func (s *sQuestionBank) ExportUserScore(r *ghttp.Request, ctx context.Context, req *v1.UserScoreOutputReq) { |
|
|
|
|
|
// === 1. 数据查询和验证 ===
|
|
|
|
|
|
var result []*v1.UserScoreOutputRes |
|
|
|
|
|
|
|
|
|
|
|
// 查询总数
|
|
|
|
|
|
_, total, err := service.QuestionBank().UserScoreOutput(ctx, req) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
response.JsonExit(r, 400, "查询失败", err.Error()) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 数据量验证
|
|
|
|
|
|
if total == 0 { |
|
|
|
|
|
response.JsonExit(r, 400, "查询结果为空") |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
if total > 20000 { |
|
|
|
|
|
response.JsonExit(r, 400, "导出数据过多,请添加筛选条件后再导出") |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// === 2. 分批查询数据 ===
|
|
|
|
|
|
var num int |
|
|
|
|
|
req.PageSize = 1000 |
|
|
|
|
|
for { |
|
|
|
|
|
res, total, err := service.QuestionBank().UserScoreOutput(ctx, req) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
response.JsonExit(r, 400, "分批查询失败", err.Error()) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
result = append(result, res...) |
|
|
|
|
|
num += req.PageSize |
|
|
|
|
|
if num >= total { |
|
|
|
|
|
break |
|
|
|
|
|
} |
|
|
|
|
|
req.Page++ |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// === 3. 创建 Excel 文件 ===
|
|
|
|
|
|
excelFile := excelize.NewFile() |
|
|
|
|
|
sheetName := "Sheet1" |
|
|
|
|
|
fileName := "用户成绩导出.xlsx" |
|
|
|
|
|
|
|
|
|
|
|
// === 4. 设置表头 ===
|
|
|
|
|
|
headers := []string{"序号", "ID", "用户名", "用户身份", "精网号", "成绩", "创建时间"} |
|
|
|
|
|
for i, header := range headers { |
|
|
|
|
|
col := string('A' + i) |
|
|
|
|
|
excelFile.SetCellValue(sheetName, col+"1", header) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// === 5. 写入数据 ===
|
|
|
|
|
|
rowIndex := 2 |
|
|
|
|
|
for _, userScore := range result { |
|
|
|
|
|
excelFile.SetCellValue(sheetName, "A"+strconv.Itoa(rowIndex), rowIndex-1) |
|
|
|
|
|
excelFile.SetCellValue(sheetName, "B"+strconv.Itoa(rowIndex), userScore.Id) |
|
|
|
|
|
excelFile.SetCellValue(sheetName, "C"+strconv.Itoa(rowIndex), userScore.UserName) |
|
|
|
|
|
excelFile.SetCellValue(sheetName, "D"+strconv.Itoa(rowIndex), userScore.UserIdentity) |
|
|
|
|
|
excelFile.SetCellValue(sheetName, "E"+strconv.Itoa(rowIndex), userScore.Jwcode) |
|
|
|
|
|
excelFile.SetCellValue(sheetName, "F"+strconv.Itoa(rowIndex), userScore.Score) |
|
|
|
|
|
excelFile.SetCellValue(sheetName, "G"+strconv.Itoa(rowIndex), userScore.CreatedAt) |
|
|
|
|
|
|
|
|
|
|
|
rowIndex++ |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// === 6. 样式设置 ===
|
|
|
|
|
|
lastRow := rowIndex - 1 |
|
|
|
|
|
|
|
|
|
|
|
// 创建样式
|
|
|
|
|
|
style, err := excelFile.NewStyle(&excelize.Style{ |
|
|
|
|
|
Alignment: &excelize.Alignment{ |
|
|
|
|
|
Horizontal: "center", |
|
|
|
|
|
Vertical: "center", |
|
|
|
|
|
}, |
|
|
|
|
|
}) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
response.JsonExit(r, 400, "创建样式失败", err.Error()) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 应用样式
|
|
|
|
|
|
excelFile.SetCellStyle(sheetName, "A1", "F"+strconv.Itoa(lastRow), style) |
|
|
|
|
|
|
|
|
|
|
|
// 设置列宽
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "B", "B", 10) // ID
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "C", "C", 20) // 用户名
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "D", "D", 15) // 用户身份
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "E", "E", 15) // 精网号
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "F", "F", 10) // 成绩
|
|
|
|
|
|
excelFile.SetColWidth(sheetName, "G", "G", 20) // 创建时间
|
|
|
|
|
|
|
|
|
// === 7. 输出 Excel 文件 ===
|
|
|
// === 7. 输出 Excel 文件 ===
|
|
|
buffer, err := excelFile.WriteToBuffer() |
|
|
buffer, err := excelFile.WriteToBuffer() |
|
|
|