import PageContainerBehavior from "../../core/behavior/page-container.behavior"; import I18nBehavior from "../../i18n/behavior"; import { DraggableSheetBehavior, getDraggableSheetContext, } from "../../core/behavior/draggableSheet.behavior"; import { login } from "../../lib/logic"; import { useRouteQuery } from "../../utils/route-query"; import { appUpdate } from "../../lib/wx/update"; import { addPatientOnlineRecordClockIn } from "./request"; import { Get } from "../../lib/request/method"; const { shared, Easing, timing } = wx.worklet; const offset = shared(0); const menus = ["shareAppMessage", "shareTimeline"]; // pages/home/home.ts import { getPatients, healthReportMethod, healthIndexMethod, getSolarTerms, getShortScienceList, getPatientDescription, getNotDealLists, getCareList, } from "./request"; import { toCertificationPage, toChats } from "./router"; import { Post } from "../../lib/request/method"; // import { useLocation } from "../../lib/use/use-location"; Page({ data: { i18n: { common: { title: '生活助理', zy: '' }, home: { analysis: '评估', consult: '聊天', __showRecord__: false, __showDisplay__: false }, report: { title: '报告' }, healthTeach: { title: '' }, }, NoteTitle: "", isShowComplete: true, careList: [], displayList: [] as { id: number; conditioningProgramType: string; operateBy?: string; operateTime: string; frequencyType: string; // 频次类型 frequencyMeasure: string; // 总用量 arrangeDate: string; // 下一次开始日期 finishCount: number; // 完成量 conditioningProgramName: string; // 调养计划名称 conditioningProgramSupplierName: string; // 调养计划供应商名称 expanded: boolean; }[], allExpanded: false, fixedHeight: "370rpx", tabbarValue: "/pages/home/home", tabbarHidden: false, pageHeight: "100vh", // 默认值 popupList: [] as AnyArray, isShowPopup: false, isCompleting: false, // 防止重复点击标志 patients: [] as (App.Patient.Model & { isDefault: "Y" | "N" })[], patient: null as App.Patient.Model | null, patientDescription: "", healthId: "", healthReport: { data: null, message: "", loading: true }, healthIndex: { data: [], message: "" }, position: {} as AnyObject, location: {} as AnyObject, solarTerms: {} as AnyObject, sheet: false, scienceList: [] as AnyArray, leftColumnList: [] as AnyArray, rightColumnList: [] as AnyArray, scienceListPage: 1, scienceListSize: 10, scienceListTotal: 0, scienceListLoading: false, scienceListHasMore: true, refreshing: false, _loaded: false, statusList: [] as AnyArray, switchType: "", carouselLoading: {} as Record, carouselMediaList: [] as Array<{ type: "image" | "video"; src: string; }>, // 是否在咨询中 isConsulting: false, // 是否有新消息 hasNewMessage: false, }, behaviors: [ I18nBehavior, PageContainerBehavior, DraggableSheetBehavior(".draggable-sheet-wrapper"), ], async getCareLists() { const currentExpandedStates = this.data.displayList.map((item: any) => ({ id: item.id, expanded: item.expanded, })); const res = await getCareList(); if (res && res.length > 0) { res.forEach((item: any) => { item.carouselMediaList = []; // 添加photo if (item.photo) { item.carouselMediaList.push({ type: "image", src: item.photo, }); } // 添加itemImgFirst if (item?.itemImgFirst) { item.carouselMediaList.push({ type: "image", src: item.itemImgFirst, }); } // 添加itemVideoFirst if (item?.itemVideoFirst) { item.carouselMediaList.push({ type: "video", src: item.itemVideoFirst, }); } }); // 先设置 careList this.setData({ careList: res, }); await this.updateDisplayList(currentExpandedStates); setTimeout(() => { res.forEach((item: any, index: number) => { if (item.carouselMediaList && item.carouselMediaList.length > 0) { this.setData({ [`careList[${index}].carouselMediaList`]: [ ...item.carouselMediaList, ], }); // 同时更新 displayList const displayIndex = this.data.displayList.findIndex( (displayItem: any) => displayItem.id === item.id ); if (displayIndex !== -1) { this.setData({ [`displayList[${displayIndex}].carouselMediaList`]: [ ...item.carouselMediaList, ], }); } } }); }, 100); } }, async onLoad(options) { appUpdate(); const query = useRouteQuery(options.scene!); if (query.ys) wx.setStorageSync("doctorId", query.ys); if (options.scene) wx.setStorageSync("scene", options.scene); this.initFabAnimated(); if (options.switchType) { this.setData({ switchType: options.switchType, }); } }, async onShow() { wx.showShareMenu({ withShareTicket: true, menus }).then(); await this.load(); // 如果是从一体机扫码进来的 有switchType值就直接跳转到注册页面 if ( this.data.switchType && ((this.data.patient as any)?.isPerfectInfo ?? true) ) { wx.navigateTo({ url: "/module/user/pages/user-certification/user-certification?type=home", }); } // 检查咨询状态 this.checkConsultationStatus(); // 如果用户没有手机号每次进入页面都提示 点击跳到注册页补充 // todo 要先判断用户有没有手机号 isPerfectInfo是true 就出来弹窗提示用户 // if ((this.data.patient as any)?.isPerfectInfo ?? true) { // wx.showModal({ // title: "提示", // content: "手机号为空,请补充", // success: (res) => { // if (res.confirm) { // wx.navigateTo({ // url: "/module/user/pages/user-certification/user-certification?type=home", // }); // } // }, // }); // } }, onHide() { wx.hideShareMenu({ menus }).then(); offset.value = timing( 0, { duration: 100, easing: (Easing).linear }, () => { "worklet"; } ); }, onShareAppMessage(_opts): WechatMiniprogram.Page.ICustomShareContent { return { title: `健康为基,从容赏生活之美`, imageUrl: `https://wx.hzliuzhi.com/media/healthManager/wx/share.jpg`, path: `/pages/home/home`, }; }, onShareTimeline() { return { title: `健康为基,从容赏生活之美`, }; }, async updateDisplayList( preserveExpandedStates?: Array<{ id: number; expanded: boolean; }> ) { const { careList, allExpanded } = this.data; console.log(careList, "careList") let newDisplayList: any[] = allExpanded || careList.length <= 4 ? careList : careList.slice(0, 4); // 如果有保存的展开状态,则恢复它们 if (preserveExpandedStates && preserveExpandedStates.length > 0) { newDisplayList = newDisplayList.map((item: any) => { const savedState = preserveExpandedStates.find( (state) => state.id === item.id ); if (savedState) { return { ...item, expanded: savedState.expanded, }; } return item; }); } this.setData({ displayList: newDisplayList, }); console.log(this.data.displayList, "this.data.displayList11111") }, toggleAll() { this.setData( { allExpanded: !this.data.allExpanded }, this.updateDisplayList ); }, toggleItem(e: any) { const index = e.currentTarget.dataset.index; const key = `displayList[${index}].expanded`; this.setData({ [key]: !this.data.displayList[index].expanded }); }, // 核销记录 onRecord(e: any) { const id = e.currentTarget.dataset.id; if (id) { wx.navigateTo({ url: `/module/care/pages/care/verifyRecord?id=${id}`, }); } else { wx.showToast({ title: "暂无核销记录", icon: "none", }); } }, // 去预约 onAppointment(e: any) { const id = e.currentTarget.dataset.id; if (id) { wx.navigateTo({ url: `/module/care/pages/offlineTreatment/offlineTreatment?id=${id}`, }); } }, // 长按复制机构名称 onCopyInstitutionName(e: any) { const name = e.currentTarget.dataset.name; if (name) { wx.setClipboardData({ data: name, success: () => wx.showToast({ title: "已复制", icon: "none" }), }); } }, onClose() { this.setData({ isShowPopup: false, }); }, // 打卡 pushCard(e: any) { const id = e.currentTarget.dataset.id; wx.navigateTo({ url: `/module/article/pages/punch-card/punch-card?id=${id}`, }); }, calculatePageHeight() { const systemInfo = wx.getSystemInfoSync(); const windowHeight = systemInfo.windowHeight; // 屏幕可用高度 // 获取 tabbar 高度 const query = wx.createSelectorQuery(); query .select(".t-tabbar") .boundingClientRect((rect) => { if (rect) { const tabbarHeight = rect.height; const contentHeight = windowHeight - tabbarHeight; this.setData({ pageHeight: `${contentHeight}px`, }); } }) .exec(); }, getNotDealList() { getNotDealLists().then((res) => { if (res.length > 0) { this.setData({ popupList: res, isShowPopup: true, NoteTitle: res[0].title, }); } else { this.setData({ popupList: [], isShowPopup: false, NoteTitle: "", }); } }); }, showFollowPopup() { this.getNotDealList(); }, onVisibleChange(e: { detail: { visible: any } }) { this.setData({ isShowPopup: e.detail.visible, }); }, async goComplete(e: { currentTarget: { dataset: { page: string; id: number; title: string } }; }) { if (this.data.isCompleting) { return; } this.setData({ isCompleting: true }); try { const { title } = e.currentTarget.dataset; let page = e.currentTarget.dataset.page; let id = e.currentTarget.dataset.id; if (page === "/module/chats/pages/index/index") { if (title === "健康评估") { wx.setStorageSync("isAnalysis", 4); toChats("questionnaire", 2); } else { wx.setStorageSync("isAnalysis", 2); wx.setStorageSync("workId", id); wx.navigateTo({ url: `${page}?component=questionnaire&messageType=1&id=${id}`, }); } } else if (page === "/module/article/pages/science-info/science-info") { try { const res = await Get(`/psarticle/clickPsaNotice`, { params: { noticeSendRecordId: id }, }); const url = res?.data; const item = { url, }; wx.navigateTo({ url: `${page}`, }).then((res) => { res.eventChannel.emit("load", item); }); } catch (error) { console.log(error); } } else { const status = 'pending'; // 随访 wx.navigateTo({ url: `${page}?id=${id}&status=${status}` }); } } finally { setTimeout(() => { this.setData({ isCompleting: false }); }, 500); } }, // 随访评估报告已出 goSeeFollowReport() { wx.navigateTo({ url: "/module/follow/pages/evaluation/report" }); }, async load(forceLogin = false) { try { await login(forceLogin); wx.showLoading({ title: "加载中" }); const { patient } = await getPatients(/*this.data.patientId*/); // if (!patient) await toCertificationPage(); if (!patient) { /*if (wx.getStorageSync("doctorId")) { toCertificationPage(); }*/ this.setData({ "healthReport.loading": false, isShowComplete: true, }); } else { this.setData({ patient }); this.observerPatient(patient); } wx.hideLoading(); } catch (error: any) { await wx .showModal({ title: `加载失败`, content: `${error?.errMsg ?? error?.message ?? ""}`, showCancel: false, confirmText: `重新加载`, }) .catch(() => { }); await this.load(true); return; } // 加载健康宣教的文章 this.loadScienceList(true); if (!this.data._loaded) { getSolarTerms() .then((solarTerms) => { this.setData({ solarTerms }); }) .catch(() => { }); this.setData({ _loaded: true }); } }, async _getHealthReport() { wx.showLoading({ title: "加载中" }); this.setData({ "healthReport.loading": true }); try { const data = await healthReportMethod(); if (!data) { this.setData({ isShowComplete: true, }); } else { this.setData({ isShowComplete: false, }); } this.setData({ "healthReport.data": data, "healthReport.loading": false, healthId: data?.healthAnalysisReportId, }); let arr2 = [ [ { title: "健康状态", value: data?.willillStateName ? `${data?.willillStateName}` : "", }, { title: "程度", value: data?.willillDegreeName ? `${data?.willillDegreeName}` : "", }, { title: "表现", value: data?.willillFunctionName ? `${data?.willillFunctionName}` : "", }, ], [ { title: "中医证素", value: data?.factorItemSummary ? `${data?.factorItemSummary}` : "", }, ], [ { title: "体质", value: data?.constitutionGroupName ? `${data?.constitutionGroupName}` : "", }, ], ]; this.setData({ statusList: arr2, }); } catch (error: any) { wx.showToast({ title: error.errMsg || "加载失败", icon: "none", }); this.setData({ "healthReport.data": [], "healthReport.loading": false, "healthReport.message": error.errMsg, healthId: "", }); } wx.hideLoading(); }, async _getAbnormalHealthIndex() { this.setData({ "healthIndex.loading": true }); try { const data = await healthIndexMethod(); this.setData({ "healthIndex.data": data .map((item: AnyObject) => item.abnormalDesc) .filter(Boolean), "healthIndex.loading": false, }); } catch (error: any) { this.setData({ "healthIndex.data": [], "healthIndex.loading": false, "healthIndex.message": error.errMsg, }); } }, onBodyModel(event: WechatMiniprogram.TouchEvent) { if (event.detail?.position === "LB") { this.toReportPage(); } else if (event.detail?.position === "item0") { const report = this.data.healthReport.data as unknown as AnyObject; this.setData({ position: { LT: [ "willillState", "willillDegree", "willillSocial", "willillFunction", ] .map((key) => { const title = report[`${key}Name`]; const description = report[`${key}Description`]; return title || description ? { title, description } : null; }) .filter(Boolean), }, }); this.showDraggableSheet(); } else if (event.detail?.position === "item2") { const report = this.data.healthReport.data as unknown as AnyObject; const get = (key: string) => ({ [key]: report[key] }); this.setData({ position: { RT: { ...get("constitutionGroupName"), ...get("constitutionGroupDefinition"), ...get("faceImg"), ...get("faceAnalysisResult"), ...get("tongueAnalysisResult"), ...get("upImg"), ...get("downImg"), }, }, }); this.showDraggableSheet(); } else if (event.detail?.position === "item1") { const report = this.data.healthReport.data as unknown as AnyObject; const get = (key: string) => ({ [key]: report[key] }); this.setData({ position: { RB: { ...get("diagnoseSyndromeSummary"), ...get("diagnoseSyndromes"), ...get("factorItemSummary"), ...get("factorItems"), }, }, }); this.showDraggableSheet(); } else if (event.detail?.position === "CT") { this.setData({ position: { CT: this.data.healthIndex.data.map( (item, index) => `${index + 1}、${item}` ), }, }); this.showDraggableSheet(); } }, tabValue() { this.setData({ position: { CT: this.data.healthIndex.data.map( (item, index) => `${index + 1}、${item}` ), }, }); this.showDraggableSheet(); }, initFabAnimated() { (this).applyAnimatedStyle(".fab-wrapper", () => { "worklet"; return { right: `${Math.min(offset.value, 36) - 36}px` }; }); (this).applyAnimatedStyle(".fab-1", () => { "worklet"; return { transform: `translateY(${-offset.value}px)` }; }); (this).applyAnimatedStyle(".fab-2", () => { "worklet"; return { transform: `translateX(${-offset.value}px) translateY(${-offset.value / 2 }px)`, }; }); (this).applyAnimatedStyle(".fab-3", () => { "worklet"; return { transform: `translateX(${-offset.value}px) translateY(${offset.value / 2 }px)`, }; }); (this).applyAnimatedStyle(".fab-4", () => { "worklet"; return { transform: `translateY(${offset.value}px)` }; }); }, onFabTap() { const value = Math.abs(offset.value - 72); offset.value = timing( value, { duration: 500, easing: (Easing).linear }, () => { "worklet"; if (offset.value > 0) offset.value = 72; } ); }, async toChatsPage() { if (!this.data.patient?.patientId) { try { await this.load(); } catch (error: any) { wx.showModal({ title: "出错了", content: error?.errMsg ?? error?.message ?? "错误,请重试", showCancel: false, }); return; } } const page = "/module/chats/pages/index/index"; wx.navigateTo({ url: `${page}?component=guide&isShowGuide=true`, }); wx.setStorageSync("isAnalysis", 3); }, toSciencePage() { wx.navigateTo({ url: `/module/article/pages/science-list/science-list` }); }, async toReportPage() { // const { patient } = await getPatients(/*this.data.patientId*/); if (!this.data.patient) await toCertificationPage(); else { const id = this.data.healthId; if (id) wx.navigateTo({ url: `/module/health/pages/report/report?id=${id}` }); else wx.showToast({ title: "暂无分析报告", icon: "none" }); } }, onDraggableSizeUpdate(e: any) { "worklet"; if (e.pixels < 1) { wx.worklet.runOnJS(this.hideDraggableSheet.bind(this))(); } }, showDraggableSheet() { getDraggableSheetContext.call(this).scrollTo({ size: 0.5, pixels: 600, animated: true, duration: 300, easingFunction: "ease", }); this.setData({ sheet: true }); }, hideDraggableSheet(event?: any) { if (event) { getDraggableSheetContext.call(this).scrollTo({ size: 0, animated: true, duration: 300, easingFunction: "ease", }); } this.setData({ position: {}, sheet: false }); }, async loadScienceList(reset = false) { if (this.data.scienceListLoading) { return; } if (!reset && !this.data.scienceListHasMore) { return; } if (reset) { this.setData({ scienceListPage: 1, scienceListHasMore: true, scienceList: [], leftColumnList: [], rightColumnList: [], }); } this.setData({ scienceListLoading: true }); try { const page = reset ? 1 : this.data.scienceListPage; const { data, total, page: currentPage, } = await getShortScienceList(page, this.data.scienceListSize); const newList = reset ? data : [...this.data.scienceList, ...data]; const hasMore = newList.length < total; this.setData({ scienceList: newList, scienceListTotal: total, scienceListPage: currentPage + 1, scienceListHasMore: hasMore, scienceListLoading: false, }); this.distributeCardsToColumns(newList, reset); } catch (error) { this.setData({ scienceListLoading: false }); wx.showToast({ title: "加载失败,请重试", icon: "none", }); } }, // 下拉刷新 async onRefreshScienceList() { this.setData({ refreshing: true }); await this.loadScienceList(true); this.setData({ refreshing: false }); }, // 上拉加载更多 onLoadMoreScienceList() { if (this.data.scienceListHasMore && !this.data.scienceListLoading) { this.loadScienceList(false); } }, // 将卡片分配到两列,实现瀑布流布局 distributeCardsToColumns(list: AnyArray, reset = false) { // 如果是重置,使用空数组;否则过滤出新增的卡片 const itemsToDistribute = reset ? list : list.filter( (item: any) => !this.data.leftColumnList.some( (existing: any) => existing.id === item.id ) && !this.data.rightColumnList.some( (existing: any) => existing.id === item.id ) ); if (itemsToDistribute.length === 0) return; // 计算当前两列的高度(重置时两列已为空,高度为0) let leftHeight = reset ? 0 : this.data.leftColumnList.reduce( (sum: number, item: any) => sum + this.estimateCardHeight(item), 0 ); let rightHeight = reset ? 0 : this.data.rightColumnList.reduce( (sum: number, item: any) => sum + this.estimateCardHeight(item), 0 ); const leftColumn = reset ? [] : [...this.data.leftColumnList]; const rightColumn = reset ? [] : [...this.data.rightColumnList]; itemsToDistribute.forEach((item: any) => { const estimatedHeight = this.estimateCardHeight(item); if (leftHeight <= rightHeight) { leftColumn.push(item); leftHeight += estimatedHeight; } else { rightColumn.push(item); rightHeight += estimatedHeight; } }); this.setData({ leftColumnList: leftColumn, rightColumnList: rightColumn, }); }, estimateCardHeight(item: any): number { let height = 0; if (item.briefImg) { const imgMinHeight = 120; const imgMaxHeight = 260; const imgHeightRange = imgMaxHeight - imgMinHeight; const idHash = item.id ? String(item.id) .split("") .reduce((acc: number, char: string) => acc + char.charCodeAt(0), 0) : 0; const imgHeight = imgMinHeight + (idHash % imgHeightRange); height += imgHeight; } const title = item.title || ""; const titleLength = title.length; const charsPerLine = 12; const titleLines = Math.min(Math.ceil(titleLength / charsPerLine), 3); const titleHeight = titleLines * 24; const contentPadding = 24; const metaHeight = 40; height += titleHeight + contentPadding + metaHeight; height += 12; height += 4; if (!item.briefImg) { const minContentHeight = titleHeight + contentPadding + metaHeight + 12 + 4; if (height < minContentHeight) { height = minContentHeight; } } return Math.round(height); }, observerPatient(model: { patientId: string; sex: "0" | "1" }) { wx.setStorageSync("patientId", model.patientId); this._getHealthReport(); this._getAbnormalHealthIndex(); const patientIcon = { 0: "gender-male", 1: "gender-female" }[model.sex]; const patientIconColor = { 0: "#0f40f5", 1: "#E560B3" }[model.sex]; this.setData({ patientIcon, patientIconColor }); getPatientDescription(model).then((patientDescription) => { this.setData({ patientDescription }); }); // 获取未处理随访列表 this.getNotDealList(); // 获取调养计划 this.getCareLists(); }, // 没有健康分析去做健康分析 goHealthAnalyze() { wx.redirectTo({ url: `/module/chats/pages/index/index?component=guide&isShowGuide=true`, }); wx.setStorageSync("showGuideActive", 1); wx.setStorageSync("isAnalysis", 3); }, // 检查咨询状态 async checkConsultationStatus() { //获取正在咨询中的咨询id const res = await Post("/consultManage/getConsultIng"); const isConsulting = !!res.data?.id; const hasNewMessage = res.data?.patientUnreadCount > 0; // 是否有新消息 this.setData({ hasNewMessage }); if (isConsulting) { // 保存咨询id,标记咨询未结束 wx.setStorageSync("consultId", res.data); wx.setStorageSync("consultEnded", false); this.setData({ isConsulting: true, }); } else { // 没有咨询,清理相关数据 wx.setStorageSync("consultEnded", true); wx.removeStorageSync("consultId"); this.setData({ isConsulting: false, hasNewMessage: false, }); } }, // 跳转到咨询页面 goToConsultation() { // 跳转之后 未读的消息变为已读 就没有最新消息了 不显示绿点 this.setData({ hasNewMessage: false }); // 跳转到咨询页面,显示 message-consult 组件 wx.navigateTo({ url: `/module/chats/pages/index/index?component=questionnaire&messageType=3`, }); wx.setStorageSync("isAnalysis", 5); }, async isGoPunchcard(e: any) { const { id, signintime } = e.currentTarget.dataset; // 已经打卡了 if (signintime) { // 已打卡 跳转到打卡页面 wx.navigateTo({ url: `/module/article/pages/punch-card/punch-card?id=${id}`, }); } else { // 打卡 const cardId = e.currentTarget.dataset.id; await addPatientOnlineRecordClockIn(cardId); wx.showToast({ title: "打卡成功", icon: "success", duration: 1500, }); await this.refreshCareListsWithState(); } }, async refreshCareListsWithState() { // 保存当前的展开状态 const currentExpandedStates = this.data.displayList.map((item: any) => ({ id: item.id, expanded: item.expanded, carouselMediaList: item.carouselMediaList, })); // 获取新数据 const res = await getCareList(); if (res && res.length > 0) { res.forEach((item: any) => { const oldItem = currentExpandedStates.find( (state) => state.id === item.id ); if (oldItem && oldItem.carouselMediaList) { item.carouselMediaList = oldItem.carouselMediaList; } else { item.carouselMediaList = []; // 添加photo if (item.photo) { item.carouselMediaList.push({ type: "image", src: item.photo, }); } // 添加itemImgFirst if (item?.itemImgFirst) { item.carouselMediaList.push({ type: "image", src: item.itemImgFirst, }); } // 添加itemVideoFirst if (item?.itemVideoFirst) { item.carouselMediaList.push({ type: "video", src: item.itemVideoFirst, }); } } }); // 更新 careList this.setData({ careList: res, }); // 更新 displayList 并恢复展开状态 const { allExpanded } = this.data; let newDisplayList: any[] = allExpanded || res.length <= 4 ? res : res.slice(0, 4); // 恢复展开状态 newDisplayList = newDisplayList.map((item: any) => { const savedState = currentExpandedStates.find( (state) => state.id === item.id ); if (savedState) { return { ...item, expanded: savedState.expanded, carouselMediaList: savedState.carouselMediaList || item.carouselMediaList, }; } return item; }); this.setData({ displayList: newDisplayList, }); console.log(this.data.displayList, "this.data.displayList") } }, /** * 轮播组件进入/退出全屏时,隐藏/显示底部 tabbar,防止遮挡视频进度条 */ onCarouselFullscreenChange(e: { detail?: { fullScreen?: boolean } }) { const fullScreen = !!e.detail?.fullScreen; this.setData({ tabbarHidden: fullScreen, }); }, });