report.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. var tcm = require('../../../../utils/tcm.js')
  2. var compliance = require('../../../../utils/compliance.js')
  3. Page({
  4. data: {
  5. loading: true,
  6. status: 'loading',
  7. errorMessage: '',
  8. examId: '',
  9. scaleUserId: '',
  10. exam: null,
  11. scaleUser: null,
  12. latestScaleResult: null,
  13. statList: [],
  14. questionList: [],
  15. sectionList: [],
  16. imageList: [],
  17. reportTime: ''
  18. },
  19. timer: null,
  20. pollCount: 0,
  21. onLoad: function (options) {
  22. this.setData({
  23. examId: options.examId || '',
  24. scaleUserId: options.scaleUserId || ''
  25. })
  26. this.loadReport(false)
  27. },
  28. onUnload: function () {
  29. this.clearTimer()
  30. },
  31. loadReport: function (silent) {
  32. var that = this
  33. if (!silent) {
  34. that.setData({
  35. loading: true,
  36. errorMessage: ''
  37. })
  38. }
  39. var requestPromise = that.data.examId
  40. ? tcm.getExamDetail(that.data.examId)
  41. : tcm.getLatestExam(that.data.scaleUserId)
  42. requestPromise.then(function (data) {
  43. var exam = data && data.exam ? data.exam : null
  44. var aiSections = data && data.aiSections ? data.aiSections : {}
  45. var hasSections = that.buildSectionList(aiSections).length > 0
  46. if (!exam) {
  47. that.setData({
  48. loading: false,
  49. status: 'empty',
  50. exam: null,
  51. sectionList: [],
  52. imageList: []
  53. })
  54. return
  55. }
  56. var status = exam.status || 'pending'
  57. if (status === 'completed' && !hasSections) {
  58. status = 'generating'
  59. }
  60. that.setData({
  61. loading: false,
  62. status: status,
  63. exam: exam,
  64. scaleUser: data.scaleUser || null,
  65. latestScaleResult: data.latestScaleResult || null,
  66. statList: that.buildStatList(data.scaleUser || null, data.latestScaleResult || null),
  67. questionList: that.buildQuestionList(data.questionAnswersLocalizedExpanded || {}),
  68. sectionList: that.buildSectionList(aiSections),
  69. imageList: that.buildImageList(exam.observationImagesOss || exam.observationImages || {}),
  70. errorMessage: aiSections && aiSections.error ? compliance.sanitizeText(aiSections.error) : '',
  71. reportTime: that.formatDateTime(exam.CreatedAt || '')
  72. })
  73. if (status === 'pending' || status === 'generating') {
  74. if (!that.timer) {
  75. that.startPolling()
  76. }
  77. } else {
  78. that.clearTimer()
  79. }
  80. }).catch(function (err) {
  81. that.setData({
  82. loading: false,
  83. status: 'error',
  84. errorMessage: err && err.message ? compliance.sanitizeText(err.message) : '报告加载失败'
  85. })
  86. })
  87. },
  88. buildQuestionList: function (source) {
  89. var list = []
  90. if (Array.isArray(source)) {
  91. return compliance.sanitizeValue(source)
  92. }
  93. for (var key in source) {
  94. list.push({
  95. title: compliance.sanitizeText(key),
  96. value: compliance.sanitizeText(Array.isArray(source[key]) ? source[key].join(',') : source[key])
  97. })
  98. }
  99. return list
  100. },
  101. buildSectionList: function (aiSections) {
  102. var mapping = [
  103. { key: 'general', title: '一般情况', badge: '壹' },
  104. { key: 'inquiry', title: '健康问答分析', badge: '贰' },
  105. { key: 'observation', title: '图片分析', badge: '叁' },
  106. { key: 'constitution', title: '体质分析', badge: '肆' },
  107. { key: 'advice', title: '调养建议', badge: '伍' },
  108. { key: 'summary', title: '报告摘要', badge: '陆' }
  109. ]
  110. var list = []
  111. for (var i = 0; i < mapping.length; i++) {
  112. if (aiSections && aiSections[mapping[i].key]) {
  113. list.push({
  114. key: mapping[i].key,
  115. badge: mapping[i].badge,
  116. title: mapping[i].title,
  117. content: compliance.sanitizeText(aiSections[mapping[i].key])
  118. })
  119. }
  120. }
  121. return list
  122. },
  123. buildStatList: function (scaleUser, latestScaleResult) {
  124. var list = []
  125. if (scaleUser) {
  126. if (scaleUser.sex !== undefined && scaleUser.sex !== null) {
  127. list.push({
  128. label: '性别',
  129. value: Number(scaleUser.sex) === 1 ? '女' : '男'
  130. })
  131. }
  132. if (scaleUser.age) {
  133. list.push({
  134. label: '年龄',
  135. value: scaleUser.age + '岁'
  136. })
  137. }
  138. if (scaleUser.height) {
  139. list.push({
  140. label: '身高',
  141. value: scaleUser.height + 'cm'
  142. })
  143. }
  144. }
  145. if (latestScaleResult) {
  146. var weight = latestScaleResult.weight_kg || latestScaleResult.weight
  147. if (weight) {
  148. list.push({
  149. label: '体重',
  150. value: this.formatValue(weight) + 'kg'
  151. })
  152. }
  153. if (latestScaleResult.bodyScore) {
  154. list.push({
  155. label: '评分',
  156. value: this.formatValue(latestScaleResult.bodyScore) + '分'
  157. })
  158. }
  159. }
  160. return list.slice(0, 5)
  161. },
  162. formatDateTime: function (value) {
  163. if (!value) {
  164. return ''
  165. }
  166. return String(value).replace('T', ' ').slice(0, 16)
  167. },
  168. formatValue: function (value) {
  169. if (value === undefined || value === null || value === '') {
  170. return '--'
  171. }
  172. var num = Number(value)
  173. if (isNaN(num)) {
  174. return String(value)
  175. }
  176. if (Math.floor(num) === num) {
  177. return String(num)
  178. }
  179. return num.toFixed(1).replace(/\.0$/, '')
  180. },
  181. buildImageList: function (images) {
  182. var mapping = {
  183. tongue: '舌面',
  184. tongueBottom: '舌下',
  185. face: '面部',
  186. body: '全身'
  187. }
  188. var orderedKeys = ['tongue', 'tongueBottom', 'face', 'body']
  189. if (typeof images === 'string' && images) {
  190. try {
  191. images = JSON.parse(images)
  192. } catch (err) {
  193. images = {}
  194. }
  195. }
  196. var list = []
  197. for (var i = 0; i < orderedKeys.length; i++) {
  198. var key = orderedKeys[i]
  199. var urls = images ? images[key] : null
  200. if (Array.isArray(urls) && urls.length) {
  201. list.push({
  202. title: mapping[key],
  203. url: urls[0]
  204. })
  205. } else if (typeof urls === 'string' && urls) {
  206. list.push({
  207. title: mapping[key],
  208. url: urls
  209. })
  210. }
  211. }
  212. return list
  213. },
  214. startPolling: function () {
  215. var that = this
  216. that.clearTimer()
  217. that.pollCount = 0
  218. that.timer = setInterval(function () {
  219. that.pollCount++
  220. if (that.pollCount > 60) {
  221. that.clearTimer()
  222. that.setData({
  223. status: 'error',
  224. errorMessage: '报告生成超时,请稍后重新查看'
  225. })
  226. return
  227. }
  228. that.loadReport(true)
  229. }, 3000)
  230. },
  231. clearTimer: function () {
  232. if (this.timer) {
  233. clearInterval(this.timer)
  234. this.timer = null
  235. }
  236. },
  237. previewReportImage: function (e) {
  238. var current = e.currentTarget.dataset.src
  239. var urls = this.data.imageList.map(function (item) {
  240. return item.url
  241. })
  242. wx.previewImage({
  243. current: current,
  244. urls: urls
  245. })
  246. },
  247. retryReport: function () {
  248. this.clearTimer()
  249. this.loadReport(false)
  250. },
  251. goDiagnosis: function () {
  252. wx.redirectTo({
  253. url: '/packageWellness/pages/tcm/diagnosis/diagnosis'
  254. })
  255. }
  256. })