diff --git a/api/controller/Login.go b/api/controller/Login.go index 0b39430..2078ec5 100644 --- a/api/controller/Login.go +++ b/api/controller/Login.go @@ -47,6 +47,15 @@ func (r *Login) LoginPhone(c *gin.Context) { } } + // 开始事务 + tx := global.Db.Begin() + defer func() { + if r := recover(); r != nil { + fmt.Println(r) + tx.Rollback() + } + }() + // 检测用户信息 userDao := dao.UserDao{} maps := make(map[string]interface{}) @@ -54,15 +63,6 @@ func (r *Login) LoginPhone(c *gin.Context) { user, _ := userDao.GetUser(maps) // 新用户处理方式 if user == nil { - // 开始事务 - tx := global.Db.Begin() - defer func() { - if r := recover(); r != nil { - fmt.Println(r) - tx.Rollback() - } - }() - // 头像 avatar := "www.baidu.com" @@ -73,18 +73,18 @@ func (r *Login) LoginPhone(c *gin.Context) { // 新增用户 user = &model.User{ UserName: "", + AppIden: "", Mobile: req.Mobile, RegisterSource: req.Source, OpenId: "", UnionId: "", Age: nil, - Sex: 0, + Sex: nil, Avatar: avatar, IsMember: 0, MemberExpireDate: nil, LoginIp: loginIp, } - loginAt := model.LocalTime(time.Now()) user.LoginAt = &loginAt @@ -95,17 +95,61 @@ func (r *Login) LoginPhone(c *gin.Context) { return } - fmt.Println(user) + // 新增用户详情 + userInfo := &model.UserInfo{ + UserId: user.UserId, + Height: "", + Weight: "", + NationId: nil, + IsFamilyHistory: nil, + IsPregnant: nil, + ExpectedDate: nil, + ProvinceId: nil, + Province: "", + CityId: nil, + City: "", + CountyId: nil, + County: "", + } + userInfoDao := dao.UserInfoDao{} + userInfo, err = userInfoDao.AddUserInfo(tx, userInfo) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } - // 获取app用户信息 - //var result *string - //if result == nil { - // // 新增app用户信息 - //} + // 处理app用户数据 + userService := service.UserService{} + err = userService.HandleAppUserInfo(tx, user, userInfo) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } - tx.Commit() + } else { + // 获取用户详情数据 + userInfoDao := dao.UserInfoDao{} + userInfo, err := userInfoDao.GetUserInfoByUserId(user.UserId) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理app用户数据 + userService := service.UserService{} + err = userService.HandleAppUserInfo(tx, user, userInfo) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } } + tx.Commit() + // 下发token token := &utils.Token{ UserId: fmt.Sprintf("%d", user.UserId), @@ -118,6 +162,13 @@ func (r *Login) LoginPhone(c *gin.Context) { return } + // 获取用户数据 + user, err = userDao.GetUser(maps) + if err != nil { + responses.FailWithMessage("登陆失败", c) + return + } + // 处理返回值 g := dto.LoginMobileDto(user) @@ -194,7 +245,7 @@ func (r *Login) LoginWx(c *gin.Context) { OpenId: userInfo.OpenId, UnionId: userInfo.UnionId, Age: nil, - Sex: userInfo.Sex, + Sex: &userInfo.Sex, Avatar: avatar, IsMember: 0, MemberExpireDate: nil, diff --git a/api/dao/UserCase.go b/api/dao/UserCase.go new file mode 100644 index 0000000..8d52ea6 --- /dev/null +++ b/api/dao/UserCase.go @@ -0,0 +1,108 @@ +package dao + +import ( + "gorm.io/gorm" + "gorm.io/gorm/clause" + "hepa-calc-api/api/model" + "hepa-calc-api/global" +) + +type UserCaseDao struct { +} + +// GetUserCaseById 获取数据-id +func (r *UserCaseDao) GetUserCaseById(UserCaseId int64) (m *model.UserCase, err error) { + err = global.Db.First(&m, UserCaseId).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetUserCasePreloadById 获取数据-加载全部关联-id +func (r *UserCaseDao) GetUserCasePreloadById(UserCaseId int64) (m *model.UserCase, err error) { + err = global.Db.Preload(clause.Associations).First(&m, UserCaseId).Error + if err != nil { + return nil, err + } + return m, nil +} + +// DeleteUserCase 删除 +func (r *UserCaseDao) DeleteUserCase(tx *gorm.DB, maps interface{}) error { + err := tx.Where(maps).Delete(&model.UserCase{}).Error + if err != nil { + return err + } + return nil +} + +// DeleteUserCaseById 删除-id +func (r *UserCaseDao) DeleteUserCaseById(tx *gorm.DB, UserCaseId int64) error { + if err := tx.Delete(&model.UserCase{}, UserCaseId).Error; err != nil { + return err + } + return nil +} + +// EditUserCase 修改 +func (r *UserCaseDao) EditUserCase(tx *gorm.DB, maps interface{}, data interface{}) error { + err := tx.Model(&model.UserCase{}).Where(maps).Updates(data).Error + if err != nil { + return err + } + return nil +} + +// EditUserCaseById 修改-id +func (r *UserCaseDao) EditUserCaseById(tx *gorm.DB, UserCaseId int64, data interface{}) error { + err := tx.Model(&model.UserCase{}).Where("user_case_id = ?", UserCaseId).Updates(data).Error + if err != nil { + return err + } + return nil +} + +// GetUserCaseList 获取列表 +func (r *UserCaseDao) GetUserCaseList(maps interface{}) (m []*model.UserCase, err error) { + err = global.Db.Where(maps).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetUserCaseCount 获取数量 +func (r *UserCaseDao) GetUserCaseCount(maps interface{}) (total int64, err error) { + err = global.Db.Model(&model.UserCase{}).Where(maps).Count(&total).Error + if err != nil { + return 0, err + } + return total, nil +} + +// GetUserCaseListRand 获取列表-随机 +func (r *UserCaseDao) GetUserCaseListRand(maps interface{}, limit int) (m []*model.UserCase, err error) { + err = global.Db.Where(maps).Order("rand()").Limit(limit).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// AddUserCase 新增 +func (r *UserCaseDao) AddUserCase(tx *gorm.DB, model *model.UserCase) (*model.UserCase, error) { + if err := tx.Create(model).Error; err != nil { + return nil, err + } + return model, nil +} + +// GetUserCase 获取 +func (r *UserCaseDao) GetUserCase(maps interface{}) (m *model.UserCase, err error) { + err = global.Db.Where(maps).First(&m).Error + if err != nil { + return nil, err + } + return m, nil +} diff --git a/api/dao/UserInfo.go b/api/dao/UserInfo.go index 5e97ddd..e32d191 100644 --- a/api/dao/UserInfo.go +++ b/api/dao/UserInfo.go @@ -28,6 +28,15 @@ func (r *UserInfoDao) GetUserInfoPreloadById(UserInfoId int64) (m *model.UserInf return m, nil } +// GetUserInfoByUserId 获取数据-user_id +func (r *UserInfoDao) GetUserInfoByUserId(userId int64) (m *model.UserInfo, err error) { + err = global.Db.Where("user_id = ?", userId).First(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + // DeleteUserInfo 删除 func (r *UserInfoDao) DeleteUserInfo(tx *gorm.DB, maps interface{}) error { err := tx.Where(maps).Delete(&model.UserInfo{}).Error diff --git a/api/dto/User.go b/api/dto/User.go index b7a47f9..0c64315 100644 --- a/api/dto/User.go +++ b/api/dto/User.go @@ -15,8 +15,9 @@ type UserDto struct { RegisterSource int `json:"register_source"` // 注册来源(1:app注册 2:公众号注册) OpenId string `json:"open_id"` // 用户微信标识 UnionId string `json:"union_id"` // 微信开放平台标识 + Birthday *model.LocalTime `json:"birthday"` // 出生日期 Age *uint `json:"age"` // 年龄 - Sex uint `json:"sex"` // 性别(0:未知 1:男 2:女) + Sex *int `json:"sex"` // 性别(0:未知 1:男 2:女) Avatar string `json:"avatar"` // 头像 IsMember int `json:"is_member"` // 是否会员(0:否 1:是) MemberExpireDate *model.LocalTime `json:"member_expire_date"` // 会员到期时间(非会员时为null) @@ -34,8 +35,9 @@ func GetUserDto(m *model.User) *UserDto { Mobile: m.Mobile, UserStatus: m.UserStatus, RegisterSource: m.RegisterSource, + Birthday: m.Birthday, Age: m.Age, - Sex: uint(m.Sex), + Sex: m.Sex, Avatar: utils.AddOssDomain(m.Avatar), IsMember: m.IsMember, MemberExpireDate: m.MemberExpireDate, diff --git a/api/model/User.go b/api/model/User.go index e88e72b..745854e 100644 --- a/api/model/User.go +++ b/api/model/User.go @@ -9,14 +9,16 @@ import ( // User 用户表 type User struct { UserId int64 `gorm:"column:user_id;type:bigint(19);primary_key;comment:用户id" json:"user_id"` + AppIden string `gorm:"column:app_iden;type:varchar(50);comment:app唯一标识" json:"app_iden"` UserName string `gorm:"column:user_name;type:varchar(200);comment:用户名称" json:"user_name"` Mobile string `gorm:"column:mobile;type:varchar(20);comment:手机号;NOT NULL" json:"mobile"` UserStatus int `gorm:"column:user_status;type:tinyint(1);default:1;comment:状态(1:正常 2:禁用)" json:"user_status"` RegisterSource int `gorm:"column:register_source;type:tinyint(1);default:1;comment:注册来源(1:app注册 2:公众号注册)" json:"register_source"` OpenId string `gorm:"column:open_id;type:varchar(100);comment:用户微信标识" json:"open_id"` UnionId string `gorm:"column:union_id;type:varchar(100);comment:微信开放平台标识" json:"union_id"` + Birthday *LocalTime `gorm:"column:birthday;type:datetime;comment:出生日期" json:"birthday"` Age *uint `gorm:"column:age;type:int(10) unsigned;comment:年龄" json:"age"` - Sex int `gorm:"column:sex;type:tinyint(1) unsigned;default:0;comment:性别(0:未知 1:男 2:女)" json:"sex"` + Sex *int `gorm:"column:sex;type:tinyint(1) unsigned;comment:性别(0:未知 1:男 2:女)" json:"sex"` Avatar string `gorm:"column:avatar;type:varchar(255);comment:头像" json:"avatar"` IsMember int `gorm:"column:is_member;type:tinyint(1);default:0;comment:是否会员(0:否 1:是)" json:"is_member"` MemberExpireDate *LocalTime `gorm:"column:member_expire_date;type:datetime;comment:会员到期时间(非会员时为null)" json:"member_expire_date"` diff --git a/api/model/UserCase.go b/api/model/UserCase.go new file mode 100644 index 0000000..6609dac --- /dev/null +++ b/api/model/UserCase.go @@ -0,0 +1,19 @@ +package model + +// UserCase 用户表-病例 +type UserCase struct { + UserCaseId int64 `gorm:"column:user_case_id;type:bigint(19);primary_key;comment:主键id" json:"user_case_id"` + UserId int64 `gorm:"column:user_id;type:bigint(19);comment:用户id;NOT NULL" json:"user_id"` + IsHospital *int `gorm:"column:is_hospital;type:tinyint(1);comment:是否医院就诊(0:否 1:是)" json:"is_hospital"` + LiverStatus string `gorm:"column:liver_status;type:varchar(30);comment:肝脏状态" json:"liver_status"` + IsMedication *int `gorm:"column:is_medication;type:tinyint(1);comment:是否服药(0:否 1:是)" json:"is_medication"` + Medication string `gorm:"column:medication;type:varchar(20);comment:服药名称" json:"medication"` + Disease string `gorm:"column:disease;type:varchar(500);comment:慢性疾病名称(逗号分隔)" json:"disease"` + IsAllergyHistory *int `gorm:"column:is_allergy_history;type:tinyint(1);comment:过敏史(0:否 1:是)" json:"is_allergy_history"` + AllergyHistory string `gorm:"column:allergy_history;type:varchar(100);comment:过敏史描述" json:"allergy_history"` + Model +} + +func (m *UserCase) TableName() string { + return "user_case" +} diff --git a/api/model/UserInfo.go b/api/model/UserInfo.go index e8592fc..7829345 100644 --- a/api/model/UserInfo.go +++ b/api/model/UserInfo.go @@ -8,19 +8,20 @@ import ( // UserInfo 用户表-基础信息 type UserInfo struct { - UserInfoId int64 `gorm:"column:user_info_id;type:bigint(19);primary_key;comment:主键id" json:"user_info_id"` - UserId int64 `gorm:"column:user_id;type:bigint(19);comment:用户id" json:"user_id"` - Height string `gorm:"column:height;type:varchar(20);comment:身高(cm)" json:"height"` - Weight string `gorm:"column:weight;type:varchar(20);comment:体重(kg)" json:"weight"` - NationId int64 `gorm:"column:nation_id;type:bigint(19);comment:民族id" json:"nation_id"` - FamilyHistoryId int64 `gorm:"column:family_history_id;type:bigint(19);comment:家族病史id" json:"family_history_id"` - ProvinceId int `gorm:"column:province_id;type:int(11);comment:省份id" json:"province_id"` - Province string `gorm:"column:province;type:varchar(40);comment:省份" json:"province"` - CityId int `gorm:"column:city_id;type:int(11);comment:城市id" json:"city_id"` - City string `gorm:"column:city;type:varchar(50);comment:城市" json:"city"` - CountyId int `gorm:"column:county_id;type:int(11);comment:区县id" json:"county_id"` - County string `gorm:"column:county;type:varchar(255);comment:区县" json:"county"` - DiseaseClassId int64 `gorm:"column:disease_class_id;type:bigint(19);comment:疾病分类id" json:"disease_class_id"` + UserInfoId int64 `gorm:"column:user_info_id;type:bigint(19);primary_key;comment:主键id" json:"user_info_id"` + UserId int64 `gorm:"column:user_id;type:bigint(19);comment:用户id" json:"user_id"` + Height string `gorm:"column:height;type:varchar(20);comment:身高(cm)" json:"height"` + Weight string `gorm:"column:weight;type:varchar(20);comment:体重(kg)" json:"weight"` + NationId *int64 `gorm:"column:nation_id;type:bigint(19);comment:民族id" json:"nation_id"` + IsFamilyHistory *int `gorm:"column:is_family_history;type:tinyint(1);comment:是否存在家族病史(0:未知 1:是 2:否)" json:"is_family_history"` + IsPregnant *int `gorm:"column:is_pregnant;type:tinyint(1);comment:是否怀孕(1:无计划 2:计划中 3:已怀孕 4:家有宝宝)" json:"is_pregnant"` + ExpectedDate *LocalTime `gorm:"column:expected_date;type:datetime;comment:预产期" json:"expected_date"` + ProvinceId *int `gorm:"column:province_id;type:int(11);comment:省份id" json:"province_id"` + Province string `gorm:"column:province;type:varchar(40);comment:省份" json:"province"` + CityId *int `gorm:"column:city_id;type:int(11);comment:城市id" json:"city_id"` + City string `gorm:"column:city;type:varchar(50);comment:城市" json:"city"` + CountyId *int `gorm:"column:county_id;type:int(11);comment:区县id" json:"county_id"` + County string `gorm:"column:county;type:varchar(255);comment:区县" json:"county"` Model } diff --git a/api/service/User.go b/api/service/User.go index 9bd3b3f..0bb125a 100644 --- a/api/service/User.go +++ b/api/service/User.go @@ -7,6 +7,8 @@ import ( "hepa-calc-api/api/dao" "hepa-calc-api/api/model" "hepa-calc-api/extend/aliyun" + "hepa-calc-api/extend/app" + "hepa-calc-api/utils" "io" "math/rand" "net/http" @@ -152,3 +154,190 @@ func (r *UserService) AddUserMemberBuyCount(tx *gorm.DB, userId int64) (bool, er return true, nil } + +// HandleAppUserInfo 处理app用户数据 +func (r *UserService) HandleAppUserInfo(tx *gorm.DB, user *model.User, userInfo *model.UserInfo) error { + appUserInfo, err := app.GetInfoByMobile(user.Mobile) + if err != nil { + return err + } + + // 对比处理用户数据 + userData := make(map[string]interface{}) // 用户数据 + userInfoData := make(map[string]interface{}) // 用户详情数据 + + // 出生日期/年龄 + if appUserInfo.Data.Birthday != "" { + if user.Birthday != nil { + birthday := time.Time(*user.Birthday).Format("2006-01-02 15:04:05") + if appUserInfo.Data.Birthday != birthday { + userData["birthday"] = appUserInfo.Data.Birthday + } + } else { + userData["birthday"] = appUserInfo.Data.Birthday + } + + // 年龄 + age, err := utils.CalculateAge(appUserInfo.Data.Birthday) + if err != nil { + return err + } + userData["age"] = age + } + + // 是否怀孕 1无计划 2计划中 3已怀孕 4家有宝宝 + if appUserInfo.Data.IsPregnant != nil { + if userInfo.IsPregnant != nil { + if *appUserInfo.Data.IsPregnant != *userInfo.IsPregnant { + userInfoData["is_pregnant"] = appUserInfo.Data.IsPregnant + } + } else { + userInfoData["is_pregnant"] = appUserInfo.Data.IsPregnant + } + + // 预产期 + if appUserInfo.Data.ExpectedDateOfChildbirth != "" { + userInfoData["expected_date"] = appUserInfo.Data.ExpectedDateOfChildbirth + } + } + + // 性别 + if appUserInfo.Data.Sex != nil { + if user.Sex != nil { + if *appUserInfo.Data.Sex != *user.Sex { + userData["sex"] = appUserInfo.Data.Sex + } + } else { + userData["sex"] = appUserInfo.Data.Sex + } + } + + // 体重 + if appUserInfo.Data.Weight != nil { + weight := fmt.Sprintf("%f", appUserInfo.Data.Weight) + + if userInfo.Weight != "" { + if weight != userInfo.Weight { + userInfoData["weight"] = weight + } + } else { + userInfoData["weight"] = weight + } + } + + // 省份 id + if appUserInfo.Data.ProvinceID != nil { + // 获取省份数据 + + if userInfo.ProvinceId != nil { + if *appUserInfo.Data.ProvinceID != *userInfo.ProvinceId { + userInfoData["province_id"] = appUserInfo.Data.ProvinceID + } + } else { + userInfoData["province_id"] = appUserInfo.Data.ProvinceID + } + } + + // 城市 id + if appUserInfo.Data.CityID != nil { + // 获取城市数据 + + if userInfo.CityId != nil { + if *appUserInfo.Data.CityID != *userInfo.CityId { + userInfoData["city_id"] = appUserInfo.Data.CityID + } + } else { + userInfoData["city_id"] = appUserInfo.Data.CityID + } + } + + // 市区 id + if appUserInfo.Data.CountyID != nil { + // 获取区县数据 + + if userInfo.CountyId != nil { + if *appUserInfo.Data.CountyID != *userInfo.CountyId { + userInfoData["county_id"] = appUserInfo.Data.CountyID + } + } else { + userInfoData["county_id"] = appUserInfo.Data.CountyID + } + } + + // 家族病史 + if appUserInfo.Data.IsHBV != nil { + // 有无 肝硬化或肝癌家族史 0无1有2未知 + // 是否存在家族病史(0:未知 1:是 2:否) + // 转换双方状态 + if *appUserInfo.Data.IsHBV == 0 { + *appUserInfo.Data.IsHBV = 2 + } else if *appUserInfo.Data.IsHBV == 1 { + *appUserInfo.Data.IsHBV = 1 + } else if *appUserInfo.Data.IsHBV == 2 { + *appUserInfo.Data.IsHBV = 0 + } + + if userInfo.IsFamilyHistory != nil { + if *appUserInfo.Data.IsHBV != *userInfo.IsFamilyHistory { + userInfoData["is_family_history"] = appUserInfo.Data.IsHBV + } + } else { + userInfoData["is_family_history"] = appUserInfo.Data.IsHBV + } + } + + // 民族 + if appUserInfo.Data.NationUUID != "" { + // 获取民族数据 + var nationId int64 + if userInfo.NationId != nil { + if nationId != *userInfo.NationId { + userInfoData["nation_id"] = nationId + } + } else { + userInfoData["nation_id"] = nationId + } + } + + // 患者 uuid + if appUserInfo.Data.PatientUUID != "" { + if user.AppIden != "" { + if appUserInfo.Data.PatientUUID != user.AppIden { + userData["app_iden"] = appUserInfo.Data.PatientUUID + } + } else { + userData["app_iden"] = appUserInfo.Data.PatientUUID + } + } + + // 姓名 + if appUserInfo.Data.Name != "" { + if user.UserName != "" { + if appUserInfo.Data.Name != user.UserName { + userData["user_name"] = appUserInfo.Data.Name + } + } else { + userData["user_name"] = appUserInfo.Data.Name + } + } + + // 修改用户数据 + if len(userData) > 0 { + userDao := dao.UserDao{} + err := userDao.EditUserById(tx, user.UserId, userData) + if err != nil { + return err + } + } + + // 修改用户详情数据 + if len(userInfoData) > 0 { + userInfoDao := dao.UserInfoDao{} + err := userInfoDao.EditUserInfoById(tx, userInfo.UserInfoId, userInfoData) + if err != nil { + return err + } + } + + return nil +} diff --git a/extend/app/base.go b/extend/app/base.go new file mode 100644 index 0000000..22c4053 --- /dev/null +++ b/extend/app/base.go @@ -0,0 +1,65 @@ +package app + +import ( + "encoding/json" + "hepa-calc-api/utils" + "sort" +) + +const ( + apiUrl = "https://dev-wx.igandan.com" // 本机认证服务身份证实人认证在线检测接口地址 + secretKey = "RY8pcn04#TSdzHVX6YgWnyCue9!T&QP^" // 产品私有密钥,服务端生成签名信息使用,请严格保管,避免泄露 + platform = "suanyisuan" // 所属平台 +) + +// GenSignature 生成签名信息 +func GenSignature(params map[string]interface{}) (string, error) { + // 对map的key进行排序,包括多层嵌套的情况 + data := sortMapRecursively(params) + + // 转换为JSON + jsonData, err := json.Marshal(data) + if err != nil { + return "", err + } + + sing := utils.HmacSHA256(string(jsonData), secretKey) + return sing, nil +} + +// sortMapRecursively 对map的key进行排序,包括多层嵌套的情况 +func sortMapRecursively(data map[string]interface{}) map[string]interface{} { + sortedMap := make(map[string]interface{}) + keys := make([]string, 0, len(data)) + + // 收集所有的key + for key := range data { + keys = append(keys, key) + } + + // 对key进行排序 + sort.Strings(keys) + + // 通过排序后的key插入新map中 + for _, key := range keys { + value := data[key] + switch valueTyped := value.(type) { + case map[string]interface{}: + // 如果是嵌套的map,递归调用 + sortedMap[key] = sortMapRecursively(valueTyped) + case []interface{}: + // 如果是嵌套的slice,对其中的map进行递归调用 + for i, v := range valueTyped { + if vMap, ok := v.(map[string]interface{}); ok { + valueTyped[i] = sortMapRecursively(vMap) + } + } + sortedMap[key] = valueTyped + default: + // 否则直接插入 + sortedMap[key] = value + } + } + + return sortedMap +} diff --git a/extend/app/userInfo.go b/extend/app/userInfo.go new file mode 100644 index 0000000..ca12677 --- /dev/null +++ b/extend/app/userInfo.go @@ -0,0 +1,132 @@ +package app + +import ( + "bytes" + "encoding/json" + "errors" + "hepa-calc-api/utils" + "io" + "net/http" + "strconv" + "time" +) + +// GetInfoByMobileRequest 根据手机号获取用户信息-请求数据 +type GetInfoByMobileRequest struct { + Mobile string `json:"mobile"` // 手机号 + Platform string `json:"platform"` // 所属平台 + Timestamp string `json:"timestamp"` // 当前时间戳(10位) +} + +// GetInfoByMobileResponse 根据手机号获取用户信息-返回数据 +type GetInfoByMobileResponse struct { + Code int `json:"code"` // 接口调用状态。200:正常;其它值:调用出错 + Msg string `json:"msg"` // 结果说明。如果接口调用出错,那么返回错误描述。成功则返回 ok + Data GetInfoByMobileData `json:"data"` // 接口返回结果,各个接口自定义,数据结构参考具体文档说明 + Success bool `json:"success"` + Message string `json:"message"` +} + +// GetInfoByMobileData 根据手机号获取用户信息-data详细数据 +type GetInfoByMobileData struct { + Birthday string `json:"birthday" description:"出生日期"` + IsPregnant *int `json:"isPregnant" description:"是否怀孕 1无计划 2计划中 3已怀孕 4家有宝宝"` + Sex *int `json:"sex" description:"性别 0男 1女"` + Mobile string `json:"mobile" description:"手机号"` + Photo string `json:"photo" description:"头像地址"` + Weight *float64 `json:"weight" description:"体重 KG"` + CityID *int `json:"cityId" description:"城市 id"` + ExpectedDateOfChildbirth string `json:"expectedDateOfChildbirth" description:"预产期"` + CountyID *int `json:"countyId" description:"市区 id"` + IsHBV *int `json:"isHbv" description:"有无 肝硬化或肝癌家族史 0无1有2未知"` + NationUUID string `json:"nationUuid" description:"民族 uuid"` + PatientUUID string `json:"patientUuid" description:"患者 uuid"` + Name string `json:"name" description:"姓名"` + ProvinceID *int `json:"provId" description:"省份 id"` + Height *float64 `json:"height" description:"身高 cm"` + OpenId string `json:"openid" description:"openid"` + UnionId string `json:"unionid" description:"unionid"` +} + +// GetInfoByMobile 根据手机号获取用户信息 +func GetInfoByMobile(mobile string) (g *GetInfoByMobileResponse, err error) { + // 准备要发送的 JSON 数据 + requestData := GetInfoByMobileRequest{ + Mobile: mobile, + Platform: platform, + Timestamp: strconv.FormatInt(time.Now().Unix(), 10), + } + + // 将 JSON 数据编码为字节数组 + jsonData, err := json.Marshal(requestData) + if err != nil { + return g, err + } + + maps := make(map[string]interface{}) + err = json.Unmarshal(jsonData, &maps) + if err != nil { + return g, err + } + + // 获取请求签名 + sign, err := GenSignature(maps) + if err != nil { + return g, err + } + + // 准备请求体 + requestBody := bytes.NewBuffer(jsonData) + + // 设置请求 URL + url := apiUrl + "/patient-api/getInfo" + + // 创建 POST 请求 + req, err := http.NewRequest("POST", url, requestBody) + if err != nil { + return g, err + } + + // 设置请求头 + req.Header.Set("Content-Type", "application/json") + req.Header.Set("sign", sign) + + // 发送请求 + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return g, err + } + + defer func(Body io.ReadCloser) { + _ = Body.Close() + }(resp.Body) + + body, err := io.ReadAll(resp.Body) + if err != nil { + return g, err + } + + // 检查响应状态码 + if resp.StatusCode != 200 { + return g, errors.New("登陆失败") + } + + err = json.Unmarshal(body, &g) + if err != nil { + // json解析失败 + return g, err + } + + utils.LogJsonInfo("获取app数据返回", g) + + if g.Code != 200 { + if g.Msg != "" { + return g, errors.New(g.Msg) + } else { + return g, errors.New("登陆失败") + } + } + + return g, nil +} diff --git a/utils/aes.go b/utils/aes.go index ba70469..4f6ba0c 100644 --- a/utils/aes.go +++ b/utils/aes.go @@ -3,6 +3,7 @@ package utils import ( "crypto/aes" "crypto/cipher" + "crypto/hmac" "crypto/rand" "crypto/sha256" "encoding/base64" @@ -83,6 +84,16 @@ func HashString(s string) string { return s } +// HmacSHA256 计算 HMAC-SHA256 签名 +func HmacSHA256(data string, key string) string { + // 创建新的 HMAC 使用 SHA256 哈希函数 + h := hmac.New(sha256.New, []byte(key)) + // 写入数据 + h.Write([]byte(data)) + // 计算 HMAC-SHA256 并返回其字节切片 + return hex.EncodeToString(h.Sum(nil)) +} + // 将任意长度的密钥转换为适合 AES 的长度(32 字节) func hashKey(key string) []byte { hash := sha256.Sum256([]byte(key)) diff --git a/utils/compute.go b/utils/compute.go index 1370d56..3299905 100644 --- a/utils/compute.go +++ b/utils/compute.go @@ -6,6 +6,7 @@ import ( "image/jpeg" "os" "path/filepath" + "time" ) // 一些计算 @@ -83,3 +84,26 @@ func ConvertPDFToImages(pdfPath string, outputDir string, filename string) error return nil } + +// CalculateAge 计算年龄 +func CalculateAge(birthdate string) (int, error) { + // 解析出生日期字符串 + layout := "2006-01-02 15:04:05" + birthTime, err := time.Parse(layout, birthdate) + if err != nil { + return 0, err + } + + // 获取当前时间 + now := time.Now() + + // 计算年龄 + years := now.Year() - birthTime.Year() + + // 如果今年的生日还没到,年龄减一 + if now.Month() < birthTime.Month() || (now.Month() == birthTime.Month() && now.Day() < birthTime.Day()) { + years-- + } + + return years, nil +}