util.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import { Base_URL } from "../app.config";
  2. /**
  3. * 拼接图片完整地址
  4. * - 相对路径:拼接当前环境域名
  5. * - 完整地址(http/https):直接返回
  6. * @param url 图片地址(完整URL或相对路径)
  7. */
  8. export const getFullImageUrl = (url?: string): string => {
  9. if (!url) return '';
  10. if (url.startsWith('http')) return url;
  11. return `${Base_URL.replace(/\/manager\/.*$/, '')}${url}`;
  12. }
  13. export const formatTime = (date: Date) => {
  14. const year = date.getFullYear()
  15. const month = date.getMonth() + 1
  16. const day = date.getDate()
  17. const hour = date.getHours()
  18. const minute = date.getMinutes()
  19. const second = date.getSeconds()
  20. return (
  21. [year, month, day].map(formatNumber).join('/') +
  22. ' ' +
  23. [hour, minute, second].map(formatNumber).join(':')
  24. )
  25. }
  26. const formatNumber = (n: number) => {
  27. const s = n.toString()
  28. return s[1] ? s : '0' + s
  29. }
  30. export function groupBy<T>(items: Iterable<T>, callbackFn: (element: T, index: number) => any): Record<string, T[]> {
  31. const obj = Object.create(null);
  32. let k = 0;
  33. for (const value of items) {
  34. const key = callbackFn(value, k++);
  35. if (key in obj) { obj[key].push(value); } else { obj[key] = [value]; }
  36. }
  37. return obj;
  38. }
  39. export const HealthReportSymptomItemConfig = {
  40. 有一点: 2.0,
  41. 偶尔: 2.0,
  42. 轻: 2.0,
  43. 有些: 3.0,
  44. 有时: 3.0,
  45. 中: 3.0,
  46. 相当: 4.0,
  47. 经常: 4.0,
  48. 重: 4.0,
  49. 非常: 5.0,
  50. 总是: 5.0,
  51. 非常重: 5.0,
  52. } as const;
  53. export interface HealthReportSymptomItemVo {
  54. /**
  55. * 症状ID
  56. */
  57. id: string;
  58. /**
  59. * 症状名称
  60. */
  61. name: string;
  62. /**
  63. * 症状描述
  64. */
  65. label: string;
  66. /**
  67. * 症状得分
  68. */
  69. value: number;
  70. }
  71. export interface HealthReportSymptomVo {
  72. items: HealthReportSymptomItemVo[];
  73. value?: string;
  74. duration?: string;
  75. influence?: string;
  76. }
  77. export interface HealthReportDTO {
  78. tonguefaceAnalysisReportId: string;
  79. healthAnalysisReportId: string;
  80. reportTime: string;
  81. pickedSymptomList?: { id: string; name: string; value: string; score: number }[];
  82. pickedSymptom?: string;
  83. duration?: string;
  84. influenceDegree?: string;
  85. willillStateName: string;
  86. willillDegreeName: string;
  87. willillFunctionName: string;
  88. willillSocialName: string;
  89. constitutionGroupName: string;
  90. constitutionGroupDefinition: string;
  91. factorItemSummary: string;
  92. diagnoseSyndromeSummary: string;
  93. }
  94. export function fromHealthReportSymptom(data: Partial<HealthReportDTO>, config = HealthReportSymptomItemConfig): HealthReportSymptomVo {
  95. const result: HealthReportSymptomVo = {
  96. value: data.pickedSymptom,
  97. items:
  98. data.pickedSymptomList?.map(({ id, name, ...item }) => ({
  99. id,
  100. name,
  101. label: item.value,
  102. value: +item.score,
  103. })) ?? [],
  104. duration: data.duration,
  105. influence: data.influenceDegree,
  106. };
  107. if (!result.items?.length && result.value) {
  108. const matches = result.value?.matchAll(/([^,(]+)(([^)]+))/g) ?? [];
  109. for (const [_, name, label] of matches) {
  110. // @ts-ignore
  111. const value = config[label] ?? 0;
  112. result.items.push({ id: name, name, label, value });
  113. }
  114. }
  115. return result;
  116. }
  117. /**
  118. * 唤起微信支付
  119. * @param {Object} paymentParams - 支付参数对象
  120. * @param {string} paymentParams.timeStamp - 时间戳
  121. * @param {string} paymentParams.packageVal - 统一下单接口返回的 prepay_id 参数值,格式为 "prepay_id=xxx"(兼容 packageValue)
  122. * @param {string} paymentParams.packageValue - 统一下单接口返回的 prepay_id 参数值,格式为 "prepay_id=xxx"(API返回的字段名)
  123. * @param {string} paymentParams.paySign - 支付签名
  124. * @param {string} paymentParams.nonceStr - 随机字符串
  125. * @param {string} paymentParams.signType - 签名类型,默认为 'RSA'
  126. * @param {string} paymentParams.appId - 小程序 appId(可选)
  127. * @param {Function} onSuccess - 支付成功回调函数
  128. * @param {Function} onFail - 支付失败回调函数
  129. */
  130. export const handleWeChatPayment = (paymentParams: any, onSuccess: any, onFail: any = () => {}) => {
  131. // 兼容 packageValue 和 packageVal 两种字段名
  132. const packageVal = paymentParams.packageValue || paymentParams.packageVal
  133. // 验证支付参数
  134. if (!paymentParams || !paymentParams.timeStamp || !packageVal || !paymentParams.paySign) {
  135. const error = new Error('支付参数不完整')
  136. console.error('支付参数错误:', error)
  137. if (onFail) {
  138. onFail(error)
  139. }
  140. return
  141. }
  142. // wx.showLoading({
  143. // title: '正在调起支付...',
  144. // mask: true
  145. // })
  146. wx.requestPayment({
  147. provider: 'wxpay',
  148. timeStamp: String(paymentParams.timeStamp), // 确保是字符串类型
  149. nonceStr: paymentParams.nonceStr,
  150. package: packageVal, // 兼容 packageValue 和 packageVal
  151. signType: paymentParams.signType || 'RSA',
  152. paySign: paymentParams.paySign,
  153. success: (res) => {
  154. wx.hideLoading()
  155. if (onSuccess) {
  156. onSuccess(res)
  157. }
  158. },
  159. fail: (err) => {
  160. if (onFail) {
  161. onFail(err)
  162. }
  163. if (err.errMsg === 'requestPayment:fail cancel') {
  164. wx.showToast({
  165. title: '支付已取消',
  166. icon: 'none'
  167. })
  168. } else {
  169. console.error('支付失败:', err)
  170. }
  171. }
  172. })
  173. }