123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- package api
- import (
- "context"
- "copter-train/db/model"
- "copter-train/db/repo"
- "errors"
- "fmt"
- "strconv"
- "time"
- "github.com/gin-gonic/gin"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/mongo"
- )
- // 本年每月学习时长
- func StatisticsLearnProcess(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- db := c.Param("scope")
- if len(db) == 0 {
- return nil, errors.New("scope不能为空")
- }
- // 如果没有uid参数,则查询当前用户的
- uid := c.Query("uid")
- if len(uid) == 0 {
- uid = apictx.User.ID
- }
- _type := c.Query("type")
- // 如果没有年份参数,则查询当前年份的
- _year := c.Query("year")
- year := 2024
- if len(_year) == 0 {
- year = time.Now().Year()
- } else {
- year_, err := strconv.Atoi(_year)
- if err != nil {
- return nil, errors.New("year参数错误")
- }
- year = year_
- }
- fmt.Println("year:", year)
- colls := apictx.CreateRepoCtx().Client.GetDbCollection(db, repo.CollectionLearnLog)
- return AggregateMonthlyLearnTime(colls, uid, _type, year)
- }
- // 整个模块的学习时长 不需要cid约束
- func AggregateMonthlyLearnTime(colls *mongo.Collection, uid string, learnType string, year int) ([]bson.M, error) {
- chinaTimeZone := time.FixedZone("CST", 8*60*60) // 中国时区
- pipeline := mongo.Pipeline{
- // {
- // {Key: "$addFields", Value: bson.D{
- // {Key: "dateParts", Value: bson.D{
- // {Key: "$dateToParts", Value: bson.M{
- // "date": "$createTime",
- // "timezone": "Asia/Shanghai",
- // }},
- // }},
- // }},
- // },
- // {
- // {Key: "$match", Value: bson.D{
- // {Key: "uid", Value: uid},
- // {Key: "dateParts.year", Value: year},
- // // {Key: "dateParts.month", Value: bson.D{
- // // {Key: "$gte", Value: 1},
- // // {Key: "$lt", Value: 13},
- // // }},
- // }},
- // },
- // {
- // {Key: "$project", Value: bson.D{
- // {Key: "month", Value: bson.D{
- // {Key: "$month", Value: "$createTime"},
- // }},
- // {Key: "learnTime", Value: 1},
- // }},
- // },
- // {
- // {Key: "$group", Value: bson.D{
- // {Key: "_id", Value: "$month"},
- {
- {Key: "$match", Value: bson.D{
- {Key: "createTime", Value: bson.D{
- {Key: "$gte", Value: time.Date(year, time.January, 1, 0, 0, 0, 0, chinaTimeZone)},
- {Key: "$lt", Value: time.Date(year+1, time.January, 1, 0, 0, 0, 0, chinaTimeZone)},
- }},
- }},
- },
- // 将 createTime 字段分解为年和月
- {
- {Key: "$addFields", Value: bson.D{
- // {"year", bson.D{{"$year", bson.D{{"$add", []interface{}{"$createTime", 8 * 60 * 60 * 1000}}}}}},
- {Key: "month", Value: bson.D{{Key: "$month", Value: bson.D{{Key: "$add", Value: []interface{}{"$createTime", 8 * 60 * 60 * 1000}}}}}},
- }},
- },
- // 按年和月分组,并计算每个月的正确和错误数量
- {
- {Key: "$group", Value: bson.D{
- {Key: "_id", Value: "$month"},
- {Key: "totalLearnTime", Value: bson.D{
- {Key: "$sum", Value: "$learnTime"},
- }},
- }},
- },
- {
- {Key: "$sort", Value: bson.D{
- {Key: "_id", Value: 1},
- }},
- },
- }
- cursor, err := colls.Aggregate(context.TODO(), pipeline)
- if err != nil {
- return nil, err
- }
- var results []bson.M
- if err = cursor.All(context.TODO(), &results); err != nil {
- return nil, err
- }
- return results, nil
- }
- // 个人:上次学习时长
- // 获取最新一条数据
- func StatisticsLastLearnTime(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- db := c.Param("scope")
- if len(db) == 0 {
- return nil, errors.New("scope不能为空")
- }
- // 如果没有uid参数,则查询当前用户的
- uid := c.Query("uid")
- if len(uid) == 0 {
- uid = apictx.User.ID
- }
- learnLog := &model.LearnLog{}
- found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
- Db: db,
- CollectName: repo.CollectionLearnLog,
- Query: repo.Map{"uid": uid},
- Sort: bson.M{"createTime": -1},
- }, learnLog)
- if err != nil {
- return nil, err
- }
- if !found {
- return 0, nil
- }
- return learnLog.LearnTime, nil
- }
- // 个人:用户总学习时长
- func StatisticsTotalLearnTime(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- db := c.Param("scope")
- if len(db) == 0 {
- return nil, errors.New("scope不能为空")
- }
- // 如果没有uid参数,则查询当前用户的
- uid := c.Query("uid")
- if len(uid) == 0 {
- uid = apictx.User.ID
- }
- colls := apictx.CreateRepoCtx().Client.GetDbCollection(db, repo.CollectionLearnLog)
- return AggregateTotalLearnTime(colls, uid)
- }
- // 查询用户学习总时长
- func AggregateTotalLearnTime(colls *mongo.Collection, uid string) (int, error) {
- pipeline := mongo.Pipeline{
- {
- {Key: "$match", Value: bson.D{
- {Key: "uid", Value: uid},
- }},
- },
- {
- {Key: "$group", Value: bson.D{
- {Key: "_id", Value: "$uid"},
- {Key: "totalLearnTime", Value: bson.D{
- {Key: "$sum", Value: "$learnTime"},
- }},
- }},
- },
- }
- cursor, err := colls.Aggregate(context.TODO(), pipeline)
- if err != nil {
- return 0, err
- }
- var results []bson.M
- if err = cursor.All(context.TODO(), &results); err != nil {
- return 0, err
- }
- if len(results) > 0 {
- if v, ok := results[0]["totalLearnTime"].(int32); ok {
- return int(v), nil
- }
- return 0, nil
- }
- return 0, nil
- }
- // 个人: 获取最后一场考试的成绩
- func StatisticsLastExeamScore(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- db := c.Param("scope")
- if len(db) == 0 {
- return nil, errors.New("scope不能为空")
- }
- // 如果没有uid参数,则查询当前用户的
- uid := c.Query("uid")
- if len(uid) == 0 {
- uid = apictx.User.ID
- }
- exeamLog := &model.ExeamLog{}
- found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
- Db: db,
- CollectName: repo.CollectionExeamLog,
- Query: repo.Map{"uid": uid},
- Sort: bson.M{"createTime": -1},
- }, exeamLog)
- if err != nil {
- return nil, err
- }
- if !found {
- return 0, nil
- }
- fmt.Println(exeamLog)
- return exeamLog.Score, nil
- }
- // 个人: 获取历史最好成绩
- func StatisticsBestExeamScore(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- db := c.Param("scope")
- if len(db) == 0 {
- return nil, errors.New("scope不能为空")
- }
- // 如果没有uid参数,则查询当前用户的
- uid := c.Query("uid")
- if len(uid) == 0 {
- uid = apictx.User.ID
- }
- exeamLog := &model.ExeamLog{}
- found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
- Db: db,
- CollectName: repo.CollectionExeamLog,
- Query: repo.Map{"uid": uid},
- Sort: bson.M{"score": -1},
- }, exeamLog)
- if err != nil {
- return nil, err
- }
- if !found {
- return 0, nil
- }
- return exeamLog.Score, nil
- }
- // 个人: 已学习模块数
- // 统计各个模块的学习总时长,根据总时长时间判断是否已学习
- // 只需要返回统计各个模块的时长汇总,cid相同的为同一个模块
- func StatisticsLearnedModules(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- db := c.Param("scope")
- if len(db) == 0 {
- return nil, errors.New("scope不能为空")
- }
- // 如果没有uid参数,则查询当前用户的
- uid := c.Query("uid")
- if len(uid) == 0 {
- uid = apictx.User.ID
- }
- colls := apictx.CreateRepoCtx().Client.GetDbCollection(db, repo.CollectionLearnLog)
- pipeline := mongo.Pipeline{
- {
- {Key: "$match", Value: bson.D{
- {Key: "uid", Value: uid},
- }},
- },
- {
- {Key: "$group", Value: bson.D{
- {Key: "_id", Value: "$cid"},
- {Key: "totalLearnTime", Value: bson.D{{Key: "$sum", Value: "$learnTime"}}},
- }},
- },
- }
- cursor, err := colls.Aggregate(apictx.CreateRepoCtx().Ctx, pipeline)
- if err != nil {
- return nil, err
- }
- var results []bson.M
- if err = cursor.All(apictx.CreateRepoCtx().Ctx, &results); err != nil {
- return nil, err
- }
- return results, nil
- }
- // 个人: 统计用户本年每月考核正确和错误数
- func StatisticsExeamTFRate(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- db := c.Param("scope")
- if len(db) == 0 {
- return nil, errors.New("scope不能为空")
- }
- // 如果没有uid参数,则查询当前用户的
- uid := c.Query("uid")
- if len(uid) == 0 {
- uid = apictx.User.ID
- }
- _year := c.Query("year")
- year := 2024
- if len(_year) == 0 {
- year = time.Now().Year()
- } else {
- year_, err := strconv.Atoi(_year)
- if err != nil {
- return nil, errors.New("year参数错误")
- }
- year = year_
- }
- fmt.Println(year)
- colls := apictx.CreateRepoCtx().Client.GetDbCollection(db, repo.CollectionExeamLog)
- chinaTimeZone := time.FixedZone("CST", 8*60*60) // 中国时区
- fmt.Println(uid)
- pipeline := mongo.Pipeline{
- // 筛选出特定时间范围的记录
- {
- {Key: "$match", Value: bson.D{
- {Key: "createTime", Value: bson.D{
- {Key: "$gte", Value: time.Date(year, time.January, 1, 0, 0, 0, 0, chinaTimeZone)},
- {Key: "$lt", Value: time.Date(year+1, time.January, 1, 0, 0, 0, 0, chinaTimeZone)},
- }},
- }},
- },
- // 将 createTime 字段分解为年和月
- {
- {Key: "$addFields", Value: bson.D{
- // {"year", bson.D{{"$year", bson.D{{"$add", []interface{}{"$createTime", 8 * 60 * 60 * 1000}}}}}},
- {Key: "month", Value: bson.D{{Key: "$month", Value: bson.D{{Key: "$add", Value: []interface{}{"$createTime", 8 * 60 * 60 * 1000}}}}}},
- }},
- },
- // 按年和月分组,并计算每个月的正确和错误数量
- {
- {Key: "$group", Value: bson.D{
- {Key: "_id", Value: "$month"},
- {Key: "correct", Value: bson.D{{Key: "$sum", Value: "$correct"}}},
- {Key: "error", Value: bson.D{{Key: "$sum", Value: "$error"}}},
- }},
- },
- // 排序结果
- {
- {Key: "$sort", Value: bson.D{{Key: "_id", Value: 1}}},
- },
- }
- cursor, err := colls.Aggregate(context.TODO(), pipeline)
- if err != nil {
- return nil, err
- }
- var results []bson.M
- if err = cursor.All(apictx.CreateRepoCtx().Ctx, &results); err != nil {
- return nil, err
- }
- return results, nil
- }
|