2025-03-07 16:57:28 +08:00

662 lines
16 KiB
Go

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)
}