1、增加导出药房关联医生列表导出
2、检测到有绑定/默认医生时直接报错,强制要求管理员先手动处理;
This commit is contained in:
@@ -781,3 +781,51 @@ func (r *Export) OrderService(c *gin.Context) {
|
|||||||
|
|
||||||
responses.OkWithData(ossAddress, c)
|
responses.OkWithData(ossAddress, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PharmacyDoctor 药房关联医生
|
||||||
|
func (r *Export) PharmacyDoctor(c *gin.Context) {
|
||||||
|
pharmacyRequest := requests.PharmacyRequest{}
|
||||||
|
req := pharmacyRequest.PharmacyDoctorExportList
|
||||||
|
if err := c.ShouldBind(&req); err != nil {
|
||||||
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 参数验证
|
||||||
|
if err := global.Validate.Struct(req); err != nil {
|
||||||
|
responses.FailWithMessage(utils.Translate(err), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
doctorPharmacyDao := dao.DoctorPharmacyDao{}
|
||||||
|
list, err := doctorPharmacyDao.GetPharmacyDoctorExportListSearch(req)
|
||||||
|
if err != nil {
|
||||||
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 业务处理
|
||||||
|
exportService := service.ExportService{}
|
||||||
|
ossAddress, err := exportService.PharmacyDoctor(list)
|
||||||
|
if err != nil {
|
||||||
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前登陆用户id
|
||||||
|
userId := c.GetInt64("UserId")
|
||||||
|
if userId != 0 {
|
||||||
|
// 记录日志
|
||||||
|
logExport := &model.LogExport{
|
||||||
|
AdminUserId: userId,
|
||||||
|
ExportModule: "药房关联医生",
|
||||||
|
ExportFile: utils.RemoveOssDomain(ossAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
logExportDao := dao.LogExportDao{}
|
||||||
|
_, _ = logExportDao.AddLogExportUnTransaction(logExport)
|
||||||
|
}
|
||||||
|
|
||||||
|
responses.OkWithData(ossAddress, c)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package dao
|
package dao
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"hospital-admin-api/api/model"
|
"hospital-admin-api/api/model"
|
||||||
"hospital-admin-api/api/requests"
|
"hospital-admin-api/api/requests"
|
||||||
@@ -168,3 +172,94 @@ func (r *DoctorPharmacyDao) GetPharmacyDoctorListByPharmacyId(pharmacyId int64)
|
|||||||
}
|
}
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDoctorPharmacyCountsByPharmacyId 获取药房绑定的医生数量(有效绑定数、设为默认药房数)
|
||||||
|
func (r *DoctorPharmacyDao) GetDoctorPharmacyCountsByPharmacyId(pharmacyId int64) (totalCount int64, defaultCount int64, err error) {
|
||||||
|
err = global.Db.Model(&model.DoctorPharmacy{}).
|
||||||
|
Where("pharmacy_id = ? AND status = 1", pharmacyId).
|
||||||
|
Count(&totalCount).Error
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = global.Db.Model(&model.DoctorPharmacy{}).
|
||||||
|
Where("pharmacy_id = ? AND status = 1 AND is_default = 1", pharmacyId).
|
||||||
|
Count(&defaultCount).Error
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalCount, defaultCount, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPharmacyDoctorExportListSearch 获取药房关联医生列表-导出
|
||||||
|
func (r *DoctorPharmacyDao) GetPharmacyDoctorExportListSearch(req requests.PharmacyDoctorExportList) (m []*model.DoctorPharmacy, err error) {
|
||||||
|
query := global.Db.Model(&model.DoctorPharmacy{}).
|
||||||
|
Where("gdxz_doctor_pharmacy.status = 1")
|
||||||
|
|
||||||
|
// 药房id过滤
|
||||||
|
if req.PharmacyId != "" {
|
||||||
|
pharmacyId, _ := strconv.ParseInt(req.PharmacyId, 10, 64)
|
||||||
|
if pharmacyId >= 0 {
|
||||||
|
query = query.Where("gdxz_doctor_pharmacy.pharmacy_id = ?", pharmacyId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1:当前搜索数据
|
||||||
|
if req.Type == 1 {
|
||||||
|
needJoinDoctor := req.DoctorName != "" || req.Mobile != ""
|
||||||
|
if needJoinDoctor {
|
||||||
|
query = query.Joins("JOIN gdxz_user_doctor ON gdxz_user_doctor.doctor_id = gdxz_doctor_pharmacy.doctor_id")
|
||||||
|
if req.DoctorName != "" {
|
||||||
|
query = query.Where("gdxz_user_doctor.user_name LIKE ?", "%"+req.DoctorName+"%")
|
||||||
|
}
|
||||||
|
if req.Mobile != "" {
|
||||||
|
query = query.Joins("JOIN gdxz_user ON gdxz_user.user_id = gdxz_user_doctor.user_id").
|
||||||
|
Where("gdxz_user.mobile LIKE ?", "%"+req.Mobile+"%")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2:当前选中数据
|
||||||
|
if req.Type == 2 {
|
||||||
|
if req.Id == "" {
|
||||||
|
return nil, errors.New("未提供需导出数据编号")
|
||||||
|
}
|
||||||
|
id := strings.Split(req.Id, ",")
|
||||||
|
query = query.Where("gdxz_doctor_pharmacy.doctor_pharmacy_id IN (?) OR gdxz_doctor_pharmacy.doctor_id IN (?)", id, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3:全部数据(无额外搜索条件)
|
||||||
|
|
||||||
|
err = query.Order("gdxz_doctor_pharmacy.is_default desc, gdxz_doctor_pharmacy.created_at desc").
|
||||||
|
Preload("Pharmacy").
|
||||||
|
Preload("UserDoctor.User").
|
||||||
|
Preload("UserDoctor.Hospital").
|
||||||
|
Find(&m).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GORM 在外键为 0 时会自动跳过 Preload,因此针对未能预加载的记录进行兜底补全
|
||||||
|
var zeroPharmacy *model.Pharmacy
|
||||||
|
for _, dp := range m {
|
||||||
|
if dp.Pharmacy == nil {
|
||||||
|
if dp.PharmacyId == 0 {
|
||||||
|
if zeroPharmacy == nil {
|
||||||
|
var ph model.Pharmacy
|
||||||
|
if err := global.Db.Where("pharmacy_id = 0").First(&ph).Error; err == nil {
|
||||||
|
zeroPharmacy = &ph
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dp.Pharmacy = zeroPharmacy
|
||||||
|
} else {
|
||||||
|
var ph model.Pharmacy
|
||||||
|
if err := global.Db.Where("pharmacy_id = ?", dp.PharmacyId).First(&ph).Error; err == nil {
|
||||||
|
dp.Pharmacy = &ph
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,13 +1,23 @@
|
|||||||
package requests
|
package requests
|
||||||
|
|
||||||
type PharmacyRequest struct {
|
type PharmacyRequest struct {
|
||||||
GetPharmacyList // 获取药房列表
|
GetPharmacyList // 获取药房列表
|
||||||
GetPharmacyPage // 获取药房列表-分页
|
GetPharmacyPage // 获取药房列表-分页
|
||||||
AddPharmacy // 新增药房
|
AddPharmacy // 新增药房
|
||||||
PutPharmacy // 修改药房
|
PutPharmacy // 修改药房
|
||||||
PutPharmacyStatus // 修改药房状态
|
PutPharmacyStatus // 修改药房状态
|
||||||
GetPharmacyDoctorPage // 药房绑定的医生列表-分页
|
GetPharmacyDoctorPage // 药房绑定的医生列表-分页
|
||||||
GetPharmacyDoctorList // 药房绑定的医生列表
|
GetPharmacyDoctorList // 药房绑定的医生列表
|
||||||
|
PharmacyDoctorExportList // 药房关联医生-导出
|
||||||
|
}
|
||||||
|
|
||||||
|
// PharmacyDoctorExportList 药房关联医生-导出
|
||||||
|
type PharmacyDoctorExportList struct {
|
||||||
|
Type int `json:"type" form:"type" label:"类型" validate:"required,oneof=1 2 3"` // 1:当前搜索数据 2:当前选择数据 3:全部数据
|
||||||
|
Id string `json:"id" form:"id" label:"id"` // 选择数据的id(doctor_pharmacy_id或doctor_id),逗号分隔
|
||||||
|
PharmacyId string `json:"pharmacy_id" form:"pharmacy_id" label:"药房id"` // 药房id
|
||||||
|
DoctorName string `json:"doctor_name" form:"doctor_name" label:"医生姓名"` // 医生姓名
|
||||||
|
Mobile string `json:"mobile" form:"mobile" label:"手机号"` // 手机号
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPharmacyDoctorPage 药房绑定的医生列表-分页
|
// GetPharmacyDoctorPage 药房绑定的医生列表-分页
|
||||||
|
|||||||
@@ -391,6 +391,9 @@ func privateRouter(r *gin.Engine, api controller.Api) {
|
|||||||
// 设置医生的默认药房
|
// 设置医生的默认药房
|
||||||
doctorPharmacyGroup.PUT("/default/:id", api.DoctorPharmacy.SetDefaultDoctorPharmacy)
|
doctorPharmacyGroup.PUT("/default/:id", api.DoctorPharmacy.SetDefaultDoctorPharmacy)
|
||||||
doctorPharmacyGroup.PUT("/default", api.DoctorPharmacy.SetDefaultDoctorPharmacyPut)
|
doctorPharmacyGroup.PUT("/default", api.DoctorPharmacy.SetDefaultDoctorPharmacyPut)
|
||||||
|
|
||||||
|
// 药房关联医生-导出
|
||||||
|
doctorPharmacyGroup.POST("/export", api.Export.PharmacyDoctor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 身份审核列表
|
// 身份审核列表
|
||||||
@@ -809,6 +812,13 @@ func privateRouter(r *gin.Engine, api controller.Api) {
|
|||||||
// 系统药品
|
// 系统药品
|
||||||
productGroup.POST("", api.Export.Product)
|
productGroup.POST("", api.Export.Product)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 药房
|
||||||
|
pharmacyGroup := exportGroup.Group("/pharmacy")
|
||||||
|
{
|
||||||
|
// 药房关联医生
|
||||||
|
pharmacyGroup.POST("/doctor", api.Export.PharmacyDoctor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 商品管理
|
// 商品管理
|
||||||
@@ -943,6 +953,9 @@ func privateRouter(r *gin.Engine, api controller.Api) {
|
|||||||
|
|
||||||
// 药房绑定的医生列表
|
// 药房绑定的医生列表
|
||||||
pharmacyGroup.GET("/doctor/:pharmacy_id", api.Pharmacy.GetPharmacyDoctorList)
|
pharmacyGroup.GET("/doctor/:pharmacy_id", api.Pharmacy.GetPharmacyDoctorList)
|
||||||
|
|
||||||
|
// 药房关联医生-导出
|
||||||
|
pharmacyGroup.POST("/doctor/export", api.Export.PharmacyDoctor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 科普分类管理
|
// 科普分类管理
|
||||||
|
|||||||
@@ -380,6 +380,21 @@ type ProductData struct {
|
|||||||
CreatedAt string // 创建时间
|
CreatedAt string // 创建时间
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PharmacyDoctorData 药房关联医生
|
||||||
|
type PharmacyDoctorData struct {
|
||||||
|
PharmacyName string // 药房名称
|
||||||
|
PharmacyCode string // 药房代码
|
||||||
|
DoctorName string // 医生姓名
|
||||||
|
Mobile string // 手机号
|
||||||
|
DoctorTitle string // 医生职称
|
||||||
|
HospitalName string // 医院名称
|
||||||
|
DepartmentCustomName string // 科室名称
|
||||||
|
DepartmentCustomMobile string // 科室电话
|
||||||
|
IsDefault string // 是否默认药房(0:否 1:是)
|
||||||
|
Status string // 状态(0:禁用 1:正常)
|
||||||
|
CreatedAt string // 关联时间
|
||||||
|
}
|
||||||
|
|
||||||
// DoctorWithdrawal 提现记录
|
// DoctorWithdrawal 提现记录
|
||||||
func (r *ExportService) DoctorWithdrawal(doctorWithdrawals []*model.DoctorWithdrawal) (string, error) {
|
func (r *ExportService) DoctorWithdrawal(doctorWithdrawals []*model.DoctorWithdrawal) (string, error) {
|
||||||
header := []utils.HeaderCellData{
|
header := []utils.HeaderCellData{
|
||||||
@@ -2052,3 +2067,75 @@ func (r *ExportService) Product(d []*model.Product) (string, error) {
|
|||||||
ossPath = utils.AddOssDomain("/" + ossPath)
|
ossPath = utils.AddOssDomain("/" + ossPath)
|
||||||
return ossPath, nil
|
return ossPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PharmacyDoctor 药房关联医生
|
||||||
|
func (r *ExportService) PharmacyDoctor(d []*model.DoctorPharmacy) (string, error) {
|
||||||
|
header := []utils.HeaderCellData{
|
||||||
|
{Value: "药房名称", CellType: "string", NumberFmt: "", ColWidth: 25},
|
||||||
|
{Value: "药房代码", CellType: "string", NumberFmt: "", ColWidth: 18},
|
||||||
|
{Value: "医生姓名", CellType: "string", NumberFmt: "", ColWidth: 18},
|
||||||
|
{Value: "手机号", CellType: "string", NumberFmt: "", ColWidth: 18},
|
||||||
|
{Value: "医生职称", CellType: "string", NumberFmt: "", ColWidth: 18},
|
||||||
|
{Value: "医院名称", CellType: "string", NumberFmt: "", ColWidth: 30},
|
||||||
|
{Value: "科室名称", CellType: "string", NumberFmt: "", ColWidth: 20},
|
||||||
|
{Value: "科室电话", CellType: "string", NumberFmt: "", ColWidth: 18},
|
||||||
|
{Value: "是否默认药房", CellType: "string", NumberFmt: "", ColWidth: 18},
|
||||||
|
{Value: "状态", CellType: "string", NumberFmt: "", ColWidth: 15},
|
||||||
|
{Value: "关联时间", CellType: "date", NumberFmt: "yyyy-mm-dd hh:mm:ss", ColWidth: 30},
|
||||||
|
}
|
||||||
|
|
||||||
|
var dataSlice []interface{}
|
||||||
|
for _, v := range d {
|
||||||
|
data := PharmacyDoctorData{
|
||||||
|
IsDefault: utils.IsDefaultToString(v.IsDefault),
|
||||||
|
Status: "正常",
|
||||||
|
}
|
||||||
|
if v.Status == 0 {
|
||||||
|
data.Status = "禁用"
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Pharmacy != nil {
|
||||||
|
data.PharmacyName = v.Pharmacy.PharmacyName
|
||||||
|
data.PharmacyCode = v.Pharmacy.PharmacyCode
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.UserDoctor != nil {
|
||||||
|
data.DoctorName = v.UserDoctor.UserName
|
||||||
|
data.DoctorTitle = utils.DoctorTitleToString(v.UserDoctor.DoctorTitle)
|
||||||
|
data.DepartmentCustomName = v.UserDoctor.DepartmentCustomName
|
||||||
|
data.DepartmentCustomMobile = v.UserDoctor.DepartmentCustomMobile
|
||||||
|
if v.UserDoctor.Hospital != nil {
|
||||||
|
data.HospitalName = v.UserDoctor.Hospital.HospitalName
|
||||||
|
}
|
||||||
|
if v.UserDoctor.User != nil {
|
||||||
|
data.Mobile = v.UserDoctor.User.Mobile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.CreatedAt != (model.LocalTime{}) {
|
||||||
|
data.CreatedAt = time.Time(v.CreatedAt).Format("2006-01-02 15:04:05")
|
||||||
|
}
|
||||||
|
|
||||||
|
dataSlice = append(dataSlice, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := utils.Export(header, dataSlice)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置文件名字
|
||||||
|
now := time.Now()
|
||||||
|
dateTimeString := now.Format("20060102150405") // 当前时间字符串
|
||||||
|
rand.New(rand.NewSource(time.Now().UnixNano())) // 设置随机数
|
||||||
|
ossPath := "admin/export/药房关联医生" + dateTimeString + fmt.Sprintf("%d", rand.Intn(9000)+1000) + ".xlsx"
|
||||||
|
|
||||||
|
// 上传oss
|
||||||
|
_, err = aliyun.PutObjectByte(ossPath, file.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
ossPath = utils.AddOssDomain("/" + ossPath)
|
||||||
|
return ossPath, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -109,6 +109,18 @@ func (r *PharmacyService) PutPharmacy(pharmacyId int64, req requests.PutPharmacy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 若修改为禁用,校验是否有医生设为默认药房
|
||||||
|
if req.Status != nil && *req.Status == 0 && pharmacy.Status == 1 {
|
||||||
|
doctorPharmacyDao := dao.DoctorPharmacyDao{}
|
||||||
|
totalCount, defaultCount, err := doctorPharmacyDao.GetDoctorPharmacyCountsByPharmacyId(pharmacyId)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.New("查询药房关联医生失败")
|
||||||
|
}
|
||||||
|
if defaultCount > 0 {
|
||||||
|
return false, fmt.Errorf("该药房已被 %d 位医生设为默认药房(共 %d 位医生绑定),无法禁用。请先在【药房关联医生】中调整默认药房或解除绑定后再试", defaultCount, totalCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tx := global.Db.Begin()
|
tx := global.Db.Begin()
|
||||||
defer func() {
|
defer func() {
|
||||||
if rec := recover(); rec != nil {
|
if rec := recover(); rec != nil {
|
||||||
@@ -201,6 +213,18 @@ func (r *PharmacyService) PutPharmacyStatus(pharmacyId int64, req requests.PutPh
|
|||||||
return false, errors.New("药房不存在或已删除")
|
return false, errors.New("药房不存在或已删除")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 若修改为禁用,校验是否有医生设为默认药房
|
||||||
|
if req.Status != nil && *req.Status == 0 {
|
||||||
|
doctorPharmacyDao := dao.DoctorPharmacyDao{}
|
||||||
|
totalCount, defaultCount, err := doctorPharmacyDao.GetDoctorPharmacyCountsByPharmacyId(pharmacyId)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.New("查询药房关联医生失败")
|
||||||
|
}
|
||||||
|
if defaultCount > 0 {
|
||||||
|
return false, fmt.Errorf("该药房已被 %d 位医生设为默认药房(共 %d 位医生绑定),无法禁用。请先在【药房关联医生】中调整默认药房或解除绑定后再试", defaultCount, totalCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
"status": *req.Status,
|
"status": *req.Status,
|
||||||
}
|
}
|
||||||
@@ -230,6 +254,19 @@ func (r *PharmacyService) DeletePharmacy(pharmacyId int64) (bool, error) {
|
|||||||
return false, errors.New("药房不存在或已删除")
|
return false, errors.New("药房不存在或已删除")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 删除药房前校验:若有关联医生(特别是默认药房),拦截禁止删除
|
||||||
|
doctorPharmacyDao := dao.DoctorPharmacyDao{}
|
||||||
|
totalCount, defaultCount, err := doctorPharmacyDao.GetDoctorPharmacyCountsByPharmacyId(pharmacyId)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.New("查询药房关联医生失败")
|
||||||
|
}
|
||||||
|
if defaultCount > 0 {
|
||||||
|
return false, fmt.Errorf("该药房已被 %d 位医生设为默认药房(共 %d 位医生绑定),无法删除。请先在【药房关联医生】中调整默认药房或解除绑定后再试", defaultCount, totalCount)
|
||||||
|
}
|
||||||
|
if totalCount > 0 {
|
||||||
|
return false, fmt.Errorf("该药房仍有 %d 位医生绑定,无法删除。请先在【药房关联医生】中解除绑定后再试", totalCount)
|
||||||
|
}
|
||||||
|
|
||||||
tx := global.Db.Begin()
|
tx := global.Db.Begin()
|
||||||
defer func() {
|
defer func() {
|
||||||
if rec := recover(); rec != nil {
|
if rec := recover(); rec != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user