package service import ( "XT_New/models" "fmt" "strings" ) func GetDialysisTotalDatas() { } func GetNewDialysiTotal(startime int64, endtime int64, orgid int64, origin int64) (int64, error) { counts := models.PatientPrescriptionCountStruct{} var err error if origin == 1 { //透析记录,上机为准 db := XTReadDB().Table("xt_dialysis_order as x") err = db.Select("count(x.id) as count").Where("x.dialysis_date >= ? and x.dialysis_date<=? and x.user_org_id = ? AND x.status = 1", startime, endtime, orgid).Scan(&counts).Error return counts.Count, err } else { db := XTReadDB().Table("xt_schedule as sch") //err = db.Select("COUNT(DISTINCT patient_id) AS total_employees").Where("x.dialysis_date >= ? and x.dialysis_date<=? and x.user_org_id = ? AND x.status = 1", startime, endtime, orgid).Scan(&counts).Error var count int64 err := db.Model(&Schedule{}). Select("patient_id, schedule_date"). Group("patient_id, schedule_date"). Where("schedule_date >= ? AND schedule_date <= ?", startime, endtime). Count(&count). Error return count, err } } type TreatmentMode struct { ModeID int `json:"mode_id"` ModeName string `json:"mode_name"` } type DialysisStat struct { Date string `json:"日期"` Counts map[string]int `json:"counts"` Total int `json:"合计"` } func getTreatmentModes() ([]TreatmentMode, error) { var modes []TreatmentMode if err := XTReadDB().Find(&modes).Error; err != nil { return nil, err } return modes, nil } func GetDialysisStats(startDate int64, endDate int64, groupBy int64, mode int64) ([]DialysisStat, error) { var stats []DialysisStat var modes []TreatmentMode if mode > 0 { modes, _ = getTreatmentModes() } else { modes_two, _ := getTreatmentModes() for _, item := range modes_two { if item.ModeID == int(mode) { modes = append(modes, item) } } } // 获取透析模式 if err != nil { return nil, err } // 构建日期格式 dateFormat := "%Y-%m-%d" switch groupBy { case 2: dateFormat = "%Y-%m-%d" case 1: dateFormat = "%Y-%u" case 3: dateFormat = "%Y-%m" case 4: dateFormat = "%Y" default: return nil, fmt.Errorf("invalid group by option") } // 构建动态查询语句 selectClauses := []string{fmt.Sprintf("DATE_FORMAT(p.record_date, '%s') AS `日期`", dateFormat)} for _, mode := range modes { selectClauses = append(selectClauses, fmt.Sprintf("SUM(CASE WHEN t.mode_name = '%s' THEN 1 ELSE 0 END) AS `%s`", mode.ModeName, mode.ModeName)) } selectClauses = append(selectClauses, "COUNT(*) AS `合计`") query := fmt.Sprintf(` SELECT %s FROM xt_dialysis_prescription p JOIN xt_treatment_mode t ON p.mode_id = t.mode_id WHERE p.record_date >= ? AND p.record_date <= ? GROUP BY DATE_FORMAT(p.record_date, '%s') `, dateFormat, dateFormat, selectClauses) rows, err := readDb.Raw(query, startDate, endDate).Rows() if err != nil { return nil, err } defer rows.Close() // 解析查询结果 for rows.Next() { var stat DialysisStat stat.Counts = make(map[string]int) cols := []interface{}{&stat.Date} for _, mode := range modes { var count int cols = append(cols, &count) stat.Counts[mode.ModeName] = count } var total int cols = append(cols, &total) stat.Total = total if err := rows.Scan(cols...); err != nil { return nil, err } stats = append(stats, stat) } return stats, nil } func GetScheduleStats(startDate int64, endDate int64, groupBy int64, mode int64) ([]DialysisStat, error) { var stats []DialysisStat var modes []TreatmentMode if mode > 0 { modes, _ = getTreatmentModes() } else { modes_two, _ := getTreatmentModes() for _, item := range modes_two { if item.ModeID == int(mode) { modes = append(modes, item) } } } // 获取透析模式 if err != nil { return nil, err } // 构建日期格式 dateFormat := "%Y-%m-%d" switch groupBy { case 2: dateFormat = "%Y-%m-%d" case 1: dateFormat = "%Y-%u" case 3: dateFormat = "%Y-%m" case 4: dateFormat = "%Y" default: return nil, fmt.Errorf("invalid group by option") } // 构建动态查询语句 selectClauses := []string{fmt.Sprintf("DATE_FORMAT(p.schudle_date, '%s') AS `日期`", dateFormat)} for _, mode := range modes { selectClauses = append(selectClauses, fmt.Sprintf("SUM(CASE WHEN t.mode_name = '%s' THEN 1 ELSE 0 END) AS `%s`", mode.ModeName, mode.ModeName)) } selectClauses = append(selectClauses, "COUNT(*) AS `合计`") query := fmt.Sprintf(` SELECT %s FROM xt_schedule p JOIN xt_treatment_mode t ON p.mode_id = t.mode_id WHERE p.schedule_date >= ? AND p.schedule_date <= ? GROUP BY DATE_FORMAT(p.schedule_date, '%s') `, dateFormat, dateFormat, selectClauses) rows, err := readDb.Raw(query, startDate, endDate).Rows() if err != nil { return nil, err } defer rows.Close() // 解析查询结果 for rows.Next() { var stat DialysisStat stat.Counts = make(map[string]int) cols := []interface{}{&stat.Date} for _, mode := range modes { var count int cols = append(cols, &count) stat.Counts[mode.ModeName] = count } var total int cols = append(cols, &total) stat.Total = total if err := rows.Scan(cols...); err != nil { return nil, err } stats = append(stats, stat) } return stats, nil } func GetNewDialysisCountMode(starttime int64, endtime int64, orgid int64, origin int64, mode_id int64) (counts []*models.PatientPrescriptionCountStruct, err error) { if origin == 1 { db := readDb.Table("xt_dialysis_order as o").Where("o.status = 1") if starttime > 0 { db = db.Where("o.dialysis_date >=?", starttime) } if endtime > 0 { db = db.Where("o.dialysis_date<=?", endtime) } if orgid > 0 { db = db.Where("o.user_org_id = ?", orgid) } if mode_id == 0 { err = db.Select("s.mode_id,count(s.mode_id) as count").Joins("join xt_dialysis_prescription as s on s.patient_id = o.patient_id and s.record_date = o.dialysis_date and s.status= 1 AND s.record_date >= ? AND s.record_date <= ? AND s.mode_id > 0 ", starttime, endtime).Group("s.mode_id").Scan(&counts).Error } else { err = db.Select("s.mode_id,count(s.mode_id) as count").Joins("join xt_dialysis_prescription as s on s.patient_id = o.patient_id and s.record_date = o.dialysis_date and s.status= 1 AND s.record_date >= ? AND s.record_date <= ? AND s.mode_id = ? ", starttime, endtime, mode_id).Group("s.mode_id").Scan(&counts).Error } return counts, err } else { db := readDb.Table("xt_schedule as o").Where("o.status = 1").Select("patient_id, schedule_date").Group("patient_id, schedule_date,mode_id") if starttime > 0 { db = db.Where("o.schedule_date >= ?", starttime) } if endtime > 0 { db = db.Where("o.schedule_date <= ?", endtime) } if orgid > 0 { db = db.Where("o.user_org_id = ?", orgid) } err = db.Select("o.mode_id,count(o.mode_id) as count").Scan(&counts).Error return counts, err } } func GetNewDialysisCountModeTwo(starttime int64, endtime int64, orgid int64, origin int64, mode_id int64) (counts models.CustomDialysisData, err error) { if origin == 1 { db := readDb.Table("xt_dialysis_order as o").Where("o.status = 1") if starttime > 0 { db = db.Where("o.dialysis_date >=?", starttime) } if endtime > 0 { db = db.Where("o.dialysis_date<=?", endtime) } if orgid > 0 { db = db.Where("o.user_org_id = ?", orgid) } err = db.Select("s.mode_id,count(s.mode_id) as count").Joins("join xt_dialysis_prescription as s on s.patient_id = o.patient_id and s.record_date = o.dialysis_date and s.status= 1 AND s.record_date >= ? AND s.record_date <= ? AND s.mode_id = ? ", starttime, endtime, mode_id).Group("s.mode_id").Scan(&counts).Error return counts, err } else { db := readDb.Table("xt_schedule as o").Where("o.status = 1").Select("patient_id, schedule_date").Group("patient_id, schedule_date,mode_id") if starttime > 0 { db = db.Where("o.schedule_date >= ?", starttime) } if endtime > 0 { db = db.Where("o.schedule_date <= ?", endtime) } if orgid > 0 { db = db.Where("o.user_org_id = ?", orgid) } if mode_id > 0 { db = db.Where("o.mode_id = ?", mode_id) } err = db.Select("o.mode_id,count(o.mode_id) as count").Scan(&counts).Error return counts, err } } var anticoagulantMap = map[int]string{ 1: "无肝素", 2: "普通肝素", 3: "低分子肝素", 4: "阿加曲班", 5: "枸橼酸钠", 6: "低分子肝素钙", 7: "低分子肝素钠", 8: "依诺肝素", 9: "达肝素", 10: "体外抗凝", 11: "那屈肝素", 12: "无抗凝剂", 13: "那屈肝素钙", 14: "肝素钙注射液", 15: "甲磺酸萘莫司他", 16: "低分子量肝素钙", 17: "肝素钠", } func GetAnticoagulantData(start_time int64, end_time int64, org_id int64) (map[string]int, error) { var results []struct { Anticoagulant int Count int } err := XTReadDB().Model(&models.DialysisPrescription{}). Select("anticoagulant, COUNT(*) as count"). Where("status = 1 and record_date >= ? and record_date <= ? and user_org_id = ?", start_time, end_time, org_id). Group("anticoagulant"). Scan(&results).Error if err != nil { return nil, err } anticoagulantData := make(map[string]int) for _, result := range results { if name, ok := anticoagulantMap[result.Anticoagulant]; ok { anticoagulantData[name] = result.Count } else { anticoagulantData[fmt.Sprintf("Unknown (%d)", result.Anticoagulant)] = result.Count } } return anticoagulantData, nil } func GetAnticoagulantTotal(start_time int64, end_time int64, org_id int64) (total int64, err error) { err = XTReadDB().Model(&models.DialysisPrescription{}). Where("record_date >= ? and record_date <= ? and user_org_id = ? and status = 1", start_time, end_time, org_id). Count(&total).Error return } func GetDialyzerSummary(org_id int64) ([]string, error) { var Dialyzer []string err := XTReadDB().Model(&models.DialysisPrescription{}). Select("dialysis_dialyszers"). Where(" user_org_id = ? and status = 1", org_id). Group("dialysis_dialyszers"). Scan(&Dialyzer).Error if err != nil { return nil, err } return Dialyzer, nil } type DialyzerResult struct { Dialyzer string Count int } func GetDialyzerData(start_time int64, end_time int64, org_id int64) (dr []DialyzerResult, err error) { err = XTReadDB().Model(&models.DialysisPrescription{}). Select("dialysis_dialyszers as dialyzer, COUNT(*) as count"). Where("record_date >= ? and record_date <= ? and user_org_id = ? and status = 1", start_time, end_time, org_id). Group("dialysis_dialyszers"). Scan(&dr).Error return } func GetDialyzerTotal(start_time int64, end_time int64, org_id int64) (total int64, err error) { err = XTReadDB().Model(&models.DialysisPrescription{}). Where("status = 1 and record_date >= ? and record_date <= ? and user_org_id = ? and dialysis_dialyszers <> ''", start_time, end_time, org_id). Count(&total).Error return } func GetPrescriptionByAnticoagulant(page int64, limit int64, orgid int64, anticoagulant int64, start_time int64, end_time int64) (solution []*models.DialysisPrescription, total int64, err error) { db := XTReadDB().Model(&models.DialysisPrescription{}).Where("status = 1") if anticoagulant > 0 { db = db.Where("anticoagulant = ?", anticoagulant) } if orgid > 0 { db = db.Where("user_org_id = ?", orgid) } db = db.Where("record_date >= ? and record_date <= ?", start_time, end_time) offset := (page - 1) * limit err = db.Count(&total).Offset(offset).Limit(limit).Find(&solution).Error return solution, total, err } func GetPrescriptionByDialyzer(page int64, limit int64, orgid int64, dialyzer string, start_time int64, end_time int64) (solution []*models.DialysisPrescription, total int64, err error) { db := XTReadDB().Model(&models.DialysisPrescription{}).Where("status = 1") if len(dialyzer) > 0 { db = db.Where("dialysis_dialyszers = ?", dialyzer) } if orgid > 0 { db = db.Where("user_org_id = ?", orgid) } db = db.Where("record_date >= ? and record_date <= ?", start_time, end_time) offset := (page - 1) * limit err = db.Count(&total).Offset(offset).Limit(limit).Find(&solution).Error return solution, total, err } type DialysisData struct { DialysisStatus string `json:"dialysis_status"` Count int `json:"count"` } type CustomData struct { DialysisNo string PatientName string DialysisDate string DialysisDuration string ActualDuration string Diff string Doctor string Nurse string } func GetDialysisCompletionRate(org_id int64, start_time int64, end_time int64) (map[string]int, error) { var results []DialysisData query := ` SELECT CASE WHEN ABS(TIMESTAMPDIFF(MINUTE, MAKETIME(p.dialysis_duration_hour, p.dialysis_duration_minute, 0), MAKETIME(a.actual_treatment_hour, a.actual_treatment_minute, 0))) <= 15 THEN '达标' WHEN TIMESTAMPDIFF(MINUTE, MAKETIME(p.dialysis_duration_hour, p.dialysis_duration_minute, 0), MAKETIME(a.actual_treatment_hour, a.actual_treatment_minute, 0)) < 0 THEN '未达标' ELSE '超时' END AS dialysis_status, COUNT(*) AS count FROM xt_dialysis_order o JOIN xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ? JOIN xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ? WHERE o.stage = 2 AND o.user_org_id = ? AND o.dialysis_date >= ? AND o.dialysis_date <= ? GROUP BY dialysis_status; ` if err := readDb.Raw(query, org_id, org_id, org_id, start_time, end_time).Scan(&results).Error; err != nil { return nil, err } dialysisCompletionRate := make(map[string]int) for _, result := range results { dialysisCompletionRate[result.DialysisStatus] = result.Count } return dialysisCompletionRate, nil } func GetDialysisCompletionTotal(org_id int64, start_time int64, end_time int64) (int64, error) { var Count int64 query := ` SELECT COUNT(*) AS count FROM xt_dialysis_order o JOIN xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ? JOIN xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ? WHERE o.stage = 2 AND o.user_org_id = ? AND o.dialysis_date >= ? AND o.dialysis_date <= ? GROUP BY dialysis_status; ` if err := readDb.Raw(query, org_id, org_id, org_id, start_time, end_time).Scan(&Count).Error; err != nil { return 0, err } return Count, nil } func GetDialysisCompletionDetail(org_id int64, start_time int64, end_time int64, mode int64, limit int64, page int64) (date []*CustomData, total int64, err error) { var query string if mode == 0 { query = ` SELECT p.dialysis_no as dialysis_no, p.name as patient_name, FROM_UNIXTIME(o.dialysis_date) as dialysis_date, CONCAT(p.dialysis_duration_hour, 'h', p.dialysis_duration_minute,'min') as dialysis_duration, CONCAT(a.actual_treatment_hour, 'h', a.actual_treatment_minute,'min') as actual_duration, ABS(TIMESTAMPDIFF(MINUTE, MAKETIME(p.dialysis_duration_hour, p.dialysis_duration_minute, 0), MAKETIME(a.actual_treatment_hour, a.actual_treatment_minute, 0))) as diff, p.prescription_doctor as doctor, p.finish_nurse as nurse FROM xt_dialysis_order o JOIN xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ? JOIN xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ? JOIN xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ? WHERE o.stage = 2 AND o.user_org_id = ? AND o.dialysis_date >= ? AND o.dialysis_date <= ? ` } else if mode == 1 { query = ` SELECT p.dialysis_no as dialysis_no, p.name as patient_name, FROM_UNIXTIME(o.dialysis_date) as dialysis_date, CONCAT(p.dialysis_duration_hour, 'h', p.dialysis_duration_minute,'min') as dialysis_duration, CONCAT(a.actual_treatment_hour, 'h', a.actual_treatment_minute,'min') as actual_duration, ABS(TIMESTAMPDIFF(MINUTE, MAKETIME(p.dialysis_duration_hour, p.dialysis_duration_minute, 0), MAKETIME(a.actual_treatment_hour, a.actual_treatment_minute, 0))) as diff, p.prescription_doctor as doctor, p.finish_nurse as nurse FROM xt_dialysis_order o JOIN xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ? JOIN xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ? JOIN xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ? WHERE o.stage = 2 AND o.user_org_id = ? AND o.dialysis_date >= ? AND o.dialysis_date <= ? AND ABS(TIMESTAMPDIFF(MINUTE, MAKETIME(p.dialysis_duration_hour, p.dialysis_duration_minute, 0), MAKETIME(a.actual_treatment_hour, a.actual_treatment_minute, 0))) <= 15 ` } else if mode == 2 { query = ` SELECT p.dialysis_no as dialysis_no, p.name as patient_name, FROM_UNIXTIME(o.dialysis_date) as dialysis_date, CONCAT(p.dialysis_duration_hour, 'h', p.dialysis_duration_minute,'min') as dialysis_duration, CONCAT(a.actual_treatment_hour, 'h', a.actual_treatment_minute,'min') as actual_duration, ABS(TIMESTAMPDIFF(MINUTE, MAKETIME(p.dialysis_duration_hour, p.dialysis_duration_minute, 0), MAKETIME(a.actual_treatment_hour, a.actual_treatment_minute, 0))) as diff, p.prescription_doctor as doctor, p.finish_nurse as nurse FROM xt_dialysis_order o JOIN xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ? JOIN xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ? JOIN xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ? WHERE o.stage = 2 AND o.user_org_id = ? AND o.dialysis_date >= ? AND o.dialysis_date <= ? AND TIMESTAMPDIFF(MINUTE, MAKETIME(p.dialysis_duration_hour, p.dialysis_duration_minute, 0), MAKETIME(a.actual_treatment_hour, a.actual_treatment_minute, 0)) < 0 ` } else if mode == 3 { query = ` SELECT p.dialysis_no as dialysis_no, p.name as patient_name, FROM_UNIXTIME(o.dialysis_date) as dialysis_date, CONCAT(p.dialysis_duration_hour, 'h', p.dialysis_duration_minute,'min') as dialysis_duration, CONCAT(a.actual_treatment_hour, 'h', a.actual_treatment_minute,'min') as actual_duration, ABS(TIMESTAMPDIFF(MINUTE, MAKETIME(p.dialysis_duration_hour, p.dialysis_duration_minute, 0), MAKETIME(a.actual_treatment_hour, a.actual_treatment_minute, 0))) as diff, p.prescription_doctor as doctor, p.finish_nurse as nurse FROM xt_dialysis_order o JOIN xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ? JOIN xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ? JOIN xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ? WHERE o.stage = 2 AND o.user_org_id = ? AND o.dialysis_date >= ? AND o.dialysis_date <= ? AND TIMESTAMPDIFF(MINUTE, MAKETIME(p.dialysis_duration_hour, p.dialysis_duration_minute, 0), MAKETIME(a.actual_treatment_hour, a.actual_treatment_minute, 0)) > 15 ` } offset := (page - 1) * limit if err := readDb.Raw(query, org_id, org_id, org_id, org_id, start_time, end_time).Count(&total).Offset(offset).Limit(limit).Scan(&date).Error; err != nil { return nil, 0, err } return } type QualityControlStandard struct { ItemName string `json:"item_name"` ProjectMame string `json:"project_name"` InspectionMajor int64 `json:"inspection_major"` InspectionMinor int64 `json:"inspection_minor"` } func getQualityControlStandards(org_id int64) ([]QualityControlStandard, error) { var standards []QualityControlStandard if err := readDb.Model(&models.XtQualityControlStandard{}).Select("re.project_name as project_name,re.item_name as item_name,xt_quality_control_standard.inspection_major as inspection_major,xt_quality_control_standard.inspection_minor as inspection_minor").Joins("join xt_inspection_reference re on re.project_id = xt_quality_control_standard.inspection_major and re.item_id = xt_quality_control_standard.inspection_minor and re.org_id = ?", org_id).Where("xt_quality_control_standard.user_org_id = ? and xt_quality_control_standard.status = 1", org_id).Scan(&standards).Error; err != nil { return nil, err } return standards, nil } type DialysisQualityStat struct { Month string `json:"月"` Name string `json:"姓名"` Counts map[string]float64 `json:"counts"` } func GetLatestInspectionValues(org_id int64, yearMonth string) ([]map[string]interface{}, error) { standards, err := getQualityControlStandards(org_id) if err != nil { return nil, err } var selectFields []string for _, standard := range standards { field := fmt.Sprintf("MAX(CASE WHEN i.item_name = %s THEN i.inspect_value END) AS `%s`", "'"+standard.ItemName+"'", standard.ItemName) selectFields = append(selectFields, field) } query := fmt.Sprintf(` SELECT p.name as '姓名', %s FROM xt_inspection i JOIN xt_patients p On p.id = i.patient_id WHERE DATE_FORMAT(FROM_UNIXTIME(i.inspect_date), '%%Y-%%m') = ? and org_id = ? GROUP BY i.patient_id `, strings.Join(selectFields, ", ")) var results []map[string]interface{} rows, err := readDb.Raw(query, yearMonth, org_id).Rows() if err != nil { return nil, err } defer rows.Close() columns, err := rows.Columns() if err != nil { return nil, err } for rows.Next() { // 创建一个长度为列数的切片,用于存储每一行的值 columnValues := make([]interface{}, len(columns)) columnPointers := make([]interface{}, len(columns)) for i := range columnValues { columnPointers[i] = &columnValues[i] } // 扫描当前行的值 if err := rows.Scan(columnPointers...); err != nil { return nil, err } // 将扫描到的值放入结果 map 中 result := make(map[string]interface{}) for i, colName := range columns { val := columnPointers[i].(*interface{}) result[colName] = *val } results = append(results, result) } return results, nil }