初始
This commit is contained in:
807
internal/app/system/logic/busQuestionSave/bus_question_save.go
Normal file
807
internal/app/system/logic/busQuestionSave/bus_question_save.go
Normal file
@ -0,0 +1,807 @@
|
||||
// ==========================================================================
|
||||
// GFast自动生成logic操作代码。
|
||||
// 生成日期:2023-11-01 17:33:04
|
||||
// 生成路径: internal/app/system/logic/bus_question_save.go
|
||||
// 生成人:gfast
|
||||
// desc:用户试卷存储
|
||||
// company:云南奇讯科技有限公司
|
||||
// ==========================================================================
|
||||
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/jung-kurt/gofpdf"
|
||||
"github.com/tiger1103/gfast/v3/api/v1/common/coryCommon"
|
||||
"github.com/tiger1103/gfast/v3/api/v1/system"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/consts"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model/do"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/service"
|
||||
wxModel "github.com/tiger1103/gfast/v3/internal/app/wxApplet/model"
|
||||
"github.com/tiger1103/gfast/v3/library/liberr"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func init() {
|
||||
service.RegisterBusQuestionSave(New())
|
||||
}
|
||||
|
||||
func New() *sBusQuestionSave {
|
||||
return &sBusQuestionSave{}
|
||||
}
|
||||
|
||||
type sBusQuestionSave struct{}
|
||||
|
||||
//func (s *sBusQuestionSave) WeChatPdfWoFunc(ctx context.Context, req *system.WeChatPdfWoReq) (listRes *system.WeChatPdfWoRes, err error) {
|
||||
// listRes = new(system.WeChatPdfWoRes)
|
||||
// err = g.Try(ctx, func(ctx context.Context) {
|
||||
// mp := make(map[string]*model.ModelWeChatPdfWoRes)
|
||||
// //0、获取配置信息
|
||||
// var configurationEntity *model.BusQuestionsConfigurationInfoRes
|
||||
// err = dao.BusQuestionsConfiguration.Ctx(ctx).Limit(1).Scan(&configurationEntity)
|
||||
// liberr.ErrIsNil(ctx, err, "查询失败")
|
||||
// leftjion := ""
|
||||
// if req.ProjectId > 0 && req.TeamId == 0 { //查项目
|
||||
// leftjion = "b.openid = a.openid and b.project_id = '" + strconv.FormatInt(req.ProjectId, 10) + "' and b.deleted_at is null"
|
||||
// }
|
||||
// if req.ProjectId > 0 && req.TeamId > 0 { //查项目+班组
|
||||
// leftjion = "b.openid = a.openid and b.project_id = '" + strconv.FormatInt(req.ProjectId, 10) + "' and team_id = '" + strconv.FormatInt(req.TeamId, 10) + "' and b.deleted_at is null"
|
||||
// }
|
||||
// //1、获取线上的试卷信息
|
||||
// var mwor []*model.ModelWeChatPdfWoRes
|
||||
// m := dao.BusQuestionSave.Ctx(ctx).As("a").Fields(`a.openid,
|
||||
// b.user_name as userName,
|
||||
// a.pass,
|
||||
// (select sum( score ) from bus_question_save WHERE correct = 1 and openid = a.openid) as sumScore,
|
||||
// c.path,
|
||||
// a.time_out as timeOut,
|
||||
// a.take_time as takeTime,
|
||||
// a.created_at as createdAt`).
|
||||
// RightJoin("bus_construction_user", "b", leftjion).
|
||||
// LeftJoin("bus_question_save_pdf", "c", "c.openid = b.openid").
|
||||
// Where(`a.pass is not null`)
|
||||
// //if strings.EqualFold(req.IsPaging, "YES") {
|
||||
// array, err := m.Array()
|
||||
// listRes.Total = len(array)
|
||||
// if err != nil {
|
||||
// liberr.ErrIsNil(ctx, err, "获取总行数失败")
|
||||
// return
|
||||
// }
|
||||
// if req.PageNum == 0 {
|
||||
// req.PageNum = 1
|
||||
// }
|
||||
// listRes.CurrentPage = req.PageNum
|
||||
// if req.PageSize == 0 {
|
||||
// req.PageSize = consts.PageSize
|
||||
// }
|
||||
// m = m.Page(req.PageNum, req.PageSize)
|
||||
// //}
|
||||
// order := "a.created_at"
|
||||
// if req.OrderBy != "" {
|
||||
// order = req.OrderBy
|
||||
// }
|
||||
// err = m.Order(order).Scan(&mwor)
|
||||
// for i := range mwor {
|
||||
// mwor[i].TakeTimeStr = formatTime(mwor[i].TakeTime)
|
||||
// mwor[i].TimeOutStr = formatTime(mwor[i].TimeOut * 60)
|
||||
// mwor[i].Type = "1" //pdf
|
||||
// mp[mwor[i].Openid] = mwor[i]
|
||||
// }
|
||||
// //2、获取线下的试卷信息
|
||||
// var tj = "b.openid = a.openid and b.project_id = '" + strconv.FormatInt(req.ProjectId, 10) + "'"
|
||||
// if req.TeamId != 0 {
|
||||
// tj = tj + " and team_id = '" + strconv.FormatInt(req.TeamId, 10) + "'"
|
||||
// }
|
||||
// tj = tj + " and b.deleted_at is null"
|
||||
// var offlineEnitnty []*model.ModelWeChatPdfWoRes
|
||||
// err = g.DB().Model("bus_question_offline").As("a").
|
||||
// Fields(
|
||||
// "a.openid,"+
|
||||
// "b.user_name as userName,"+
|
||||
// "concat_ws( ',',a.pass,a.full_mark ) as pass,"+
|
||||
// "a.score as sumScore,"+
|
||||
// "a.img as path,").
|
||||
// LeftJoin("bus_construction_user", "b", tj).Scan(&offlineEnitnty)
|
||||
// //3、数据信息合并(同一个人选取最大分数的试卷信息)
|
||||
// for i := range offlineEnitnty {
|
||||
// //如果发现有重复的openid,那么就选取得分最大的
|
||||
// mpdata, ok := mp[offlineEnitnty[i].Openid]
|
||||
// if ok {
|
||||
// mpdataSplit := strings.Split(mpdata.Pass, ",")
|
||||
// mpdataFloat, _ := strconv.ParseFloat(mpdataSplit[1], 64)
|
||||
// mpdataScore, _ := strconv.ParseFloat(mpdata.SumScore, 64)
|
||||
// mpdataScoreOne := 100.00 / mpdataFloat * mpdataScore
|
||||
// offlineSplit := strings.Split(offlineEnitnty[i].Pass, ",")
|
||||
// offlineFloat, _ := strconv.ParseFloat(offlineSplit[1], 64)
|
||||
// offlineScore, _ := strconv.ParseFloat(offlineEnitnty[i].SumScore, 64)
|
||||
// offlineScoreTwo := 100.00 / offlineFloat * offlineScore
|
||||
// if mpdataScoreOne < offlineScoreTwo {
|
||||
// offlineEnitnty[i].Type = "2" //图片
|
||||
// mp[offlineEnitnty[i].Openid] = offlineEnitnty[i]
|
||||
// }
|
||||
// } else { //没有重复的就直接给
|
||||
// if offlineEnitnty[i].UserName != "" {
|
||||
// offlineEnitnty[i].Type = "2" //图片
|
||||
// mp[offlineEnitnty[i].Openid] = offlineEnitnty[i]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// var r []*model.ModelWeChatPdfWoRes
|
||||
// for _, v := range mp {
|
||||
// r = append(r, v)
|
||||
// }
|
||||
// listRes.List = r
|
||||
// liberr.ErrIsNil(ctx, err, "获取数据失败")
|
||||
// })
|
||||
// return
|
||||
//}
|
||||
|
||||
func (s *sBusQuestionSave) WeChatPdfWoFunc(ctx context.Context, req *system.WeChatPdfWoReq) (listRes *system.WeChatPdfWoRes, err error) {
|
||||
listRes = new(system.WeChatPdfWoRes)
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
r, err := WeChatPdfWo(ctx, req)
|
||||
liberr.ErrIsNil(ctx, err, "获取数据失败")
|
||||
//排序然后进行代码分页
|
||||
sortByNames(r)
|
||||
lenI := len(r)
|
||||
listRes.Total = lenI
|
||||
if req.PageNum == 0 {
|
||||
req.PageNum = 1
|
||||
}
|
||||
listRes.CurrentPage = req.PageNum
|
||||
if req.PageSize == 0 {
|
||||
req.PageSize = consts.PageSize
|
||||
}
|
||||
var num = req.PageNum*req.PageSize - req.PageSize
|
||||
var mun = req.PageSize + num
|
||||
if mun > lenI {
|
||||
mun = lenI
|
||||
} else {
|
||||
mun = req.PageSize + num
|
||||
}
|
||||
if req.Name != "" { //有查询条件就从第0个走
|
||||
r = r[0:mun]
|
||||
} else {
|
||||
r = r[num:mun]
|
||||
}
|
||||
listRes.List = r
|
||||
liberr.ErrIsNil(ctx, err, "获取数据失败")
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func WeChatPdfWo(ctx context.Context, req *system.WeChatPdfWoReq) (r []*model.ModelWeChatPdfWoRes, err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
mp := make(map[string]*model.ModelWeChatPdfWoRes)
|
||||
//0、获取配置信息
|
||||
var configurationEntity *model.BusQuestionsConfigurationInfoRes
|
||||
err = dao.BusQuestionsConfiguration.Ctx(ctx).Limit(1).Scan(&configurationEntity)
|
||||
liberr.ErrIsNil(ctx, err, "查询失败")
|
||||
//1、获取线上的试卷信息
|
||||
leftjion := ""
|
||||
if req.ProjectId > 0 && req.TeamId == 0 { //查项目
|
||||
leftjion = "a.project_id = '" + strconv.FormatInt(req.ProjectId, 10) + "' and b.user_name like '%" + req.Name + "%'"
|
||||
}
|
||||
if req.ProjectId > 0 && req.TeamId > 0 { //查项目+班组
|
||||
leftjion = "a.project_id = '" + strconv.FormatInt(req.ProjectId, 10) + "' and b.team_id = '" + strconv.FormatInt(req.TeamId, 10) + "' and b.user_name like '%" + req.Name + "%'"
|
||||
}
|
||||
//2、获取线下的试卷信息
|
||||
var tj = "a.project_id = '" + strconv.FormatInt(req.ProjectId, 10) + "' and b.user_name like '%" + req.Name + "%'"
|
||||
if req.TeamId != 0 {
|
||||
tj = tj + " and b.team_id = '" + strconv.FormatInt(req.TeamId, 10) + "'"
|
||||
}
|
||||
//3、数据合并
|
||||
var mwor []*model.ModelWeChatPdfWoRes
|
||||
sql := `SELECT
|
||||
openid,
|
||||
user_name AS userName,
|
||||
pass,
|
||||
sumScore,
|
||||
path,
|
||||
timeOut,
|
||||
takeTime,
|
||||
createdAt,
|
||||
oto
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
a.openid,
|
||||
b.user_name,
|
||||
a.pass,
|
||||
(
|
||||
SELECT
|
||||
SUM(score)
|
||||
FROM
|
||||
bus_question_save
|
||||
WHERE
|
||||
correct = 1
|
||||
AND openid = a.openid
|
||||
) AS sumScore,
|
||||
c.path,
|
||||
a.time_out AS timeOut,
|
||||
a.take_time AS takeTime,
|
||||
a.created_at AS createdAt,
|
||||
'1' as oto
|
||||
FROM
|
||||
bus_question_save AS a
|
||||
RIGHT JOIN bus_construction_user AS b ON (` + "b.openid = a.openid and b.deleted_at is null" + `)
|
||||
LEFT JOIN bus_question_save_pdf AS c ON (c.openid = b.openid)
|
||||
WHERE
|
||||
` + leftjion + `
|
||||
AND a.pass IS NOT NULL
|
||||
AND a.deleted_at IS NULL
|
||||
AND b.deleted_at IS NULL
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
a.openid,
|
||||
b.user_name,
|
||||
CONCAT_WS(',', a.pass, a.full_mark) AS pass,
|
||||
a.score AS sumScore,
|
||||
a.img AS path,
|
||||
NULL AS timeOut,
|
||||
NULL AS takeTime,
|
||||
a.created_at AS createdAt,
|
||||
'2' as oto
|
||||
FROM
|
||||
bus_question_offline AS a
|
||||
LEFT JOIN bus_construction_user AS b ON (` + "b.openid = a.openid and b.deleted_at is null" + `)
|
||||
WHERE
|
||||
` + tj + `
|
||||
AND b.deleted_at IS NULL
|
||||
) AS merged_data;`
|
||||
err := g.DB().Raw(sql).Scan(&mwor)
|
||||
liberr.ErrIsNil(ctx, err, "获取数据失败")
|
||||
for i := range mwor {
|
||||
mwor[i].TakeTimeStr = formatTime(mwor[i].TakeTime)
|
||||
mwor[i].TimeOutStr = formatTime(mwor[i].TimeOut * 60)
|
||||
mwor[i].Type = "1" //pdf
|
||||
mp[mwor[i].Openid] = mwor[i]
|
||||
}
|
||||
//3、数据信息合并(同一个人选取最大分数的试卷信息)
|
||||
for i := range mwor {
|
||||
//如果发现有重复的openid,那么就选取得分最大的
|
||||
mpdata, ok := mp[mwor[i].Openid]
|
||||
if ok {
|
||||
//mp里面的分数
|
||||
mpdataSplit := strings.Split(mpdata.Pass, ",")
|
||||
mpdataFloat, _ := strconv.ParseFloat(mpdataSplit[1], 64)
|
||||
mpdataScore, _ := strconv.ParseFloat(mpdata.SumScore, 64)
|
||||
mpdataScoreOne := 100.00 / mpdataFloat * mpdataScore
|
||||
//当前分数
|
||||
offlineSplit := strings.Split(mwor[i].Pass, ",")
|
||||
offlineFloat, _ := strconv.ParseFloat(offlineSplit[1], 64)
|
||||
offlineScore, _ := strconv.ParseFloat(mwor[i].SumScore, 64)
|
||||
offlineScoreTwo := 100.00 / offlineFloat * offlineScore
|
||||
if mpdataScoreOne < offlineScoreTwo {
|
||||
mwor[i].Type = "2" //图片
|
||||
mp[mwor[i].Openid] = mwor[i]
|
||||
}
|
||||
}
|
||||
//else { //没有重复的就直接给
|
||||
// if offlineEnitnty[i].UserName != "" {
|
||||
// offlineEnitnty[i].Type = "2" //图片
|
||||
// mp[offlineEnitnty[i].Openid] = offlineEnitnty[i]
|
||||
// }
|
||||
//}
|
||||
}
|
||||
for _, v := range mp {
|
||||
if v.UserName != "" {
|
||||
r = append(r, v)
|
||||
}
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 定义排序函数
|
||||
func sortByNames(slice []*model.ModelWeChatPdfWoRes) {
|
||||
// 使用 sort.Slice 函数进行排序
|
||||
sort.Slice(slice, func(i, j int) bool {
|
||||
return slice[i].UserName < slice[j].UserName // 按照 name 字段升序排序
|
||||
})
|
||||
}
|
||||
|
||||
func formatTime(seconds int64) string {
|
||||
hours := seconds / 3600 // 计算小时数
|
||||
minutes := (seconds % 3600) / 60 // 计算分钟数
|
||||
seconds = seconds % 60 // 计算剩余的秒数
|
||||
var result = ""
|
||||
if minutes == 0 {
|
||||
result = fmt.Sprintf("%02d秒", seconds)
|
||||
} else if hours == 0 {
|
||||
result = fmt.Sprintf("%02d分%02d秒", minutes, seconds)
|
||||
} else {
|
||||
result = fmt.Sprintf("%02d时%02d分%02d秒", hours, minutes, seconds)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *sBusQuestionSave) PassOrNotFunc(ctx context.Context, openid string) (res *system.PassOrNotRes, err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
res = new(system.PassOrNotRes)
|
||||
bqs := dao.BusQuestionSave.Ctx(ctx).Where("openid", openid).Safe()
|
||||
//1、查询及格分和满分
|
||||
value1, err := bqs.Fields("pass").Value()
|
||||
if value1 == nil {
|
||||
res.IsPass = "3"
|
||||
return
|
||||
}
|
||||
liberr.ErrIsNil(ctx, err, "获取信息失败")
|
||||
//2、查询用户所答对的分数
|
||||
value2, err := bqs.Fields("sum(score) as sumScore").Where("correct", "1").Value()
|
||||
liberr.ErrIsNil(ctx, err, "获取信息失败")
|
||||
//2.5、获取线下考试分数、计算得到最终及格线分数
|
||||
var offlineEnitnty *model.ModelWeChatPdfWoRes
|
||||
err = g.DB().Model("bus_question_offline").As("a").
|
||||
Fields(
|
||||
"a.openid,"+
|
||||
"b.user_name as userName,"+
|
||||
"concat_ws(a.pass,',',a.full_mark) asc pass,"+
|
||||
"a.score as sumScore,"+
|
||||
"a.img as path,").
|
||||
RightJoin(
|
||||
"bus_construction_user",
|
||||
"b",
|
||||
"b.openid = a.openid and b.deleted_at is null").
|
||||
Where("a.openid", openid).
|
||||
Scan(&offlineEnitnty)
|
||||
liberr.ErrIsNil(ctx, err, "获取信息失败")
|
||||
var scoreOne float64
|
||||
if offlineEnitnty != nil {
|
||||
offlineSplit := strings.Split(offlineEnitnty.Pass, ",")
|
||||
offlineFloat, _ := strconv.ParseFloat(offlineSplit[1], 64)
|
||||
offlineScore, _ := strconv.ParseFloat(offlineEnitnty.SumScore, 64)
|
||||
scoreOne = 100.00 / offlineFloat * offlineScore
|
||||
}
|
||||
//3、计算上次分数是否及格
|
||||
split := strings.Split(value1.String(), ",")
|
||||
fullMark, _ := strconv.ParseFloat(split[1], 64)
|
||||
passingGrade, _ := strconv.ParseFloat(split[0], 64)
|
||||
score := 100.00 / fullMark * value2.Float64()
|
||||
if scoreOne > score {
|
||||
if scoreOne >= passingGrade {
|
||||
res.IsPass = "1"
|
||||
} else {
|
||||
res.IsPass = "2"
|
||||
}
|
||||
res.PdfStr = offlineEnitnty.Path
|
||||
res.Type = "2" //图片
|
||||
liberr.ErrIsNil(ctx, err, "获取信息失败")
|
||||
} else {
|
||||
if score >= passingGrade {
|
||||
res.IsPass = "1"
|
||||
} else {
|
||||
res.IsPass = "2"
|
||||
}
|
||||
//4、返回上传试卷的pdf 供查看
|
||||
value3, err := g.DB().Model("bus_question_save_pdf").Ctx(ctx).Where("openid", openid).Fields("path").Value()
|
||||
res.PdfStr = value3.String()
|
||||
res.Type = "1" //pdf
|
||||
liberr.ErrIsNil(ctx, err, "获取信息失败")
|
||||
}
|
||||
return
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sBusQuestionSave) List(ctx context.Context, req *system.BusQuestionSaveSearchReq) (listRes *system.BusQuestionSaveSearchRes, err error) {
|
||||
listRes = new(system.BusQuestionSaveSearchRes)
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
m := dao.BusQuestionSave.Ctx(ctx).WithAll()
|
||||
if req.Id != "" {
|
||||
m = m.Where(dao.BusQuestionSave.Columns().Id+" = ?", req.Id)
|
||||
}
|
||||
if req.Openid != "" {
|
||||
m = m.Where(dao.BusQuestionSave.Columns().Openid+" = ?", req.Openid)
|
||||
}
|
||||
if req.BankId != "" {
|
||||
m = m.Where(dao.BusQuestionSave.Columns().BankId+" = ?", gconv.Int64(req.BankId))
|
||||
}
|
||||
if req.Answer != "" {
|
||||
m = m.Where(dao.BusQuestionSave.Columns().Answer+" = ?", req.Answer)
|
||||
}
|
||||
if req.Correct != "" {
|
||||
m = m.Where(dao.BusQuestionSave.Columns().Correct+" = ?", req.Correct)
|
||||
}
|
||||
if req.Sign != "" {
|
||||
m = m.Where(dao.BusQuestionSave.Columns().Sign+" = ?", req.Sign)
|
||||
}
|
||||
if req.TakeTime != "" {
|
||||
m = m.Where(dao.BusQuestionSave.Columns().TakeTime+" = ?", gconv.Int64(req.TakeTime))
|
||||
}
|
||||
if req.TimeOut != "" {
|
||||
m = m.Where(dao.BusQuestionSave.Columns().TimeOut+" = ?", gconv.Int(req.TimeOut))
|
||||
}
|
||||
if req.Pass != "" {
|
||||
m = m.Where(dao.BusQuestionSave.Columns().Pass+" = ?", req.Pass)
|
||||
}
|
||||
if len(req.DateRange) != 0 {
|
||||
m = m.Where(dao.BusQuestionSave.Columns().CreatedAt+" >=? AND "+dao.BusQuestionSave.Columns().CreatedAt+" <=?", req.DateRange[0], req.DateRange[1])
|
||||
}
|
||||
listRes.Total, err = m.Count()
|
||||
liberr.ErrIsNil(ctx, err, "获取总行数失败")
|
||||
if req.PageNum == 0 {
|
||||
req.PageNum = 1
|
||||
}
|
||||
listRes.CurrentPage = req.PageNum
|
||||
if req.PageSize == 0 {
|
||||
req.PageSize = consts.PageSize
|
||||
}
|
||||
order := "id desc"
|
||||
if req.OrderBy != "" {
|
||||
order = req.OrderBy
|
||||
}
|
||||
var res []*model.BusQuestionSaveInfoRes
|
||||
err = m.Fields(system.BusQuestionSaveSearchRes{}).Page(req.PageNum, req.PageSize).Order(order).Scan(&res)
|
||||
liberr.ErrIsNil(ctx, err, "获取数据失败")
|
||||
listRes.List = make([]*model.BusQuestionSaveListRes, len(res))
|
||||
for k, v := range res {
|
||||
listRes.List[k] = &model.BusQuestionSaveListRes{
|
||||
Id: v.Id,
|
||||
Openid: v.Openid,
|
||||
BankId: v.BankId,
|
||||
Answer: v.Answer,
|
||||
Correct: v.Correct,
|
||||
Score: v.Score,
|
||||
Sign: v.Sign,
|
||||
TakeTime: v.TakeTime,
|
||||
TimeOut: v.TimeOut,
|
||||
Pass: v.Pass,
|
||||
CreatedAt: v.CreatedAt,
|
||||
}
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sBusQuestionSave) GetById(ctx context.Context, id int64) (res *model.BusQuestionSaveInfoRes, err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
err = dao.BusQuestionSave.Ctx(ctx).WithAll().Where(dao.BusQuestionSave.Columns().Id, id).Scan(&res)
|
||||
liberr.ErrIsNil(ctx, err, "获取信息失败")
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sBusQuestionSave) Add(ctx context.Context, req *system.BusQuestionSaveAddReq) (res *system.BusQuestionSaveAddRes, err error) {
|
||||
res = new(system.BusQuestionSaveAddRes)
|
||||
err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
// 获取当前用户所在的项目,将试卷与项目进行绑定(复制人员迁移将试卷也带到另外一个项目)
|
||||
project, projectErr := dao.BusConstructionUser.Ctx(ctx).Where(dao.BusConstructionUser.Columns().Openid, req.Openid).Fields("project_id").Value()
|
||||
if projectErr != nil {
|
||||
liberr.ErrIsNil(ctx, errors.New("无法确认当前用户所在项目!"))
|
||||
return
|
||||
}
|
||||
/**
|
||||
第零部分:获取分数进行判断,判断是否存储此次试卷
|
||||
*/
|
||||
var scoreOne = 0.00 //第一次分数
|
||||
var scoreTwo = 0.00 //当前考试的分数
|
||||
type spEntity struct {
|
||||
SumScore float64 `p:"sumScore"`
|
||||
Pass string `p:"pass"`
|
||||
Sign string `p:"sign"`
|
||||
}
|
||||
var sp *spEntity
|
||||
err = dao.BusQuestionSave.Ctx(ctx).Fields("sum( score ) AS sumScore,"+
|
||||
"( SELECT pass FROM bus_question_save WHERE openid = '"+req.Openid+"' AND deleted_at IS NULL ORDER BY id asc LIMIT 1) as pass,"+"( SELECT sign FROM bus_question_save WHERE openid = '"+req.Openid+"' AND deleted_at IS NULL ORDER BY id asc LIMIT 1) as sign").
|
||||
Where("correct", "1").
|
||||
Where("openid", req.Openid).Scan(&sp)
|
||||
if err == nil {
|
||||
if sp.Pass != "" {
|
||||
split := strings.Split(sp.Pass, ",")
|
||||
float1, _ := strconv.ParseFloat(split[1], 64)
|
||||
scoreOne = 100.00 / float1 * sp.SumScore
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
/**
|
||||
第一部分:计算分数、存储
|
||||
*/
|
||||
//1、获取配置信息
|
||||
var configurationEntity *model.BusQuestionsConfigurationInfoRes
|
||||
err = dao.BusQuestionsConfiguration.Ctx(ctx).Limit(1).Scan(&configurationEntity)
|
||||
liberr.ErrIsNil(ctx, err, "添加失败")
|
||||
////3、图片上传
|
||||
//str, err := coryCommon.UploadFile(ctx, req.Sign, coryCommon.Helmet)
|
||||
//3、获取当前openid的签名,如果没有就提示“未查询到签名信息”
|
||||
var signature *wxModel.BusConstructiomUserSignatureRes
|
||||
err := g.DB().Model("bus_constructiom_user_signature").Where("openid", req.Openid).Scan(&signature)
|
||||
liberr.ErrIsNil(ctx, err, "添加失败")
|
||||
if signature == nil {
|
||||
err = errors.New("未查询到签名信息")
|
||||
liberr.ErrIsNil(ctx, err)
|
||||
return
|
||||
}
|
||||
//4、存储用户答题信息
|
||||
var bqs []*do.BusQuestionSave
|
||||
var fenshu = 0.0
|
||||
var number = 0
|
||||
for iii, data := range req.List {
|
||||
var correct = ""
|
||||
var pass = ""
|
||||
//获取题库的正确答案,然后和用户的答案作对比
|
||||
var bqb *model.BusQuestionBankInfoRes
|
||||
err = dao.BusQuestionBank.Ctx(ctx).WherePri(data.BankId).Scan(&bqb)
|
||||
if err != nil {
|
||||
err = errors.New("您的试卷被外星人卷走了!")
|
||||
liberr.ErrIsNil(ctx, err)
|
||||
return
|
||||
} else {
|
||||
if data.Answer == "" {
|
||||
err = errors.New("您还有题未答完!")
|
||||
liberr.ErrIsNil(ctx, err)
|
||||
return
|
||||
}
|
||||
if strings.Contains(strings.ToLower(bqb.CorrectAnswer), strings.ToLower(data.Answer)) {
|
||||
//if bqb.CorrectAnswer == data.Answer {
|
||||
correct = "1"
|
||||
fenshu = fenshu + data.Score
|
||||
number = number + 1
|
||||
} else {
|
||||
correct = "2"
|
||||
}
|
||||
}
|
||||
//记录这次的及格线和总分
|
||||
float1 := strconv.FormatFloat(configurationEntity.PassingScore, 'f', -1, 64)
|
||||
float2 := strconv.FormatFloat(configurationEntity.FullMark, 'f', -1, 64)
|
||||
pass = float1 + "," + float2
|
||||
var bqsTwo = &do.BusQuestionSave{
|
||||
Openid: req.Openid,
|
||||
BankId: data.BankId,
|
||||
Answer: data.Answer,
|
||||
Correct: correct,
|
||||
Score: data.Score,
|
||||
ProjectId: project,
|
||||
}
|
||||
if iii == 0 { //这几条数据只在每张试卷的第一条数据中存储(重复的没必要每条都存储)
|
||||
//bqsTwo.Sign = str
|
||||
bqsTwo.TakeTime = req.TakeTime
|
||||
bqsTwo.TimeOut = configurationEntity.AnswerTime
|
||||
bqsTwo.Pass = pass
|
||||
}
|
||||
bqs = append(bqs, bqsTwo)
|
||||
}
|
||||
scoreTwo = 100.00 / configurationEntity.FullMark * fenshu
|
||||
//6、返回数据
|
||||
res.AnswerTime = configurationEntity.AnswerTime
|
||||
res.TakeTime = req.TakeTime
|
||||
res.FullMark = configurationEntity.FullMark
|
||||
res.PassingScore = configurationEntity.PassingScore
|
||||
res.Score = fenshu
|
||||
res.Number = number
|
||||
//7、两次卷子的分数对比,第一次的分数比第二次大那么第二次只返回结果;第二次的分数比第一次大那么删除第一次的数据再重新插入
|
||||
if scoreOne > scoreTwo {
|
||||
return
|
||||
} else {
|
||||
//上面是比对
|
||||
//2、先查询当前用户是否有答题,有就把之前的删除(真删)
|
||||
value, _ := g.DB().Model("bus_question_save_pdf").Ctx(ctx).Where("openid", req.Openid).Limit(1).Fields("path").Value()
|
||||
if value != nil {
|
||||
//os.Remove(coryCommon.GetCWD() + "/" + sp.Sign) //删除签名
|
||||
coryCommon.BatchFile(strings.Split(value.String(), ",")) //删除pdf
|
||||
_, err = g.DB().Model("bus_question_save_pdf").Ctx(ctx).Where("openid", req.Openid).Delete()
|
||||
_, err = dao.BusQuestionSave.Ctx(ctx).Unscoped().Where("openid", req.Openid).Delete()
|
||||
}
|
||||
_, err = dao.BusQuestionSave.Ctx(ctx).Insert(bqs)
|
||||
}
|
||||
/**
|
||||
第二部分:生成pdf试卷
|
||||
*/
|
||||
//1、组装数据
|
||||
var we []*model.WoEntity
|
||||
//获取 单选、多选、判断
|
||||
err = dao.BusQuestionSave.Ctx(ctx).As("a").Fields(`
|
||||
c.question_type,
|
||||
c.question_text,
|
||||
c.options,
|
||||
a.answer,
|
||||
c.correct_answer,
|
||||
a.correct,
|
||||
a.score,
|
||||
a.sign,
|
||||
a.id,
|
||||
a.pass,
|
||||
b.user_name`).
|
||||
LeftJoin(`(SELECT openid,user_name from bus_construction_user where deleted_at is null) as b on a.openid = CONVERT(b.openid USING utf8)`).
|
||||
LeftJoin(`(SELECT id,question_type,question_text,options,correct_answer from bus_question_bank ) as c on a.bank_id = c.id`).
|
||||
Where("a.openid", req.Openid).OrderAsc("a.id").Scan(&we)
|
||||
if len(we) > 0 {
|
||||
value, _ := dao.BusQuestionSave.Ctx(ctx).Where("openid", req.Openid).Where("correct", "1").Fields("sum(score)").Value()
|
||||
s := configurationEntity.SingleChoice
|
||||
m := configurationEntity.MultipleChoice
|
||||
e := configurationEntity.Estimate
|
||||
var rs *model.ExaminationPaperRes
|
||||
rs = &model.ExaminationPaperRes{
|
||||
UserName: we[0].UserName,
|
||||
Pass: we[0].Pass,
|
||||
SumScore: value.String(),
|
||||
Sign: signature.Signature,
|
||||
Openid: req.Openid,
|
||||
}
|
||||
var one = new(model.ExaminationPaperOne)
|
||||
var two = new(model.ExaminationPaperOne)
|
||||
var three = new(model.ExaminationPaperOne)
|
||||
one.Topic = "一、单选题,共" + strconv.Itoa(s) + "道题,每小题" + strconv.FormatFloat(configurationEntity.SingleScore, 'f', -1, 64) + "分,共计" + strconv.FormatFloat(float64(s)*configurationEntity.SingleScore, 'f', -1, 64) + "分"
|
||||
two.Topic = "二、多选题,共" + strconv.Itoa(m) + "道题,每小题" + strconv.FormatFloat(configurationEntity.MultipleScore, 'f', -1, 64) + "分,共计" + strconv.FormatFloat(float64(m)*configurationEntity.MultipleScore, 'f', -1, 64) + "分"
|
||||
three.Topic = "三、判断题,共" + strconv.Itoa(e) + "道题,每小题" + strconv.FormatFloat(configurationEntity.EstimateScore, 'f', -1, 64) + "分,共计" + strconv.FormatFloat(float64(e)*configurationEntity.EstimateScore, 'f', -1, 64) + "分"
|
||||
var sEntity []*model.ExaminationPaperTwo
|
||||
var mEntity []*model.ExaminationPaperTwo
|
||||
var eEntity []*model.ExaminationPaperTwo
|
||||
for _, data := range we {
|
||||
var sy *model.ExaminationPaperTwo
|
||||
sy = &model.ExaminationPaperTwo{
|
||||
QuestionText: data.QuestionText,
|
||||
Options: data.Options,
|
||||
Answer: data.Answer,
|
||||
CorrectAnswer: data.CorrectAnswer,
|
||||
Correct: data.Correct,
|
||||
Score: data.Score,
|
||||
}
|
||||
if data.QuestionType == "1" {
|
||||
sEntity = append(sEntity, sy)
|
||||
} else if data.QuestionType == "2" {
|
||||
mEntity = append(mEntity, sy)
|
||||
} else if data.QuestionType == "3" {
|
||||
eEntity = append(eEntity, sy)
|
||||
}
|
||||
}
|
||||
one.List = sEntity
|
||||
two.List = mEntity
|
||||
three.List = eEntity
|
||||
rs.Single = one
|
||||
rs.Multiple = two
|
||||
rs.Estimate = three
|
||||
path, errPath := Wo(rs)
|
||||
if errPath != nil {
|
||||
errPath = errors.New("生成PDF试卷出现了意外,请重新提交!")
|
||||
liberr.ErrIsNil(ctx, errPath)
|
||||
return
|
||||
} else {
|
||||
path = strings.Replace(path, "resource/public", "/wxfile", 1)
|
||||
_, err = g.DB().Insert(ctx, "bus_question_save_pdf", gdb.Map{
|
||||
"openid": req.Openid,
|
||||
"path": path,
|
||||
})
|
||||
res.PdfStr = path
|
||||
}
|
||||
}
|
||||
liberr.ErrIsNil(ctx, err, "添加失败")
|
||||
})
|
||||
return err
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sBusQuestionSave) Delete(ctx context.Context, ids []int64) (err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
_, err = dao.BusQuestionSave.Ctx(ctx).Delete(dao.BusQuestionSave.Columns().Id+" in (?)", ids)
|
||||
liberr.ErrIsNil(ctx, err, "删除失败")
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func DeleteFunc(ctx context.Context, openidArr []string) (err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
//1、查询需要删除的pdf
|
||||
value, _ := g.DB().Model("bus_question_save_pdf").Ctx(ctx).Where("openid in (?)", openidArr).Fields("path").Array()
|
||||
for i := range value {
|
||||
coryCommon.BatchFile(strings.Split(value[i].String(), ",")) //删除pdf
|
||||
}
|
||||
//2、删除存储pdf的数据信息
|
||||
_, err = g.DB().Model("bus_question_save_pdf").Ctx(ctx).Where("openid in (?)", openidArr).Delete()
|
||||
liberr.ErrIsNil(ctx, err, "安全考试-删除pdf试卷失败")
|
||||
//3、删除用户存储的试卷信息
|
||||
_, err = dao.BusQuestionSave.Ctx(ctx).Unscoped().Where("openid in (?)", openidArr).Delete()
|
||||
liberr.ErrIsNil(ctx, err, "安全考试-删除用户试卷信息失败")
|
||||
//4、删除线下安全考试的用户信息
|
||||
_, err := g.DB().Model("bus_question_offline").Where("openid in (?)", openidArr).Delete()
|
||||
liberr.ErrIsNil(ctx, err, "安全考试-线下数据删除失败")
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Wo 导出试卷PDF
|
||||
func Wo(rs *model.ExaminationPaperRes) (path string, err error) {
|
||||
//1、创建pdf 并新增pdf页
|
||||
pdf := gofpdf.New("P", "mm", "A4", "")
|
||||
pdf.AddPage()
|
||||
//2、设置字体 分别为不加粗和加粗
|
||||
//fontStr := coryCommon.GetCWD() + "/resource/font/simhei.ttf"
|
||||
fontStr := "/resource/font/simhei.ttf"
|
||||
pdf.AddUTF8Font("simhei", "", fontStr)
|
||||
pdf.AddUTF8Font("simheiB", "B", fontStr)
|
||||
// 标题居中加粗
|
||||
pdf.SetFont("simheiB", "B", 36)
|
||||
pdf.CellFormat(190, 10, "中煤科工安全考试A卷", "0", 1, "C", false, 0, "")
|
||||
pdf.Ln(10)
|
||||
// 姓名、总分、实际得分
|
||||
pdf.SetFont("simhei", "", 16)
|
||||
pdf.CellFormat(63, 10, "姓名: "+rs.UserName, "0", 0, "L", false, 0, "")
|
||||
pdf.CellFormat(63, 10, "及格线/总分: "+rs.Pass, "0", 0, "L", false, 0, "")
|
||||
pdf.CellFormat(63, 10, "实际得分: "+rs.SumScore, "0", 1, "L", false, 0, "")
|
||||
pdf.Ln(6)
|
||||
//内容
|
||||
for i := 1; i <= 3; i++ {
|
||||
var ep = new(model.ExaminationPaperOne)
|
||||
if i == 1 {
|
||||
ep = rs.Single
|
||||
} else if i == 2 {
|
||||
ep = rs.Multiple
|
||||
} else if i == 3 {
|
||||
ep = rs.Estimate
|
||||
}
|
||||
//大题 单选、多选、判断
|
||||
pdf.SetFont("simhei", "", 20)
|
||||
pdf.CellFormat(190, 10, ep.Topic, "0", 1, "L", false, 0, "")
|
||||
pdf.SetFont("simhei", "", 12)
|
||||
for iTwo, data := range ep.List {
|
||||
//小题
|
||||
if i == 3 {
|
||||
pdf.MultiCell(0, 5, strconv.Itoa(iTwo+1)+"、"+data.QuestionText+"( "+data.Answer+" )", "", "", false)
|
||||
} else {
|
||||
pdf.MultiCell(0, 5, strconv.Itoa(iTwo+1)+"、"+Bracket(data.QuestionText, data.Answer), "", "", false)
|
||||
}
|
||||
split := strings.Split(data.Options, "@")
|
||||
num := len(split)
|
||||
for j, dataTwo := range split {
|
||||
//选项
|
||||
pdf.SetX(20)
|
||||
pdf.MultiCell(0, 5, dataTwo, "", "", false)
|
||||
if j == num-1 {
|
||||
if data.Correct == "2" {
|
||||
pdf.SetTextColor(255, 0, 0) // 设置文字颜色为红色
|
||||
pdf.SetX(20)
|
||||
pdf.CellFormat(190, 10, "正确答案为:"+data.CorrectAnswer, "0", 1, "L", false, 0, "")
|
||||
pdf.SetTextColor(35, 35, 35) // 设置文字颜色为红色
|
||||
}
|
||||
pdf.Ln(3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//签字
|
||||
pdf.Ln(20)
|
||||
pdf.SetX(120)
|
||||
pdf.SetFont("simheiB", "B", 16)
|
||||
pdf.CellFormat(15, 10, "签字:", "0", 0, "L", false, 0, "")
|
||||
//嵌入图片
|
||||
pdf.TransformBegin()
|
||||
pdf.TransformRotate(90, pdf.GetX(), pdf.GetY()) // 逆时针旋转 45 度
|
||||
imageOptions := gofpdf.ImageOptions{ImageType: "png", ReadDpi: false}
|
||||
getwd, err := os.Getwd()
|
||||
getwd = filepath.ToSlash(getwd)
|
||||
pathSign := getwd + "/" + rs.Sign
|
||||
pdf.ImageOptions(pathSign, pdf.GetX()-10, pdf.GetY(), 24, 0, true, imageOptions, 0, "")
|
||||
pdf.TransformEnd()
|
||||
//导出pdf
|
||||
fn := coryCommon.FileName("pdf")
|
||||
str := coryCommon.Ynr(coryCommon.Helmet)
|
||||
path = filepath.ToSlash(str + fn + ".pdf")
|
||||
err = pdf.OutputFileAndClose(getwd + "/" + path)
|
||||
return
|
||||
}
|
||||
|
||||
func Bracket(str string, replace string) (rn string) {
|
||||
rn = ""
|
||||
// 定义正则表达式模式,匹配不同的括号格式
|
||||
re := regexp.MustCompile(`\s*(\s*)\s*`)
|
||||
// 使用正则表达式替换所有匹配的括号格式为"(abc)"
|
||||
rn = re.ReplaceAllString(str, "( "+replace+" )")
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user