This commit is contained in:
wucongxing 2023-07-06 11:01:47 +08:00
parent 2944d42281
commit 1c108f8a1f
27 changed files with 1034 additions and 222 deletions

80
api/controller/admin.go Normal file
View File

@ -0,0 +1,80 @@
package controller
import (
"github.com/gin-gonic/gin"
"hospital-admin-api/api/requests"
"hospital-admin-api/api/responses"
"hospital-admin-api/api/service"
"hospital-admin-api/global"
"hospital-admin-api/utils"
)
type Admin struct{}
// GetCaptcha 获取验证码
func (b *Admin) GetCaptcha(c *gin.Context) {
id, b64s, err := utils.GenerateCaptcha()
if err != nil {
responses.FailWithMessage("验证码获取失败", c)
}
responses.OkWithData(gin.H{
"id": id,
"b64s": b64s,
}, c)
}
// Login 登陆
func (b *Admin) Login(c *gin.Context) {
var adminRequest requests.AdminRequest
if err := c.ShouldBind(&adminRequest.Login); err != nil {
responses.FailWithMessage(err.Error(), c)
return
}
// 参数验证
if err := global.Validate.Struct(adminRequest.Login); err != nil {
responses.FailWithMessage(utils.Translate(err), c)
return
}
// 验证验证码
// isValid := utils.VerifyCaptcha(login)
// if !isValid {
// // 验证码错误
// responses.FailWithMessage("验证码错误", c)
// return
// }
// 登陆
adminService := service.AdminService{}
token, err := adminService.Login(adminRequest.Login)
if err != nil {
responses.FailWithMessage(err.Error(), c)
return
}
responses.OkWithData(token, c)
}
// GetOssSign 获取oss签名
func (b *Admin) GetOssSign(c *gin.Context) {
var adminRequest requests.AdminRequest
if err := c.ShouldBind(&adminRequest.GetOssSign); err != nil {
responses.FailWithMessage(err.Error(), c)
return
}
// 参数验证
if err := global.Validate.Struct(adminRequest.GetOssSign); err != nil {
responses.FailWithMessage(utils.Translate(err), c)
return
}
// 获取oss签名
adminService := service.AdminService{}
ossSign, _ := adminService.GetOssSign(adminRequest.GetOssSign)
responses.OkWithData(ossSign, c)
}

View File

