statistis_qc_service.go 34KB

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