package controller import ( "case-api/api/dao" "case-api/api/dto" "case-api/api/model" "case-api/api/requests" "case-api/api/responses" "case-api/api/service" "case-api/global" "case-api/utils" "github.com/gin-gonic/gin" "math" "strconv" "time" ) type Case struct { } // GetCasePage 获取列表-分页 func (b *Case) GetCasePage(c *gin.Context) { caseRequest := requests.CaseRequest{} req := caseRequest.GetCasePage if err := c.ShouldBind(&req); err != nil { responses.FailWithMessage(err.Error(), c) return } // 参数验证 if err := global.Validate.Struct(req); err != nil { responses.FailWithMessage(utils.Translate(err), c) return } if req.Page == 0 { req.Page = 1 } if req.PageSize == 0 { req.PageSize = 20 } platformId := c.GetInt64("PlatformId") // 平台id if platformId == 0 { responses.FailWithMessage("内部错误", c) return } req.PlatformId = platformId userId := c.GetInt64("UserId") // 用户id if userId == 0 { responses.FailWithMessage("内部错误", c) return } req.UserId = userId // 获取用户信息 userDao := dao.UserDao{} user, err := userDao.GetUserById(userId) if err != nil { responses.FailWithMessage("内部错误", c) return } // 获取数据 caseDao := dao.CaseDao{} cases, total, err := caseDao.GetCasePageSearch(req, req.Page, req.PageSize) if err != nil { responses.FailWithMessage(err.Error(), c) return } // 处理返回值 g := dto.GetCaseListDto(cases) projectPlatformDao := dao.ProjectPlatformDao{} casePlatformDao := dao.CasePlatformDao{} userService := service.UserService{} for _, caseDto := range g { // 加载是否为新病例(最近7天) caseDto.LoadIsNew(caseDto.CreatedAt) // 获取项目关联平台 maps := make(map[string]interface{}) maps["project_id"] = caseDto.ProjectId maps["platform_id"] = platformId projectPlatform, _ := projectPlatformDao.GetProjectPlatform(maps) if projectPlatform != nil { if caseDto.CaseStatus != 1 { continue } // 获取病例平台表 maps = make(map[string]interface{}) maps["case_id"] = caseDto.CaseId maps["platform_id"] = platformId casePlatform, err := casePlatformDao.GetCasePlatform(maps) if err != nil && casePlatform == nil { continue } if projectPlatform.IsWelfare == 1 { // 单个病例总积分-单个病例已发放积分 diffScore := projectPlatform.SingleCaseScore - casePlatform.IssuedScore if diffScore > 0 { caseDto.IsWelfare = 1 } } } // 检测用户是否已参与过病例 -- 需考虑相同手机号的用户 caseId, err := strconv.ParseInt(caseDto.CaseId, 10, 64) if err != nil { responses.Fail(c) return } isJoin := userService.CheckUserIsJoinCase(caseId, user.MobileEncryption) if isJoin == true { caseDto.LoadIsJoin(true) } } result := make(map[string]interface{}) result["page"] = req.Page result["page_size"] = req.PageSize result["total"] = total result["data"] = g responses.OkWithData(result, c) } // GetCaseQuestionSelectList 获取病例题目选择列表 func (b *Case) GetCaseQuestionSelectList(c *gin.Context) { id := c.Param("case_id") if id == "" { responses.FailWithMessage("缺少参数", c) return } // 将 id 转换为 int64 类型 caseId, err := strconv.ParseInt(id, 10, 64) if err != nil { responses.Fail(c) return } platformId := c.GetInt64("PlatformId") // 平台id if platformId == 0 { responses.FailWithMessage("内部错误", c) return } userId := c.GetInt64("UserId") // 用户id if userId == 0 { responses.FailWithMessage("内部错误", c) return } // 检测病例是否属于平台 casePlatformDao := dao.CasePlatformDao{} maps := make(map[string]interface{}) maps["case_id"] = caseId maps["platform_id"] = platformId _, err = casePlatformDao.GetCasePlatform(maps) if err != nil { responses.FailWithMessage("非法数据", c) return } // 获取病例详情 caseDao := dao.CaseDao{} result, err := caseDao.GetCaseById(caseId) if err != nil { responses.FailWithMessage(err.Error(), c) return } // 获取病例题目列表 caseItemQuestionDao := dao.CaseItemQuestionDao{} maps = make(map[string]interface{}) maps["case_id"] = caseId caseItemQuestions, err := caseItemQuestionDao.GetCaseItemQuestionPreloadList(maps) g := make([]*dto.CaseItemQuestionDto, len(caseItemQuestions)) for i, v := range caseItemQuestions { questionDto := dto.GetCaseItemQuestionDto(v) // 加载数据-病例明细-题目-选项 if len(v.CaseItemQuestionOption) > 0 { questionDto = questionDto.LoadCaseItemQuestionOption(v.CaseItemQuestionOption) } if len(v.StatCaseQuestion) > 0 { for _, optionDto := range questionDto.CaseItemQuestionOption { for _, caseQuestionDto := range v.StatCaseQuestion { // 将 id 转换为 int64 类型 optionId, err := strconv.ParseInt(optionDto.OptionId, 10, 64) if err != nil { responses.Fail(c) return } if optionId == caseQuestionDto.QuestionId { // 占比 proportion := math.Round(float64(caseQuestionDto.SelectNum)/float64(result.JoinNum)*10000) / 100 optionDto.LoadProportion(proportion) } } } } // 将转换后的结构体添加到新切片中 g[i] = questionDto } responses.OkWithData(g, c) } // FinishCase 完成病例 func (b *Case) FinishCase(c *gin.Context) { caseRequest := requests.CaseRequest{} req := caseRequest.FinishCase if err := c.ShouldBindJSON(&req); err != nil { responses.FailWithMessage(err.Error(), c) return } // 参数验证 if err := global.Validate.Struct(req); err != nil { responses.FailWithMessage(utils.Translate(err), c) return } if len(req.Answer) > 0 || req.Answer == nil { for _, answer := range req.Answer { if err := global.Validate.Struct(answer); err != nil { responses.FailWithMessage(utils.Translate(err), c) return } } } id := c.Param("case_id") if id == "" { responses.FailWithMessage("缺少参数", c) return } // 将 id 转换为 int64 类型 caseId, err := strconv.ParseInt(id, 10, 64) if err != nil { responses.Fail(c) return } platformId := c.GetInt64("PlatformId") // 平台id if platformId == 0 { responses.FailWithMessage("内部错误", c) return } userId := c.GetInt64("UserId") // 用户id if userId == 0 { responses.FailWithMessage("内部错误", c) return } projectId, err := strconv.ParseInt(req.ProjectId, 10, 64) if err != nil { responses.Fail(c) return } req.PlatformId = platformId req.UserId = userId // 获取病例数据 caseDao := dao.CaseDao{} caseResult, err := caseDao.GetCaseById(caseId) if err != nil { responses.FailWithMessage("非法病例", c) return } if caseResult.CaseStatus == 2 { responses.FailWithMessage("非法病例", c) return } // 检测病例是否属于平台 casePlatformDao := dao.CasePlatformDao{} maps := make(map[string]interface{}) maps["case_id"] = caseId maps["platform_id"] = platformId casePlatform, err := casePlatformDao.GetCasePlatform(maps) if err != nil { responses.FailWithMessage("非法数据", c) return } // 获取用户信息 userDao := dao.UserDao{} user, err := userDao.GetUserById(userId) if err != nil { responses.FailWithMessage("非法用户", c) return } // 检测用户是否属于白名单 projectPlatformWhiteService := service.ProjectPlatformWhiteService{} isWhite, _ := projectPlatformWhiteService.CheckProjectPlatformWhiteByUser(user, projectId, platformId) // 开始事务 tx := global.Db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() // 检测用户是否已参与过病例 -- 需考虑相同手机号的用户 userService := service.UserService{} isJoin := userService.CheckUserIsJoinCase(caseId, user.MobileEncryption) if isJoin == true { tx.Rollback() // 已参与该病例,无法完成 responses.Ok(c) return } caseService := service.CaseService{} if req.Content != "" { // 处理评论内容 basicSensitiveWordService := service.BasicSensitiveWordService{} content, isSensitive := basicSensitiveWordService.Filter(req.Content) // 新增评论 caseCommentDao := dao.CaseCommentDao{} caseComment := &model.CaseComment{ CaseId: caseId, PlatformId: platformId, Level: 1, UserId: userId, Status: 1, IsSensitive: isSensitive, IsHighQuality: 0, IsGrantHighQuality: 0, LikeNum: 0, Content: content, } if isSensitive == 1 { caseComment.ContentWord = req.Content } caseComment, err = caseCommentDao.AddCaseComment(tx, caseComment) if err != nil { tx.Rollback() responses.FailWithMessage("评论失败", c) return } // 增加病例留言人数 err = caseService.AddCaseMessageNum(tx, caseId, casePlatform.CasePlatformId) if err != nil { tx.Rollback() responses.FailWithMessage("评论失败", c) return } } if req.StartRead == "" || req.EndRead == "" { tx.Rollback() responses.FailWithMessage("参数错误", c) return } // 新增参与记录 caseUser := &model.CaseUser{ CaseId: caseId, PlatformId: platformId, UserId: userId, ShareUserIden: req.ShareUserIden, TotalScore: 0, } // 开始参与时间 startRead, err := time.Parse("2006-01-02 15:04:05", req.StartRead) if err != nil { tx.Rollback() responses.FailWithMessage("评论失败9", c) return } caseUser.StartTime = model.LocalTime(startRead) // 结束参与时间 endRead, err := time.Parse("2006-01-02 15:04:05", req.EndRead) if err != nil { tx.Rollback() responses.FailWithMessage("评论失败8", c) return } caseUser.EndTime = model.LocalTime(endRead) // 计算阅读时长 readDuration := endRead.Sub(startRead) if readDuration <= 0 { tx.Rollback() responses.FailWithMessage("评论失败7", c) return } caseUser.ReadDuration = int(readDuration.Seconds()) caseUserDao := dao.CaseUserDao{} _, err = caseUserDao.AddCaseUser(tx, caseUser) if err != nil { tx.Rollback() responses.FailWithMessage("评论失败6", c) return } // 增加病例参加人数 err = caseService.AddCaseJoinNum(tx, caseId, casePlatform.CasePlatformId, isWhite) if err != nil { tx.Rollback() responses.FailWithMessage("评论失败5", c) return } // 增加用户答题记录 if len(req.Answer) > 0 || req.Answer == nil { err = userService.AddCaseUserAnswer(tx, caseId, platformId, userId, caseUser.CaseUserId, req.Answer) if err != nil { tx.Rollback() responses.FailWithMessage("评论失败4", c) return } } // 发放积分-完成阅读 err = userService.ReportUserScore(tx, caseResult.ProjectId, caseId, platformId, 1, user) if err != nil { tx.Rollback() responses.FailWithMessage("评论失败3", c) return } // 获取项目关联平台配置 projectPlatformDao := dao.ProjectPlatformDao{} maps = make(map[string]interface{}) maps["project_id"] = req.ProjectId maps["platform_id"] = platformId projectPlatform, err := projectPlatformDao.GetProjectPlatform(maps) if err != nil { tx.Rollback() responses.FailWithMessage("评论失败1", c) return } // 发放积分-阅读时间满足 if int(readDuration.Seconds()) >= projectPlatform.ReadDuration { err = userService.ReportUserScore(tx, caseResult.ProjectId, caseId, platformId, 2, user) if err != nil { tx.Rollback() responses.FailWithMessage("评论失败2", c) return } } // 上报用户答题数据 if len(req.Answer) > 0 || req.Answer == nil { err = userService.ReportCaseUserAnswer(caseId, platformId, user, caseUser) if err != nil { // 失败不返回,只记录日志。 utils.LogJsonErr("上报用户答题数据", err.Error()) } } tx.Commit() responses.Ok(c) } // GetCase 获取详情 func (b *Case) GetCase(c *gin.Context) { id := c.Param("case_id") if id == "" { responses.FailWithMessage("缺少参数", c) return } // 将 id 转换为 int64 类型 caseId, err := strconv.ParseInt(id, 10, 64) if err != nil { responses.Fail(c) return } platformId := c.GetInt64("PlatformId") // 平台id if platformId == 0 { responses.FailWithMessage("内部错误", c) return } userId := c.GetInt64("UserId") // 用户id if userId == 0 { responses.FailWithMessage("内部错误", c) return } // 获取用户信息 userDao := dao.UserDao{} user, err := userDao.GetUserById(userId) if err != nil { responses.FailWithMessage("内部错误", c) return } // 检测病例是否属于平台 casePlatformDao := dao.CasePlatformDao{} maps := make(map[string]interface{}) maps["case_id"] = caseId maps["platform_id"] = platformId _, err = casePlatformDao.GetCasePlatform(maps) if err != nil { responses.FailWithMessage("非法数据", c) return } // 获取病例详情 caseDao := dao.CaseDao{} result, err := caseDao.GetCaseById(caseId) if err != nil { responses.FailWithMessage(err.Error(), c) return } if result.CaseStatus == 2 { responses.FailWithMessage("数据异常", c) return } g := dto.GetCaseDto(result) caseItemDao := dao.CaseItemDao{} maps = make(map[string]interface{}) maps["case_id"] = caseId caseItems, err := caseItemDao.GetCaseItemList(maps) if err != nil { responses.FailWithMessage("数据异常", c) return } // 检测用户是否已参与过病例 -- 需考虑相同手机号的用户 userService := service.UserService{} isJoin := userService.CheckUserIsJoinCase(caseId, user.MobileEncryption) if isJoin == true { // 已参与该病例 g.LoadIsJoin(true) } // 加载数据-病例明细 g.LoadCaseItem(caseItems) // 获取项目关联平台 projectPlatformDao := dao.ProjectPlatformDao{} maps = make(map[string]interface{}) maps["project_id"] = result.ProjectId maps["platform_id"] = platformId projectPlatform, _ := projectPlatformDao.GetProjectPlatform(maps) if projectPlatform == nil { responses.FailWithMessage("数据异常", c) return } // 获取病例平台表 maps = make(map[string]interface{}) maps["case_id"] = result.CaseId maps["platform_id"] = platformId casePlatform, _ := casePlatformDao.GetCasePlatform(maps) if casePlatform == nil { responses.FailWithMessage("数据异常", c) return } if projectPlatform.IsWelfare == 1 { // 单个病例总积分-单个病例已发放积分 diffScore := projectPlatform.SingleCaseScore - casePlatform.IssuedScore if diffScore > 0 { g.IsWelfare = 1 } } caseItemQuestionDao := dao.CaseItemQuestionDao{} caseItemModelDao := dao.CaseItemModelDao{} for _, item := range g.CaseItem { // 模块 maps = make(map[string]interface{}) maps["case_item_id"] = item.CaseItemId caseItemModel, err := caseItemModelDao.GetCaseItemModelList(maps) if err != nil { responses.FailWithMessage("数据异常", c) return } item.LoadCaseItemModel(caseItemModel) maps = make(map[string]interface{}) maps["case_item_id"] = item.CaseItemId caseItemQuestions, err := caseItemQuestionDao.GetCaseItemQuestionPreloadList(maps) if err == nil && len(caseItemQuestions) > 0 { // 加载数据-病例明细-题目 caseItemQuestionDto := make([]*dto.CaseItemQuestionDto, len(caseItemQuestions)) for i, v := range caseItemQuestions { questionDto := dto.GetCaseItemQuestionDto(v) // 加载数据-病例明细-题目-选项 if len(v.CaseItemQuestionOption) > 0 { questionDto = questionDto.LoadCaseItemQuestionOption(v.CaseItemQuestionOption) } if len(v.StatCaseQuestion) > 0 { for _, optionDto := range questionDto.CaseItemQuestionOption { for _, caseQuestionDto := range v.StatCaseQuestion { // 将 id 转换为 int64 类型 optionId, err := strconv.ParseInt(optionDto.OptionId, 10, 64) if err != nil { responses.Fail(c) return } if optionId == caseQuestionDto.OptionId { // 计算占比 proportion := math.Round(float64(caseQuestionDto.SelectNum)/float64(result.JoinNum)*10000) / 100 // 加载数据-占比 optionDto.LoadProportion(proportion) // 加载数据-被选择数量 optionDto.LoadSelectNum(caseQuestionDto.SelectNum) } } } } // 将转换后的结构体添加到新切片中 caseItemQuestionDto[i] = questionDto } item.CaseItemQuestion = caseItemQuestionDto } } responses.OkWithData(g, c) }