From 382f6b98110512f5e1a60235b694ba698ab6b5b8 Mon Sep 17 00:00:00 2001
From: zhu <1812073942@qq.com>
Date: Fri, 27 Mar 2026 17:55:18 +0800
Subject: [PATCH] 1
---
.cloudbase/container/debug.json | 1 -
app.js | 1 -
app.json | 11 +-
app.scss | 2 +
custom-tab-bar/index.js | 5 +
pages/chat/index.js | 292 +++++++++++++++++++++++++++++++
pages/chat/index.json | 6 +
pages/chat/index.scss | 179 +++++++++++++++++++
pages/chat/index.wxml | 103 +++++++++++
pages/chat/makedown.scss | 17 ++
pages/chat/read.md | 15 ++
pages/expert/index.js | 68 +++++++
pages/expert/index.scss | 171 +++++++++++++++++-
pages/expert/index.wxml | 82 ++++++++-
pages/home/index.js | 36 +++-
pages/home/index.scss | 7 +-
pages/home/index.wxml | 68 +++++--
pages/joinFlow/access/index.js | 31 ----
pages/joinFlow/access/index.json | 4 -
pages/joinFlow/access/index.scss | 80 ---------
pages/joinFlow/access/index.wxml | 40 -----
pages/joinFlow/manual/index.js | 36 ----
pages/joinFlow/manual/index.json | 4 -
pages/joinFlow/manual/index.scss | 8 -
pages/joinFlow/manual/index.wxml | 26 ---
pages/joinFlow/person/index.js | 130 ++++++++++++--
pages/joinFlow/person/index.scss | 7 +-
pages/joinFlow/person/index.wxml | 156 +++++++++++------
pages/system/welcome/index.js | 5 +-
project.config.json | 2 +-
project.private.config.json | 16 +-
utils/common.js | 16 ++
utils/request.js | 67 ++++++-
utils/wxs/comment.wxs | 90 +++++++---
34 files changed, 1406 insertions(+), 376 deletions(-)
delete mode 100644 .cloudbase/container/debug.json
create mode 100644 pages/chat/index.js
create mode 100644 pages/chat/index.json
create mode 100644 pages/chat/index.scss
create mode 100644 pages/chat/index.wxml
create mode 100644 pages/chat/makedown.scss
create mode 100644 pages/chat/read.md
delete mode 100644 pages/joinFlow/access/index.js
delete mode 100644 pages/joinFlow/access/index.json
delete mode 100644 pages/joinFlow/access/index.scss
delete mode 100644 pages/joinFlow/access/index.wxml
delete mode 100644 pages/joinFlow/manual/index.js
delete mode 100644 pages/joinFlow/manual/index.json
delete mode 100644 pages/joinFlow/manual/index.scss
delete mode 100644 pages/joinFlow/manual/index.wxml
diff --git a/.cloudbase/container/debug.json b/.cloudbase/container/debug.json
deleted file mode 100644
index 0d44458..0000000
--- a/.cloudbase/container/debug.json
+++ /dev/null
@@ -1 +0,0 @@
-{"containers":[],"config":{}}
\ No newline at end of file
diff --git a/app.js b/app.js
index e5ae361..01b45ed 100644
--- a/app.js
+++ b/app.js
@@ -1,4 +1,3 @@
-// app.js
App({
towxml: require('/towxml/index'),
globalData: {
diff --git a/app.json b/app.json
index a23e110..b27272f 100644
--- a/app.json
+++ b/app.json
@@ -3,16 +3,18 @@
"pages/system/welcome/index",
"pages/home/index",
"pages/test/index",
- "pages/joinFlow/access/index",
- "pages/joinFlow/manual/index",
"pages/joinFlow/person/index",
- "pages/expert/index"
+ "pages/expert/index",
+ "pages/chat/index"
],
"tabBar": {
"custom": true,
"list": [
{
"pagePath": "pages/home/index"
+ },
+ {
+ "pagePath": "pages/chat/index"
},
{
"pagePath": "pages/expert/index"
@@ -65,6 +67,7 @@
"t-cascader": "tdesign-miniprogram/cascader/cascader",
"t-form": "tdesign-miniprogram/form/form",
"t-form-item": "tdesign-miniprogram/form-item/form-item",
- "t-divider": "tdesign-miniprogram/divider/divider"
+ "t-divider": "tdesign-miniprogram/divider/divider",
+ "t-loading": "tdesign-miniprogram/loading/loading"
}
}
\ No newline at end of file
diff --git a/app.scss b/app.scss
index f301de9..af67f45 100644
--- a/app.scss
+++ b/app.scss
@@ -15,7 +15,9 @@ navigator {
page {
+ --td-brand-color: rgba(0, 106, 106, 1);
--background: linear-gradient(135deg, rgba(0, 33, 33, 1), rgba(0, 106, 106, 1));
+ --area-bottom: calc(130rpx + env(safe-area-inset-bottom));
.t-navbar__capsule::before {
display: none;
}
diff --git a/custom-tab-bar/index.js b/custom-tab-bar/index.js
index bb31e41..1fbe696 100644
--- a/custom-tab-bar/index.js
+++ b/custom-tab-bar/index.js
@@ -19,6 +19,11 @@ Component({
label: '首页',
icon: 'home'
},
+ {
+ path: "/pages/chat/index",
+ label: 'AI助手',
+ icon: 'chat-bubble'
+ },
{
path: "/pages/expert/index",
label: '专家服务',
diff --git a/pages/chat/index.js b/pages/chat/index.js
new file mode 100644
index 0000000..6999467
--- /dev/null
+++ b/pages/chat/index.js
@@ -0,0 +1,292 @@
+import request, { streamRequest } from "@/utils/request";
+import { copyText } from "@/utils/common"
+let outTimer; //输出定时器
+let outStrList = [];//输出字符串数组
+const app = getApp()
+
+let chat_uuid
+//工具
+let toolText = ''
+let toolInfo = {}
+Page({
+ data: {
+ chatList: [], //会话记录
+ aiStatus: 3,//1表示接口响应中,2表示接口响应完毕,3表示完全输出完毕
+ keyboardBottom: 0, //底部键盘高度
+ scrollTop: 0, //滚动条位置
+ inputText: '',//输入框内容
+ },
+ onLoad() {
+ let str = `您好!我是术极守护AI助手 🤖\n\n我可以为您解答术后康复相关的问题。请注意,我只能提供基于康复指南的一般性建议,如遇紧急情况请立即就医或联系您的主治医生。`
+ let mdResult = app.towxml(str, 'markdown', {
+ base: "www.xxx.com",
+ });
+ let list = [
+ {
+ loading: false,
+ end: true,
+ chat_type: 2,
+ md_content: mdResult,
+ chat_content: str,
+ quick_btn: [
+ { text: '🩹伤口有轻微渗液怎么办?' },
+ { text: '🌡️术后轻微发烧正常吗?' },
+ { text: '🚿什么时候可以洗澡?' },
+ { text: '🥗饮食需要注意什么?' }
+ ]
+ }
+ ]
+ this.setData({
+ chatList: list
+ })
+ },
+ onShow() {
+ this.getTabBar((tabBar) => {
+ tabBar.setData({
+ selected: 'AI助手',
+ })
+ })
+ },
+ //监听键盘弹出
+ bindkeyboardheightchange(event) {
+ let height = event.detail.height
+ let { keyboardBottom } = this.data
+ let scrollTop = 0
+ //获取当前滚动距离
+ const query = wx.createSelectorQuery().in(this)
+ query.select(".silder").scrollOffset()
+ query.exec(function (res) {
+ scrollTop = res[0].scrollTop
+ })
+ this.setData({
+ keyboardBottom: height > 0 ? height - 50 : keyboardBottom,
+ }, () => {
+ if (height > 0) {
+ setTimeout(() => {
+ this.setData({
+ scrollTop: scrollTop + height
+ })
+ }, 300)
+ }
+ })
+ },
+ //键盘失去焦点
+ bindkeyboardBlur() {
+ let { scrollTop, keyboardBottom } = this.data
+ let endScrollTop = scrollTop - keyboardBottom
+ this.setData({
+ keyboardBottom: 0
+ }, () => {
+ this.setData({
+ scrollTop: endScrollTop
+ })
+ })
+ },
+ //监听输入框内容
+ changeInput(e) {
+ let value = e.detail.value
+ this.setData({
+ inputText: value
+ })
+ },
+ async handQuick(e) {
+ let { data } = e.currentTarget.dataset
+ this.pushUserTemplate(data.text)
+ this.sendMessage(data.text)
+
+ },
+
+ // 文字提交发送
+ submitInput() {
+ let { inputText, aiStatus } = this.data
+ if (!inputText.trim() == '' && aiStatus) {
+ console.log('111--');
+ this.pushUserTemplate(inputText)
+ this.sendMessage(inputText)
+ }
+ },
+ //发送聊天
+ async sendMessage(text) {
+ let { chatList, aiStatus } = this.data
+ if (aiStatus == 3) {
+ let that = this
+ //初始化变量
+ toolText = ''
+ toolInfo = {}
+ chat_uuid = String(new Date().getTime())
+ this.setData({
+ aiStatus: 1
+ })
+ //输出
+ this.timerOutput()
+ //请求
+ streamRequest("/ai/chat", {
+ message: text,
+ chat_uuid: chat_uuid,
+ }, this.onChunkReceived).then(() => {
+ console.log('-------------成功-----------');
+ if (this.data.aiStatus != 3) {
+ that.setData({
+ aiStatus: 2
+ })
+ }
+ }).catch(() => {
+ console.log("------失败1---------");
+ that.data.chatList.at(-1).loading = false
+ that.setData({
+ aiStatus: 3,
+ chatList: chatList
+ })
+ })
+ }
+ },
+
+ //填充用户的聊天数据
+ pushUserTemplate(text) {
+ let { chatList } = this.data
+ let userItem = {
+ loading: false,
+ chat_type: 1,
+ con_type: 1,
+ chat_content: text,
+ md_content: '',
+ }
+ let aiItem = {
+ chat_type: 2,
+ chat_content: '',
+ md_content: '',
+ con_type: 1,
+ loading: true,
+ }
+ chatList.push(userItem)
+
+ chatList.push(aiItem)
+
+ //要修改的数据
+ let setData = {
+ chatList,
+ scrollTop: 80000,
+ inputText: ''
+ }
+ this.setData(setData, () => {
+ this.setData({
+ scrollTop: 80000
+ })
+ })
+ },
+ //只填充ai的默认回复
+ pushAiTemplate(text, options = {}) {
+ let { chatList } = this.data
+ let mdResult = app.towxml(text, 'markdown', {
+ base: "www.xxx.com",
+ });
+ let aiItem = {
+ chat_type: 2,
+ chat_content: text,
+ md_content: mdResult,
+ con_type: 1,
+ quick_btn: options.quick_btn || [],
+ ...options
+ }
+ chatList.push(aiItem)
+ //要修改的数据
+ let setData = {
+ chatList,
+ scrollTop: 80000,
+ inputText: ''
+ }
+ this.setData(setData, () => {
+ this.setData({
+ scrollTop: 80000
+ })
+ })
+ },
+
+ //定时器输出
+ timerOutput() {
+ let { chatList } = this.data
+ let that = this
+ clearInterval(outTimer)
+ outStrList = []
+ let lastChat = this.data.chatList.at(-1)
+ //定时
+ outTimer = setInterval(async () => {
+ if ((outStrList.length == 0) && that.data.aiStatus == 2) {
+ clearInterval(outTimer)
+ lastChat.end = true
+ //如果有工具,设置工具对象
+ let text = lastChat.chat_content
+ // 上传AI响应结果
+ if (text) {
+ await request.post("/ai/history/upload", {
+ chat_content: text,
+ chat_uuid: chat_uuid,
+ })
+ }
+ //调用工具
+ if (toolText) { }
+ that.setData({
+ chatList,
+ aiStatus: 3
+ })
+
+ } else if (outStrList.length > 0) {
+ let firstValue = outStrList.shift();
+ lastChat.chat_content += firstValue
+ //转换md
+ let mdResult = app.towxml(lastChat.chat_content, 'markdown', {
+ base: "www.xxx.com",
+ });
+ lastChat.md_content = mdResult
+ lastChat.loading = false
+ that.setData({
+ chatList: chatList,
+ scrollTop: 80000
+ })
+ }
+ }, 50)
+ },
+ //流回调
+ onChunkReceived(data) {
+ data.forEach((item) => {
+ let value = item?.choices[0].delta.content ?? ''
+ let call = item?.choices[0].delta.tool_calls
+ //储存tool的id和名称
+ if (call) {
+ if (call[0].id) {
+ toolInfo.tool_call_id = call[0].id
+ toolInfo.name = call[0].function.name
+ }
+ let tool = call[0].function.arguments ?? ''
+ toolText += tool
+ }
+ if (value) {
+ outStrList.push(value)
+ }
+ })
+ },
+ //停止
+ async stopMessage() {
+ clearInterval(outTimer)
+ let lastChat = this.data.chatList.at(-1)
+ lastChat.chat_status = 2
+ this.setData({
+ aiStatus: 3,
+ chatList: this.data.chatList
+ })
+ await request.post("/ai/history/upload", {
+ chat_content: lastChat.chat_content || 'nocontent',
+ chat_status: 2,
+ chat_uuid: chat_uuid
+ })
+ },
+ //复制文字
+ copy(e) {
+ let { content, chat_content } = e.currentTarget.dataset.text
+ console.log(e);
+ if (!content) {
+ content = chat_content
+ }
+ copyText(content)
+ },
+})
\ No newline at end of file
diff --git a/pages/chat/index.json b/pages/chat/index.json
new file mode 100644
index 0000000..8e2df44
--- /dev/null
+++ b/pages/chat/index.json
@@ -0,0 +1,6 @@
+{
+ "usingComponents": {
+ "towxml": "/towxml/towxml"
+ },
+ "navigationStyle": "custom"
+}
\ No newline at end of file
diff --git a/pages/chat/index.scss b/pages/chat/index.scss
new file mode 100644
index 0000000..95cadff
--- /dev/null
+++ b/pages/chat/index.scss
@@ -0,0 +1,179 @@
+@import "./makedown.scss";
+
+.c-container {
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ padding-bottom: var(--area-bottom);
+
+ .t-navbar__content {
+ backdrop-filter: blur(18px);
+ }
+}
+
+.silder {
+ overflow: auto;
+ flex: 1;
+ padding: 30rpx 0;
+ box-sizing: border-box;
+
+ .chat-item {
+ padding: 10rpx 30rpx;
+
+ &+.chat-item {
+ margin-top: 30rpx;
+ }
+
+ .lawyer-info {
+ margin-bottom: 20rpx;
+ font-size: 0.75rem;
+
+ image {
+ width: 50rpx;
+ height: 50rpx;
+ border-radius: 50%;
+ margin-right: 10rpx;
+ display: block;
+ }
+ }
+
+ .chat-image {
+ width: 250rpx;
+ height: 250rpx;
+ border-radius: 20rpx;
+ }
+
+ .chat-message {
+ max-width: calc(100% - 100rpx);
+ min-height: 60rpx;
+ width: fit-content;
+ padding: 20rpx;
+ border-radius: 10rpx;
+ font-size: 0.9rem;
+ overflow: hidden;
+
+ .loading {
+ height: 40rpx;
+ width: 40rpx;
+ border-radius: 50%;
+ box-shadow: inset 0 0 0 var(--td-brand-color);
+ animation: load 2s linear infinite alternate;
+ }
+
+ .stop-tip {
+ margin-top: 20rpx;
+ font-size: 0.64rem;
+ color: var(--text-3);
+ }
+
+ .m-footer {
+ margin-top: 10rpx;
+
+ .tip {
+ @extend .stop-tip;
+ margin-top: 0;
+ opacity: 0.1;
+ }
+
+ .sound-icon {
+ color: var(--text-2);
+ font-size: 1rem;
+ }
+ }
+ }
+
+ .quick-warpper {
+ font-size: 0.75rem;
+ gap: 30rpx;
+ margin-top: 20rpx;
+ display: flex;
+ flex-wrap: wrap;
+
+ .quick-item {
+ background-color: white;
+ padding: 10rpx 20rpx;
+ border-radius: 50rpx;
+ border: 1px solid #dfdddd;
+
+ &.color {
+ color: white;
+ border-color: transparent;
+ ;
+ }
+ }
+ }
+ }
+
+ .ai-msg {
+ .chat-message {
+ background-color: white;
+ border-radius: 20rpx 30rpx 30rpx 10rpx;
+ box-shadow: 0 0 15rpx #e2e2e2;
+ }
+
+ }
+
+ .user-msg {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+
+ .chat-message {
+ background-color: var(--td-brand-color);
+ color: white;
+ border-radius: 30rpx 30rpx 0 30rpx;
+ }
+ }
+}
+
+.bottom-position {
+ margin: 0 30rpx;
+ position: relative;
+
+ //输入框
+ .input-warpper {
+ box-shadow: 0 0 15rpx #e2e2e2;
+ padding: 20rpx 30rpx;
+ background-color: white;
+ border-radius: 50rpx;
+
+ input {
+ flex: 1;
+ }
+
+
+ .push-btn {
+ border-radius: 50%;
+ width: 65rpx;
+ height: 65rpx;
+ color: var(--text-3);
+ transition: opacity 0.3s;
+
+ &.active-push {
+ background-color: var(--td-brand-color);
+ color: white;
+ }
+ }
+
+ .stop-btn {
+ font-size: 65rpx;
+ color: var(--td-brand-color);
+ }
+ }
+}
+
+//占位
+.empty {
+ transition: height 0.3s;
+}
+
+//ai响应loading
+@keyframes load {
+ 0% {
+ box-shadow: inset -20rpx 40rpx 0 var(--td-brand-color);
+ }
+
+ 100% {
+ box-shadow: inset 20rpx -40rpx 0 var(--td-brand-color);
+ }
+}
\ No newline at end of file
diff --git a/pages/chat/index.wxml b/pages/chat/index.wxml
new file mode 100644
index 0000000..cc122ee
--- /dev/null
+++ b/pages/chat/index.wxml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+ AI助手
+
+
+
+
+
+
+
+
+ {{item.tool}}
+
+
+ {{item.chat_content}}
+
+
+
+
+ (已停止)
+
+
+
+
+
+
+ {{quick.text}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/chat/makedown.scss b/pages/chat/makedown.scss
new file mode 100644
index 0000000..964f6be
--- /dev/null
+++ b/pages/chat/makedown.scss
@@ -0,0 +1,17 @@
+.h2w__main,
+.h2w__p {
+ padding: 0 !important;
+ margin: 0 !important;
+ font-size: 0.9rem;
+
+}
+
+.h2w__li {
+ margin-top: 20rpx;
+}
+
+
+.h2w__h3 {
+ font-size: 32rpx !important;
+ margin-top: 20rpx !important;
+}
\ No newline at end of file
diff --git a/pages/chat/read.md b/pages/chat/read.md
new file mode 100644
index 0000000..3c4e09d
--- /dev/null
+++ b/pages/chat/read.md
@@ -0,0 +1,15 @@
+ 聊天列表类型
+``` typescript
+interface ChatType{
+ loading: boolean, // 是否开始响应
+ end:boolean,//响应输出完成
+ chat_type: 1 | 2, // 1用户,2ai普通响应
+ chat_content: string, //文本内容
+ md_content: string, //md格式
+ con_type:1, //消息类型,1文本,2图片
+ tool:string, //用工具时的默认内容,为空代表不是工具
+ chat_status?:number, //2停止
+ quick_btn:[], //快捷菜单按钮,为空不显示
+ drugList:[],//药品信息,只用来设置提醒
+}
+```
\ No newline at end of file
diff --git a/pages/expert/index.js b/pages/expert/index.js
index 509cf71..0248814 100644
--- a/pages/expert/index.js
+++ b/pages/expert/index.js
@@ -1,9 +1,77 @@
+import request from "@/utils/request"
+
+const app = getApp()
Page({
+ data: {
+ list: [
+ {
+ s: "李",
+ name: "李医生",
+ title: "主任医师 · 骨科专家",
+ desc: "20年临床经验"
+ },
+ {
+ s: "王",
+ name: "王医生",
+ title: "副主任医师 · 康复医学",
+ desc: "15年临床经验"
+ },
+ {
+ s: "张",
+ name: "张护士长",
+ title: "主管护师 · 伤口护理",
+ desc: "18年护理经验"
+ }
+ ],
+ count: 0
+ },
onShow() {
+ let userInfo = app.globalData.userInfo
+ this.setData({
+ count: userInfo.consult_remains
+ })
this.getTabBar((tabBar) => {
tabBar.setData({
selected: '专家服务',
})
})
+ },
+
+ async onPlay() {
+ if (this.data.count <= 0) {
+ wx.showToast({
+ title: '免费次数已用完',
+ icon: 'none'
+ });
+ return;
+ }
+ // 2. 弹窗确认
+ wx.showModal({
+ title: '拨打专家热线',
+ content: '确认拨打专家咨询电话吗?本次咨询将使用1次免费机会',
+ success: async (res) => {
+ if (res.confirm) {
+ try {
+ wx.showLoading({ title: '正在呼叫...', mask: true });
+ const info = await request.get("/expert/phone");
+ this.setData({
+ count: this.data.count - 1
+ });
+ wx.hideLoading();
+
+ // 5. 吊起拨号盘
+ if (info && info.expert_phone) {
+ wx.makePhoneCall({
+ phoneNumber: info.expert_phone,
+ });
+ } else {
+ wx.showToast({ title: '暂无专家电话', icon: 'none' });
+ }
+ } catch (error) {
+ wx.hideLoading();
+ }
+ }
+ }
+ });
}
})
\ No newline at end of file
diff --git a/pages/expert/index.scss b/pages/expert/index.scss
index 4b400bb..f8d486d 100644
--- a/pages/expert/index.scss
+++ b/pages/expert/index.scss
@@ -1,5 +1,6 @@
page {
background-color: rgba(247, 249, 252, 1);
+ padding-bottom: 200rpx;
}
.head {
@@ -47,11 +48,175 @@ page {
color: rgba(255, 255, 255, 0.8);
}
}
- .btn{
+
+ .btn {
padding: 50rpx 0;
background-color: rgba(29, 120, 116, 1);
}
- .c-2{
-
+
+ .service-card {
+ width: 100%;
+ background-color: #fff;
+ border-radius: 12px;
+ padding: 16px;
+ box-sizing: border-box;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
+ margin-top: 30rpx;
+
+ .flex-align {
+ display: flex;
+ align-items: center;
+ }
+
+ .header {
+ .icon {
+ width: 32px;
+ height: 32px;
+ background-color: #f0f5f0; // 图标背景色
+ border-radius: 50%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-right: 8px;
+ }
+
+ .title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
+ }
+
+ .content {
+ margin-top: 12px;
+
+ .row {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 6px;
+
+ .label {
+ font-size: 14px;
+ color: #666;
+ }
+
+ .time {
+ font-size: 14px;
+ font-weight: 600;
+ color: #18a74f; // 绿色
+ }
+ }
+ }
+
+ .status {
+ display: flex;
+ align-items: center;
+ margin-top: 12px;
+
+ .dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background-color: #18a74f;
+ margin-right: 6px;
+ }
+
+ .text {
+ font-size: 12px;
+ color: #18a74f;
+ }
+ }
+ }
+
+ .emergency-card {
+ background: rgba(255, 235, 238, 1);
+ border-radius: 16rpx;
+ padding: 32rpx;
+ margin-top: 30rpx;
+ gap: 30rpx;
+ display: flex;
+ align-items: flex-start;
+ --color: rgba(198, 40, 40, 1);
+ color: var(--color);
+
+
+ .icon {
+ width: 90rpx;
+ aspect-ratio: 1;
+ background-color: rgba(186, 26, 26, 0.15);
+ border-radius: 20rpx;
+ }
+
+ .t-1 {
+ font-weight: 700;
+ font-size: 34rpx;
+ margin-bottom: 20rpx;
+ }
+
+ .num {
+ font-weight: 700;
+ font-size: 40rpx;
+ }
+
+ .item {
+ font-size: 28rpx;
+ line-height: 60rpx;
+ display: flex;
+ align-items: center;
+ gap: 20rpx;
+
+ &::before {
+ content: "";
+ display: block;
+ width: 8rpx;
+ height: 8rpx;
+ background-color: var(--color);
+ border-radius: 50%;
+ }
+ }
+ }
+
+ .service {
+ background-color: white;
+ --color: black;
+
+ .icon {
+ background-color: rgba(0, 106, 106, 0.1);
+ }
+ }
+
+ .express {
+ background-color: white;
+ padding: 30rpx;
+ border-radius: 16rpx;
+ margin-top: 30rpx;
+
+ .item {
+ gap: 30rpx;
+ margin-top: 40rpx;
+
+ .icon {
+ width: 100rpx;
+ aspect-ratio: 1;
+ border-radius: 50%;
+ color: white;
+ font-weight: 700;
+ background: linear-gradient(rgba(29, 120, 116, 1), rgba(46, 139, 139, 1));
+ }
+
+ .t-1 {
+ font-weight: 700;
+ }
+
+ .t-2 {
+ font-size: 28rpx;
+ color: rgba(69, 70, 78, 1);
+ }
+
+ .t-3 {
+ font-size: 24rpx;
+ color: rgba(69, 70, 78, 1);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/pages/expert/index.wxml b/pages/expert/index.wxml
index 79a9a36..1de41b8 100644
--- a/pages/expert/index.wxml
+++ b/pages/expert/index.wxml
@@ -14,21 +14,91 @@
可咨询次数
- 3
+ {{count}}
- 本月剩余 3 次免费咨询机会
+ 本月剩余 {{count}} 次免费咨询机会
+ icon="call-1"
+ bind:tap="onPlay">
一键拨打专家电话
-
-
-
+
+
+
+
+
+ 工作日
+ 09:00 - 21:00
+
+
+ 周末及节假日
+ 10:00 - 18:00
+
+
+
+
+
+ 当前服务中
+
+
+
+
+
+
+
+
+ 紧急情况处理
+ 如遇以下紧急情况,请立即拨打
+ 120 或前往急诊
+
+
+ 大量出血或伤口裂开
+ 高热不退(体温≥39°C)
+ 剧烈疼痛无法缓解
+ 呼吸困难或胸痛
+ 意识模糊或昏迷
+
+
+
+
+
+
+
+
+
+ 服务说明
+
+
+ 每次通话时长不超过15分钟
+ 专家会根据您的情况提供专业建议
+ 复杂问题可能需要您到院面诊
+ 建议提前准备好相关检查报告
+ 咨询记录会同步到您的康复档案
+
+
+
+
+
+ 专家团队
+
+ {{item.s}}
+
+ {{item.name}}
+ {{item.title}}
+ {{item.desc}}
+
\ No newline at end of file
diff --git a/pages/home/index.js b/pages/home/index.js
index c686d29..2c9df2a 100644
--- a/pages/home/index.js
+++ b/pages/home/index.js
@@ -1,7 +1,15 @@
+import request from "@/utils/request"
Page({
-
data: {
+ detail: {
+ overview: {},
+ tasks: [{}, {}, {}],
+ },
+ loading: true,
+ },
+ onLoad() {
+ this.init()
},
onShow() {
@@ -10,5 +18,31 @@ Page({
selected: '首页',
})
})
+ },
+
+ async init() {
+ let res = await request.get("/home")
+ this.setData({
+ detail: res,
+ loading: false,
+ })
+ },
+ //手动标记是否完成
+ handDone(e) {
+ const { data } = e.currentTarget.dataset;
+ const newTasks = this.data.detail.tasks.map(v => {
+ if (v.task_id == data.task_id) {
+ // 如果当前是 1 则变为 0,如果是 0 则变为 1
+ return { ...v, is_completed: v.is_completed == 1 ? 0 : 1 };
+ }
+ return v;
+ });
+ request.post("/home/task-record", {
+ ...data,
+ is_completed: data.is_completed == 1 ? 0 : 1
+ })
+ this.setData({
+ 'detail.tasks': newTasks
+ });
}
})
\ No newline at end of file
diff --git a/pages/home/index.scss b/pages/home/index.scss
index 5580e62..edb13a9 100644
--- a/pages/home/index.scss
+++ b/pages/home/index.scss
@@ -1,5 +1,6 @@
page {
background-color: rgba(247, 249, 252, 1);
+ padding-bottom: 160rpx;
}
.header {
@@ -78,11 +79,15 @@ page {
width: 90rpx;
aspect-ratio: 1;
border-radius: 20rpx;
- background-color: var(--color);
+ background-color: var(--back);
color: rgba(99, 63, 0, 1);
}
.content {
+ flex: 1;
+ --td-tag-default-light-color: var(--back);
+ --td-tag-default-font-color: var(--color);
+
.time {
margin-left: 20rpx;
color: rgba(69, 70, 78, 1);
diff --git a/pages/home/index.wxml b/pages/home/index.wxml
index af80c27..8a532c9 100644
--- a/pages/home/index.wxml
+++ b/pages/home/index.wxml
@@ -1,22 +1,25 @@
+
+