export const formatTime = (date: Date) => { const year = date.getFullYear() const month = date.getMonth() + 1 const day = date.getDate() const hour = date.getHours() const minute = date.getMinutes() const second = date.getSeconds() return ( [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') ) } const formatNumber = (n: number) => { const s = n.toString() return s[1] ? s : '0' + s } export function groupBy(items: Iterable, callbackFn: (element: T, index: number) => any): Record { const obj = Object.create(null); let k = 0; for (const value of items) { const key = callbackFn(value, k++); if (key in obj) { obj[key].push(value); } else { obj[key] = [value]; } } return obj; } export const HealthReportSymptomItemConfig = { 有一点: 2.0, 偶尔: 2.0, 轻: 2.0, 有些: 3.0, 有时: 3.0, 中: 3.0, 相当: 4.0, 经常: 4.0, 重: 4.0, 非常: 5.0, 总是: 5.0, 非常重: 5.0, } as const; export interface HealthReportSymptomItemVo { /** * 症状ID */ id: string; /** * 症状名称 */ name: string; /** * 症状描述 */ label: string; /** * 症状得分 */ value: number; } export interface HealthReportSymptomVo { items: HealthReportSymptomItemVo[]; value?: string; duration?: string; influence?: string; } export interface HealthReportDTO { tonguefaceAnalysisReportId: string; healthAnalysisReportId: string; reportTime: string; pickedSymptomList?: { id: string; name: string; value: string; score: number }[]; pickedSymptom?: string; duration?: string; influenceDegree?: string; willillStateName: string; willillDegreeName: string; willillFunctionName: string; willillSocialName: string; constitutionGroupName: string; constitutionGroupDefinition: string; factorItemSummary: string; diagnoseSyndromeSummary: string; } export function fromHealthReportSymptom(data: Partial, config = HealthReportSymptomItemConfig): HealthReportSymptomVo { const result: HealthReportSymptomVo = { value: data.pickedSymptom, items: data.pickedSymptomList?.map(({ id, name, ...item }) => ({ id, name, label: item.value, value: +item.score, })) ?? [], duration: data.duration, influence: data.influenceDegree, }; if (!result.items?.length && result.value) { const matches = result.value?.matchAll(/([^,(]+)(([^)]+))/g) ?? []; for (const [_, name, label] of matches) { // @ts-ignore const value = config[label] ?? 0; result.items.push({ id: name, name, label, value }); } } return result; } /** * 唤起微信支付 * @param {Object} paymentParams - 支付参数对象 * @param {string} paymentParams.timeStamp - 时间戳 * @param {string} paymentParams.packageVal - 统一下单接口返回的 prepay_id 参数值,格式为 "prepay_id=xxx"(兼容 packageValue) * @param {string} paymentParams.packageValue - 统一下单接口返回的 prepay_id 参数值,格式为 "prepay_id=xxx"(API返回的字段名) * @param {string} paymentParams.paySign - 支付签名 * @param {string} paymentParams.nonceStr - 随机字符串 * @param {string} paymentParams.signType - 签名类型,默认为 'RSA' * @param {string} paymentParams.appId - 小程序 appId(可选) * @param {Function} onSuccess - 支付成功回调函数 * @param {Function} onFail - 支付失败回调函数 */ export const handleWeChatPayment = (paymentParams: any, onSuccess: any, onFail: any = () => {}) => { // 兼容 packageValue 和 packageVal 两种字段名 const packageVal = paymentParams.packageValue || paymentParams.packageVal // 验证支付参数 if (!paymentParams || !paymentParams.timeStamp || !packageVal || !paymentParams.paySign) { const error = new Error('支付参数不完整') console.error('支付参数错误:', error) if (onFail) { onFail(error) } return } // wx.showLoading({ // title: '正在调起支付...', // mask: true // }) wx.requestPayment({ provider: 'wxpay', timeStamp: String(paymentParams.timeStamp), // 确保是字符串类型 nonceStr: paymentParams.nonceStr, package: packageVal, // 兼容 packageValue 和 packageVal signType: paymentParams.signType || 'RSA', paySign: paymentParams.paySign, success: (res) => { wx.hideLoading() if (onSuccess) { onSuccess(res) } }, fail: (err) => { if (onFail) { onFail(err) } if (err.errMsg === 'requestPayment:fail cancel') { wx.showToast({ title: '支付已取消', icon: 'none' }) } else { console.error('支付失败:', err) } } }) }