package service import ( "case-api/api/dao" "case-api/api/model" "case-api/api/requests" "case-api/extend/aliyun" "case-api/extend/app" "case-api/extend/superKangaroo" "case-api/utils" "errors" "fmt" "gorm.io/gorm" "io" "math/rand" "net/http" "strconv" "strings" "time" ) type UserService struct { } // HandleUserImage 处理用户图片 func (r *UserService) HandleUserImage(wxAvatar string) (ossPath string, err error) { if wxAvatar == "" { return "", nil } // 发送GET请求 resp, err := http.Get(wxAvatar) if err != nil { return "", err } defer func(Body io.ReadCloser) { _ = Body.Close() }(resp.Body) if resp.StatusCode != 200 { return "", errors.New("请求失败") } // 读取响应体 respBody, err := io.ReadAll(resp.Body) if err != nil { return "", err } // 设置文件名字 now := time.Now() dateTimeString := now.Format("20060102150405") // 当前时间字符串 rand.New(rand.NewSource(time.Now().UnixNano())) // 设置随机数 ossPath = "user/avatar/" + dateTimeString + fmt.Sprintf("%d", rand.Intn(9000)+1000) + ".png" // 上传oss _, err = aliyun.PutObjectByte(ossPath, respBody) if err != nil { return "", err } ossPath = "/" + ossPath return ossPath, nil } // GetUserInfo 获取用户数据-不存在时注册,存在时更新 func (r *UserService) GetUserInfo(tx *gorm.DB, req requests.Login) (user *model.User, err error) { userDao := dao.UserDao{} basicHospitalDao := dao.BasicHospitalDao{} // 佳动力 if req.Source == 3 { // 获取用户数据 maps := make(map[string]interface{}) if req.UserIden != "" { maps["user_iden"] = req.UserIden // 以此字段来判别是否同一个用户 } if req.UnionId != "" { maps["union_id"] = req.UnionId // 以此字段来判别是否同一个用户 } user, _ = userDao.GetUser(maps) if user != nil { // 获取用户医院 basicHospital, err := basicHospitalDao.GetBasicHospitalById(user.HospitalId) if err != nil { return nil, err } // 修改用户医院 basicHospitalData := make(map[string]interface{}) if basicHospital.HospitalName != req.HospitalName { basicHospitalData["hospital_name"] = req.HospitalName } if len(basicHospitalData) > 0 { err = basicHospitalDao.EditBasicHospitalById(tx, user.HospitalId, basicHospitalData) if err != nil { return nil, err } } // 修改用户 userData := make(map[string]interface{}) if user.UserName != req.DoctorName { userData["user_name"] = req.HospitalName user.UserName = req.HospitalName } if user.MobileEncryption != req.MobileEncryption { userData["mobile_encryption"] = req.MobileEncryption } if user.Title != utils.DoctorTitleToInt(req.Title) { userData["title"] = utils.DoctorTitleToInt(req.Title) } if user.DepartmentName != req.DepartmentName { userData["department_name"] = req.DepartmentName } if user.Address != req.Address { userData["address"] = req.Address } if len(userData) > 0 { err = userDao.EditUserById(tx, user.UserId, userData) if err != nil { return nil, err } } // 处理用户白名单 err = r.HandleUserWhite(tx, req.IsWhite, req.PlatformKey, req.ProjectId, user.UserId) if err != nil { return nil, err } } else { // 佳动力 // 检测医院是否存在 maps = make(map[string]interface{}) maps["source"] = 3 maps["hospital_name"] = req.HospitalName basicHospital, _ := basicHospitalDao.GetBasicHospital(maps) if basicHospital == nil { // 添加医院 hospital := &model.BasicHospital{ HospitalName: req.HospitalName, Source: req.Source, HospitalLevel: "未知", DoctorNumber: 0, Province: "", City: "", County: "", Address: "", } basicHospital, err = basicHospitalDao.AddBasicHospital(tx, hospital) if err != nil { return nil, err } } // 添加用户 user = &model.User{ UserIden: req.UserIden, UserName: req.DoctorName, UserMobile: "", MobileEncryption: req.MobileEncryption, Status: 1, RegisterSource: 3, OpenId: "", UnionId: "", Sex: 0, Avatar: "", Title: utils.DoctorTitleToInt(req.Title), DepartmentName: req.DepartmentName, HospitalId: basicHospital.HospitalId, Address: req.Address, } user, err = userDao.AddUser(tx, user) if err != nil { return nil, err } // 添加医院拥有医生人数 err = basicHospitalDao.Inc(tx, basicHospital.HospitalId, "doctor_number", 1) if err != nil { return nil, err } // 处理用户白名单 err = r.HandleUserWhite(tx, req.IsWhite, req.PlatformKey, req.ProjectId, user.UserId) if err != nil { return nil, err } } } if req.Source == 2 { // 获取医生数据-app user, err = r.GetAppUserInfo(tx, req) if err != nil { return nil, err } } return user, nil } // AddCaseUserAnswer 增加用户答题记录 func (r *UserService) AddCaseUserAnswer(tx *gorm.DB, caseId, platformId, userId, caseUserId int64, answers []*requests.Answer) (err error) { // 检测是否已经答题 caseUserAnswerDao := dao.CaseUserAnswerDao{} maps := make(map[string]interface{}) maps["case_user_id"] = caseUserId caseUserAnswer, _ := caseUserAnswerDao.GetCaseUserAnswer(maps) if caseUserAnswer != nil { return nil } // 新增答题记录 caseItemQuestionDao := dao.CaseItemQuestionDao{} statCaseQuestionDao := dao.StatCaseQuestionDao{} for _, answer := range answers { questionId, err := strconv.ParseInt(answer.QuestionId, 10, 64) if err != nil { return err } // 获取题目数据 caseItemQuestion, err := caseItemQuestionDao.GetCaseItemQuestionById(questionId) if err != nil { return err } // 问答题不处理 if caseItemQuestion.QuestionType == 3 { continue } if answer.OptionId == "" { return errors.New("失败") } caseUserAnswer = &model.CaseUserAnswer{ CaseUserId: caseUserId, PlatformId: platformId, QuestionId: questionId, UserId: userId, Answer: answer.Answer, IsTrue: 0, } // 判断是否正确 if caseItemQuestion.QuestionAnswer == answer.Answer { caseUserAnswer.IsTrue = 1 } _, err = caseUserAnswerDao.AddCaseUserAnswer(tx, caseUserAnswer) if err != nil { return err } // 处理回答统计 optionIds := strings.Split(answer.OptionId, ",") for _, option := range optionIds { optionId, err := strconv.ParseInt(option, 10, 64) if err != nil { return err } maps = make(map[string]interface{}) maps["case_id"] = caseId maps["question_id"] = answer.QuestionId maps["option_id"] = optionId statCaseQuestion, _ := statCaseQuestionDao.GetStatCaseQuestion(maps) if statCaseQuestion == nil { // 新增回答统计 statCaseQuestion = &model.StatCaseQuestion{ CaseId: caseId, QuestionId: questionId, OptionId: optionId, SelectNum: 1, } _, err := statCaseQuestionDao.AddStatCaseQuestion(tx, statCaseQuestion) if err != nil { return err } } else { // 增加回答统计数量 err = statCaseQuestionDao.Inc(tx, statCaseQuestion.StatId, "select_num", 1) if err != nil { return err } } } } return nil } // ReportCaseUserAnswer 上报用户答题记录 func (r *UserService) ReportCaseUserAnswer(caseId, caseUserId int64, user *model.User, caseUser *model.CaseUser) (err error) { // 获取答题记录 caseUserAnswerDao := dao.CaseUserAnswerDao{} maps := make(map[string]interface{}) maps["case_user_id"] = caseUserId caseUserAnswers, err := caseUserAnswerDao.GetCaseUserAnswerPreloadList(maps) if err != nil { return err } // 上报用户答题数据 _, err = superKangaroo.ReportUserAnswerScore(caseId, user.UserIden, caseUserAnswers, caseUser) if err != nil { return err } return nil } // ReportUserScore 发放积分 // scoreType : 积分类型(1:完成阅读 2:阅读时间满足 3:优质留言 4:再次优质留言 ) func (r *UserService) ReportUserScore(tx *gorm.DB, projectId, caseId, platformId int64, scoreType int, user *model.User) (err error) { // 获取项目关联平台 projectPlatformDao := dao.ProjectPlatformDao{} maps := make(map[string]interface{}) maps["project_id"] = projectId maps["platform_id"] = platformId projectPlatform, err := projectPlatformDao.GetProjectPlatform(maps) if err != nil { return err } // 检测福利开关 if projectPlatform.IsWelfare == 0 { // 福利未开 return nil } // 默认为白名单用户 isWhite := true if projectPlatform.IsWhite == 1 { projectPlatformWhiteService := ProjectPlatformWhiteService{} isWhite, err = projectPlatformWhiteService.CheckProjectPlatformWhiteByUser(user, projectId, platformId) if err != nil { return err } } // 获取需发放积分 score := 0 appScoreTypeStr := "" // 积分发放原因-app superScoreTypeStr := "" // 积分发放原因-超级袋鼠 nodeName := "" // 获取积分节点名称 if scoreType == 1 { // 完成阅读 score = projectPlatform.CompleteRead appScoreTypeStr = "互动病例-完成阅读" superScoreTypeStr = "调研奖励(完成阅读)" nodeName = "学习" } else if scoreType == 2 { // 阅读时间满足 score = projectPlatform.CompleteReadTime appScoreTypeStr = "互动病例-阅读时间满足" superScoreTypeStr = "调研奖励(阅读质量)" nodeName = "阅读达标" } else if scoreType == 3 { // 优质留言 score = projectPlatform.FirstHighQuality appScoreTypeStr = "互动病例-优质留言" superScoreTypeStr = "调研奖励(社区贡献)" nodeName = "优质留言" } else if scoreType == 4 { // 再次优质留言 score = projectPlatform.OnceMoreHighQuality appScoreTypeStr = "互动病例-优质留言" superScoreTypeStr = "调研奖励(社区贡献)" nodeName = "优质留言" } // 佳动力需求:非白名单用户也需要请求积分记录 // 当用户为非白名单时,重置积分数 if isWhite == false { score = 0 } recordScoreDao := dao.RecordScoreDao{} // 检测是否有相同手机号用户 userDao := dao.UserDao{} maps = make(map[string]interface{}) maps["mobile_encryption"] = user.MobileEncryption users, err := userDao.GetUserList(maps) if err != nil { return nil } for _, m := range users { // 检测该类型积分是否已经发放(其他平台也算) maps = make(map[string]interface{}) maps["project_id"] = projectId maps["case_id"] = caseId //maps["platform_id"] = platformId maps["user_id"] = m.UserId //maps["type"] = scoreType // 类型问题。查询时不要携带类型。如果只阅读完成,但是没有满足时间,满足时间的是否允许发放 recordScore, _ := recordScoreDao.GetRecordScore(maps) if recordScore != nil { // 积分已发放过 return nil } } // 获取病例关联平台数据 casePlatformDao := dao.CasePlatformDao{} maps = make(map[string]interface{}) maps["case_id"] = caseId maps["platform_id"] = platformId casePlatform, err := casePlatformDao.GetCasePlatform(maps) if err != nil { return err } // 检测全部积分是否已发放完毕 remainingScore := projectPlatform.SingleCaseScore - casePlatform.IssuedScore if remainingScore <= 0 { // 积分已发放完毕 return nil } // 新增发放记录-每发一次记录一次 recordScore := &model.RecordScore{ ProjectId: projectId, CaseId: caseId, PlatformId: platformId, UserId: user.UserId, UserName: user.UserName, Type: scoreType, NodeName: nodeName, Score: score, } recordScore, err = recordScoreDao.AddRecordScore(tx, recordScore) if err != nil { return err } // 获取用户参与记录 caseUserDao := dao.CaseUserDao{} maps = make(map[string]interface{}) maps["case_id"] = caseId maps["platform_id"] = platformId maps["user_id"] = user.UserId caseUser, _ := caseUserDao.GetCaseUserUseTx(tx, maps) if caseUser == nil { return errors.New("积分发放失败") } // 累计用户领取积分数据 err = caseUserDao.Inc(tx, caseUser.CaseUserId, "total_score", score) if err != nil { return err } // 累计平台发放积分数据 err = casePlatformDao.Inc(tx, casePlatform.CasePlatformId, "issued_score", score) if err != nil { return err } // 累计发放积分数据 caseDao := dao.CaseDao{} err = caseDao.Inc(tx, caseId, "issued_score", score) if err != nil { return err } // 发放积分- if platformId != 1 && platformId != 2 { return errors.New("积分发放失败") } // 肝胆相照 if platformId == 1 && score > 0 { _, err = app.ReportUserScore(appScoreTypeStr, user.UserIden, score) if err != nil { return err } } // 超级袋鼠 if platformId == 2 { // 获取病例数据 caseDao := dao.CaseDao{} result, err := caseDao.GetCaseById(caseId) if err != nil { return err } _, err = superKangaroo.ReportUserScore(caseId, user.UserIden, superScoreTypeStr, recordScore, result) if err != nil { return err } } return nil } // GetAppUserInfo 获取医生数据-app func (r *UserService) GetAppUserInfo(tx *gorm.DB, req requests.Login) (user *model.User, err error) { userDao := dao.UserDao{} // 医院唯一标识 var hospitalIden string var g *app.GetDoctorInfoResponse // 手机号 if req.MobileEncryption != "" { g, err = app.GetDoctorInfoByMobile(req.MobileEncryption) if err != nil { return nil, err } } // uuid if req.UserIden != "" { g, err = app.GetDoctorInfoByUuid(req.UserIden) if err != nil { return nil, err } } // UnionId if req.UnionId != "" { g, err = app.GetDoctorInfoByUnionId(req.UnionId) if err != nil { return nil, err } } // token if req.Token != "" { g, err = app.GetDoctorInfoByToken(req.Token) if err != nil { return nil, err } } maps := make(map[string]interface{}) maps["user_iden"] = g.Data.Uuid // 以此字段来判别是否同一个用户 user, _ = userDao.GetUser(maps) if user == nil { // 肝胆相照 user = &model.User{ UserIden: g.Data.Uuid, UserName: g.Data.RealName, UserMobile: g.Data.Mobile, MobileEncryption: utils.GenerateMD5(g.Data.Mobile), Status: 1, RegisterSource: 2, OpenId: "", UnionId: req.UnionId, Sex: 0, Avatar: "", Title: utils.DoctorTitleToInt(g.Data.PositionName), DepartmentName: g.Data.OfficeName, Address: g.Data.ProvName, } user, err = userDao.AddUser(tx, user) if err != nil { return nil, err } } else { userData := make(map[string]interface{}) if user.UserName != g.Data.RealName { userData["user_name"] = g.Data.RealName } if user.UserMobile != g.Data.Mobile { userData["user_mobile"] = g.Data.Mobile userData["mobile_encryption"] = utils.GenerateMD5(g.Data.Mobile) } if user.Title != utils.DoctorTitleToInt(g.Data.PositionName) { userData["title"] = utils.DoctorTitleToInt(g.Data.PositionName) } if user.DepartmentName != g.Data.OfficeName { userData["department_name"] = g.Data.OfficeName } if user.Address != g.Data.ProvName { userData["address"] = g.Data.ProvName } if len(userData) > 0 { err = userDao.EditUserById(tx, user.UserId, userData) if err != nil { return nil, err } } } hospitalIden = g.Data.HospitalUuid if hospitalIden == "" { return nil, errors.New("失败") } // 检测医院是否存在 basicHospitalDao := dao.BasicHospitalDao{} maps = make(map[string]interface{}) maps["source"] = 2 maps["hospital_iden"] = hospitalIden basicHospital, _ := basicHospitalDao.GetBasicHospital(maps) if basicHospital == nil { // 获取医院数据 gHospital, err := app.GetHospitalByUuid(hospitalIden) if err != nil { return nil, err } // 添加医院 hospital := &model.BasicHospital{ HospitalIden: hospitalIden, HospitalName: gHospital.Data.Name, Source: req.Source, HospitalLevel: gHospital.Data.Level, DoctorNumber: gHospital.Data.ExpertNum, Province: gHospital.Data.ProvName, City: "", County: "", Address: "", } basicHospital, err = basicHospitalDao.AddBasicHospital(tx, hospital) if err != nil { return nil, err } } // 修改用户所属医院 if basicHospital.HospitalId != user.HospitalId { maps = make(map[string]interface{}) dataMaps := make(map[string]interface{}) dataMaps["hospital_id"] = basicHospital.HospitalId err = userDao.EditUserById(tx, user.UserId, dataMaps) if err != nil { return nil, err } } return user, nil } // HandleUserWhite 处理用户白名单 func (r *UserService) HandleUserWhite(tx *gorm.DB, isWhite int, platformKey, projectId string, userId int64) error { platformDao := dao.PlatformDao{} maps := make(map[string]interface{}) maps["platform_key"] = platformKey platform, err := platformDao.GetPlatform(maps) if err != nil { return err } projectPlatformDao := dao.ProjectPlatformDao{} maps = make(map[string]interface{}) maps["project_id"] = projectId maps["platform_id"] = platform.PlatformId projectPlatform, err := projectPlatformDao.GetProjectPlatform(maps) if err != nil { return err } // 获取白名单数据 ProjectPlatformDoctorDao := dao.ProjectPlatformDoctorDao{} maps = make(map[string]interface{}) maps["project_platform_id"] = projectPlatform.ProjectPlatformId maps["user_id"] = userId projectPlatformDoctor, _ := ProjectPlatformDoctorDao.GetProjectPlatformDoctor(maps) if projectPlatformDoctor == nil { // 新增白名单 if isWhite == 1 { projectPlatformDoctor = &model.ProjectPlatformDoctor{ ProjectPlatformId: projectPlatform.ProjectPlatformId, UserId: userId, } projectPlatformDoctor, err = ProjectPlatformDoctorDao.AddProjectPlatformDoctor(tx, projectPlatformDoctor) if err != nil { return err } } } else { // 删除白名单 if isWhite == 0 { maps = make(map[string]interface{}) maps["project_platform_id"] = projectPlatform.ProjectPlatformId maps["user_id"] = userId err = ProjectPlatformDoctorDao.DeleteProjectPlatformDoctor(tx, maps) if err != nil { return err } } } return nil } // ReportUserScore 获取需发放积分用户 -- 需考虑相同手机号的用户 func (r *UserService) getReportScoreUser(tx *gorm.DB, projectId, caseId, platformId int64, scoreType int, user *model.User) (u *model.User, id int64) { // 检测是否有相同手机号用户 userDao := dao.UserDao{} maps := make(map[string]interface{}) maps["mobile_encryption"] = user.MobileEncryption users, err := userDao.GetUserList(maps) if err != nil { return nil, platformId } if len(users) > 2 { // 存在相同手机号用户 for _, m := range users { if m.UserId == user.UserId { continue } // 检测积分是否已在其他平台发放过 recordScoreDao := dao.RecordScoreDao{} maps = make(map[string]interface{}) maps["project_id"] = projectId maps["case_id"] = caseId maps["user_id"] = user.UserId recordScore, _ := recordScoreDao.GetRecordScoreUseTx(tx, maps) if recordScore != nil { if recordScore.PlatformId != platformId { // 由其他平台进行发放积分 修改平台id为其他平台id return user, recordScore.PlatformId } } // 检测该类型积分是否已经发放 maps = make(map[string]interface{}) maps["project_id"] = projectId maps["case_id"] = caseId maps["platform_id"] = platformId maps["user_id"] = user.UserId maps["type"] = scoreType recordScore, _ = recordScoreDao.GetRecordScore(maps) if recordScore != nil { // 积分已发放过 return nil, platformId } } } return user, platformId } // CheckUserIsJoinCase 检测用户是否已参与过病例 -- 需考虑相同手机号的用户 func (r *UserService) CheckUserIsJoinCase(caseId int64, mobileEncryption string) (isJoin bool) { // 获取全部相同手机号 userDao := dao.UserDao{} maps := make(map[string]interface{}) maps["mobile_encryption"] = mobileEncryption users, err := userDao.GetUserList(maps) if err != nil { return true } caseUserDao := dao.CaseUserDao{} // 存在相同手机号用户 for _, m := range users { // 检测积分是否已在其他平台发放过 maps = make(map[string]interface{}) maps["case_id"] = caseId maps["user_id"] = m.UserId caseUser, _ := caseUserDao.GetCaseUser(maps) if caseUser != nil { return true } } return false }