@ -2,9 +2,10 @@ package controller
// Api api接口
type Api struct {
Basic // 基础数据
sysSetting // 系统设置
userDoctorManage // 医生管理
Admin // 公共方法
basic // 基础数据
}
// SysSetting 系统设置
@ -21,3 +22,8 @@ type sysSetting struct {
type userDoctorManage struct {
UserDoctor // 医生列表
}
// Basic 基础数据
type basic struct {
Department // 科室
}

View File

@ -1,59 +1 @@
package controller
import (
"github.com/gin-gonic/gin"
"hospital-admin-api/api/requests"
"hospital-admin-api/api/responses"
"hospital-admin-api/api/service"
"hospital-admin-api/global"
"hospital-admin-api/utils"
)
type Basic struct{}
// GetCaptcha 获取验证码
func (b *Basic) GetCaptcha(c *gin.Context) {
id, b64s, err := utils.GenerateCaptcha()
if err != nil {
responses.FailWithMessage("验证码获取失败", c)
}
responses.OkWithData(gin.H{
"id": id,
"b64s": b64s,
}, c)
}
// Login 登陆
func (b *Basic) Login(c *gin.Context) {
var basicRequest requests.BasicRequest
if err := c.ShouldBind(&basicRequest.Login); err != nil {
responses.FailWithMessage(err.Error(), c)
return
}
// 参数验证
if err := global.Validate.Struct(basicRequest.Login); err != nil {
responses.FailWithMessage(utils.Translate(err), c)
return
}
// 验证验证码
// isValid := utils.VerifyCaptcha(login)
// if !isValid {
// // 验证码错误
// responses.FailWithMessage("验证码错误", c)
// return
// }
// 登陆
BasicService := service.BasicService{}
token, err := BasicService.Login(basicRequest.Login)
if err != nil {
responses.FailWithMessage(err.Error(), c)
return
}
responses.OkWithData(token, c)
}

View File

@ -0,0 +1,27 @@
// Package controller 科室管理
package controller
import (
"github.com/gin-gonic/gin"
"hospital-admin-api/api/dao"
"hospital-admin-api/api/responses"
"hospital-admin-api/api/responses/hosDepCustomResponse"
)
type Department struct{}
// GetDepartmentList 获取自定义科室列表
func (b *Department) GetDepartmentList(c *gin.Context) {
hospitalDepartmentCustomDao := dao.HospitalDepartmentCustom{}
maps := make(map[string]interface{})
hospitalDepartmentCustom, err := hospitalDepartmentCustomDao.GetHospitalDepartmentCustomList(maps)
if err != nil {
responses.FailWithMessage(err.Error(), c)
return
}
// 处理返回值
getDepartmentListResponse := hosDepCustomResponse.GetHospitalDepartmentCustomListResponse(hospitalDepartmentCustom)
responses.OkWithData(getDepartmentListResponse, c)
}

3
api/controller/public.go Normal file
View File

@ -0,0 +1,3 @@
package controller
type Public struct{}

View File

@ -6,6 +6,7 @@ import (
"hospital-admin-api/api/requests"
"hospital-admin-api/api/responses"
"hospital-admin-api/api/responses/userDoctorResponse"
"hospital-admin-api/api/service"
"hospital-admin-api/global"
"hospital-admin-api/utils"
"strconv"
@ -82,3 +83,41 @@ func (r *UserDoctor) GetPostUserDoctor(c *gin.Context) {
responses.OkWithData(getUserDoctorResponses, c)
}
// PutPostUserDoctor 修改医生
func (r *UserDoctor) PutPostUserDoctor(c *gin.Context) {
userDoctorRequest := requests.UserDoctorRequest{}
if err := c.ShouldBindJSON(&userDoctorRequest.PutPostUserDoctor); err != nil {
responses.FailWithMessage(err.Error(), c)
return
}
// 参数验证
if err := global.Validate.Struct(userDoctorRequest.PutPostUserDoctor); err != nil {
responses.FailWithMessage(utils.Translate(err), c)
return
}
id := c.Param("doctor_id")
if id == "" {
responses.FailWithMessage("缺少参数", c)
return
}
// 将 id 转换为 int64 类型
doctorId, err := strconv.ParseInt(id, 10, 64)
if err != nil {
responses.Fail(c)
return
}
// 业务处理
userDoctorService := service.UserDoctorService{}
_, err = userDoctorService.PutPostUserDoctor(doctorId, userDoctorRequest.PutPostUserDoctor)
if err != nil {
responses.FailWithMessage("修改失败", c)
return
}
responses.Ok(c)
}

53
api/dao/hospital.go Normal file
View File

@ -0,0 +1,53 @@
package dao
import (
"gorm.io/gorm"
"hospital-admin-api/api/model"
"hospital-admin-api/global"
)
type Hospital struct {
}
// GetHospitalById 获取医院数据-医院id
func (r *Hospital) GetHospitalById(hospitalId int64) (m *model.Hospital, err error) {
err = global.Db.First(&m, hospitalId).Error
if err != nil {
return nil, err
}
return m, nil
}
// AddHospital 新增医院
func (r *Hospital) AddHospital(tx *gorm.DB, model *model.Hospital) (*model.Hospital, error) {
if err := tx.Create(model).Error; err != nil {
return nil, err
}
return model, nil
}
// GetHospitalList 获取医院列表
func (r *Hospital) GetHospitalList(maps interface{}) (m []*model.Hospital, err error) {
err = global.Db.Where(maps).Find(&m).Error
if err != nil {
return nil, err
}
return m, nil
}
// DeleteHospitalById 删除医院-医院id
func (r *Hospital) DeleteHospitalById(tx *gorm.DB, hospitalId int64) error {
if err := tx.Delete(&model.Hospital{}, hospitalId).Error; err != nil {
return err
}
return nil
}
// EditHospitalById 修改医院-医院id
func (r *Hospital) EditHospitalById(tx *gorm.DB, hospitalId int64, data interface{}) error {
err := tx.Model(&model.Hospital{}).Where("hospital_id = ?", hospitalId).Updates(data).Error
if err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,53 @@
package dao
import (
"gorm.io/gorm"
"hospital-admin-api/api/model"
"hospital-admin-api/global"
)
type HospitalDepartmentCustom struct {
}
// GetHospitalDepartmentCustomById 获取自定义科室数据-自定义科室id
func (r *HospitalDepartmentCustom) GetHospitalDepartmentCustomById(departmentCustomId int64) (m *model.HospitalDepartmentCustom, err error) {
err = global.Db.First(&m, departmentCustomId).Error
if err != nil {
return nil, err
}
return m, nil
}
// AddHospitalDepartmentCustom 新增自定义科室
func (r *HospitalDepartmentCustom) AddHospitalDepartmentCustom(tx *gorm.DB, model *model.HospitalDepartmentCustom) (*model.HospitalDepartmentCustom, error) {
if err := tx.Create(model).Error; err != nil {
return nil, err
}
return model, nil
}
// GetHospitalDepartmentCustomList 获取自定义科室列表
func (r *HospitalDepartmentCustom) GetHospitalDepartmentCustomList(maps interface{}) (m []*model.HospitalDepartmentCustom, err error) {
err = global.Db.Where(maps).Find(&m).Error
if err != nil {
return nil, err
}
return m, nil
}
// DeleteHospitalDepartmentCustomById 删除自定义科室-自定义科室id
func (r *HospitalDepartmentCustom) DeleteHospitalDepartmentCustomById(tx *gorm.DB, departmentCustomId int64) error {
if err := tx.Delete(&model.HospitalDepartmentCustom{}, departmentCustomId).Error; err != nil {
return err
}
return nil
}
// EditHospitalDepartmentCustomById 修改自定义科室-自定义科室id
func (r *HospitalDepartmentCustom) EditHospitalDepartmentCustomById(tx *gorm.DB, departmentCustomId int64, data interface{}) error {
err := tx.Model(&model.HospitalDepartmentCustom{}).Where("department_custom_id = ?", departmentCustomId).Updates(data).Error
if err != nil {
return err
}
return nil
}

89
api/dao/userDoctorInfo.go Normal file
View File

@ -0,0 +1,89 @@
package dao
import (
"gorm.io/gorm"
"hospital-admin-api/api/model"
"hospital-admin-api/global"
)
type UserDoctorInfoDao struct {
}
// GetUserDoctorInfoById 获取医生详情数据-医生详情id
func (r *UserDoctorInfoDao) GetUserDoctorInfoById(doctorInfoId int64) (m *model.UserDoctorInfo, err error) {
err = global.Db.First(&m, doctorInfoId).Error
if err != nil {
return nil, err
}
return m, nil
}
// GetUserDoctorInfoByDoctorId 获取医生详情数据-医生id
func (r *UserDoctorInfoDao) GetUserDoctorInfoByDoctorId(doctorId int64) (m *model.UserDoctorInfo, err error) {
err = global.Db.Where("doctor_id = ?", doctorId).First(&m).Error
if err != nil {
return nil, err
}
return m, nil
}
// DeleteUserDoctorInfo 删除医生详情
func (r *UserDoctorInfoDao) DeleteUserDoctorInfo(tx *gorm.DB, maps interface{}) error {
err := tx.Where(maps).Delete(&model.UserDoctorInfo{}).Error
if err != nil {
return err
}
return nil
}
// DeleteUserDoctorInfoById 删除医生详情-医生详情id
func (r *UserDoctorInfoDao) DeleteUserDoctorInfoById(tx *gorm.DB, doctorInfoId int64) error {
if err := tx.Delete(&model.UserDoctorInfo{}, doctorInfoId).Error; err != nil {
return err
}
return nil
}
// EditUserDoctorInfo 修改医生详情
func (r *UserDoctorInfoDao) EditUserDoctorInfo(tx *gorm.DB, maps interface{}, data interface{}) error {
err := tx.Model(&model.UserDoctorInfo{}).Where(maps).Updates(data).Error
if err != nil {
return err
}
return nil
}
// EditUserDoctorInfoById 修改医生详情-医生详情id
func (r *UserDoctorInfoDao) EditUserDoctorInfoById(tx *gorm.DB, doctorInfoId int64, data interface{}) error {
err := tx.Model(&model.UserDoctorInfo{}).Where("doctor_info_id = ?", doctorInfoId).Updates(data).Error
if err != nil {
return err
}
return nil
}
// GetUserDoctorInfoList 获取医生详情列表
func (r *UserDoctorInfoDao) GetUserDoctorInfoList(maps interface{}) (m []*model.UserDoctorInfo, err error) {
err = global.Db.Where(maps).Find(&m).Error
if err != nil {
return nil, err
}
return m, nil
}
// AddUserDoctorInfo 新增医生详情
func (r *UserDoctorInfoDao) AddUserDoctorInfo(tx *gorm.DB, model *model.UserDoctorInfo) (*model.UserDoctorInfo, error) {
if err := tx.Create(model).Error; err != nil {
return nil, err
}
return model, nil
}
// AddUserDoctorInfoByMap 新增医生详情-map
func (r *UserDoctorInfoDao) AddUserDoctorInfoByMap(tx *gorm.DB, data map[string]interface{}) (*model.UserDoctorInfo, error) {
userDoctorInfo := &model.UserDoctorInfo{}
if err := tx.Model(&model.UserDoctorInfo{}).Create(data).Error; err != nil {
return nil, err
}
return userDoctorInfo, nil
}

View File

@ -112,6 +112,54 @@ func Auth() gin.HandlerFunc {
}
}
path := c.Request.URL.Path
// 匹配路由为/:id的接口
reg := regexp.MustCompile("/(\\d+)$")
match := reg.MatchString(c.Request.RequestURI)
if match {
// 找到最后一个数字的索引
lastSlashIndex := strings.LastIndex(c.Request.RequestURI, "/")
if lastSlashIndex != -1 {
// 替换最后一个数字部分为 :id
path = path[:lastSlashIndex] + "/:id"
} else {
c.JSON(http.StatusOK, gin.H{
"message": "请求路径错误",
"code": consts.SERVER_ERROR,
"data": "",
})
c.Abort()
return
}
}
// 检测接口是否需要验证权限
adminApiDao := dao.AdminApiDao{}
maps := make(map[string]interface{})
maps["api_path"] = path
maps["api_method"] = c.Request.Method
adminApis, err := adminApiDao.GetAdminApiList(maps)
if len(adminApis) == 0 || err != nil {
c.JSON(http.StatusOK, gin.H{
"message": "请求路径错误",
"code": consts.SERVER_ERROR,
"data": "",
})
}
// 接口无需验证权限
if adminApis[0].IsAuth == 0 {
c.Next()
return
}
path = path + c.Request.Method
// 获取角色菜单id
AdminRoleMenuDao := dao.AdminRoleMenuDao{}
adminRoleMenu, _ := AdminRoleMenuDao.GetAdminRoleMenuListByRoleId(roleId)
@ -130,46 +178,18 @@ func Auth() gin.HandlerFunc {
// 获取菜单对应api
adminMenuApiDao := dao.AdminMenuApiDao{}
for _, v := range adminRoleMenu {
AdminMenuApi, _ := adminMenuApiDao.GetAdminMenuApiListWithAPIByMenuID(v.MenuID)
if AdminMenuApi == nil {
// 菜单无需权限
c.Next()
return
adminMenuApi, _ := adminMenuApiDao.GetAdminMenuApiListWithAPIByMenuID(v.MenuID)
if adminMenuApi == nil {
// 菜单无绑定接口
continue
}
// 将API权限存储在apiPermissions中
for _, api := range AdminMenuApi {
for _, api := range adminMenuApi {
apiPermissions[api.API.APIPath+api.API.APIMethod] = true
}
}
path := c.Request.URL.Path
// 编译正则表达式
reg := regexp.MustCompile("/(\\d+)$")
// 进行匹配
match := reg.MatchString(c.Request.RequestURI)
if match {
// 找到最后一个数字的索引
lastSlashIndex := strings.LastIndex(c.Request.RequestURI, "/")
if lastSlashIndex != -1 {
// 替换最后一个数字部分为 :id
path = path[:lastSlashIndex] + "/:id" + c.Request.Method
} else {
c.JSON(http.StatusOK, gin.H{
"message": "请求路径错误",
"code": consts.SERVER_ERROR,
"data": "",
})
c.Abort()
return
}
} else {
path = path + c.Request.Method
}
// 在apiPermissions中查找对应的API权限
hasPermission := apiPermissions[path]
if !hasPermission {
@ -186,25 +206,3 @@ func Auth() gin.HandlerFunc {
c.Next()
}
}
// Auth 权限
// func Auth() gin.HandlerFunc {
// return func(c *gin.Context) {
// fmt.Println(123)
//
// // result, err := dao.AdminRole.GetAdminRoleById(roleId)
// // fmt.Println(result)
// // if err != nil {
// // responses.FailWithMessage("用户数据错误", c)
// // c.Abort()
// // return
// // }
// // responses.OkWithData(&result, c)
// // c.Abort()
//
// // 获取请求路径
// // url := c.Request.RequestURI
// c.Next()
// }
// }

View File

@ -0,0 +1,16 @@
package model
// HospitalDepartmentCustom 医院科室表-自定义
type HospitalDepartmentCustom struct {
DepartmentCustomId int64 `gorm:"column:department_custom_id;type:bigint(19);primary_key;comment:主键id" json:"department_custom_id"`
DepartmentId int64 `gorm:"column:department_id;type:bigint(19);comment:医院科室-标准id" json:"department_id"`
DepartmentCustomName string `gorm:"column:department_custom_name;type:varchar(100);comment:科室名称-自定义" json:"department_custom_name"`
DepartmentName string `gorm:"column:department_name;type:varchar(255);comment:科室名称-标准" json:"department_name"`
DepartmentCode string `gorm:"column:department_code;type:varchar(100);comment:科室编码-标准" json:"department_code"`
DepartmentStatus int `gorm:"column:department_status;type:tinyint(1);default:1;comment:状态1:正常 2:删除)" json:"department_status"`
Model
}
func (m *HospitalDepartmentCustom) TableName() string {
return "gdxz_hospital_department_custom"
}

20
api/requests/admin.go Normal file
View File

@ -0,0 +1,20 @@
package requests
type AdminRequest struct {
Login // 登陆
GetOssSign // 获取医生列表-分页
}
// Login 登陆
type Login struct {
Access string `json:"access" form:"access" validate:"required" label:"用户名"` // 用户名
Password string `json:"password" form:"password" validate:"required" label:"密码"` // 密码
Captcha string `json:"captcha" form:"captcha" validate:"required" label:"验证码"` // 验证码
CaptchaId string `json:"captchaId" form:"captchaId" validate:"required"` // 验证码ID
}
// GetOssSign 获取oss签名
type GetOssSign struct {
UserType int `json:"user_type" form:"user_type" validate:"required,oneof=1 2 3 4" label:"用户类型"` // 1:患者 2:医生 3:药师 4:后台)
Scene int `json:"scene" form:"scene" validate:"required,oneof=1 2 3 4" label:"场景"` // 1:头像 2:证书 3:名片)
}

View File

@ -1,13 +1,4 @@
package requests
type BasicRequest struct {
Login // 登陆
}
// Login 登陆
type Login struct {
Access string `json:"access" form:"access" validate:"required" label:"用户名"` // 用户名
Password string `json:"password" form:"password" validate:"required" label:"密码"` // 密码
Captcha string `json:"captcha" form:"captcha" validate:"required" label:"验证码"` // 验证码
CaptchaId string `json:"captchaId" form:"captchaId" validate:"required"` // 验证码ID
}

View File

@ -2,6 +2,7 @@ package requests
type UserDoctorRequest struct {
GetUserDoctorPage // 获取医生列表-分页
PutPostUserDoctor // 修改医生
}
// GetUserDoctorPage 获取医生列表-分页
@ -21,3 +22,23 @@ type GetUserDoctorPage struct {
InquiryService string `json:"inquiry_service" form:"inquiry_service" label:"问诊服务"` // 1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
IsEnterpriseDeepCooperation int `json:"is_enterprise_deep_cooperation" form:"is_enterprise_deep_cooperation" label:"是否企业深度合作"` // 0:否 1:是)
}
// PutPostUserDoctor 修改医生
type PutPostUserDoctor struct {
IsRecommend int `json:"is_recommend" form:"is_recommend" label:"是否首页推荐"` // 0:否 1:是)
Avatar string `json:"avatar" form:"avatar" validate:"required" label:"头像"`
DoctorTitle int `json:"doctor_title" form:"doctor_title" validate:"required oneof=1 2 3 4 5 6" label:"医生职称"` // 1:主任医师 2:主任中医师 3:副主任医师 4:副主任中医师 5:主治医师 6:住院医师)
DepartmentCustomId string `json:"department_custom_id" form:"department_custom_id" validate:"required" label:"科室"`
DepartmentCustomName string `json:"department_custom_name" form:"department_custom_name" validate:"required" label:"科室名称"` // (如未自己输入,填入标准科室名称)
DepartmentCustomMobile string `json:"department_custom_mobile" form:"department_custom_mobile" label:"科室电话"`
HospitalId string `json:"hospital_id" form:"hospital_id" validate:"required" label:"所属医院id"`
BeGoodAt string `json:"be_good_at" form:"be_good_at" validate:"required" label:"擅长"`
BriefIntroduction string `json:"brief_introduction" form:"brief_introduction" validate:"required" label:"医生简介"`
LicenseCert []string `json:"license_cert" form:"license_cert" label:"医师执业证"`
QualificationCert []string `json:"qualification_cert" form:"qualification_cert" label:"医师资格证"`
QualificationCertNum string `json:"qualification_cert_num" form:"qualification_cert_num" label:"医师资格证号"`
WorkCert []string `json:"work_cert" form:"work_cert" label:"医师工作证"`
IdCardFront string `json:"id_card_front" form:"id_card_front" label:"身份证正面图片"`
IdCardBack string `json:"id_card_back" form:"id_card_back" label:"身份证背面图片"`
SignImage string `json:"sign_image" form:"sign_image" label:"签名图片"`
}

View File

@ -0,0 +1,17 @@
package adminResponse
import "hospital-admin-api/config"
// Login 登陆
type Login struct {
UserId string `json:"user_id"` // 用户id
NickName string `json:"nick_name"` // 昵称
Avatar string `json:"avatar"` // 头像
Token string `json:"token"` // 用户名
}
// GetFullAvatar 返回带有指定字符串的头像路径
func (l *Login) GetFullAvatar() Login {
l.Avatar = config.C.Oss.OssCustomDomainName + "/" + l.Avatar
return Login{}
}

View File

@ -1,17 +1 @@
package basicResponse
import "hospital-admin-api/config"
// Login 登陆
type Login struct {
UserId string `json:"user_id"` // 用户id
NickName string `json:"nick_name"` // 昵称
Avatar string `json:"avatar"` // 头像
Token string `json:"token"` // 用户名
}
// GetFullAvatar 返回带有指定字符串的头像路径
func (l *Login) GetFullAvatar() Login {
l.Avatar = config.C.Oss.OssCustomDomainName + "/" + l.Avatar
return Login{}
}

View File

@ -0,0 +1,52 @@
package hosDepCustomResponse
import (
"hospital-admin-api/api/model"
"strconv"
)
type HosDepCustom struct {
DepartmentCustomId string `json:"department_custom_id"` // 主键
DepartmentId string `json:"department_id"` // 医院科室-标准id
DepartmentCustomName string `json:"department_custom_name"` // 科室名称-自定义
DepartmentName string `json:"department_name"` // 科室名称-标准
DepartmentCode string `json:"department_code"` // 科室编码-标准
DepartmentStatus int `json:"department_status"` // 状态1:正常 2:删除)
}
// HospitalDepartmentCustomResponse 自定义详情
func HospitalDepartmentCustomResponse(hospitalDepartmentCustom *model.HospitalDepartmentCustom) *HosDepCustom {
return &HosDepCustom{
DepartmentCustomId: strconv.FormatInt(hospitalDepartmentCustom.DepartmentCustomId, 10),
DepartmentId: strconv.FormatInt(hospitalDepartmentCustom.DepartmentId, 10),
DepartmentCustomName: hospitalDepartmentCustom.DepartmentCustomName,
DepartmentName: hospitalDepartmentCustom.DepartmentName,
DepartmentCode: hospitalDepartmentCustom.DepartmentCode,
DepartmentStatus: hospitalDepartmentCustom.DepartmentStatus,
}
}
// GetHospitalDepartmentCustomListResponse 自定义列表
func GetHospitalDepartmentCustomListResponse(hospitalDepartmentCustom []*model.HospitalDepartmentCustom) []HosDepCustom {
// 处理返回值
getHospitalDepartmentCustomListResponses := make([]HosDepCustom, len(hospitalDepartmentCustom))
if len(hospitalDepartmentCustom) > 0 {
for i, v := range hospitalDepartmentCustom {
// 将原始结构体转换为新结构体
getHospitalDepartmentCustomListResponse := HosDepCustom{
DepartmentCustomId: strconv.FormatInt(v.DepartmentCustomId, 10),
DepartmentId: strconv.FormatInt(v.DepartmentId, 10),
DepartmentCustomName: v.DepartmentCustomName,
DepartmentName: v.DepartmentName,
DepartmentCode: v.DepartmentCode,
DepartmentStatus: v.DepartmentStatus,
}
// 将转换后的结构体添加到新切片中
getHospitalDepartmentCustomListResponses[i] = getHospitalDepartmentCustomListResponse
}
}
return getHospitalDepartmentCustomListResponses
}

View File

@ -46,10 +46,13 @@ func Init() *gin.Engine {
// 验证权限
r.Use(middlewares.Auth())
// 注册私有路由
// 私有路由-验证权限
privateRouter(r, api)
// 注册私有路由-基础数据
// 公共路由-验证权限
adminRouter(r, api)
// 基础数据-验证权限
basicRouter(r, api)
return r
@ -59,24 +62,26 @@ func Init() *gin.Engine {
func publicRouter(r *gin.Engine, api controller.Api) {
adminGroup := r.Group("/admin")
// 验证码
adminGroup.GET("/captcha", api.Basic.GetCaptcha)
adminGroup.GET("/captcha", api.Admin.GetCaptcha)
// 登陆
adminGroup.POST("/login", api.Basic.Login)
adminGroup.POST("/login", api.Admin.Login)
}
// basicRouter 私有路由-验证权限 基础数据
func basicRouter(r *gin.Engine, api controller.Api) {
basicGroup := r.Group("/basic")
// adminRouter 公共路由-验证权限
func adminRouter(r *gin.Engine, api controller.Api) {
// 签名
signGroup := basicGroup.Group("/sign")
signGroup := r.Group("/sign")
{
// 获取角色列表-分页
signGroup.GET("/oss", api.Role.GetRolePage)
// 获取oss签名
signGroup.GET("/oss", api.Admin.GetOssSign)
}
}
// basicRouter 基础数据-验证权限
func basicRouter(r *gin.Engine, api controller.Api) {
}
// privateRouter 私有路由-验证权限
func privateRouter(r *gin.Engine, api controller.Api) {
adminGroup := r.Group("/admin")
@ -228,6 +233,9 @@ func privateRouter(r *gin.Engine, api controller.Api) {
// 医生详情
doctorGroup.GET("/:doctor_id", api.UserDoctor.GetPostUserDoctor)
// 修改医生
doctorGroup.PUT("/:doctor_id", api.UserDoctor.PutPostUserDoctor)
// // 新增医生
// doctorGroup.POST("", api.Post.AddPost)
//
@ -241,4 +249,14 @@ func privateRouter(r *gin.Engine, api controller.Api) {
// doctorGroup.PUT("/:post_id", api.Post.PutPost)
}
// 科室
departmentGroup := adminGroup.Group("/department")
{
// 自定义科室
customGroup := departmentGroup.Group("/custom")
{
// 获取自定义科室列表
customGroup.GET("/list", api.Department.GetDepartmentList)
}
}
}

100
api/service/admin.go Normal file
View File

@ -0,0 +1,100 @@
package service
import (
"crypto/md5"
"encoding/hex"
"errors"
"hospital-admin-api/api/dao"
"hospital-admin-api/api/requests"
"hospital-admin-api/api/responses/adminResponse"
"hospital-admin-api/extend/aliyun"
"hospital-admin-api/utils"
"strconv"
)
type AdminService struct {
}
// Login 登陆
func (b *AdminService) Login(LoginRequest requests.Login) (*adminResponse.Login, error) {
// 获取用户信息
AdminUserDao := dao.AdminUserDao{}
adminUser, err := AdminUserDao.GetAdminUserFirstByAccess(LoginRequest.Access)
if err != nil || adminUser == nil {
return nil, errors.New("用户名或密码错误")
}
// 检测用户密码
password := md5.Sum([]byte(LoginRequest.Password + adminUser.Salt))
// 将哈希值转换为16进制字符串
passwordString := hex.EncodeToString(password[:])
if passwordString != adminUser.Password {
return nil, errors.New("用户名或密码错误")
}
// 检测用户状态
if adminUser.IsDeleted == 1 {
return nil, errors.New("非法用户")
}
if adminUser.IsDisabled == 1 {
return nil, errors.New("您的账号已被禁用,请联系管理员处理")
}
token := &utils.Token{
UserId: strconv.FormatInt(adminUser.UserID, 10),
RoleId: strconv.FormatInt(adminUser.RoleID, 10),
DeptId: strconv.FormatInt(adminUser.DeptID, 10),
PostId: strconv.FormatInt(adminUser.PostID, 10),
}
// 生成jwt
jwt, err := token.NewJWT()
if err != nil {
return nil, errors.New("登陆失败")
}
result := &adminResponse.Login{
UserId: strconv.FormatInt(adminUser.UserID, 10),
NickName: adminUser.NickName,
Avatar: adminUser.Avatar,
Token: jwt,
}
result.GetFullAvatar()
return result, nil
}
// GetOssSign 获取oss签名
func (a *AdminService) GetOssSign(getOssSignRequest requests.GetOssSign) (*aliyun.GetOssSignResponse, error) {
var dir string
if getOssSignRequest.UserType == 1 {
dir = "applet/patient/"
} else if getOssSignRequest.UserType == 2 {
dir = "applet/doctor/"
} else if getOssSignRequest.UserType == 3 {
dir = "applet/pharmacist/"
} else if getOssSignRequest.UserType == 4 {
dir = "applet/admin/"
}
if dir != "" {
if getOssSignRequest.Scene == 1 {
dir = dir + "avatar/"
} else if getOssSignRequest.Scene == 2 {
dir = dir + "cert/"
} else if getOssSignRequest.Scene == 3 {
dir = dir + "card/"
}
}
if dir == "" {
return nil, errors.New("获取签名失败")
}
// 生成签名
ossSign, _ := aliyun.GetOssSign(dir)
return ossSign, nil
}

View File

@ -1,66 +1,3 @@
package service
import (
"crypto/md5"
"encoding/hex"
"errors"
"hospital-admin-api/api/dao"
"hospital-admin-api/api/requests"
"hospital-admin-api/api/responses/basicResponse"
"hospital-admin-api/utils"
"strconv"
)
type BasicService struct{}
// Login 登陆
func (b *BasicService) Login(LoginRequest requests.Login) (basicResponse.Login, error) {
// 获取用户信息
AdminUserDao := dao.AdminUserDao{}
adminUser, err := AdminUserDao.GetAdminUserFirstByAccess(LoginRequest.Access)
if err != nil || adminUser == nil {
return basicResponse.Login{}, errors.New("用户名或密码错误")
}
// 检测用户密码
password := md5.Sum([]byte(LoginRequest.Password + adminUser.Salt))
// 将哈希值转换为16进制字符串
passwordString := hex.EncodeToString(password[:])
if passwordString != adminUser.Password {
return basicResponse.Login{}, errors.New("用户名或密码错误")
}
// 检测用户状态
if adminUser.IsDeleted == 1 {
return basicResponse.Login{}, errors.New("非法用户")
}
if adminUser.IsDisabled == 1 {
return basicResponse.Login{}, errors.New("您的账号已被禁用,请联系管理员处理")
}
token := &utils.Token{
UserId: strconv.FormatInt(adminUser.UserID, 10),
RoleId: strconv.FormatInt(adminUser.RoleID, 10),
DeptId: strconv.FormatInt(adminUser.DeptID, 10),
PostId: strconv.FormatInt(adminUser.PostID, 10),
}
// 生成jwt
jwt, err := token.NewJWT()
if err != nil {
return basicResponse.Login{}, errors.New("登陆失败")
}
result := basicResponse.Login{
UserId: strconv.FormatInt(adminUser.UserID, 10),
NickName: adminUser.NickName,
Avatar: adminUser.Avatar,
Token: jwt,
}
result.GetFullAvatar()
return result, nil
}

View File

@ -1,4 +1,247 @@
package service
import (
"errors"
"hospital-admin-api/api/dao"
"hospital-admin-api/api/requests"
"hospital-admin-api/config"
"hospital-admin-api/global"
"strconv"
"strings"
)
type UserDoctorService struct {
}
// PutPostUserDoctor 修改医生
func (r *UserDoctorService) PutPostUserDoctor(doctorId int64, userDoctorRequest requests.PutPostUserDoctor) (bool, error) {
// 获取医生数据
userDoctorDao := dao.UserDoctorDao{}
userDoctor, err := userDoctorDao.GetUserDoctorById(doctorId)
if err != nil || userDoctor == nil {
return false, errors.New("医生数据错误")
}
// 获取医生详情数据
userDoctorInfoDao := dao.UserDoctorInfoDao{}
userDoctorInfo, err := userDoctorInfoDao.GetUserDoctorInfoByDoctorId(doctorId)
if err != nil {
return false, errors.New("医生详情数据错误")
}
// 医生数据
var userDoctorData map[string]interface{}
// 医生详情数据
var userDoctorInfoData map[string]interface{}
// 处理头像
userDoctorRequest.Avatar = strings.Replace(userDoctorRequest.Avatar, config.C.Oss.OssCustomDomainName, "", 1)
if userDoctor.Avatar != userDoctorRequest.Avatar {
userDoctorData["avatar"] = userDoctorRequest.Avatar
userDoctorInfoData["avatar"] = userDoctorRequest.Avatar
}
// 处理职称
if userDoctor.DoctorTitle != userDoctorRequest.DoctorTitle {
userDoctorData["doctor_title"] = userDoctorRequest.DoctorTitle
}
// 处理科室
departmentCustomId, err := strconv.ParseInt(userDoctorRequest.DepartmentCustomId, 10, 64)
if err != nil {
return false, errors.New("科室错误")
}
if userDoctor.DepartmentCustomId != departmentCustomId || userDoctor.DepartmentCustomName != userDoctorRequest.DepartmentCustomName {
// 获取科室数据
hospitalDepartmentCustomDao := dao.HospitalDepartmentCustom{}
hospitalDepartmentCustom, err := hospitalDepartmentCustomDao.GetHospitalDepartmentCustomById(departmentCustomId)
if err != nil || hospitalDepartmentCustom == nil {
return false, errors.New("科室错误")
}
userDoctorData["department_custom_id"] = userDoctorRequest.DepartmentCustomId
userDoctorData["department_custom_name"] = hospitalDepartmentCustom.DepartmentCustomName
if userDoctorRequest.DepartmentCustomName != "" {
userDoctorData["department_custom_name"] = userDoctorRequest.DepartmentCustomName
}
}
// 处理科室电话
if userDoctor.DepartmentCustomMobile != userDoctorRequest.DepartmentCustomMobile {
userDoctorData["department_custom_id"] = userDoctorRequest.DepartmentCustomMobile
}
// 处理医院
hospitalId, err := strconv.ParseInt(userDoctorRequest.HospitalId, 10, 64)
if err != nil {
return false, errors.New("科室错误")
}
if userDoctor.HospitalID != hospitalId {
// 获取医院数据
hospitalDao := dao.Hospital{}
hospital, err := hospitalDao.GetHospitalById(hospitalId)
if err != nil || hospital == nil {
return false, errors.New("医院错误")
}
userDoctorData["department_custom_id"] = userDoctorRequest.HospitalId
}
// 处理擅长
if userDoctor.BeGoodAt != userDoctorRequest.BeGoodAt {
userDoctorData["be_good_at"] = userDoctorRequest.BeGoodAt
}
// 医生简介
if userDoctor.BriefIntroduction != userDoctorRequest.BriefIntroduction {
userDoctorData["brief_introduction"] = userDoctorRequest.BriefIntroduction
}
// 处理医师执业证
var licenseCert string
if len(userDoctorRequest.LicenseCert) > 0 {
result := make([]string, len(userDoctorRequest.LicenseCert))
for i, url := range userDoctorRequest.LicenseCert {
result[i] = strings.TrimPrefix(url, config.C.Oss.OssCustomDomainName)
}
licenseCert = strings.Join(result, ",")
}
if userDoctorInfo != nil {
if userDoctorInfo.LicenseCert != licenseCert {
userDoctorInfoData["license_cert"] = licenseCert
}
} else {
userDoctorInfoData["license_cert"] = licenseCert
}
// 处理医师资格证
var qualificationCert string
if len(userDoctorRequest.QualificationCert) > 0 {
result := make([]string, len(userDoctorRequest.QualificationCert))
for i, url := range userDoctorRequest.QualificationCert {
result[i] = strings.TrimPrefix(url, config.C.Oss.OssCustomDomainName)
}
qualificationCert = strings.Join(result, ",")
}
if userDoctorInfo != nil {
if userDoctorInfo.QualificationCert != qualificationCert {
userDoctorInfoData["qualification_cert"] = qualificationCert
}
} else {
userDoctorInfoData["qualification_cert"] = qualificationCert
}
// 处理医师资格证号
if userDoctorInfo != nil {
if userDoctorInfo.QualificationCertNum != userDoctorRequest.QualificationCertNum {
userDoctorInfoData["qualification_cert_num"] = userDoctorRequest.QualificationCertNum
}
} else {
userDoctorInfoData["qualification_cert_num"] = userDoctorRequest.QualificationCertNum
}
// 处理医师工作证
var workCert string
if len(userDoctorRequest.WorkCert) > 0 {
result := make([]string, len(userDoctorRequest.WorkCert))
for i, url := range userDoctorRequest.WorkCert {
result[i] = strings.TrimPrefix(url, config.C.Oss.OssCustomDomainName)
}
workCert = strings.Join(result, ",")
}
if userDoctorInfo != nil {
if userDoctorInfo.WorkCert != workCert {
userDoctorInfoData["work_cert"] = workCert
}
} else {
userDoctorInfoData["work_cert"] = workCert
}
// 处理身份证正面图片
if userDoctorRequest.IdCardFront != "" {
idCardFront := strings.Replace(userDoctorRequest.IdCardFront, "https://img.applets.igandanyiyuan.com", "", 1)
if idCardFront != userDoctorInfo.IdCardFront {
userDoctorInfoData["id_card_front"] = idCardFront
}
}
// 身份证背面图片
if userDoctorRequest.IdCardBack != "" {
idCardBack := strings.Replace(userDoctorRequest.IdCardBack, "https://img.applets.igandanyiyuan.com", "", 1)
if idCardBack != userDoctorInfo.IdCardBack {
userDoctorInfoData["id_card_back"] = idCardBack
}
}
// 签名图片
if userDoctorRequest.SignImage != "" {
signImage := strings.Replace(userDoctorRequest.SignImage, "https://img.applets.igandanyiyuan.com", "", 1)
if signImage != userDoctorInfo.SignImage {
userDoctorInfoData["sign_image"] = signImage
}
}
// 开始事务
tx := global.Db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
// 修改医生数据
if len(userDoctorData) != 0 {
err = userDoctorDao.EditUserDoctorById(tx, doctorId, userDoctorData)
if err != nil {
tx.Rollback()
return false, errors.New("修改失败")
}
}
// 修改医生详情数据
if userDoctorInfo == nil {
// 新增医生详情表
if len(userDoctorInfoData) != 0 {
userDoctorInfo, err := userDoctorInfoDao.AddUserDoctorInfoByMap(tx, userDoctorInfoData)
if userDoctorInfo == nil || err != nil {
tx.Rollback()
return false, errors.New("修改失败")
}
}
} else {
if len(userDoctorInfoData) != 0 {
err = userDoctorInfoDao.EditUserDoctorInfoById(tx, userDoctorInfo.DoctorInfoId, userDoctorInfoData)
if err != nil {
tx.Rollback()
return false, errors.New("修改失败")
}
}
}
// _, ok := userDoctorData["department_custom_id"]
// if ok {
// // 变更科室
//
// }
//
// paramMap := map[string]string{
// "userName": "zj",
// "age": "19",
// }
//
// sign := ca.GenerateSignature(paramMap)
// fmt.Println(sign)
tx.Commit()
return true, nil
//
}

View File

@ -39,4 +39,9 @@ oss:
oss-bucket: gdxz-hospital
oss-endpoint: oss-cn-chengdu.aliyuncs.com
oss-custom-domain-name: https://img.applets.igandanyiyuan.com
oss-env: applet-dev
oss-env: applet-dev
ca-online:
ca-online-app-id: SCCA1646691325903052802
ca-online-app-secret: adf718ebc1fb4bb7b158de9117d1313a
ca-online-api-url: http://testmicrosrv.scca.com.cn:9527

7
config/caOnline.go Normal file
View File

@ -0,0 +1,7 @@
package config
type CaOnline struct {
CaOnlineAppId string `mapstructure:"ca-online-app-id" json:"ca-online-app-id" yaml:"ca-online-app-id"`
CaOnlineAppSecret string `mapstructure:"ca-online-app-secret" json:"ca-online-app-secret" yaml:"ca-online-app-secret"`
CaOnlineApiUrl string `mapstructure:"ca-online-api-url" json:"ca-online-api-url" yaml:"ca-online-api-url"`
}

View File

@ -3,12 +3,13 @@ package config
var C Config
type Config struct {
Port int `mapstructure:"port" json:"port" yaml:"port"`
Env string `mapstructure:"env" json:"Env" yaml:"Env"`
Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
Log Log `mapstructure:"log" json:"log" yaml:"log"`
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
Jwt Jwt `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
Oss Oss `mapstructure:"oss" json:"oss" yaml:"oss"`
Snowflake int64 `mapstructure:"snowflake" json:"snowflake" yaml:"snowflake"`
Port int `mapstructure:"port" json:"port" yaml:"port"`
Env string `mapstructure:"env" json:"Env" yaml:"Env"`
Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
Log Log `mapstructure:"log" json:"log" yaml:"log"`
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
Jwt Jwt `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
Oss Oss `mapstructure:"oss" json:"oss" yaml:"oss"`
Snowflake int64 `mapstructure:"snowflake" json:"snowflake" yaml:"snowflake"`
CaOnline CaOnline `mapstructure:"ca_online" json:"ca_online" yaml:"ca_online"`
}

69
extend/aliyun/oss.go Normal file
View File

@ -0,0 +1,69 @@
package aliyun
import (
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"encoding/json"
"hospital-admin-api/config"
"strings"
"time"
)
// GetOssSignResponse 获取oss签名返回值
type GetOssSignResponse struct {
AccessId string `json:"access_id"` // 主键id
Host string `json:"host"`
Policy string `json:"policy"`
Signature string `json:"signature"`
Expire int64 `json:"expire"`
Callback string `json:"callback"`
Dir string `json:"dir"`
}
// GetOssSign 获取oss签名
func GetOssSign(dir string) (*GetOssSignResponse, error) {
// Endpoint := config.C.Oss.OssEndpoint
// accessKey := config.C.Oss.OssAccessKey
// accessSecret := config.C.Oss.OssAccessKeySecret
// client, err := oss.New(Endpoint, accessKey, accessSecret)
// if err != nil {
// return nil, err
// }
//
// bucket, err := client.Bucket(viper.GetString("aliyun.Bucket"))
// if err != nil {
// return "", err
// }
now := time.Now()
expire := 30 // 设置该policy超时时间是30s即这个policy过了这个有效时间将不能访问。
end := now.Add(time.Second * time.Duration(expire))
expiration := strings.Replace(end.Format("2006-01-02T15:04:05.000Z"), "+00:00", ".000Z", 1)
start := []interface{}{"starts-with", "$key", dir}
conditions := [][]interface{}{start}
arr := map[string]interface{}{
"expiration": expiration,
"conditions": conditions,
}
policy, _ := json.Marshal(arr)
base64Policy := base64.StdEncoding.EncodeToString(policy)
stringToSign := base64Policy
h := hmac.New(sha1.New, []byte(config.C.Oss.OssAccessKeySecret))
h.Write([]byte(stringToSign))
signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
response := &GetOssSignResponse{
AccessId: config.C.Oss.OssAccessKey,
Host: config.C.Oss.OssCustomDomainName,
Policy: base64Policy,
Signature: signature,
Expire: end.Unix(),
Callback: "",
Dir: dir,
}
return response, nil
}

36
extend/ca/ca.go Normal file
View File

@ -0,0 +1,36 @@
package ca
import (
"crypto/hmac"
"crypto/sha1"
"encoding/hex"
"hospital-admin-api/config"
"sort"
"strings"
)
// GenerateSignature 生成签名
func GenerateSignature(paramMap map[string]string) string {
keys := make([]string, 0, len(paramMap))
for k := range paramMap {
if k == "pdfFile" {
continue
}
keys = append(keys, k)
}
sort.Strings(keys)
var toSign string
for _, k := range keys {
v := paramMap[k]
toSign += v + "&"
}
toSign = strings.TrimSuffix(toSign, "&")
// Step 3: Calculate HMAC-SHA1 and convert to hex format
h := hmac.New(sha1.New, []byte(config.C.CaOnline.CaOnlineAppSecret))
h.Write([]byte(toSign))
signature := hex.EncodeToString(h.Sum(nil))
return signature
}

5
extend/ca/caOnline.go Normal file
View File

@ -0,0 +1,5 @@
package ca
// func GenerateSi1gnature(paramMap map[string]string, secret string) string {
//
// }