diff --git a/api/controller/export.go b/api/controller/export.go index 3a1b4a4..911e625 100644 --- a/api/controller/export.go +++ b/api/controller/export.go @@ -219,3 +219,37 @@ func (r *Export) OrderInquiryForAccount(c *gin.Context) { responses.OkWithData(ossAddress, c) } + +// UserPatient 患者列表 +func (r *Export) UserPatient(c *gin.Context) { + userPatientRequest := requests.UserPatientRequest{} + req := userPatientRequest.UserPatientExportList + 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 + } + + // 获取数据 + userPatientDao := dao.UserPatientDao{} + userPatients, err := userPatientDao.GetUserPatientExportListSearch(req) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 业务处理 + exportService := service.ExportService{} + ossAddress, err := exportService.UserPatient(userPatients) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + responses.OkWithData(ossAddress, c) +} diff --git a/api/dao/userPatient.go b/api/dao/userPatient.go index 26177ff..6753c9d 100644 --- a/api/dao/userPatient.go +++ b/api/dao/userPatient.go @@ -1,6 +1,7 @@ package dao import ( + "errors" "gorm.io/gorm" "gorm.io/gorm/clause" "hospital-admin-api/api/model" @@ -155,3 +156,82 @@ func (r *UserPatientDao) AddUserPatient(tx *gorm.DB, model *model.UserPatient) ( } return model, nil } + +// GetUserPatientExportListSearch 获取患者列表-导出 +func (r *UserPatientDao) GetUserPatientExportListSearch(req requests.UserPatientExportList) (m []*model.UserPatient, err error) { + // 构建查询条件 + query := global.Db.Model(&model.UserPatient{}).Omit("open_id", "union_id", "wx_session_key") + + // 用户表 + query = query.Preload("User", func(db *gorm.DB) *gorm.DB { + return db.Omit("user_password", "salt") + }) + + // 家庭成员表 + query = query.Preload("PatientFamily") + + // 当前搜索数据 + if req.Type == 1 { + // 手机号 + if req.Mobile != "" { + subQuery := global.Db.Model(&model.User{}). + Select("user_id"). + Where("mobile = ?", req.Mobile) + + query = query.Where(gorm.Expr("user_id IN (?)", subQuery)) + } + + // 用户名称-用户-就诊人 + if req.UserName != "" { + // 用户 + query = query.Where("user_name LIKE ?", "%"+req.UserName+"%") + + // 就诊人 + patientFamilySubQuery := global.Db.Model(&model.PatientFamily{}). + Select("patient_id"). + Where("card_name LIKE ?", "%"+req.UserName+"%") + + query = query.Or("patient_id IN (?)", patientFamilySubQuery).Or(query) + } + + // 用户状态 + if req.Status != nil { + query = query.Where("status = ?", req.Status) + } + + // 注册时间 + if req.CreatedAt != "" { + cancelTime := strings.Split(req.CreatedAt, "&") + if len(cancelTime) == 2 { + startTime, _ := time.Parse("2006-01-02", cancelTime[0]) + endTime, _ := time.Parse("2006-01-02", cancelTime[1]) + + if startTime == endTime { + endTime = endTime.Add(23*time.Hour + 59*time.Minute + 59*time.Second) + } + + query = query.Where("created_at BETWEEN ? AND ?", startTime, endTime) + } + } + } + + // 当前选中数据 + if req.Type == 2 { + if req.Id == "" { + return nil, errors.New("未提供需导出数据编号") + } + + id := strings.Split(req.Id, ",") + query = query.Where("patient_id IN (?)", id) + } + + // 排序 + query = query.Order("created_at desc") + + err = query.Find(&m).Error + if err != nil { + return nil, err + } + + return m, nil +} diff --git a/api/requests/userPatient.go b/api/requests/userPatient.go index 6fb4d3c..8db3717 100644 --- a/api/requests/userPatient.go +++ b/api/requests/userPatient.go @@ -1,8 +1,9 @@ package requests type UserPatientRequest struct { - GetUserPatientPage // 获取患者列表-分页 - PutUserDoctorStatus // 修改患者状态 + GetUserPatientPage // 获取患者列表-分页 + PutUserDoctorStatus // 修改患者状态 + UserPatientExportList // 患者列表-导出 } // GetUserPatientPage 获取患者列表-分页 @@ -20,3 +21,13 @@ type PutUserDoctorStatus struct { Status int `json:"status" form:"status" validate:"oneof=0 1 2" label:"状态"` // (0:禁用 1:正常 2:删除) DisableReason string `json:"disable_reason" form:"disable_reason" label:"禁用理由"` } + +// UserPatientExportList 患者列表-导出 +type UserPatientExportList 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,逗号分隔,当type为2时必填 + UserName string `json:"user_name" form:"user_name" label:"用户名称"` + Status *int `json:"status" form:"status" label:"状态"` // (0:禁用 1:正常 2:删除) + Mobile string `json:"mobile" form:"mobile" label:"手机号"` + CreatedAt string `json:"created_at" form:"created_at" label:"注册时间"` // 时间区间,数组形式,下标0为开始时间,下标1为结束时间 +} diff --git a/api/router/router.go b/api/router/router.go index 0995910..c064a5f 100644 --- a/api/router/router.go +++ b/api/router/router.go @@ -625,7 +625,7 @@ func privateRouter(r *gin.Engine, api controller.Api) { patientGroup := exportGroup.Group("/patient") { // 患者列表 - patientGroup.POST("", api.UserCaCert.RenewUserCloudCert) + patientGroup.POST("", api.Export.UserPatient) // 就诊人列表 patientGroup.POST("/family", api.UserCaCert.RenewUserCloudCert) diff --git a/api/service/export.go b/api/service/export.go index 6d78b12..fd75d11 100644 --- a/api/service/export.go +++ b/api/service/export.go @@ -172,6 +172,17 @@ type OrderInquiryForAccount struct { CreatedAt time.Time // 创建时间 } +// UserPatientData 患者列表 +type UserPatientData struct { + UserName string // 用户名称 + Status string // 状态(0:禁用 1:正常 2:删除) + Mobile string // 手机号 + Avatar string // 头像 + DisableReason string // 禁用理由 + PatientFamilyCount string // 家庭成员数量 + CreatedAt time.Time // 创建时间 +} + // DoctorWithdrawal 提现记录 func (r *ExportService) DoctorWithdrawal(doctorWithdrawals []*model.DoctorWithdrawal) (string, error) { header := []utils.HeaderCellData{ @@ -1026,3 +1037,60 @@ func (r *ExportService) OrderInquiryForAccount(d []*model.OrderInquiry) (string, ossPath = utils.AddOssDomain("/" + ossPath) return ossPath, nil } + +// UserPatient 患者列表 +func (r *ExportService) UserPatient(d []*model.UserPatient) (string, error) { + header := []utils.HeaderCellData{ + {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: 18}, + {Value: "创建时间", CellType: "date", NumberFmt: "yyyy-mm-dd hh:mm:ss", ColWidth: 30}, + } + + var dataSlice []interface{} + for _, v := range d { + data := UserPatientData{ + UserName: v.UserName, + Status: utils.UserPatientStatusToString(v.Status), + Avatar: utils.AddOssDomain(v.Avatar), + DisableReason: v.DisableReason, + } + + if v.User != nil { + data.Mobile = v.User.Mobile + } + + if v.CreatedAt != (model.LocalTime{}) { + t := time.Time(v.CreatedAt) + data.CreatedAt = t + } + + if len(v.PatientFamily) > 0 { + data.PatientFamilyCount = fmt.Sprintf("%d", len(v.PatientFamily)) + } + dataSlice = append(dataSlice, data) + } + + file, err := utils.Export(header, dataSlice) + if err != nil { + return "", err + } + + // 设置文件名字 + now := time.Now() + dateTimeString := now.Format("20060102150405") // 当前时间字符串 + rand.Seed(time.Now().UnixNano()) // 设置随机数 + ossPath := "admin/export/output" + 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 +} diff --git a/utils/intToString.go b/utils/intToString.go index 912c992..e9a84f7 100644 --- a/utils/intToString.go +++ b/utils/intToString.go @@ -1,6 +1,6 @@ package utils -// int抓字符串 +// int转字符串 // UserDoctorStatusToString 用户状态(0:禁用 1:正常 2:删除) func UserDoctorStatusToString(i int) string { @@ -16,6 +16,20 @@ func UserDoctorStatusToString(i int) string { } } +// UserPatientStatusToString 用户状态(0:禁用 1:正常 2:删除) +func UserPatientStatusToString(i int) string { + switch i { + case 0: + return "禁用" + case 1: + return "正常" + case 2: + return "删除" + default: + return "未知" + } +} + // IdcardStatusToString 实名认证状态(0:未认证 1:认证通过 2:认证失败) func IdcardStatusToString(i int) string { switch i {