import dayjs from "dayjs"; import I18nBehavior from "../../../../i18n/behavior"; import { Post } from "../../../../lib/request/method"; // module/chats/components/questionnaire/questionnaire.ts interface Message { id: string; type: | "system" | "analysis" | "select" | "text" | "report" | "again" | "follow" | "count" | "consult"; payload: AnyObject; } interface HandleEvent { target: { id: string }; detail: AnyObject; type: "next"; } interface MessageType { messageType: number; } Component({ behaviors: [I18nBehavior], lifetimes: { attached: function () { let isAnalysis: number; isAnalysis = wx.getStorageSync("isAnalysis"); console.log("isAnalysis", isAnalysis); if (isAnalysis === 3 || isAnalysis === 4 || isAnalysis === 5) { // 对话管家 this._start(); } else if (isAnalysis === 2) { // 随访提醒 this.setData({ [`_next.classify`]: "", [`_next.dialogId`]: "", [`_next.questions`]: [], _timestamp: Date.now(), }); this._next(); } }, }, properties: { messageType: { type: Number, value: 0 }, workId: { type: Number, value: 0 }, }, /** * 组件的初始数据 */ data: { i18n: { chats: { report: '' }, }, inputBoxBottom: 0, messages: {} as Record, lastId: "", _next: { classify: "", dialogId: "", questions: [], } as AnyObject, _timestamp: Date.now(), // 防止 _next 被并发/重复触发(例如 classify === 'tongue' 时) _requesting: false, consultStarted: false, }, observers: { "messages.**"(messages) { const message = Object.values(messages).pop() as Message; this.setData({ lastId: message?.id }); }, }, methods: { nextType(event: MessageType) { this.setData({ messageType: event.detail.MessageType }); this._next(); }, scroll(option: { id: string }) { this.triggerEvent("to", option.detail.id); }, boxBottom(event: boxBottom) { console.log("event==boxBottom", event); this.setData({ inputBoxBottom: event.detail.inputBoxBottom }); console.log("this.data.inputBoxBottom", this.data.inputBoxBottom); this.triggerEvent("boxBottom", { inputBoxBottom: this.data.inputBoxBottom + 100, }); }, handle(event: HandleEvent) { const isAnalysis = wx.getStorageSync("isAnalysis"); if (isAnalysis === 3 || isAnalysis === 4) { const index = event.target?.id.split(".").pop() ?? 0; const questions = this.data._next.questions; Object.assign(questions[index], event.detail); this.setData({ "_next.questions": questions }); this._next(); } else if (isAnalysis === 5) { // 在线咨询暂不需要在问卷组件中处理回答 return; } else { // 随访 this._createMessage({ id: `follow.${Date.now()}`, type: "follow", payload: { title: "" }, }); } }, async _start() { const isAnalysis = wx.getStorageSync("isAnalysis"); // 在线咨询:isAnalysis === 5 且 messageType === 3 if (isAnalysis === 5 && this.data.messageType === 3) { this.setData({ [`_next.classify`]: "", [`_next.dialogId`]: "", [`_next.questions`]: [], _timestamp: Date.now(), consultStarted: false, }); this._next(); return; } try { // 获取剩余次数 const count = await Post( `/patientInfoManage/rechargeUseDetail`, {}, { transform({ data }: any) { return data?.residuedCou; }, } ); this.triggerEvent("count", { count }); if (count > 0) { this.setData({ [`_next.classify`]: "", [`_next.dialogId`]: "", [`_next.questions`]: [], _timestamp: Date.now(), }); this._next(); } else { // throw { errMsg: `您的健康分析次数已用完,请联系工作人员。` }; this._createMessage({ id: `count-${Date.now()}`, type: "count", payload: { date: Date.now(), title: `您的健康分析次数已用完,请联系工作人员。`, }, }); this._end(); } } catch (error) { this._createMessage({ id: `system-start`, type: "system", payload: { date: Date.now(), title: error.errMsg ?? `分析错误,请重试!`, }, }); this._end(); } }, _end() { this.setData({ [`_next.classify`]: "", [`_next.dialogId`]: "", [`_next.questions`]: [], consultStarted: false, }); // 对于 isAnalysis === 4 的情况,不创建新的 guide 组件,直接触发滚动 // 对于 isAnalysis === 3 的情况,仍然创建 guide 组件显示三个业务选项 const isAnalysis = wx.getStorageSync("isAnalysis"); if (isAnalysis === 4) { // 触发滚动到当前 questionnaire 组件,让父页面滚动到这个组件 setTimeout(() => { this.triggerEvent("to"); }, 100); } else { this.triggerEvent("next", { component: "guide", scroll: true }); // 对于 isAnalysis === 3 的情况,延迟触发滚动,确保报告消息和业务选项都渲染完成 if (isAnalysis === 3) { setTimeout(() => { this.triggerEvent("to"); }, 300); } else { // 额外触发一次滚动到底部,确保页面滚动到最新内容 setTimeout(() => { this.triggerEvent("to", { detail: "bottom" }); }, 200); } } }, async _next() { // 并发与重复触发保护 if (this.data._requesting) { return; } this.setData({ _requesting: true }); let isAnalysis: number; isAnalysis = wx.getStorageSync("isAnalysis"); if (isAnalysis === 3 || isAnalysis === 4) { // 对话管家 if (this.data._next.classify === "tongue") { this._createMessage({ id: `tongue-loading.${Date.now()}`, type: "text", payload: { title: "分析中...", loading: true }, }); this.triggerEvent("to"); } } try { // messageType 1 是随访。messageType 2 是健康评估和对话管家。messageType 3 是在线咨询 console.log("this.data.messageType", this.data.messageType); if (this.data.messageType === 1) { this._createMessage({ id: `again.${Date.now()}`, type: "again", payload: { title: "" }, }); } else if (this.data.messageType === 3) { // 在线咨询 // 开始咨询,如果咨询已经开始,则不重新开始 if (!this.data.consultStarted) { try { // 开始咨询 获取咨询id const res = await Post(`/consultManage/start`); if (res.data) { // 存储咨询中的id wx.setStorageSync("consultId", res.data); this._createMessage({ id: `consult.${Date.now()}`, type: "consult", payload: { title: "咨询开始" }, }); this.setData({ consultStarted: true }); this.triggerEvent("to"); } } catch (error: any) { console.error("咨询开始失败", error); wx.showToast({ title: error.errMsg ?? `咨询开始失败,请重试!`, icon: "none", }); } } } else if (this.data.messageType === 2) { let data: any = {}; const res = await Post( `/dialogueManage/dialogTreat`, this.data._next ); data = res.data; data.nextQuestions?.forEach((question: any, index: number) => { // isAnalysis 2是随访 3健康管家 4健康评估 5在线咨询 if (isAnalysis === 2) { // 随访 if (question.css === "tongue") { this._createMessage({ id: `${question.classify}.${question.id}.${index}`, type: "analysis", payload: { title: question.title }, }); } } else { // 对话管家 if (question.classify === "tongue_result") { this._updateMessage({ id: `${question.classify}.${question.id}.${index}`, type: "text", payload: { title: question.content }, }); } else { if (question.css === "tongue") { this._createMessage({ id: `${question.classify}.${question.id}.${index}`, type: "analysis", payload: { title: question.title }, }); } else if (question.css === "text") { this._createMessage({ id: `${question.classify}.${question.id}.${index}`, type: "text", payload: { title: question.content }, }); } else if (["select", "checkbox"].includes(question.css)) { if (question.options && question.options.length > 0) { // 检查所有 item.options 的长度是否都为 0 const allOptionsEmpty = question.options.every( (item: any) => !item.options || item.options.length === 0 ); question.required = allOptionsEmpty; } this._createMessage({ id: `${question.classify}.${question.id}.${index}`, type: "select", payload: { title: question.title, options: question.options.map((item: AnyObject) => { if (Array.isArray(item.options)) { item.options = item.options.map((item) => { return { ...item, hide: item.css === "hide" }; }); } return { ...item, hide: item.css === "hide" }; }), multiple: question.css === "checkbox", required: question.required, belongNew: question.belongNew, }, }); } else if (question.over) { return this._end(); } } } }); // 对话管家 if ( (isAnalysis === 3 && data.classify === "report") || (isAnalysis === 4 && data.classify === "report") ) { if (data.classify === "report") { const diff = dayjs().diff(this.data._timestamp, "m"); this._createMessage({ id: "report", type: "report", payload: { title: `本次问答已结束,历时${diff || 1 }分钟,非常感谢您的配合!${this.data.i18n.chats.report}`, url: `/module/health/pages/report/report?id=${data.healthAnalysisReportId}`, }, }); // 立即触发一次滚动,确保在最后一个问题生成报告卡片后页面滚动到底部 this.triggerEvent("to"); } if (data.over) { // 延迟触发滚动,确保报告消息已经渲染完成 setTimeout(() => { this.triggerEvent("to"); }, 100); return this._end(); } } this.setData({ [`_next.classify`]: data.classify, [`_next.dialogId`]: data.dialogId, [`_next.questions`]: data.nextQuestions, }); this.triggerEvent("to"); } } catch (error) { if (this.data._next.classify === "tongue") { this._updateMessage({ id: `tongue-error-${Date.now()}`, type: "text", payload: { title: error.errMsg ?? `图像检测失败,请重新拍摄上传` }, }); this.triggerEvent("to"); // setTimeout(() => this._start(), 20); } else { const date = Date.now(); this._createMessage({ id: `system-${date}`, type: "system", payload: { date, title: error.errMsg ?? `分析错误,请重试!` }, }); this._end(); } } finally { // 恢复请求锁 this.setData({ _requesting: false }); } }, _createMessage(body: Message, data?: Record) { const messages = this.data.messages; const index = Object.keys(messages).length; this.setData({ [`messages.${index}`]: body, ...data, }); }, _updateMessage(body: Message) { const messages = this.data.messages; const index = Object.keys(messages).length; this.setData({ [`messages.${index - 1}`]: body, }); }, // 处理咨询事件 handleConsultEvent(event: { detail: { type: string } }) { if (event.detail.type === "end") { // 结束咨询时,通知父组件显示guide菜单组件 this.triggerEvent("next", { component: "guide", scroll: true }); setTimeout(() => { this.triggerEvent("to"); }, 100); } }, }, });