statistis_qc_service.go 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. package service
  2. import (
  3. "XT_New/models"
  4. "fmt"
  5. "reflect"
  6. "strings"
  7. "time"
  8. )
  9. func GetDialysisTotalDatas() {
  10. }
  11. func GetNewDialysiTotal(startime int64, endtime int64, orgid int64, origin int64) (int64, error) {
  12. counts := models.PatientPrescriptionCountStruct{}
  13. var err error
  14. if origin == 1 { //透析记录,上机为准
  15. db := XTReadDB().Table("xt_dialysis_order as x").Joins("join xt_dialysis_prescription p on p.patient_id = x.patient_id and p.record_date = x.dialysis_date")
  16. 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
  17. return counts.Count, err
  18. } else {
  19. var count int64
  20. var schs []models.Schedule
  21. db := XTReadDB().Model(&models.Schedule{})
  22. err := db.
  23. Group("patient_id, schedule_date").
  24. Where("schedule_date >= ? AND schedule_date <= ? and user_org_id = ? and status = 1", startime, endtime, orgid).
  25. Find(&schs).
  26. Error
  27. count = int64(len(schs))
  28. return count, err
  29. }
  30. }
  31. type TreatmentMode struct {
  32. ModeID int `json:"mode_id"`
  33. ModeName string `json:"mode_name"`
  34. }
  35. type DialysisStat struct {
  36. Date string `json:"日期"`
  37. Counts map[string]int `json:"counts"`
  38. Total int `json:"合计"`
  39. }
  40. func getTreatmentModes() ([]TreatmentMode, error) {
  41. var modes []TreatmentMode
  42. if err := XTReadDB().Find(&modes).Error; err != nil {
  43. return nil, err
  44. }
  45. return modes, nil
  46. }
  47. func GetDialysisStats(startDate int64, endDate int64, groupBy int64, mode int64) ([]DialysisStat, error) {
  48. var stats []DialysisStat
  49. var modes []TreatmentMode
  50. if mode > 0 {
  51. modes, _ = getTreatmentModes()
  52. } else {
  53. modes_two, _ := getTreatmentModes()
  54. for _, item := range modes_two {
  55. if item.ModeID == int(mode) {
  56. modes = append(modes, item)
  57. }
  58. }
  59. }
  60. // 获取透析模式
  61. if err != nil {
  62. return nil, err
  63. }
  64. // 构建日期格式
  65. dateFormat := "%Y-%m-%d"
  66. switch groupBy {
  67. case 2:
  68. dateFormat = "%Y-%m-%d"
  69. case 1:
  70. dateFormat = "%Y-%u"
  71. case 3:
  72. dateFormat = "%Y-%m"
  73. case 4:
  74. dateFormat = "%Y"
  75. default:
  76. return nil, fmt.Errorf("invalid group by option")
  77. }
  78. // 构建动态查询语句
  79. selectClauses := []string{fmt.Sprintf("DATE_FORMAT(p.record_date, '%s') AS `日期`", dateFormat)}
  80. for _, mode := range modes {
  81. selectClauses = append(selectClauses, fmt.Sprintf("SUM(CASE WHEN t.mode_name = '%s' THEN 1 ELSE 0 END) AS `%s`", mode.ModeName, mode.ModeName))
  82. }
  83. selectClauses = append(selectClauses, "COUNT(*) AS `合计`")
  84. query := fmt.Sprintf(`
  85. SELECT
  86. %s
  87. FROM
  88. xt_dialysis_prescription p
  89. JOIN
  90. xt_treatment_mode t ON p.mode_id = t.mode_id
  91. WHERE
  92. p.record_date >= ? AND p.record_date <= ?
  93. GROUP BY
  94. DATE_FORMAT(p.record_date, '%s')
  95. `, dateFormat, dateFormat, selectClauses)
  96. rows, err := readDb.Raw(query, startDate, endDate).Rows()
  97. if err != nil {
  98. return nil, err
  99. }
  100. defer rows.Close()
  101. // 解析查询结果
  102. for rows.Next() {
  103. var stat DialysisStat
  104. stat.Counts = make(map[string]int)
  105. cols := []interface{}{&stat.Date}
  106. for _, mode := range modes {
  107. var count int
  108. cols = append(cols, &count)
  109. stat.Counts[mode.ModeName] = count
  110. }
  111. var total int
  112. cols = append(cols, &total)
  113. stat.Total = total
  114. if err := rows.Scan(cols...); err != nil {
  115. return nil, err
  116. }
  117. stats = append(stats, stat)
  118. }
  119. return stats, nil
  120. }
  121. func GetScheduleStats(startDate int64, endDate int64, groupBy int64, mode int64) ([]DialysisStat, error) {
  122. var stats []DialysisStat
  123. var modes []TreatmentMode
  124. if mode > 0 {
  125. modes, _ = getTreatmentModes()
  126. } else {
  127. modes_two, _ := getTreatmentModes()
  128. for _, item := range modes_two {
  129. if item.ModeID == int(mode) {
  130. modes = append(modes, item)
  131. }
  132. }
  133. }
  134. // 获取透析模式
  135. if err != nil {
  136. return nil, err
  137. }
  138. // 构建日期格式
  139. dateFormat := "%Y-%m-%d"
  140. switch groupBy {
  141. case 2:
  142. dateFormat = "%Y-%m-%d"
  143. case 1:
  144. dateFormat = "%Y-%u"
  145. case 3:
  146. dateFormat = "%Y-%m"
  147. case 4:
  148. dateFormat = "%Y"
  149. default:
  150. return nil, fmt.Errorf("invalid group by option")
  151. }
  152. // 构建动态查询语句
  153. selectClauses := []string{fmt.Sprintf("DATE_FORMAT(p.schudle_date, '%s') AS `日期`", dateFormat)}
  154. for _, mode := range modes {
  155. selectClauses = append(selectClauses, fmt.Sprintf("SUM(CASE WHEN t.mode_name = '%s' THEN 1 ELSE 0 END) AS `%s`", mode.ModeName, mode.ModeName))
  156. }
  157. selectClauses = append(selectClauses, "COUNT(*) AS `合计`")
  158. query := fmt.Sprintf(`
  159. SELECT
  160. %s
  161. FROM
  162. xt_schedule p
  163. JOIN
  164. xt_treatment_mode t ON p.mode_id = t.mode_id
  165. WHERE
  166. p.schedule_date >= ? AND p.schedule_date <= ?
  167. GROUP BY
  168. DATE_FORMAT(p.schedule_date, '%s')
  169. `, dateFormat, dateFormat, selectClauses)
  170. rows, err := readDb.Raw(query, startDate, endDate).Rows()
  171. if err != nil {
  172. return nil, err
  173. }
  174. defer rows.Close()
  175. // 解析查询结果
  176. for rows.Next() {
  177. var stat DialysisStat
  178. stat.Counts = make(map[string]int)
  179. cols := []interface{}{&stat.Date}
  180. for _, mode := range modes {
  181. var count int
  182. cols = append(cols, &count)
  183. stat.Counts[mode.ModeName] = count
  184. }
  185. var total int
  186. cols = append(cols, &total)
  187. stat.Total = total
  188. if err := rows.Scan(cols...); err != nil {
  189. return nil, err
  190. }
  191. stats = append(stats, stat)
  192. }
  193. return stats, nil
  194. }
  195. func GetNewDialysisCountMode(starttime int64, endtime int64, orgid int64, origin int64, mode_id int64) (counts []*models.PatientPrescriptionCountStruct, err error) {
  196. if origin == 1 {
  197. db := readDb.Table("xt_dialysis_order as o").Where("o.status = 1")
  198. if starttime > 0 {
  199. db = db.Where("o.dialysis_date >=?", starttime)
  200. }
  201. if endtime > 0 {
  202. db = db.Where("o.dialysis_date<=?", endtime)
  203. }
  204. if orgid > 0 {
  205. db = db.Where("o.user_org_id = ?", orgid)
  206. }
  207. if mode_id == 0 {
  208. 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
  209. } else {
  210. 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
  211. }
  212. return counts, err
  213. } else {
  214. err = readDb.Raw("select mode_id, count(aa.`mode_id`) as count from xt_schedule aa join (SELECT DISTINCT o.patient_id, o.`schedule_date` FROM xt_schedule AS o WHERE o.status = 1 AND o.schedule_date >= ? AND o.schedule_date <= ? AND o.user_org_id = ?) as b on aa.`patient_id` = b.`patient_id` and aa.`schedule_date` = b.`schedule_date` where aa.`status` = 1 and aa.schedule_date >= ? AND aa.schedule_date <= ? AND aa.user_org_id = ? Group by aa.`mode_id`", starttime, endtime, orgid, starttime, endtime, orgid).Find(&counts).Error
  215. return counts, err
  216. }
  217. }
  218. func GetNewDialysisCountModeTwo(starttime int64, endtime int64, orgid int64, origin int64, mode_id int64) (counts models.CustomDialysisData, err error) {
  219. // 将时间戳转换为time.Time类型
  220. t := time.Unix(starttime, 0)
  221. // 使用布局定义格式化时间
  222. layout := "2006-01-02"
  223. // 将时间格式化为字符串
  224. startDate := t.Format(layout) + " 00:00:00"
  225. t2 := time.Unix(endtime, 0)
  226. // 使用布局定义格式化时间
  227. //layout := "2006-01-02"
  228. // 将时间格式化为字符串
  229. endDate := t2.Format(layout) + " 00:00:00"
  230. //fmt.Println(formattedDate)
  231. // 将日期字符串解析为time.Time类型
  232. //start, _ := time.Parse("2006-01-02 15:04:05", formattedDate)
  233. //starttime = start.Unix()
  234. //fmt.Println(starttime)
  235. if origin == 1 {
  236. db := readDb.Table("xt_dialysis_order as o").Where("o.status = 1")
  237. if starttime > 0 {
  238. db = db.Where("DATE_FORMAT(FROM_UNIXTIME(o.dialysis_date), '%Y-%m-%d %H:%i:%s') >= ?", startDate)
  239. }
  240. if endtime > 0 {
  241. db = db.Where("DATE_FORMAT(FROM_UNIXTIME(o.dialysis_date), '%Y-%m-%d %H:%i:%s') <= ?", endDate)
  242. }
  243. if orgid > 0 {
  244. db = db.Where("o.user_org_id = ?", orgid)
  245. }
  246. 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 DATE_FORMAT(FROM_UNIXTIME(s.record_date), '%Y-%m-%d %H:%i:%s') >= ? AND DATE_FORMAT(FROM_UNIXTIME(s.record_date), '%Y-%m-%d %H:%i:%s') <= ? AND s.mode_id = ? ", startDate, endDate, mode_id).Group("s.mode_id").Scan(&counts).Error
  247. return counts, err
  248. } else {
  249. db := readDb.Table("xt_schedule as o").Where("o.status = 1").Select("patient_id, schedule_date").Group("mode_id")
  250. if starttime > 0 {
  251. db = db.Where("DATE_FORMAT(FROM_UNIXTIME(o.schedule_date),'%Y-%m-%d %H:%i:%s') >= ?", startDate)
  252. }
  253. if endtime > 0 {
  254. db = db.Where("DATE_FORMAT(FROM_UNIXTIME(o.schedule_date),'%Y-%m-%d %H:%i:%s') <= ?", endDate)
  255. }
  256. if orgid > 0 {
  257. db = db.Where("o.user_org_id = ?", orgid)
  258. }
  259. if mode_id > 0 {
  260. db = db.Where("o.mode_id = ?", mode_id)
  261. }
  262. err = db.Select("o.mode_id,count(o.mode_id) as count").Scan(&counts).Error
  263. return counts, err
  264. }
  265. }
  266. var anticoagulantMap = map[int]string{
  267. 1: "无肝素",
  268. 2: "普通肝素",
  269. 3: "低分子肝素",
  270. 4: "阿加曲班",
  271. 5: "枸橼酸钠",
  272. 6: "低分子肝素钙",
  273. 7: "低分子肝素钠",
  274. 8: "依诺肝素",
  275. 9: "达肝素",
  276. 10: "体外抗凝",
  277. 11: "那屈肝素",
  278. 12: "无抗凝剂",
  279. 13: "那屈肝素钙",
  280. 14: "肝素钙注射液",
  281. 15: "甲磺酸萘莫司他",
  282. 16: "低分子量肝素钙",
  283. 17: "肝素钠",
  284. }
  285. func GetAnticoagulantData(start_time int64, end_time int64, org_id int64) (map[string]int, error) {
  286. var results []struct {
  287. Anticoagulant int
  288. Count int
  289. }
  290. err := XTReadDB().Model(&models.DialysisPrescription{}).
  291. Select("anticoagulant, COUNT(*) as count").
  292. Where("status = 1 and record_date >= ? and record_date <= ? and user_org_id = ?", start_time, end_time, org_id).
  293. Group("anticoagulant").
  294. Scan(&results).Error
  295. if err != nil {
  296. return nil, err
  297. }
  298. anticoagulantData := make(map[string]int)
  299. for _, result := range results {
  300. if name, ok := anticoagulantMap[result.Anticoagulant]; ok {
  301. anticoagulantData[name] = result.Count
  302. } else {
  303. anticoagulantData[fmt.Sprintf("Unknown (%d)", result.Anticoagulant)] = result.Count
  304. }
  305. }
  306. return anticoagulantData, nil
  307. }
  308. func GetAnticoagulantTotal(start_time int64, end_time int64, org_id int64) (total int64, err error) {
  309. err = XTReadDB().Model(&models.DialysisPrescription{}).
  310. Where("record_date >= ? and record_date <= ? and user_org_id = ? and status = 1", start_time, end_time, org_id).
  311. Count(&total).Error
  312. return
  313. }
  314. func GetDialyzerSummary(org_id int64) ([]string, error) {
  315. var Dialyzer []string
  316. err := XTReadDB().Model(&models.DialysisPrescription{}).
  317. Select("dialysis_dialyszers").
  318. Where(" user_org_id = ? and status = 1", org_id).
  319. Group("dialysis_dialyszers").
  320. Scan(&Dialyzer).Error
  321. if err != nil {
  322. return nil, err
  323. }
  324. return Dialyzer, nil
  325. }
  326. type DialyzerResult struct {
  327. Dialyzer string
  328. Count int
  329. }
  330. func GetDialyzerData(start_time int64, end_time int64, org_id int64) (dr []DialyzerResult, err error) {
  331. err = XTReadDB().Model(&models.DialysisPrescription{}).
  332. Select("dialysis_dialyszers as dialyzer, COUNT(*) as count").
  333. Where("record_date >= ? and record_date <= ? and user_org_id = ? and status = 1", start_time, end_time, org_id).
  334. Group("dialysis_dialyszers").
  335. Scan(&dr).Error
  336. return
  337. }
  338. func GetDialyzerTotal(start_time int64, end_time int64, org_id int64) (total int64, err error) {
  339. err = XTReadDB().Model(&models.DialysisPrescription{}).
  340. Where("status = 1 and record_date >= ? and record_date <= ? and user_org_id = ? and dialysis_dialyszers <> ''", start_time, end_time, org_id).
  341. Count(&total).Error
  342. return
  343. }
  344. func GetPrescriptionByAnticoagulant(page int64, limit int64, orgid int64, anticoagulant int64, start_time int64, end_time int64) (solution []*models.DialysisPrescription, total int64, err error) {
  345. db := XTReadDB().Model(&models.DialysisPrescription{}).Where("status = 1")
  346. if anticoagulant > 0 {
  347. db = db.Where("anticoagulant = ?", anticoagulant)
  348. }
  349. if orgid > 0 {
  350. db = db.Where("user_org_id = ?", orgid)
  351. }
  352. db = db.Where("record_date >= ? and record_date <= ?", start_time, end_time)
  353. offset := (page - 1) * limit
  354. err = db.Count(&total).Offset(offset).Limit(limit).Find(&solution).Error
  355. return solution, total, err
  356. }
  357. func GetPrescriptionByDialyzer(page int64, limit int64, orgid int64, dialyzer string, start_time int64, end_time int64) (solution []*models.DialysisPrescription, total int64, err error) {
  358. db := XTReadDB().Model(&models.DialysisPrescription{}).Where("status = 1")
  359. if len(dialyzer) > 0 {
  360. db = db.Where("dialysis_dialyszers = ?", dialyzer)
  361. }
  362. if orgid > 0 {
  363. db = db.Where("user_org_id = ?", orgid)
  364. }
  365. db = db.Where("record_date >= ? and record_date <= ?", start_time, end_time)
  366. offset := (page - 1) * limit
  367. err = db.Count(&total).Offset(offset).Limit(limit).Find(&solution).Error
  368. return solution, total, err
  369. }
  370. type DialysisData struct {
  371. DialysisStatus string `json:"dialysis_status"`
  372. Count int `json:"count"`
  373. }
  374. type CustomData struct {
  375. DialysisNo string
  376. PatientName string
  377. DialysisDate string
  378. DialysisDuration string
  379. ActualDuration string
  380. Diff string
  381. Doctor string
  382. Nurse string
  383. }
  384. func GetDialysisCompletionRate(org_id int64, start_time int64, end_time int64) (map[string]int, error) {
  385. var results []DialysisData
  386. query := `
  387. SELECT
  388. CASE
  389. 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 '达标'
  390. 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 '未达标'
  391. ELSE '超时'
  392. END AS dialysis_status,
  393. COUNT(*) AS count
  394. FROM
  395. xt_dialysis_order o
  396. JOIN
  397. xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ?
  398. JOIN
  399. xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ?
  400. WHERE
  401. o.stage = 2 AND o.user_org_id = ? AND o.dialysis_date >= ? AND o.dialysis_date <= ?
  402. GROUP BY
  403. dialysis_status;
  404. `
  405. if err := readDb.Raw(query, org_id, org_id, org_id, start_time, end_time).Scan(&results).Error; err != nil {
  406. return nil, err
  407. }
  408. dialysisCompletionRate := make(map[string]int)
  409. for _, result := range results {
  410. dialysisCompletionRate[result.DialysisStatus] = result.Count
  411. }
  412. return dialysisCompletionRate, nil
  413. }
  414. func GetDialysisCompletionTotal(org_id int64, start_time int64, end_time int64) (int64, error) {
  415. var Count int64
  416. query := `
  417. SELECT
  418. COUNT(*) AS count
  419. FROM
  420. xt_dialysis_order o
  421. JOIN
  422. xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ?
  423. JOIN
  424. xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ?
  425. WHERE
  426. o.stage = 2 AND o.user_org_id = ? AND o.dialysis_date >= ? AND o.dialysis_date <= ?
  427. `
  428. if err := readDb.Raw(query, org_id, org_id, org_id, start_time, end_time).Count(&Count).Error; err != nil {
  429. return 0, err
  430. }
  431. return Count, nil
  432. }
  433. func GetDialysisCompletionDetail(org_id int64, start_time int64, end_time int64, mode int64, limit int64, page int64) (results []interface{}, total int64, err error) {
  434. var query string
  435. if mode == 0 {
  436. query = `
  437. SELECT
  438. p.dialysis_no as dialysis_no,
  439. p.name as patient_name,
  440. FROM_UNIXTIME(o.dialysis_date) as dialysis_date,
  441. CONCAT(p.dialysis_duration_hour, 'h', p.dialysis_duration_minute,'min') as dialysis_duration,
  442. CONCAT(a.actual_treatment_hour, 'h', a.actual_treatment_minute,'min') as actual_duration,
  443. 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,
  444. p.prescription_doctor as doctor,
  445. o.finish_nurse as nurse
  446. FROM
  447. xt_dialysis_order o
  448. JOIN
  449. xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ?
  450. JOIN
  451. xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ?
  452. JOIN
  453. xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ?
  454. WHERE
  455. o.stage = 2 AND o.user_org_id = ? AND o.dialysis_date >= ? AND o.dialysis_date <= ?
  456. `
  457. readDb.Table("xt_dialysis_order o").
  458. Joins("JOIN xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ?", org_id).
  459. Joins("JOIN xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ?", org_id).
  460. Joins("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 = ?", org_id).
  461. Where("o.stage = 2 AND o.user_org_id = ? AND o.dialysis_date >= ? AND o.dialysis_date <= ?", org_id, start_time, end_time).Count(&total)
  462. } else if mode == 1 {
  463. query = `
  464. SELECT
  465. pp.dialysis_no as dialysis_no,
  466. pp.name as patient_name,
  467. FROM_UNIXTIME(o.dialysis_date) as dialysis_date,
  468. CONCAT(p.dialysis_duration_hour, 'h', p.dialysis_duration_minute,'min') as dialysis_duration,
  469. CONCAT(a.actual_treatment_hour, 'h', a.actual_treatment_minute,'min') as actual_duration,
  470. 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,
  471. p.prescription_doctor as doctor,
  472. o.finish_nurse as nurse
  473. FROM
  474. xt_dialysis_order o
  475. JOIN
  476. xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ?
  477. JOIN
  478. xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ?
  479. JOIN
  480. xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ?
  481. WHERE
  482. 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
  483. `
  484. readDb.Table("xt_dialysis_order o").
  485. Joins("JOIN xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ?", org_id).
  486. Joins("JOIN xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ?", org_id).
  487. Joins("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 = ?", org_id).
  488. 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", org_id, start_time, end_time).Count(&total)
  489. } else if mode == 2 {
  490. query = `
  491. SELECT
  492. pp.dialysis_no as dialysis_no,
  493. pp.name as patient_name,
  494. FROM_UNIXTIME(o.dialysis_date) as dialysis_date,
  495. CONCAT(p.dialysis_duration_hour, 'h', p.dialysis_duration_minute,'min') as dialysis_duration,
  496. CONCAT(a.actual_treatment_hour, 'h', a.actual_treatment_minute,'min') as actual_duration,
  497. 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,
  498. p.prescription_doctor as doctor,
  499. o.finish_nurse as nurse
  500. FROM
  501. xt_dialysis_order o
  502. JOIN
  503. xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ?
  504. JOIN
  505. xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ?
  506. JOIN
  507. xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ?
  508. WHERE
  509. 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
  510. `
  511. readDb.Table("xt_dialysis_order o").
  512. Joins("JOIN xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ?", org_id).
  513. Joins("JOIN xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ?", org_id).
  514. Joins("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 = ?", org_id).
  515. 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", org_id, start_time, end_time).Count(&total)
  516. } else if mode == 3 {
  517. query = `
  518. SELECT
  519. pp.dialysis_no as dialysis_no,
  520. pp.name as patient_name,
  521. FROM_UNIXTIME(o.dialysis_date) as dialysis_date,
  522. CONCAT(p.dialysis_duration_hour, 'h', p.dialysis_duration_minute,'min') as dialysis_duration,
  523. CONCAT(a.actual_treatment_hour, 'h', a.actual_treatment_minute,'min') as actual_duration,
  524. 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,
  525. p.prescription_doctor as doctor,
  526. o.finish_nurse as nurse
  527. FROM
  528. xt_dialysis_order o
  529. JOIN
  530. xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ?
  531. JOIN
  532. xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ?
  533. JOIN
  534. xt_assessment_after_dislysis a ON o.dialysis_date = a.assessment_date AND o.patient_id = a.patient_id AND a.user_org_id = ?
  535. WHERE
  536. 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
  537. `
  538. readDb.Table("xt_dialysis_order o").
  539. Joins("JOIN xt_patients pp ON o.patient_id = pp.id AND pp.user_org_id = ?", org_id).
  540. Joins("JOIN xt_dialysis_prescription p ON o.dialysis_date = p.record_date AND o.patient_id = p.patient_id AND p.user_org_id = ?", org_id).
  541. Joins("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 = ?", org_id).
  542. 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", org_id, start_time, end_time).Count(&total)
  543. }
  544. offset := (page - 1) * limit
  545. rows, err := readDb.Raw(query, org_id, org_id, org_id, org_id, start_time, end_time).Offset(offset).Limit(limit).Rows()
  546. if err != nil {
  547. fmt.Println(err)
  548. }
  549. defer rows.Close()
  550. // Define a map to hold the dynamic fields
  551. fields := map[string]interface{}{
  552. "dialysis_no": "",
  553. "patient_name": "",
  554. "dialysis_date": "",
  555. "dialysis_duration": "",
  556. "actual_duration": "",
  557. "diff": 0,
  558. "doctor": "",
  559. "nurse": "",
  560. }
  561. // Create the dynamic struct type
  562. dynamicStructType := createDynamicStruct(fields)
  563. // Slice to hold the results
  564. //var results []interface{}
  565. // Iterate over the rows and scan into the dynamic struct
  566. for rows.Next() {
  567. // Create a new instance of the dynamic struct
  568. result := reflect.New(dynamicStructType).Interface()
  569. // Create a slice of pointers to the fields in the struct
  570. fieldPtrs := []interface{}{
  571. reflect.ValueOf(result).Elem().FieldByName("Dialysis_no").Addr().Interface(),
  572. reflect.ValueOf(result).Elem().FieldByName("Patient_name").Addr().Interface(),
  573. reflect.ValueOf(result).Elem().FieldByName("Dialysis_date").Addr().Interface(),
  574. reflect.ValueOf(result).Elem().FieldByName("Dialysis_duration").Addr().Interface(),
  575. reflect.ValueOf(result).Elem().FieldByName("Actual_duration").Addr().Interface(),
  576. reflect.ValueOf(result).Elem().FieldByName("Diff").Addr().Interface(),
  577. reflect.ValueOf(result).Elem().FieldByName("Doctor").Addr().Interface(),
  578. reflect.ValueOf(result).Elem().FieldByName("Nurse").Addr().Interface(),
  579. }
  580. // Scan the row into the struct
  581. if err := rows.Scan(fieldPtrs...); err != nil {
  582. //log.Fatalf("failed to scan row: %v", err)
  583. fmt.Println(err)
  584. }
  585. // Append the result to the slice
  586. results = append(results, result)
  587. }
  588. return results, total, err
  589. }
  590. type QualityControlStandard struct {
  591. ItemName string `json:"item_name"`
  592. ProjectMame string `json:"project_name"`
  593. InspectionMajor int64 `json:"inspection_major"`
  594. InspectionMinor int64 `json:"inspection_minor"`
  595. }
  596. func getQualityControlStandards(org_id int64) ([]QualityControlStandard, error) {
  597. var standards []QualityControlStandard
  598. 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 {
  599. return nil, err
  600. }
  601. return standards, nil
  602. }
  603. type DialysisQualityStat struct {
  604. Month string `json:"月"`
  605. Name string `json:"姓名"`
  606. Counts map[string]float64 `json:"counts"`
  607. }
  608. func GetLatestInspectionValues(org_id int64, yearMonth string) ([]map[string]interface{}, error) {
  609. standards, err := getQualityControlStandards(org_id)
  610. if err != nil {
  611. return nil, err
  612. }
  613. var selectFields []string
  614. for _, standard := range standards {
  615. field := fmt.Sprintf("IFNULL(MAX(CASE WHEN i.item_name = %s THEN i.inspect_value END),'') AS `%s`",
  616. "'"+standard.ItemName+"'", standard.ItemName)
  617. selectFields = append(selectFields, field)
  618. }
  619. query := fmt.Sprintf(`
  620. SELECT
  621. p.name as '姓名',
  622. %s
  623. FROM xt_inspection i
  624. JOIN xt_patients p On p.id = i.patient_id
  625. WHERE DATE_FORMAT(FROM_UNIXTIME(i.inspect_date), '%%Y-%%m') = ? and org_id = ?
  626. GROUP BY i.patient_id
  627. `, strings.Join(selectFields, ", "))
  628. var results []map[string]interface{}
  629. rows, err := readDb.Raw(query, yearMonth, org_id).Rows()
  630. if err != nil {
  631. return nil, err
  632. }
  633. defer rows.Close()
  634. columns, err := rows.Columns()
  635. if err != nil {
  636. return nil, err
  637. }
  638. for rows.Next() {
  639. // 创建一个长度为列数的切片,用于存储每一行的值
  640. columnValues := make([]interface{}, len(columns))
  641. columnPointers := make([]interface{}, len(columns))
  642. for i := range columnValues {
  643. columnPointers[i] = &columnValues[i]
  644. }
  645. // 扫描当前行的值
  646. if err := rows.Scan(columnPointers...); err != nil {
  647. return nil, err
  648. }
  649. // 将扫描到的值放入结果 map 中
  650. result := make(map[string]interface{})
  651. for i, colName := range columns {
  652. val := columnPointers[i].(*interface{})
  653. result[colName] = *val
  654. }
  655. results = append(results, result)
  656. }
  657. return results, nil
  658. }
  659. func createDynamicStruct(fields map[string]interface{}) reflect.Type {
  660. var structFields []reflect.StructField
  661. for name, value := range fields {
  662. structFields = append(structFields, reflect.StructField{
  663. Name: strings.Title(name),
  664. Type: reflect.TypeOf(value),
  665. Tag: reflect.StructTag(fmt.Sprintf(`json:"%s"`, name)),
  666. })
  667. }
  668. return reflect.StructOf(structFields)
  669. }