diff --git a/api/controller/doctorPharmacy.go b/api/controller/doctorPharmacy.go index 1a240dc..5821429 100644 --- a/api/controller/doctorPharmacy.go +++ b/api/controller/doctorPharmacy.go @@ -2,6 +2,7 @@ package controller import ( "github.com/gin-gonic/gin" + "hospital-admin-api/api/dao" "hospital-admin-api/api/requests" "hospital-admin-api/api/responses" "hospital-admin-api/api/service" @@ -14,9 +15,12 @@ type DoctorPharmacy struct{} // GetDoctorPharmacies 获取指定医生绑定的药房列表 func (r *DoctorPharmacy) GetDoctorPharmacies(c *gin.Context) { - id := c.Param("doctor_id") + id := c.Param("id") if id == "" { - responses.FailWithMessage("缺少参数", c) + id = c.Param("doctor_id") + } + if id == "" { + responses.FailWithMessage("缺少医生ID参数", c) return } @@ -38,9 +42,12 @@ func (r *DoctorPharmacy) GetDoctorPharmacies(c *gin.Context) { // BindDoctorPharmacies 批量设置/覆盖医生绑定的药房列表 func (r *DoctorPharmacy) BindDoctorPharmacies(c *gin.Context) { - id := c.Param("doctor_id") + id := c.Param("id") if id == "" { - responses.FailWithMessage("缺少参数", c) + id = c.Param("doctor_id") + } + if id == "" { + responses.FailWithMessage("缺少医生ID参数", c) return } @@ -73,16 +80,14 @@ func (r *DoctorPharmacy) BindDoctorPharmacies(c *gin.Context) { // AddDoctorPharmacy 为医生新增单个药房绑定 func (r *DoctorPharmacy) AddDoctorPharmacy(c *gin.Context) { - id := c.Param("doctor_id") + id := c.Param("id") if id == "" { - responses.FailWithMessage("缺少参数", c) - return + id = c.Param("doctor_id") } - doctorId, err := strconv.ParseInt(id, 10, 64) - if err != nil { - responses.Fail(c) - return + var doctorId int64 + if id != "" { + doctorId, _ = strconv.ParseInt(id, 10, 64) } req := requests.AddDoctorPharmacy{} @@ -91,13 +96,22 @@ func (r *DoctorPharmacy) AddDoctorPharmacy(c *gin.Context) { return } + if doctorId == 0 && req.DoctorId != "" { + doctorId, _ = strconv.ParseInt(req.DoctorId, 10, 64) + } + + if doctorId == 0 { + responses.FailWithMessage("缺少医生ID", c) + return + } + if err := global.Validate.Struct(req); err != nil { responses.FailWithMessage(utils.Translate(err), c) return } doctorPharmacyService := service.DoctorPharmacyService{} - _, err = doctorPharmacyService.AddDoctorPharmacy(doctorId, req) + _, err := doctorPharmacyService.AddDoctorPharmacy(doctorId, req) if err != nil { responses.FailWithMessage(err.Error(), c) return @@ -106,64 +120,174 @@ func (r *DoctorPharmacy) AddDoctorPharmacy(c *gin.Context) { responses.Ok(c) } -// UnbindDoctorPharmacy 解除医生与指定药房的绑定 +// UnbindDoctorPharmacy 解除医生与指定药房的绑定(DELETE /admin/doctor/pharmacy/:id) func (r *DoctorPharmacy) UnbindDoctorPharmacy(c *gin.Context) { - docId := c.Param("doctor_id") - pharId := c.Param("pharmacy_id") - if docId == "" || pharId == "" { - responses.FailWithMessage("缺少参数", c) - return + idStr := c.Param("id") + if idStr == "" { + idStr = c.Param("doctor_pharmacy_id") } - doctorId, err := strconv.ParseInt(docId, 10, 64) - if err != nil { - responses.Fail(c) - return - } - - pharmacyId, err := strconv.ParseInt(pharId, 10, 64) - if err != nil { - responses.Fail(c) + id, err := strconv.ParseInt(idStr, 10, 64) + if err != nil || id == 0 { + responses.FailWithMessage("缺少ID参数", c) return } + doctorPharmacyDao := dao.DoctorPharmacyDao{} doctorPharmacyService := service.DoctorPharmacyService{} - _, err = doctorPharmacyService.UnbindDoctorPharmacy(doctorId, pharmacyId) - if err != nil { + + // 1. 优先作为 doctor_pharmacy_id 判定 + dp, _ := doctorPharmacyDao.GetDoctorPharmacyById(id) + if dp != nil { + _, err = doctorPharmacyService.UnbindDoctorPharmacyById(id) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + responses.Ok(c) + return + } + + // 2. 若作为 doctor_id,从 query 或 body 获取 pharmacy_id + pharmacyIdStr := c.Query("pharmacy_id") + if pharmacyIdStr != "" { + pharmacyId, err := strconv.ParseInt(pharmacyIdStr, 10, 64) + if err == nil && pharmacyId > 0 { + _, err = doctorPharmacyService.UnbindDoctorPharmacy(id, pharmacyId) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + responses.Ok(c) + return + } + } + + responses.FailWithMessage("未找到绑定记录或缺少药房ID", c) +} + +// UnbindDoctorPharmacyPost 解绑药房(POST /admin/doctor/pharmacy/unbind) +func (r *DoctorPharmacy) UnbindDoctorPharmacyPost(c *gin.Context) { + req := requests.UnbindDoctorPharmacy{} + if err := c.ShouldBindJSON(&req); err != nil { responses.FailWithMessage(err.Error(), c) return } - responses.Ok(c) + doctorPharmacyService := service.DoctorPharmacyService{} + + // 优先按 doctor_pharmacy_id + if req.DoctorPharmacyId != "" { + dpid, err := strconv.ParseInt(req.DoctorPharmacyId, 10, 64) + if err == nil && dpid > 0 { + _, err = doctorPharmacyService.UnbindDoctorPharmacyById(dpid) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + responses.Ok(c) + return + } + } + + // 其次按 doctor_id + pharmacy_id + if req.DoctorId != "" && req.PharmacyId != "" { + docId, err1 := strconv.ParseInt(req.DoctorId, 10, 64) + pharId, err2 := strconv.ParseInt(req.PharmacyId, 10, 64) + if err1 == nil && err2 == nil { + _, err := doctorPharmacyService.UnbindDoctorPharmacy(docId, pharId) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + responses.Ok(c) + return + } + } + + responses.FailWithMessage("缺少解绑参数", c) } -// SetDefaultDoctorPharmacy 设为医生的默认药房 +// SetDefaultDoctorPharmacy 设置默认药房(PUT /admin/doctor/pharmacy/default/:id) func (r *DoctorPharmacy) SetDefaultDoctorPharmacy(c *gin.Context) { - docId := c.Param("doctor_id") - pharId := c.Param("pharmacy_id") - if docId == "" || pharId == "" { - responses.FailWithMessage("缺少参数", c) - return - } - - doctorId, err := strconv.ParseInt(docId, 10, 64) - if err != nil { - responses.Fail(c) - return - } - - pharmacyId, err := strconv.ParseInt(pharId, 10, 64) - if err != nil { - responses.Fail(c) + idStr := c.Param("id") + id, err := strconv.ParseInt(idStr, 10, 64) + if err != nil || id == 0 { + responses.FailWithMessage("缺少ID参数", c) return } + doctorPharmacyDao := dao.DoctorPharmacyDao{} doctorPharmacyService := service.DoctorPharmacyService{} - _, err = doctorPharmacyService.SetDefaultPharmacy(doctorId, pharmacyId) - if err != nil { + + // 1. 优先作为 doctor_pharmacy_id 判定 + dp, _ := doctorPharmacyDao.GetDoctorPharmacyById(id) + if dp != nil { + _, err = doctorPharmacyService.SetDefaultPharmacyById(id) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + responses.Ok(c) + return + } + + // 2. 若作为 doctor_id,从 query 或 body 获取 pharmacy_id + pharmacyIdStr := c.Query("pharmacy_id") + if pharmacyIdStr != "" { + pharmacyId, err := strconv.ParseInt(pharmacyIdStr, 10, 64) + if err == nil && pharmacyId > 0 { + _, err = doctorPharmacyService.SetDefaultPharmacy(id, pharmacyId) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + responses.Ok(c) + return + } + } + + responses.FailWithMessage("未找到绑定记录或缺少药房ID", c) +} + +// SetDefaultDoctorPharmacyPut 设置默认药房(PUT /admin/doctor/pharmacy/default) +func (r *DoctorPharmacy) SetDefaultDoctorPharmacyPut(c *gin.Context) { + req := requests.SetDefaultDoctorPharmacy{} + if err := c.ShouldBindJSON(&req); err != nil { responses.FailWithMessage(err.Error(), c) return } - responses.Ok(c) + doctorPharmacyService := service.DoctorPharmacyService{} + + // 优先按 doctor_pharmacy_id + if req.DoctorPharmacyId != "" { + dpid, err := strconv.ParseInt(req.DoctorPharmacyId, 10, 64) + if err == nil && dpid > 0 { + _, err = doctorPharmacyService.SetDefaultPharmacyById(dpid) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + responses.Ok(c) + return + } + } + + // 其次按 doctor_id + pharmacy_id + if req.DoctorId != "" && req.PharmacyId != "" { + docId, err1 := strconv.ParseInt(req.DoctorId, 10, 64) + pharId, err2 := strconv.ParseInt(req.PharmacyId, 10, 64) + if err1 == nil && err2 == nil { + _, err := doctorPharmacyService.SetDefaultPharmacy(docId, pharId) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + responses.Ok(c) + return + } + } + + responses.FailWithMessage("缺少参数", c) } diff --git a/api/dao/doctorPharmacy.go b/api/dao/doctorPharmacy.go index 16a67ea..f37a28f 100644 --- a/api/dao/doctorPharmacy.go +++ b/api/dao/doctorPharmacy.go @@ -8,6 +8,15 @@ import ( type DoctorPharmacyDao struct{} +// GetDoctorPharmacyById 获取绑定关系-主键id +func (r *DoctorPharmacyDao) GetDoctorPharmacyById(doctorPharmacyId int64) (m *model.DoctorPharmacy, err error) { + err = global.Db.Where("doctor_pharmacy_id = ?", doctorPharmacyId).First(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + // GetDoctorPharmacyListByDoctorId 获取医生绑定的药房列表(带预加载药房详情) func (r *DoctorPharmacyDao) GetDoctorPharmacyListByDoctorId(doctorId int64) (m []*model.DoctorPharmacy, err error) { err = global.Db.Preload("Pharmacy").Where("doctor_id = ? AND status = 1", doctorId).Order("is_default desc, created_at desc").Find(&m).Error @@ -43,6 +52,15 @@ func (r *DoctorPharmacyDao) DeleteDoctorPharmacy(tx *gorm.DB, maps interface{}) return nil } +// DeleteDoctorPharmacyById 根据绑定关系主键id删除 +func (r *DoctorPharmacyDao) DeleteDoctorPharmacyById(tx *gorm.DB, doctorPharmacyId int64) error { + err := tx.Where("doctor_pharmacy_id = ?", doctorPharmacyId).Delete(&model.DoctorPharmacy{}).Error + if err != nil { + return err + } + return nil +} + // DeleteDoctorPharmacyByDoctorAndPharmacy 解绑指定医生和指定药房 func (r *DoctorPharmacyDao) DeleteDoctorPharmacyByDoctorAndPharmacy(tx *gorm.DB, doctorId, pharmacyId int64) error { err := tx.Where("doctor_id = ? AND pharmacy_id = ?", doctorId, pharmacyId).Delete(&model.DoctorPharmacy{}).Error @@ -69,3 +87,12 @@ func (r *DoctorPharmacyDao) SetDefaultPharmacy(tx *gorm.DB, doctorId, pharmacyId } return nil } + +// SetDefaultPharmacyById 根据主键设为默认 +func (r *DoctorPharmacyDao) SetDefaultPharmacyById(tx *gorm.DB, doctorPharmacyId int64) error { + err := tx.Model(&model.DoctorPharmacy{}).Where("doctor_pharmacy_id = ?", doctorPharmacyId).Update("is_default", 1).Error + if err != nil { + return err + } + return nil +} diff --git a/api/requests/doctorPharmacy.go b/api/requests/doctorPharmacy.go index fb32db9..9e9e982 100644 --- a/api/requests/doctorPharmacy.go +++ b/api/requests/doctorPharmacy.go @@ -1,8 +1,10 @@ package requests type DoctorPharmacyRequest struct { - BindDoctorPharmacies // 批量绑定药房 - AddDoctorPharmacy // 新增单个药房绑定 + BindDoctorPharmacies // 批量绑定药房 + AddDoctorPharmacy // 新增单个药房绑定 + UnbindDoctorPharmacy // 解绑药房 + SetDefaultDoctorPharmacy // 设置默认药房 } // BindDoctorPharmacies 批量绑定药房 @@ -13,6 +15,21 @@ type BindDoctorPharmacies struct { // AddDoctorPharmacy 单个药房绑定 type AddDoctorPharmacy struct { + DoctorId string `json:"doctor_id" form:"doctor_id" label:"医生id"` PharmacyId string `json:"pharmacy_id" form:"pharmacy_id" label:"药房id" validate:"required"` IsDefault *int `json:"is_default" form:"is_default" label:"是否默认" validate:"omitempty,oneof=0 1"` } + +// UnbindDoctorPharmacy 解除药房绑定 +type UnbindDoctorPharmacy struct { + DoctorPharmacyId string `json:"doctor_pharmacy_id" form:"doctor_pharmacy_id" label:"绑定关系id"` + DoctorId string `json:"doctor_id" form:"doctor_id" label:"医生id"` + PharmacyId string `json:"pharmacy_id" form:"pharmacy_id" label:"药房id"` +} + +// SetDefaultDoctorPharmacy 设置默认药房 +type SetDefaultDoctorPharmacy struct { + DoctorPharmacyId string `json:"doctor_pharmacy_id" form:"doctor_pharmacy_id" label:"绑定关系id"` + DoctorId string `json:"doctor_id" form:"doctor_id" label:"医生id"` + PharmacyId string `json:"pharmacy_id" form:"pharmacy_id" label:"药房id"` +} diff --git a/api/router/router.go b/api/router/router.go index 72d49f1..61defd7 100644 --- a/api/router/router.go +++ b/api/router/router.go @@ -372,22 +372,25 @@ func privateRouter(r *gin.Engine, api controller.Api) { doctorGroup.POST("", api.UserDoctor.AddUserDoctor) // 医生药房管理 - doctorPharmacyGroup := doctorGroup.Group("/:doctor_id/pharmacy") + doctorPharmacyGroup := doctorGroup.Group("/pharmacy") { // 获取医生绑定的药房列表 - doctorPharmacyGroup.GET("", api.DoctorPharmacy.GetDoctorPharmacies) + doctorPharmacyGroup.GET("/:doctor_id", api.DoctorPharmacy.GetDoctorPharmacies) // 批量设置医生绑定的药房列表 - doctorPharmacyGroup.PUT("", api.DoctorPharmacy.BindDoctorPharmacies) + doctorPharmacyGroup.PUT("/:doctor_id", api.DoctorPharmacy.BindDoctorPharmacies) // 为医生新增单个药房绑定 doctorPharmacyGroup.POST("", api.DoctorPharmacy.AddDoctorPharmacy) + doctorPharmacyGroup.POST("/:doctor_id", api.DoctorPharmacy.AddDoctorPharmacy) // 解除医生与指定药房的绑定 - doctorPharmacyGroup.DELETE("/:pharmacy_id", api.DoctorPharmacy.UnbindDoctorPharmacy) + doctorPharmacyGroup.DELETE("/:id", api.DoctorPharmacy.UnbindDoctorPharmacy) + doctorPharmacyGroup.POST("/unbind", api.DoctorPharmacy.UnbindDoctorPharmacyPost) // 设置医生的默认药房 - doctorPharmacyGroup.PUT("/default/:pharmacy_id", api.DoctorPharmacy.SetDefaultDoctorPharmacy) + doctorPharmacyGroup.PUT("/default/:id", api.DoctorPharmacy.SetDefaultDoctorPharmacy) + doctorPharmacyGroup.PUT("/default", api.DoctorPharmacy.SetDefaultDoctorPharmacyPut) } // 身份审核列表 diff --git a/api/service/doctorPharmacy.go b/api/service/doctorPharmacy.go index da9059b..6d19038 100644 --- a/api/service/doctorPharmacy.go +++ b/api/service/doctorPharmacy.go @@ -95,6 +95,13 @@ func (r *DoctorPharmacyService) BindDoctorPharmacies(doctorId int64, req request // AddDoctorPharmacy 新增单个药房绑定 func (r *DoctorPharmacyService) AddDoctorPharmacy(doctorId int64, req requests.AddDoctorPharmacy) (bool, error) { + if doctorId == 0 && req.DoctorId != "" { + doctorId, _ = strconv.ParseInt(req.DoctorId, 10, 64) + } + if doctorId == 0 { + return false, errors.New("医生id无效") + } + pharmacyId, err := strconv.ParseInt(req.PharmacyId, 10, 64) if err != nil || pharmacyId == 0 { return false, errors.New("药房id无效") @@ -157,7 +164,39 @@ func (r *DoctorPharmacyService) AddDoctorPharmacy(doctorId int64, req requests.A return true, nil } -// UnbindDoctorPharmacy 解绑单个药房 +// UnbindDoctorPharmacyById 根据绑定记录ID解绑 +func (r *DoctorPharmacyService) UnbindDoctorPharmacyById(doctorPharmacyId int64) (bool, error) { + doctorPharmacyDao := dao.DoctorPharmacyDao{} + exist, err := doctorPharmacyDao.GetDoctorPharmacyById(doctorPharmacyId) + if err != nil || exist == nil { + return false, errors.New("未找到绑定记录") + } + + tx := global.Db.Begin() + defer func() { + if rec := recover(); rec != nil { + tx.Rollback() + } + }() + + if err := doctorPharmacyDao.DeleteDoctorPharmacyById(tx, doctorPharmacyId); err != nil { + tx.Rollback() + return false, errors.New("解绑失败") + } + + // 如果解绑的是默认药房,尝试将剩余的第一个药房设为默认 + if exist.IsDefault == 1 { + list, _ := doctorPharmacyDao.GetDoctorPharmacyListByDoctorId(exist.DoctorId) + if len(list) > 0 { + _ = doctorPharmacyDao.SetDefaultPharmacy(tx, exist.DoctorId, list[0].PharmacyId) + } + } + + tx.Commit() + return true, nil +} + +// UnbindDoctorPharmacy 解绑单个药房(支持通过 doctor_pharmacy_id 或 (doctor_id, pharmacy_id)) func (r *DoctorPharmacyService) UnbindDoctorPharmacy(doctorId, pharmacyId int64) (bool, error) { doctorPharmacyDao := dao.DoctorPharmacyDao{} exist, err := doctorPharmacyDao.GetDoctorPharmacyByDoctorAndPharmacy(doctorId, pharmacyId) @@ -189,7 +228,36 @@ func (r *DoctorPharmacyService) UnbindDoctorPharmacy(doctorId, pharmacyId int64) return true, nil } -// SetDefaultPharmacy 设为默认药房 +// SetDefaultPharmacyById 根据绑定关系主键设为默认 +func (r *DoctorPharmacyService) SetDefaultPharmacyById(doctorPharmacyId int64) (bool, error) { + doctorPharmacyDao := dao.DoctorPharmacyDao{} + exist, err := doctorPharmacyDao.GetDoctorPharmacyById(doctorPharmacyId) + if err != nil || exist == nil { + return false, errors.New("该药房未绑定,无法设为默认") + } + + tx := global.Db.Begin() + defer func() { + if rec := recover(); rec != nil { + tx.Rollback() + } + }() + + if err := doctorPharmacyDao.ResetDoctorDefaultPharmacy(tx, exist.DoctorId); err != nil { + tx.Rollback() + return false, errors.New("重置默认药房状态失败") + } + + if err := doctorPharmacyDao.SetDefaultPharmacyById(tx, doctorPharmacyId); err != nil { + tx.Rollback() + return false, errors.New("设置默认药房失败") + } + + tx.Commit() + return true, nil +} + +// SetDefaultPharmacy 设为默认药房(通过 doctor_id 和 pharmacy_id) func (r *DoctorPharmacyService) SetDefaultPharmacy(doctorId, pharmacyId int64) (bool, error) { doctorPharmacyDao := dao.DoctorPharmacyDao{} exist, err := doctorPharmacyDao.GetDoctorPharmacyByDoctorAndPharmacy(doctorId, pharmacyId)