-
13app.json
-
219pages/home/home.js
-
90pages/home/home.wxml
-
39pages/home/home.wxss
-
BINpages/images/aiwz.png
-
BINpages/images/banner1.png
-
BINpages/images/banner2.png
-
BINpages/images/banner3.png
-
BINpages/images/banner4.png
-
BINpages/images/sc.png
-
BINpages/images/sc1.png
-
BINpages/images/sjh.png
-
52pages/index/index.js
-
5pages/index/index.json
-
28pages/index/index.wxml
-
63pages/index/index.wxss
-
189pages/login/login.js
-
4pages/login/login.json
-
90pages/login/login.wxml
-
506pages/login/login.wxss
-
20pages/logs/logs.js
-
5pages/logs/logs.json
-
7pages/logs/logs.wxml
-
16pages/logs/logs.wxss
-
162pages/map/map.js
-
38pages/map/map.wxml
-
117pages/map/map.wxss
-
2pages/market/market.js
-
0pages/market/market.json
-
2pages/market/market.wxml
-
1pages/market/market.wxss
-
346pages/personal/personal.js
-
149pages/personal/personal.wxml
-
442pages/personal/personal.wxss
-
2pagesA/pages/socialWork/socialWork.wxml
-
1pagesA/pages/socialWork/socialWork.wxss
-
299pagesA/pages/wzai/wzai.js
-
5pagesA/pages/wzai/wzai.json
-
196pagesA/pages/wzai/wzai.wxml
-
530pagesA/pages/wzai/wzai.wxss
-
2project.config.json
-
32utils/api.js
-
6utils/baseUrl.js
-
5utils/http.js
-
19utils/tool.wxs
|
After Width: 400 | Height: 400 | Size: 27 KiB |
|
Before Width: 1920 | Height: 1232 | Size: 2.1 MiB |
|
Before Width: 431 | Height: 232 | Size: 175 KiB |
|
Before Width: 600 | Height: 394 | Size: 37 KiB |
|
Before Width: 300 | Height: 200 | Size: 21 KiB |
|
After Width: 200 | Height: 200 | Size: 3.1 KiB |
|
After Width: 200 | Height: 200 | Size: 3.2 KiB |
|
After Width: 200 | Height: 200 | Size: 4.7 KiB |
@ -1,52 +0,0 @@ |
|||
// index.js
|
|||
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0' |
|||
|
|||
Component({ |
|||
data: { |
|||
motto: 'Hello World', |
|||
userInfo: { |
|||
avatarUrl: defaultAvatarUrl, |
|||
nickName: '', |
|||
}, |
|||
hasUserInfo: false, |
|||
canIUseGetUserProfile: wx.canIUse('getUserProfile'), |
|||
canIUseNicknameComp: wx.canIUse('input.type.nickname'), |
|||
}, |
|||
methods: { |
|||
// 事件处理函数
|
|||
bindViewTap() { |
|||
wx.navigateTo({ |
|||
url: '../logs/logs' |
|||
}) |
|||
}, |
|||
onChooseAvatar(e) { |
|||
const { avatarUrl } = e.detail |
|||
const { nickName } = this.data.userInfo |
|||
this.setData({ |
|||
"userInfo.avatarUrl": avatarUrl, |
|||
hasUserInfo: nickName && avatarUrl && avatarUrl !== defaultAvatarUrl, |
|||
}) |
|||
}, |
|||
onInputChange(e) { |
|||
const nickName = e.detail.value |
|||
const { avatarUrl } = this.data.userInfo |
|||
this.setData({ |
|||
"userInfo.nickName": nickName, |
|||
hasUserInfo: nickName && avatarUrl && avatarUrl !== defaultAvatarUrl, |
|||
}) |
|||
}, |
|||
getUserProfile(e) { |
|||
// 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
|
|||
wx.getUserProfile({ |
|||
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
|
|||
success: (res) => { |
|||
console.log(res) |
|||
this.setData({ |
|||
userInfo: res.userInfo, |
|||
hasUserInfo: true |
|||
}) |
|||
} |
|||
}) |
|||
}, |
|||
}, |
|||
}) |
|||
@ -1,5 +0,0 @@ |
|||
{ |
|||
"usingComponents": { |
|||
"navigation-bar": "/components/navigation-bar/navigation-bar" |
|||
} |
|||
} |
|||
@ -1,28 +0,0 @@ |
|||
<!--index.wxml--> |
|||
<navigation-bar title="Weixin" back="{{false}}" color="black" background="#FFF"></navigation-bar> |
|||
<scroll-view class="scrollarea" scroll-y type="list"> |
|||
<view class="container"> |
|||
<view class="userinfo"> |
|||
<block wx:if="{{canIUseNicknameComp && !hasUserInfo}}"> |
|||
<button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar"> |
|||
<image class="avatar" src="{{userInfo.avatarUrl}}"></image> |
|||
</button> |
|||
<view class="nickname-wrapper"> |
|||
<text class="nickname-label">昵称</text> |
|||
<input type="nickname" class="nickname-input" placeholder="请输入昵称" bind:change="onInputChange" /> |
|||
</view> |
|||
</block> |
|||
<block wx:elif="{{!hasUserInfo}}"> |
|||
<button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button> |
|||
<view wx:else> 请使用2.10.4及以上版本基础库 </view> |
|||
</block> |
|||
<block wx:else> |
|||
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image> |
|||
<text class="userinfo-nickname">{{userInfo.nickName}}</text> |
|||
</block> |
|||
</view> |
|||
<view class="usermotto"> |
|||
<text class="user-motto">{{motto}}</text> |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
@ -1,63 +0,0 @@ |
|||
/**index.wxss**/ |
|||
page { |
|||
height: 100vh; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.scrollarea { |
|||
flex: 1; |
|||
overflow-y: hidden; |
|||
} |
|||
|
|||
.userinfo { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
color: #aaa; |
|||
width: 80%; |
|||
} |
|||
|
|||
.userinfo-avatar { |
|||
overflow: hidden; |
|||
width: 128rpx; |
|||
height: 128rpx; |
|||
margin: 20rpx; |
|||
border-radius: 50%; |
|||
} |
|||
|
|||
.usermotto { |
|||
margin-top: 200px; |
|||
} |
|||
|
|||
.avatar-wrapper { |
|||
padding: 0; |
|||
width: 56px !important; |
|||
border-radius: 8px; |
|||
margin-top: 40px; |
|||
margin-bottom: 40px; |
|||
} |
|||
|
|||
.avatar { |
|||
display: block; |
|||
width: 56px; |
|||
height: 56px; |
|||
} |
|||
|
|||
.nickname-wrapper { |
|||
display: flex; |
|||
width: 100%; |
|||
padding: 16px; |
|||
box-sizing: border-box; |
|||
border-top: .5px solid rgba(0, 0, 0, 0.1); |
|||
border-bottom: .5px solid rgba(0, 0, 0, 0.1); |
|||
color: black; |
|||
} |
|||
|
|||
.nickname-label { |
|||
width: 105px; |
|||
} |
|||
|
|||
.nickname-input { |
|||
flex: 1; |
|||
} |
|||
@ -0,0 +1,189 @@ |
|||
import http from '../../utils/api' |
|||
Page({ |
|||
data: { |
|||
isAgree: true, // 是否同意协议
|
|||
showAgreementModal: false, // 是否显示协议弹窗
|
|||
modalTitle: '', // 弹窗标题
|
|||
modalContent: '', // 弹窗内容
|
|||
isLoading: false, // 是否显示加载中,
|
|||
phoneData: {}, |
|||
}, |
|||
|
|||
onLoad() { |
|||
this.login() |
|||
}, |
|||
|
|||
|
|||
// 登录获取
|
|||
login() { |
|||
// 小程序接口
|
|||
var that = this |
|||
wx.login({ |
|||
success(res) { |
|||
//登录接口
|
|||
http.login({ |
|||
data: { |
|||
code: res.code, |
|||
clientType: 'herdsman-app' |
|||
}, |
|||
success: function (res) { |
|||
if (res.data) { |
|||
that.setData({ |
|||
phoneData: res.data |
|||
}) |
|||
wx.showToast({ |
|||
title: res.data.message, |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
} |
|||
|
|||
if (res.token) { |
|||
wx.setStorageSync('token', res.token) |
|||
wx.switchTab({ |
|||
url: '/pages/home/home' |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
}) |
|||
}, |
|||
fail: (error) => { |
|||
console.log('登录失败!' + error); |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
|
|||
|
|||
// 获取用户手机号
|
|||
getPhoneNumber(e) { |
|||
if (!this.data.isAgree) { |
|||
wx.showToast({ |
|||
title: '请先同意协议', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
// 显示加载中
|
|||
this.setData({ |
|||
isLoading: true |
|||
}); |
|||
|
|||
// 检查是否获取到手机号
|
|||
if (e.detail.errMsg === "getPhoneNumber:ok") { |
|||
// 这里应该将加密数据发送到后端进行解密
|
|||
this.data.phoneData.encryptedData = e.detail.encryptedData |
|||
this.data.phoneData.iv = e.detail.iv |
|||
http.getPhoneNumber({ |
|||
data: this.data.phoneData, |
|||
success: res => { |
|||
if (res.code == 200) { |
|||
wx.setStorageSync('token', res.token) |
|||
|
|||
setTimeout(() => { |
|||
wx.switchTab({ |
|||
url: '/pages/home/home' |
|||
}); |
|||
}, 1500); |
|||
|
|||
this.setData({ |
|||
isLoading: false |
|||
}) |
|||
wx.showToast({ |
|||
title: '登录成功', |
|||
icon: 'success', |
|||
duration: 2000 |
|||
}); |
|||
} |
|||
} |
|||
}) |
|||
} else { |
|||
// 用户拒绝授权
|
|||
this.setData({ |
|||
isLoading: false |
|||
}); |
|||
|
|||
wx.showToast({ |
|||
title: '需要手机号授权才能登录', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
// 切换协议同意状态
|
|||
toggleAgreement() { |
|||
this.setData({ |
|||
isAgree: !this.data.isAgree |
|||
}); |
|||
}, |
|||
|
|||
// 显示用户协议
|
|||
showAgreement() { |
|||
const content = `欢迎您使用与牧同行服务!
|
|||
一、服务说明 |
|||
与牧同行为您提供智慧放牧管理、牲畜追踪、草场监测等服务。通过我们的平台,您可以更高效地管理牧场资源,提升放牧效率。 |
|||
二、账号注册 |
|||
1. 您需要使用手机号完成注册 |
|||
2. 您应保证提供的信息真实、准确、完整 |
|||
3. 您对账号安全负全部责任 |
|||
三、使用规范 |
|||
1. 不得利用本服务从事任何违法违规活动 |
|||
2. 不得干扰或破坏本服务的正常运行 |
|||
3. 遵守相关法律法规和平台规则 |
|||
四、服务变更与终止 |
|||
我们可能根据需要变更服务内容,如您不同意变更,可停止使用本服务。 |
|||
五、免责声明 |
|||
对于不可抗力、网络问题等导致的服务中断,我们不承担相应责任。 |
|||
六、法律适用 |
|||
本协议受中华人民共和国法律管辖。 |
|||
感谢您选择与牧同行!`;
|
|||
|
|||
this.setData({ |
|||
showAgreementModal: true, |
|||
modalTitle: '用户协议', |
|||
modalContent: content |
|||
}); |
|||
}, |
|||
|
|||
// 显示隐私政策
|
|||
showPrivacy() { |
|||
const content = `与牧同行隐私政策
|
|||
我们深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则保护您的个人信息:权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。 |
|||
一、我们如何收集和使用您的个人信息 |
|||
我们仅会出于本政策所述的以下目的,收集和使用您的个人信息: |
|||
1. 账号注册:手机号 |
|||
2. 服务提供:位置信息、设备信息 |
|||
3. 安全保障:登录日志、操作记录 |
|||
二、我们如何共享、转让、公开披露您的个人信息 |
|||
1. 我们不会与任何公司、组织和个人共享您的个人信息 |
|||
2. 我们不会将您的个人信息转让给任何公司、组织和个人 |
|||
3. 我们仅会在法律要求的情况下公开披露您的个人信息 |
|||
三、我们如何保护您的个人信息 |
|||
1. 我们已使用符合业界标准的安全防护措施保护您提供的个人信息 |
|||
2. 我们会采取合理可行的措施,确保未收集无关的个人信息 |
|||
四、您的权利 |
|||
您有权访问、更正、删除您的个人信息,以及改变您授权同意的范围或撤回授权。 |
|||
五、我们如何处理儿童的个人信息 |
|||
我们的服务主要面向成人。如果没有父母或监护人的同意,儿童不应创建自己的个人信息主体账户。 |
|||
六、本政策如何更新 |
|||
我们可能适时修订本政策内容,并通过公告等方式通知您。 |
|||
如有任何疑问,请通过客服渠道联系我们。`;
|
|||
|
|||
this.setData({ |
|||
showAgreementModal: true, |
|||
modalTitle: '隐私政策', |
|||
modalContent: content |
|||
}); |
|||
}, |
|||
|
|||
// 隐藏弹窗
|
|||
hideModal() { |
|||
this.setData({ |
|||
showAgreementModal: false |
|||
}); |
|||
} |
|||
}) |
|||
@ -0,0 +1,4 @@ |
|||
{ |
|||
"navigationBarTitleText":"登录", |
|||
"usingComponents": {} |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
<view class="login-container"> |
|||
<!-- 顶部波浪背景 --> |
|||
<view class="wave-background"> |
|||
<view class="wave wave-1"></view> |
|||
<view class="wave wave-2"></view> |
|||
<view class="wave wave-3"></view> |
|||
</view> |
|||
|
|||
<!-- 装饰元素 --> |
|||
<view class="decorations"> |
|||
<view class="cloud cloud-1"></view> |
|||
<view class="cloud cloud-2"></view> |
|||
<view class="cloud cloud-3"></view> |
|||
<view class="grass grass-1"></view> |
|||
<view class="grass grass-2"></view> |
|||
<view class="grass grass-3"></view> |
|||
<view class="sheep"></view> |
|||
</view> |
|||
|
|||
<!-- 主要内容区域 --> |
|||
<view class="main-content"> |
|||
<!-- Logo区域 --> |
|||
<view class="logo-section"> |
|||
<view class="logo-container"> |
|||
<view class="logo-circle"> |
|||
<view class="logo-inner"> |
|||
<text class="logo-text">牧</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<text class="app-title">与牧同行</text> |
|||
</view> |
|||
|
|||
<!-- 登录区域 --> |
|||
<view class="login-section"> |
|||
<view class="welcome-text"> |
|||
<text class="welcome-main">欢迎回来</text> |
|||
<text class="welcome-desc">请使用手机号快捷登录</text> |
|||
</view> |
|||
|
|||
<!-- 手机号登录按钮 --> |
|||
<button class="phone-login-btn" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber" hover-class="phone-btn-hover"> |
|||
<view class="btn-inner"> |
|||
<image src="/pages/images/sjh.png" mode="" /> |
|||
<text class="btn-text">手机号快捷登录</text> |
|||
</view> |
|||
</button> |
|||
|
|||
<!-- 协议确认 --> |
|||
<view class="agreement-section"> |
|||
<view class="agreement-checkbox {{isAgree ? 'checked' : ''}}" bindtap="toggleAgreement"> |
|||
<text class="checkmark" wx:if="{{isAgree}}">✓</text> |
|||
</view> |
|||
<view class="agreement-text"> |
|||
我已阅读并同意 |
|||
<view class="link" bindtap="showAgreement">《用户协议》</view> |
|||
和 |
|||
<view class="link" bindtap="showPrivacy">《隐私政策》</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 底部装饰 --> |
|||
<view class="bottom-decor"> |
|||
<view class="bottom-wave"></view> |
|||
</view> |
|||
|
|||
<!-- 协议弹窗 --> |
|||
<view class="agreement-modal" wx:if="{{showAgreementModal}}"> |
|||
<view class="modal-mask" bindtap="hideModal"></view> |
|||
<view class="modal-content"> |
|||
<view class="modal-header"> |
|||
<text class="modal-title">{{modalTitle}}</text> |
|||
<view class="modal-close" bindtap="hideModal">×</view> |
|||
</view> |
|||
<scroll-view class="modal-body" scroll-y> |
|||
<text class="modal-text">{{modalContent}}</text> |
|||
</scroll-view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 加载提示 --> |
|||
<view class="loading-mask" wx:if="{{isLoading}}"> |
|||
<view class="loading-content"> |
|||
<view class="loading-spinner"></view> |
|||
<text class="loading-text">登录中...</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
@ -0,0 +1,506 @@ |
|||
/* pages/login/login.wxss */ |
|||
|
|||
.login-container { |
|||
height: 100vh; |
|||
width: 100%; |
|||
position: relative; |
|||
overflow: hidden; |
|||
background: linear-gradient(180deg, #f8fafc 0%, #f0f9ff 100%); |
|||
} |
|||
|
|||
/* 波浪背景 */ |
|||
.wave-background { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 400rpx; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.wave { |
|||
position: absolute; |
|||
bottom: 0; |
|||
width: 200%; |
|||
height: 100%; |
|||
background: linear-gradient(90deg, #86D8D0 0%, #A8E6CF 100%); |
|||
border-radius: 0 0 50% 50%; |
|||
animation: waveMove 15s linear infinite; |
|||
} |
|||
|
|||
.wave-1 { |
|||
opacity: 0.7; |
|||
animation-delay: 0s; |
|||
} |
|||
|
|||
.wave-2 { |
|||
opacity: 0.5; |
|||
animation-delay: 5s; |
|||
background: linear-gradient(90deg, #7ACCC4 0%, #98D6C6 100%); |
|||
} |
|||
|
|||
.wave-3 { |
|||
opacity: 0.3; |
|||
animation-delay: 10s; |
|||
background: linear-gradient(90deg, #6EC0B8 0%, #88C6BD 100%); |
|||
} |
|||
|
|||
@keyframes waveMove { |
|||
0% { |
|||
transform: translateX(0) rotate(0deg); |
|||
} |
|||
|
|||
50% { |
|||
transform: translateX(-25%) rotate(1deg); |
|||
} |
|||
|
|||
100% { |
|||
transform: translateX(-50%) rotate(0deg); |
|||
} |
|||
} |
|||
|
|||
/* 装饰元素 */ |
|||
.decorations { |
|||
position: absolute; |
|||
width: 100%; |
|||
height: 100%; |
|||
pointer-events: none; |
|||
} |
|||
|
|||
.cloud { |
|||
position: absolute; |
|||
background-color: rgba(255, 255, 255, 0.9); |
|||
border-radius: 100rpx; |
|||
} |
|||
|
|||
.cloud-1 { |
|||
width: 120rpx; |
|||
height: 40rpx; |
|||
top: 120rpx; |
|||
left: 10%; |
|||
box-shadow: |
|||
20rpx 0 0 0 rgba(255, 255, 255, 0.9), |
|||
40rpx 0 0 0 rgba(255, 255, 255, 0.9); |
|||
} |
|||
|
|||
.cloud-2 { |
|||
width: 90rpx; |
|||
height: 30rpx; |
|||
top: 80rpx; |
|||
right: 15%; |
|||
box-shadow: |
|||
15rpx 0 0 0 rgba(255, 255, 255, 0.9), |
|||
30rpx 0 0 0 rgba(255, 255, 255, 0.9); |
|||
} |
|||
|
|||
.cloud-3 { |
|||
width: 70rpx; |
|||
height: 25rpx; |
|||
top: 180rpx; |
|||
left: 70%; |
|||
box-shadow: |
|||
12rpx 0 0 0 rgba(255, 255, 255, 0.9), |
|||
24rpx 0 0 0 rgba(255, 255, 255, 0.9); |
|||
} |
|||
|
|||
.grass { |
|||
position: absolute; |
|||
bottom: 0; |
|||
width: 8rpx; |
|||
background-color: #86D8D0; |
|||
border-radius: 4rpx 4rpx 0 0; |
|||
} |
|||
|
|||
.grass-1 { |
|||
height: 80rpx; |
|||
left: 20%; |
|||
} |
|||
|
|||
.grass-2 { |
|||
height: 60rpx; |
|||
left: 35%; |
|||
} |
|||
|
|||
.grass-3 { |
|||
height: 100rpx; |
|||
left: 50%; |
|||
} |
|||
|
|||
.grass:before, |
|||
.grass:after { |
|||
content: ''; |
|||
position: absolute; |
|||
width: 8rpx; |
|||
background-color: #86D8D0; |
|||
border-radius: 4rpx; |
|||
} |
|||
|
|||
.grass:before { |
|||
height: 40rpx; |
|||
transform: rotate(-30deg); |
|||
top: -20rpx; |
|||
left: -10rpx; |
|||
} |
|||
|
|||
.grass:after { |
|||
height: 30rpx; |
|||
transform: rotate(30deg); |
|||
top: -15rpx; |
|||
right: -10rpx; |
|||
} |
|||
|
|||
.sheep { |
|||
position: absolute; |
|||
bottom: 120rpx; |
|||
right: 20%; |
|||
width: 80rpx; |
|||
height: 50rpx; |
|||
background-color: white; |
|||
border-radius: 50%; |
|||
box-shadow: |
|||
-15rpx -10rpx 0 0 white, |
|||
15rpx -8rpx 0 0 white; |
|||
} |
|||
|
|||
.sheep:before { |
|||
content: ''; |
|||
position: absolute; |
|||
width: 20rpx; |
|||
height: 20rpx; |
|||
background-color: #333; |
|||
border-radius: 50%; |
|||
top: -5rpx; |
|||
left: 15rpx; |
|||
} |
|||
|
|||
/* 主要内容区域 */ |
|||
.main-content { |
|||
position: relative; |
|||
z-index: 10; |
|||
height: 100%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
padding: 0 60rpx; |
|||
padding-top: 120rpx; |
|||
} |
|||
|
|||
/* Logo区域 */ |
|||
.logo-section { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
margin-bottom: 120rpx; |
|||
} |
|||
|
|||
.logo-container { |
|||
margin-bottom: 40rpx; |
|||
} |
|||
|
|||
.logo-circle { |
|||
width: 180rpx; |
|||
height: 180rpx; |
|||
border-radius: 50%; |
|||
background: linear-gradient(135deg, #86D8D0 0%, #6BC4BC 100%); |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
box-shadow: |
|||
0 20rpx 40rpx rgba(134, 216, 208, 0.3), |
|||
inset 0 -4rpx 8rpx rgba(107, 196, 188, 0.4), |
|||
inset 0 4rpx 8rpx rgba(255, 255, 255, 0.8); |
|||
position: relative; |
|||
} |
|||
|
|||
.logo-circle:before { |
|||
content: ''; |
|||
position: absolute; |
|||
width: 160rpx; |
|||
height: 160rpx; |
|||
border-radius: 50%; |
|||
border: 2rpx solid rgba(255, 255, 255, 0.3); |
|||
} |
|||
|
|||
.logo-inner { |
|||
width: 140rpx; |
|||
height: 140rpx; |
|||
border-radius: 50%; |
|||
background: white; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
box-shadow: |
|||
inset 0 4rpx 8rpx rgba(134, 216, 208, 0.2), |
|||
0 4rpx 8rpx rgba(0, 0, 0, 0.1); |
|||
} |
|||
|
|||
.logo-text { |
|||
font-size: 64rpx; |
|||
font-weight: bold; |
|||
color: #86D8D0; |
|||
letter-spacing: 4rpx; |
|||
} |
|||
|
|||
.app-title { |
|||
font-size: 56rpx; |
|||
font-weight: 700; |
|||
color: #333; |
|||
margin-bottom: 16rpx; |
|||
letter-spacing: 2rpx; |
|||
} |
|||
|
|||
|
|||
|
|||
/* 登录区域 */ |
|||
.login-section { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
} |
|||
|
|||
.welcome-text { |
|||
text-align: center; |
|||
margin-bottom: 80rpx; |
|||
} |
|||
|
|||
.welcome-main { |
|||
display: block; |
|||
font-size: 44rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
margin-bottom: 16rpx; |
|||
} |
|||
|
|||
.welcome-desc { |
|||
display: block; |
|||
font-size: 28rpx; |
|||
color: #888; |
|||
font-weight: 300; |
|||
} |
|||
|
|||
/* 手机号登录按钮 */ |
|||
.phone-login-btn { |
|||
width: 100%; |
|||
height: 100rpx; |
|||
border-radius: 50rpx; |
|||
background: linear-gradient(to right, #86D8D0, #6BC4BC); |
|||
box-shadow: |
|||
0 12rpx 24rpx rgba(134, 216, 208, 0.3), |
|||
0 4rpx 12rpx rgba(0, 0, 0, 0.08); |
|||
margin-bottom: 50rpx; |
|||
transition: all 0.3s ease; |
|||
} |
|||
|
|||
.phone-btn-hover { |
|||
transform: translateY(-4rpx); |
|||
box-shadow: |
|||
0 16rpx 32rpx rgba(134, 216, 208, 0.4), |
|||
0 6rpx 16rpx rgba(0, 0, 0, 0.12); |
|||
} |
|||
|
|||
.btn-inner { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
height: 100%; |
|||
} |
|||
|
|||
.btn-inner image { |
|||
width: 45rpx; |
|||
height: 45rpx; |
|||
padding: 0 20rpx; |
|||
} |
|||
|
|||
|
|||
.btn-text { |
|||
color: white; |
|||
font-size: 34rpx; |
|||
font-weight: 500; |
|||
letter-spacing: 2rpx; |
|||
} |
|||
|
|||
/* 协议确认 */ |
|||
.agreement-section { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.agreement-checkbox { |
|||
width: 30rpx; |
|||
height: 30rpx; |
|||
border: 2rpx solid #ccc; |
|||
border-radius: 6rpx; |
|||
margin-right: 16rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
transition: all 0.2s ease; |
|||
} |
|||
|
|||
.agreement-checkbox.checked { |
|||
background-color: #86D8D0; |
|||
border-color: #86D8D0; |
|||
} |
|||
|
|||
.checkmark { |
|||
color: white; |
|||
font-size: 24rpx; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.agreement-text { |
|||
font-size: 24rpx; |
|||
color: #888; |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
.link { |
|||
color: #86D8D0; |
|||
} |
|||
|
|||
/* 底部装饰 */ |
|||
.bottom-decor { |
|||
position: absolute; |
|||
bottom: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 60rpx; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.bottom-wave { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 200%; |
|||
height: 200%; |
|||
background: linear-gradient(90deg, #86D8D0 0%, #A8E6CF 100%); |
|||
border-radius: 50% 50% 0 0; |
|||
animation: bottomWave 20s linear infinite; |
|||
} |
|||
|
|||
@keyframes bottomWave { |
|||
0% { |
|||
transform: translateX(0) rotate(0deg); |
|||
} |
|||
|
|||
50% { |
|||
transform: translateX(-25%) rotate(0.5deg); |
|||
} |
|||
|
|||
100% { |
|||
transform: translateX(-50%) rotate(0deg); |
|||
} |
|||
} |
|||
|
|||
/* 协议弹窗 */ |
|||
.agreement-modal { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
z-index: 1000; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.modal-mask { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background-color: rgba(0, 0, 0, 0.5); |
|||
} |
|||
|
|||
.modal-content { |
|||
position: relative; |
|||
width: 85%; |
|||
max-height: 80%; |
|||
background-color: white; |
|||
border-radius: 24rpx; |
|||
overflow: hidden; |
|||
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15); |
|||
} |
|||
|
|||
.modal-header { |
|||
padding: 40rpx; |
|||
border-bottom: 1rpx solid #f0f0f0; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
.modal-title { |
|||
font-size: 36rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
} |
|||
|
|||
.modal-close { |
|||
font-size: 48rpx; |
|||
color: #999; |
|||
line-height: 1; |
|||
} |
|||
|
|||
.modal-body { |
|||
max-height: 600rpx; |
|||
padding: 20rpx; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
.modal-text { |
|||
font-size: 28rpx; |
|||
color: #666; |
|||
line-height: 1.8; |
|||
padding: 20rpx 0; |
|||
} |
|||
|
|||
/* 加载提示 */ |
|||
.loading-mask { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background-color: rgba(0, 0, 0, 0.5); |
|||
z-index: 1001; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.loading-content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
} |
|||
|
|||
.loading-spinner { |
|||
width: 80rpx; |
|||
height: 80rpx; |
|||
border: 6rpx solid rgba(134, 216, 208, 0.2); |
|||
border-top-color: #86D8D0; |
|||
border-radius: 50%; |
|||
animation: loadingSpin 1s linear infinite; |
|||
margin-bottom: 30rpx; |
|||
} |
|||
|
|||
@keyframes loadingSpin { |
|||
0% { |
|||
transform: rotate(0deg); |
|||
} |
|||
|
|||
100% { |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
|
|||
.loading-text { |
|||
font-size: 28rpx; |
|||
color: #fff; |
|||
font-weight: 300; |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
// logs.js
|
|||
const util = require('../../utils/util.js') |
|||
|
|||
Component({ |
|||
data: { |
|||
logs: [] |
|||
}, |
|||
lifetimes: { |
|||
attached() { |
|||
this.setData({ |
|||
logs: (wx.getStorageSync('logs') || []).map(log => { |
|||
return { |
|||
date: util.formatTime(new Date(log)), |
|||
timeStamp: log |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
}, |
|||
}) |
|||
@ -1,5 +0,0 @@ |
|||
{ |
|||
"usingComponents": { |
|||
"navigation-bar": "/components/navigation-bar/navigation-bar" |
|||
} |
|||
} |
|||
@ -1,7 +0,0 @@ |
|||
<!--logs.wxml--> |
|||
<navigation-bar title="查看启动日志" back="{{true}}" color="black" background="#FFF"></navigation-bar> |
|||
<scroll-view class="scrollarea" scroll-y type="list"> |
|||
<block wx:for="{{logs}}" wx:key="timeStamp" wx:for-item="log"> |
|||
<view class="log-item">{{index + 1}}. {{log.date}}</view> |
|||
</block> |
|||
</scroll-view> |
|||
@ -1,16 +0,0 @@ |
|||
page { |
|||
height: 100vh; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
.scrollarea { |
|||
flex: 1; |
|||
overflow-y: hidden; |
|||
} |
|||
.log-item { |
|||
margin-top: 20rpx; |
|||
text-align: center; |
|||
} |
|||
.log-item:last-child { |
|||
padding-bottom: env(safe-area-inset-bottom); |
|||
} |
|||
@ -0,0 +1,2 @@ |
|||
<!--pages/market/market.wxml--> |
|||
<text>pages/market/market.wxml</text> |
|||
@ -0,0 +1 @@ |
|||
/* pages/market/market.wxss */ |
|||
@ -1,66 +1,330 @@ |
|||
// pages/personal/personal.js
|
|||
Page({ |
|||
|
|||
/** |
|||
* 页面的初始数据 |
|||
*/ |
|||
data: { |
|||
|
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面加载 |
|||
*/ |
|||
onLoad(options) { |
|||
|
|||
userInfo: { |
|||
avatar: '/assets/images/avatar.png', |
|||
nickname: '用户昵称', |
|||
phone: '138****8888', |
|||
isVerified: false, |
|||
isDoctor: false |
|||
}, |
|||
|
|||
// 功能模块
|
|||
modules: [ |
|||
{ |
|||
id: 'info', |
|||
icon: 'user-circle', |
|||
name: '个人管理', |
|||
items: [ |
|||
{ |
|||
id: 'profile', |
|||
name: '信息管理', |
|||
desc: '查看和编辑个人信息', |
|||
icon: 'profile', |
|||
badge: 0, |
|||
arrow: true |
|||
}, |
|||
{ |
|||
id: 'realname', |
|||
name: '实名认证', |
|||
desc: '通过输入身份信息', |
|||
icon: 'shield-check', |
|||
badge: 0, |
|||
arrow: true, |
|||
status: '未认证', // 认证状态
|
|||
statusColor: 'text-orange' |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
id: 'security', |
|||
icon: 'lock', |
|||
name: '账户安全', |
|||
items: [ |
|||
{ |
|||
id: 'security_settings', |
|||
name: '账户安全', |
|||
desc: '设置账户密码和安全问题', |
|||
icon: 'settings', |
|||
badge: 0, |
|||
arrow: true |
|||
}, |
|||
{ |
|||
id: 'feedback', |
|||
name: '反馈建议', |
|||
desc: '向平台提交反馈和建议', |
|||
icon: 'message', |
|||
badge: 3, // 未读回复数
|
|||
arrow: true |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
id: 'notification', |
|||
icon: 'bell', |
|||
name: '消息通知', |
|||
items: [ |
|||
{ |
|||
id: 'notifications', |
|||
name: '消息通知', |
|||
desc: '问诊、问答、订单等消息', |
|||
icon: 'notification', |
|||
badge: 5, // 未读消息数
|
|||
arrow: true |
|||
}, |
|||
{ |
|||
id: 'privacy', |
|||
name: '隐私设置', |
|||
desc: '管理个人信息可见性', |
|||
icon: 'eye-off', |
|||
badge: 0, |
|||
arrow: true |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
id: 'support', |
|||
icon: 'help-circle', |
|||
name: '帮助与支持', |
|||
items: [ |
|||
{ |
|||
id: 'about', |
|||
name: '关于我们', |
|||
desc: '了解平台信息', |
|||
icon: 'info', |
|||
badge: 0, |
|||
arrow: true |
|||
}, |
|||
{ |
|||
id: 'service', |
|||
name: '客服中心', |
|||
desc: '7x24小时在线服务', |
|||
icon: 'headphones', |
|||
badge: 0, |
|||
arrow: true |
|||
}, |
|||
{ |
|||
id: 'agreement', |
|||
name: '用户协议', |
|||
desc: '查看平台使用条款', |
|||
icon: 'file-text', |
|||
badge: 0, |
|||
arrow: true |
|||
} |
|||
] |
|||
} |
|||
], |
|||
|
|||
// 统计数据
|
|||
stats: [ |
|||
{ |
|||
id: 'consultation', |
|||
name: '我的问诊', |
|||
value: '12', |
|||
icon: 'stethoscope', |
|||
color: '#07c160' |
|||
}, |
|||
{ |
|||
id: 'orders', |
|||
name: '我的订单', |
|||
value: '8', |
|||
icon: 'shopping-bag', |
|||
color: '#ff6b6b' |
|||
}, |
|||
{ |
|||
id: 'favorites', |
|||
name: '我的收藏', |
|||
value: '23', |
|||
icon: 'heart', |
|||
color: '#ff9f43' |
|||
}, |
|||
{ |
|||
id: 'coupons', |
|||
name: '我的优惠券', |
|||
value: '3', |
|||
icon: 'tag', |
|||
color: '#2e86de' |
|||
} |
|||
], |
|||
|
|||
// 快捷操作
|
|||
quickActions: [ |
|||
{ |
|||
id: 'health_record', |
|||
name: '健康档案', |
|||
icon: 'file-medical', |
|||
color: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' |
|||
}, |
|||
{ |
|||
id: 'appointment', |
|||
name: '预约挂号', |
|||
icon: 'calendar', |
|||
color: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)' |
|||
}, |
|||
{ |
|||
id: 'medicine', |
|||
name: '我的药箱', |
|||
icon: 'pill', |
|||
color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)' |
|||
}, |
|||
{ |
|||
id: 'report', |
|||
name: '检查报告', |
|||
icon: 'clipboard', |
|||
color: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)' |
|||
} |
|||
], |
|||
|
|||
// 系统信息
|
|||
systemInfo: { |
|||
version: '2.1.0', |
|||
lastLogin: '2024-01-15 14:30' |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面初次渲染完成 |
|||
*/ |
|||
onReady() { |
|||
|
|||
onLoad() { |
|||
this.loadUserInfo() |
|||
this.checkNotifications() |
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面显示 |
|||
*/ |
|||
onShow() { |
|||
// 每次显示页面时刷新数据
|
|||
this.refreshData() |
|||
}, |
|||
|
|||
// 加载用户信息
|
|||
loadUserInfo() { |
|||
// 模拟API调用
|
|||
setTimeout(() => { |
|||
this.setData({ |
|||
'userInfo.nickname': '张小凡', |
|||
'userInfo.phone': '138****5678', |
|||
'userInfo.isVerified': true, |
|||
'userInfo.isDoctor': false |
|||
}) |
|||
}, 500) |
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面隐藏 |
|||
*/ |
|||
onHide() { |
|||
// 检查通知
|
|||
checkNotifications() { |
|||
// 模拟检查未读消息
|
|||
const updatedModules = this.data.modules.map(module => { |
|||
return { |
|||
...module, |
|||
items: module.items.map(item => { |
|||
if (item.id === 'notifications') { |
|||
return { ...item, badge: Math.floor(Math.random() * 10) } |
|||
} |
|||
return item |
|||
}) |
|||
} |
|||
}) |
|||
|
|||
this.setData({ modules: updatedModules }) |
|||
}, |
|||
|
|||
// 刷新数据
|
|||
refreshData() { |
|||
// 刷新统计数据
|
|||
const updatedStats = this.data.stats.map(stat => ({ |
|||
...stat, |
|||
value: String(Math.floor(Math.random() * 20) + 5) |
|||
})) |
|||
|
|||
this.setData({ stats: updatedStats }) |
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面卸载 |
|||
*/ |
|||
onUnload() { |
|||
// 点击用户头像区域
|
|||
onTapUserInfo() { |
|||
wx.navigateTo({ |
|||
url: '/pages/profile/edit-profile' |
|||
}) |
|||
}, |
|||
|
|||
// 点击统计项
|
|||
onTapStat(e) { |
|||
const { id } = e.currentTarget.dataset |
|||
const urls = { |
|||
consultation: '/pages/consultation/my-consultation', |
|||
orders: '/pages/order/my-orders', |
|||
favorites: '/pages/favorites/favorites', |
|||
coupons: '/pages/coupon/my-coupons' |
|||
} |
|||
|
|||
if (urls[id]) { |
|||
wx.navigateTo({ url: urls[id] }) |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 页面相关事件处理函数--监听用户下拉动作 |
|||
*/ |
|||
onPullDownRefresh() { |
|||
// 点击快捷操作
|
|||
onTapQuickAction(e) { |
|||
const { id } = e.currentTarget.dataset |
|||
const urls = { |
|||
health_record: '/pages/health/record', |
|||
appointment: '/pages/appointment/list', |
|||
medicine: '/pages/medicine/medicine-box', |
|||
report: '/pages/report/list' |
|||
} |
|||
|
|||
if (urls[id]) { |
|||
wx.navigateTo({ url: urls[id] }) |
|||
} |
|||
}, |
|||
|
|||
// 点击功能项
|
|||
onTapMenuItem(e) { |
|||
const { moduleid, itemid } = e.currentTarget.dataset |
|||
console.log('点击:', moduleid, itemid) |
|||
|
|||
// 根据不同的itemid跳转到不同页面
|
|||
const pageMap = { |
|||
profile: '/pages/profile/edit-profile', |
|||
realname: '/pages/auth/realname-auth', |
|||
security_settings: '/pages/security/settings', |
|||
feedback: '/pages/feedback/feedback', |
|||
notifications: '/pages/notification/notification-center', |
|||
privacy: '/pages/privacy/settings', |
|||
about: '/pages/about/about', |
|||
service: '/pages/service/customer-service', |
|||
agreement: '/pages/agreement/user-agreement' |
|||
} |
|||
|
|||
if (pageMap[itemid]) { |
|||
wx.navigateTo({ url: pageMap[itemid] }) |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 页面上拉触底事件的处理函数 |
|||
*/ |
|||
onReachBottom() { |
|||
// 设置
|
|||
onTapSettings() { |
|||
wx.navigateTo({ |
|||
url: '/pages/settings/settings' |
|||
}) |
|||
}, |
|||
|
|||
// 退出登录
|
|||
onLogout() { |
|||
wx.showModal({ |
|||
title: '提示', |
|||
content: '确定要退出登录吗?', |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
// 清除登录状态
|
|||
wx.removeStorageSync('token') |
|||
wx.removeStorageSync('userInfo') |
|||
|
|||
// 跳转到登录页
|
|||
wx.reLaunch({ |
|||
url: '/pages/login/login' |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
/** |
|||
* 用户点击右上角分享 |
|||
*/ |
|||
// 分享
|
|||
onShareAppMessage() { |
|||
|
|||
return { |
|||
title: '健康管理,从这里开始', |
|||
path: '/pages/index/index' |
|||
} |
|||
} |
|||
}) |
|||
@ -1,2 +1,147 @@ |
|||
<!--pages/personal/personal.wxml--> |
|||
<text>pages/personal/personal.wxml</text> |
|||
<view class="personal-center"> |
|||
<!-- 顶部背景 --> |
|||
<view class="header-bg"></view> |
|||
|
|||
<!-- 用户信息卡片 --> |
|||
<view class="user-card" bindtap="onTapUserInfo"> |
|||
<view class="user-info"> |
|||
<view class="avatar-section"> |
|||
<image class="avatar" src="{{userInfo.avatar || '/assets/images/avatar-default.png'}}" mode="aspectFill"></image> |
|||
<view class="avatar-badge" wx:if="{{userInfo.isVerified}}"> |
|||
<text class="iconfont icon-check-circle"></text> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="user-details"> |
|||
<view class="user-name"> |
|||
<text class="name">{{userInfo.nickname || '点击登录'}}</text> |
|||
<text class="iconfont icon-edit" wx:if="{{userInfo.nickname}}"></text> |
|||
</view> |
|||
|
|||
<view class="user-phone"> |
|||
<text class="iconfont icon-phone"></text> |
|||
<text>{{userInfo.phone || '未绑定手机号'}}</text> |
|||
</view> |
|||
|
|||
<view class="user-tags"> |
|||
<view class="tag" wx:if="{{userInfo.isDoctor}}"> |
|||
<text class="iconfont icon-stethoscope"></text> |
|||
<text>医生认证</text> |
|||
</view> |
|||
<view class="tag" wx:if="{{userInfo.isVerified}}"> |
|||
<text class="iconfont icon-shield-check"></text> |
|||
<text>已实名</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="card-arrow"> |
|||
<text class="iconfont icon-chevron-right"></text> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 统计数据 --> |
|||
<view class="stats-grid"> |
|||
<view |
|||
wx:for="{{stats}}" |
|||
wx:key="id" |
|||
class="stat-item" |
|||
bindtap="onTapStat" |
|||
data-id="{{item.id}}" |
|||
> |
|||
<view class="stat-icon" style="color: {{item.color}};"> |
|||
<text class="iconfont icon-{{item.icon}}"></text> |
|||
</view> |
|||
<view class="stat-value">{{item.value}}</view> |
|||
<view class="stat-name">{{item.name}}</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 快捷操作 --> |
|||
<view class="quick-actions"> |
|||
<view class="section-title"> |
|||
<text class="iconfont icon-zap"></text> |
|||
<text>快捷操作</text> |
|||
</view> |
|||
<view class="actions-grid"> |
|||
<view |
|||
wx:for="{{quickActions}}" |
|||
wx:key="id" |
|||
class="action-item" |
|||
bindtap="onTapQuickAction" |
|||
data-id="{{item.id}}" |
|||
> |
|||
<view class="action-icon" style="background: {{item.color}};"> |
|||
<text class="iconfont icon-{{item.icon}}"></text> |
|||
</view> |
|||
<view class="action-name">{{item.name}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 功能模块 --> |
|||
<view class="modules"> |
|||
<block wx:for="{{modules}}" wx:key="id"> |
|||
<view class="module-section"> |
|||
<view class="section-title"> |
|||
<text class="iconfont icon-{{item.icon}}"></text> |
|||
<text>{{item.name}}</text> |
|||
</view> |
|||
|
|||
<view class="module-items"> |
|||
<view |
|||
wx:for="{{item.items}}" |
|||
wx:key="id" |
|||
class="module-item" |
|||
bindtap="onTapMenuItem" |
|||
data-moduleid="{{moduleId}}" |
|||
data-itemid="{{item.id}}" |
|||
> |
|||
<view class="item-left"> |
|||
<view class="item-icon"> |
|||
<text class="iconfont icon-{{item.icon}}"></text> |
|||
</view> |
|||
<view class="item-info"> |
|||
<view class="item-name">{{item.name}}</view> |
|||
<view class="item-desc">{{item.desc}}</view> |
|||
<view |
|||
class="item-status {{item.statusColor || ''}}" |
|||
wx:if="{{item.status}}" |
|||
> |
|||
{{item.status}} |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="item-right"> |
|||
<view class="badge" wx:if="{{item.badge > 0}}"> |
|||
{{item.badge > 99 ? '99+' : item.badge}} |
|||
</view> |
|||
<text class="iconfont icon-chevron-right" wx:if="{{item.arrow}}"></text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</block> |
|||
</view> |
|||
|
|||
<!-- 底部操作 --> |
|||
<view class="bottom-actions"> |
|||
<view class="system-info"> |
|||
<text>版本 {{systemInfo.version}}</text> |
|||
<text>最后登录 {{systemInfo.lastLogin}}</text> |
|||
</view> |
|||
|
|||
<view class="action-buttons"> |
|||
<button class="btn btn-setting" bindtap="onTapSettings"> |
|||
<text class="iconfont icon-settings"></text> |
|||
<text>设置</text> |
|||
</button> |
|||
<button class="btn btn-logout" bindtap="onLogout"> |
|||
<text class="iconfont icon-log-out"></text> |
|||
<text>退出登录</text> |
|||
</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
@ -1 +1,441 @@ |
|||
/* pages/personal/personal.wxss */ |
|||
.personal-center { |
|||
min-height: 100vh; |
|||
background: linear-gradient(to bottom, #f5f7fa 0%, #e4e8f0 100%); |
|||
padding-bottom: 120rpx; |
|||
} |
|||
|
|||
/* 顶部背景 */ |
|||
.header-bg { |
|||
height: 300rpx; |
|||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
z-index: 1; |
|||
border-radius: 0 0 40rpx 40rpx; |
|||
} |
|||
|
|||
/* 用户信息卡片 */ |
|||
.user-card { |
|||
position: relative; |
|||
z-index: 2; |
|||
background: white; |
|||
margin: 40rpx; |
|||
border-radius: 24rpx; |
|||
padding: 40rpx; |
|||
box-shadow: 0 10rpx 30rpx rgba(102, 126, 234, 0.15); |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
animation: slideUp 0.6s ease; |
|||
} |
|||
|
|||
.user-info { |
|||
display: flex; |
|||
align-items: center; |
|||
flex: 1; |
|||
} |
|||
|
|||
.avatar-section { |
|||
position: relative; |
|||
margin-right: 30rpx; |
|||
} |
|||
|
|||
.avatar { |
|||
width: 120rpx; |
|||
height: 120rpx; |
|||
border-radius: 50%; |
|||
border: 6rpx solid white; |
|||
box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.1); |
|||
} |
|||
|
|||
.avatar-badge { |
|||
position: absolute; |
|||
bottom: 0; |
|||
right: 0; |
|||
background: #07c160; |
|||
width: 36rpx; |
|||
height: 36rpx; |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
border: 3rpx solid white; |
|||
} |
|||
|
|||
.avatar-badge .iconfont { |
|||
color: white; |
|||
font-size: 20rpx; |
|||
} |
|||
|
|||
.user-details { |
|||
flex: 1; |
|||
} |
|||
|
|||
.user-name { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-bottom: 10rpx; |
|||
} |
|||
|
|||
.user-name .name { |
|||
font-size: 36rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
margin-right: 15rpx; |
|||
} |
|||
|
|||
.user-name .iconfont { |
|||
color: #667eea; |
|||
font-size: 28rpx; |
|||
} |
|||
|
|||
.user-phone { |
|||
display: flex; |
|||
align-items: center; |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
margin-bottom: 15rpx; |
|||
} |
|||
|
|||
.user-phone .iconfont { |
|||
margin-right: 10rpx; |
|||
font-size: 24rpx; |
|||
} |
|||
|
|||
.user-tags { |
|||
display: flex; |
|||
gap: 15rpx; |
|||
} |
|||
|
|||
.user-tags .tag { |
|||
background: rgba(102, 126, 234, 0.1); |
|||
padding: 6rpx 15rpx; |
|||
border-radius: 20rpx; |
|||
font-size: 22rpx; |
|||
color: #667eea; |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
.user-tags .tag .iconfont { |
|||
font-size: 20rpx; |
|||
margin-right: 5rpx; |
|||
} |
|||
|
|||
.card-arrow .iconfont { |
|||
color: #ccc; |
|||
font-size: 32rpx; |
|||
} |
|||
|
|||
/* 统计数据 */ |
|||
.stats-grid { |
|||
display: grid; |
|||
grid-template-columns: repeat(4, 1fr); |
|||
gap: 20rpx; |
|||
margin: 30rpx 40rpx; |
|||
animation: fadeIn 0.8s ease 0.2s both; |
|||
} |
|||
|
|||
.stat-item { |
|||
background: white; |
|||
border-radius: 20rpx; |
|||
padding: 30rpx 0; |
|||
text-align: center; |
|||
box-shadow: 0 5rpx 15rpx rgba(0, 0, 0, 0.05); |
|||
transition: all 0.3s ease; |
|||
position: relative; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.stat-item::before { |
|||
content: ''; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
height: 4rpx; |
|||
background: var(--item-color); |
|||
opacity: 0; |
|||
transition: opacity 0.3s ease; |
|||
} |
|||
|
|||
.stat-item:active { |
|||
transform: translateY(-5rpx); |
|||
box-shadow: 0 10rpx 25rpx rgba(0, 0, 0, 0.1); |
|||
} |
|||
|
|||
.stat-item:active::before { |
|||
opacity: 1; |
|||
} |
|||
|
|||
.stat-icon .iconfont { |
|||
font-size: 44rpx; |
|||
margin-bottom: 15rpx; |
|||
display: block; |
|||
} |
|||
|
|||
.stat-value { |
|||
font-size: 36rpx; |
|||
font-weight: 700; |
|||
color: #333; |
|||
margin-bottom: 5rpx; |
|||
} |
|||
|
|||
.stat-name { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
} |
|||
|
|||
/* 快捷操作 */ |
|||
.quick-actions { |
|||
margin: 30rpx 40rpx; |
|||
animation: fadeIn 0.8s ease 0.4s both; |
|||
} |
|||
|
|||
.section-title { |
|||
display: flex; |
|||
align-items: center; |
|||
font-size: 30rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
margin-bottom: 30rpx; |
|||
} |
|||
|
|||
.section-title .iconfont { |
|||
margin-right: 15rpx; |
|||
font-size: 32rpx; |
|||
color: #667eea; |
|||
} |
|||
|
|||
.actions-grid { |
|||
display: grid; |
|||
grid-template-columns: repeat(4, 1fr); |
|||
gap: 20rpx; |
|||
} |
|||
|
|||
.action-item { |
|||
text-align: center; |
|||
} |
|||
|
|||
.action-icon { |
|||
width: 90rpx; |
|||
height: 90rpx; |
|||
border-radius: 50%; |
|||
margin: 0 auto 20rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
color: white; |
|||
font-size: 40rpx; |
|||
box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.1); |
|||
transition: transform 0.3s ease; |
|||
} |
|||
|
|||
.action-item:active .action-icon { |
|||
transform: scale(0.95); |
|||
} |
|||
|
|||
.action-name { |
|||
font-size: 24rpx; |
|||
color: #666; |
|||
} |
|||
|
|||
/* 功能模块 */ |
|||
.modules { |
|||
margin: 30rpx 40rpx; |
|||
animation: fadeIn 0.8s ease 0.6s both; |
|||
} |
|||
|
|||
.module-section { |
|||
background: white; |
|||
border-radius: 20rpx; |
|||
padding: 30rpx; |
|||
margin-bottom: 30rpx; |
|||
box-shadow: 0 5rpx 15rpx rgba(0, 0, 0, 0.05); |
|||
} |
|||
|
|||
.module-items { |
|||
margin-top: 20rpx; |
|||
} |
|||
|
|||
.module-item { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 30rpx 0; |
|||
border-bottom: 1rpx solid #f0f0f0; |
|||
transition: background-color 0.2s ease; |
|||
} |
|||
|
|||
.module-item:active { |
|||
background-color: #f8f9fa; |
|||
} |
|||
|
|||
.module-item:last-child { |
|||
border-bottom: none; |
|||
} |
|||
|
|||
.item-left { |
|||
display: flex; |
|||
align-items: center; |
|||
flex: 1; |
|||
} |
|||
|
|||
.item-icon { |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
border-radius: 15rpx; |
|||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
margin-right: 25rpx; |
|||
} |
|||
|
|||
.item-icon .iconfont { |
|||
color: white; |
|||
font-size: 30rpx; |
|||
} |
|||
|
|||
.item-info { |
|||
flex: 1; |
|||
} |
|||
|
|||
.item-name { |
|||
font-size: 30rpx; |
|||
color: #333; |
|||
margin-bottom: 8rpx; |
|||
} |
|||
|
|||
.item-desc { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
margin-bottom: 5rpx; |
|||
} |
|||
|
|||
.item-status { |
|||
font-size: 22rpx; |
|||
padding: 4rpx 12rpx; |
|||
border-radius: 12rpx; |
|||
background: rgba(255, 107, 107, 0.1); |
|||
display: inline-block; |
|||
} |
|||
|
|||
.text-orange { |
|||
color: #ff9f43; |
|||
background: rgba(255, 159, 67, 0.1); |
|||
} |
|||
|
|||
.item-right { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
.badge { |
|||
background: #ff6b6b; |
|||
color: white; |
|||
font-size: 20rpx; |
|||
min-width: 36rpx; |
|||
height: 36rpx; |
|||
border-radius: 18rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 0 8rpx; |
|||
margin-right: 15rpx; |
|||
} |
|||
|
|||
.item-right .iconfont { |
|||
color: #ccc; |
|||
font-size: 28rpx; |
|||
} |
|||
|
|||
/* 底部操作 */ |
|||
.bottom-actions { |
|||
margin: 30rpx 40rpx; |
|||
animation: fadeIn 0.8s ease 0.8s both; |
|||
} |
|||
|
|||
.system-info { |
|||
text-align: center; |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
margin-bottom: 40rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 10rpx; |
|||
} |
|||
|
|||
.action-buttons { |
|||
display: flex; |
|||
gap: 20rpx; |
|||
} |
|||
|
|||
.btn { |
|||
flex: 1; |
|||
height: 88rpx; |
|||
border-radius: 44rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size: 28rpx; |
|||
font-weight: 500; |
|||
border: none; |
|||
transition: all 0.3s ease; |
|||
} |
|||
|
|||
.btn:active { |
|||
transform: scale(0.98); |
|||
} |
|||
|
|||
.btn-setting { |
|||
background: white; |
|||
color: #667eea; |
|||
border: 2rpx solid #667eea; |
|||
} |
|||
|
|||
.btn-logout { |
|||
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%); |
|||
color: white; |
|||
box-shadow: 0 10rpx 20rpx rgba(255, 107, 107, 0.3); |
|||
} |
|||
|
|||
.btn .iconfont { |
|||
margin-right: 10rpx; |
|||
font-size: 28rpx; |
|||
} |
|||
|
|||
/* 动画效果 */ |
|||
@keyframes slideUp { |
|||
from { |
|||
opacity: 0; |
|||
transform: translateY(30rpx); |
|||
} |
|||
to { |
|||
opacity: 1; |
|||
transform: translateY(0); |
|||
} |
|||
} |
|||
|
|||
@keyframes fadeIn { |
|||
from { |
|||
opacity: 0; |
|||
} |
|||
to { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
|
|||
/* 响应式调整 */ |
|||
@media (max-width: 375px) { |
|||
.user-card, |
|||
.stats-grid, |
|||
.quick-actions, |
|||
.modules, |
|||
.bottom-actions { |
|||
margin-left: 30rpx; |
|||
margin-right: 30rpx; |
|||
} |
|||
} |
|||
@ -1,2 +0,0 @@ |
|||
<!--pagesA/pages/socialWork/socialWork.wxml--> |
|||
<text>pagesA/pages/socialWork/socialWork.wxml</text> |
|||
@ -1 +0,0 @@ |
|||
/* pagesA/pages/socialWork/socialWork.wxss */ |
|||
@ -0,0 +1,299 @@ |
|||
Page({ |
|||
data: { |
|||
// 当前时间
|
|||
currentTime: '', |
|||
|
|||
// 聊天消息
|
|||
messages: [], |
|||
|
|||
// 输入框相关
|
|||
inputValue: '', |
|||
autoFocus: false, |
|||
|
|||
// 症状选择
|
|||
quickSymptoms: [ |
|||
'发热', '咳嗽', '腹泻', '食欲不振', |
|||
'精神萎靡', '呼吸困难', '体重下降', '皮肤问题' |
|||
], |
|||
selectedSymptoms: [], |
|||
showSymptomSelector: false, |
|||
|
|||
// 症状数据
|
|||
symptoms: [ |
|||
{ id: 1, name: '发热', category: '全身症状' }, |
|||
{ id: 2, name: '咳嗽', category: '呼吸系统' }, |
|||
{ id: 3, name: '腹泻', category: '消化系统' }, |
|||
{ id: 4, name: '呕吐', category: '消化系统' }, |
|||
{ id: 5, name: '食欲不振', category: '消化系统' }, |
|||
{ id: 6, name: '呼吸困难', category: '呼吸系统' }, |
|||
{ id: 7, name: '精神萎靡', category: '神经系统' }, |
|||
{ id: 8, name: '体重下降', category: '全身症状' }, |
|||
{ id: 9, name: '皮肤问题', category: '皮肤系统' }, |
|||
{ id: 10, name: '跛行', category: '运动系统' }, |
|||
{ id: 11, name: '眼部分泌物', category: '五官' }, |
|||
{ id: 12, name: '流鼻涕', category: '呼吸系统' } |
|||
], |
|||
|
|||
// 状态控制
|
|||
isAIThinking: false, |
|||
isLoading: false, |
|||
loadingText: '', |
|||
showMoreMenu: false |
|||
}, |
|||
|
|||
onLoad() { |
|||
this.initData(); |
|||
}, |
|||
|
|||
onShow() { |
|||
this.updateCurrentTime(); |
|||
this.setData({ autoFocus: true }); |
|||
}, |
|||
|
|||
// 初始化数据
|
|||
initData() { |
|||
// 设置当前时间
|
|||
this.updateCurrentTime(); |
|||
|
|||
// 定时更新当前时间
|
|||
setInterval(() => { |
|||
this.updateCurrentTime(); |
|||
}, 60000); |
|||
|
|||
}, |
|||
|
|||
// 更新当前时间
|
|||
updateCurrentTime() { |
|||
const now = new Date(); |
|||
const timeString = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`; |
|||
this.setData({ currentTime: timeString }); |
|||
}, |
|||
|
|||
// 输入框变化
|
|||
onInput(e) { |
|||
this.setData({ inputValue: e.detail.value }); |
|||
}, |
|||
|
|||
// 发送消息
|
|||
sendMessage() { |
|||
const message = this.data.inputValue.trim(); |
|||
if (!message) return; |
|||
|
|||
// 添加用户消息
|
|||
const userMessage = { |
|||
id: Date.now(), |
|||
type: 'user', |
|||
content: message, |
|||
time: this.getCurrentTime() |
|||
}; |
|||
|
|||
this.setData({ |
|||
messages: [...this.data.messages, userMessage], |
|||
inputValue: '', |
|||
autoFocus: true |
|||
}); |
|||
|
|||
// 模拟AI思考
|
|||
this.simulateAIResponse(message); |
|||
}, |
|||
|
|||
// 获取当前时间
|
|||
getCurrentTime() { |
|||
const now = new Date(); |
|||
return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`; |
|||
}, |
|||
|
|||
// 模拟AI响应
|
|||
simulateAIResponse(userMessage) { |
|||
this.setData({ isAIThinking: true }); |
|||
|
|||
// 模拟AI思考时间
|
|||
setTimeout(() => { |
|||
const aiMessage = this.generateAIResponse(userMessage); |
|||
console.log(333,aiMessage); |
|||
this.setData({ |
|||
messages: [...this.data.messages, aiMessage], |
|||
isAIThinking: false |
|||
}); |
|||
}, 1500 + Math.random() * 1000); |
|||
|
|||
|
|||
}, |
|||
|
|||
// 生成AI响应
|
|||
generateAIResponse(userMessage) { |
|||
console.log(444,userMessage); |
|||
const responses = { |
|||
'发热': { |
|||
content: '根据您的描述,牲畜出现发热症状。', |
|||
diagnosis: { |
|||
disease: '可能为感染性疾病或中暑', |
|||
severity: 'moderate', |
|||
severityText: '中度', |
|||
suggestion: '建议:1. 隔离观察 2. 监测体温 3. 提供充足饮水 4. 如持续发热,及时联系兽医' |
|||
} |
|||
}, |
|||
'咳嗽': { |
|||
content: '咳嗽症状提示可能存在呼吸系统问题。', |
|||
diagnosis: { |
|||
disease: '可能为呼吸道感染或肺炎', |
|||
severity: 'low', |
|||
severityText: '轻度', |
|||
suggestion: '建议:1. 保持圈舍通风 2. 避免粉尘 3. 观察呼吸频率 4. 如有加重及时就医' |
|||
} |
|||
}, |
|||
'腹泻': { |
|||
content: '腹泻症状需要关注,可能由多种原因引起。', |
|||
diagnosis: { |
|||
disease: '可能为消化不良或肠胃感染', |
|||
severity: 'moderate', |
|||
severityText: '中度', |
|||
suggestion: '建议:1. 调整饲料 2. 补充电解质 3. 观察粪便性状 4. 如持续腹泻需兽医检查' |
|||
} |
|||
} |
|||
}; |
|||
|
|||
// 匹配症状关键词
|
|||
let response = responses['发热']; // 默认响应
|
|||
for (const [symptom, data] of Object.entries(responses)) { |
|||
if (userMessage.includes(symptom)) { |
|||
response = data; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return { |
|||
id: Date.now() + 1, |
|||
type: 'assistant', |
|||
content: response.content, |
|||
diagnosis: response.diagnosis, |
|||
time: this.getCurrentTime() |
|||
}; |
|||
}, |
|||
|
|||
// 选择快捷症状
|
|||
selectQuickSymptom(e) { |
|||
console.log(1111,e); |
|||
const symptom = e.currentTarget.dataset.symptom; |
|||
this.setData({ inputValue: symptom }); |
|||
this.sendMessage(); |
|||
}, |
|||
|
|||
// 切换症状选择器
|
|||
toggleSymptomSelector() { |
|||
this.setData({ showSymptomSelector: !this.data.showSymptomSelector }); |
|||
}, |
|||
|
|||
// 关闭症状选择器
|
|||
closeSymptomSelector() { |
|||
this.setData({ showSymptomSelector: false }); |
|||
}, |
|||
|
|||
// 症状选择
|
|||
onSymptomSelect(e) { |
|||
const { symptom } = e.detail; |
|||
const selectedSymptoms = [...this.data.selectedSymptoms]; |
|||
|
|||
const index = selectedSymptoms.findIndex(s => s.id === symptom.id); |
|||
if (index > -1) { |
|||
selectedSymptoms.splice(index, 1); |
|||
} else { |
|||
selectedSymptoms.push(symptom); |
|||
} |
|||
|
|||
this.setData({ selectedSymptoms }); |
|||
}, |
|||
|
|||
// 确认症状选择
|
|||
confirmSymptoms() { |
|||
if (this.data.selectedSymptoms.length === 0) { |
|||
wx.showToast({ |
|||
title: '请选择至少一个症状', |
|||
icon: 'none' |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
const symptomNames = this.data.selectedSymptoms.map(s => s.name).join('、'); |
|||
this.setData({ |
|||
inputValue: `我的牲畜出现以下症状:${symptomNames}`, |
|||
showSymptomSelector: false |
|||
}); |
|||
}, |
|||
|
|||
|
|||
// 返回
|
|||
goBack() { |
|||
wx.navigateBack(); |
|||
}, |
|||
|
|||
// 显示更多菜单
|
|||
showMoreMenu() { |
|||
this.setData({ showMoreMenu: true }); |
|||
}, |
|||
|
|||
// 关闭更多菜单
|
|||
closeMoreMenu() { |
|||
this.setData({ showMoreMenu: false }); |
|||
}, |
|||
|
|||
// 阻止事件冒泡
|
|||
stopPropagation() {}, |
|||
|
|||
// 清空记录
|
|||
clearHistory() { |
|||
wx.showModal({ |
|||
title: '提示', |
|||
content: '确定要清空所有聊天记录吗?', |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
this.setData({ |
|||
messages: [{ |
|||
id: 1, |
|||
type: 'assistant', |
|||
content: '您好!我是AI健康助手,有什么可以帮您?\n\n请描述您或牲畜的健康状况,我会为您提供专业的分析和建议。', |
|||
time: this.getCurrentTime() |
|||
}], |
|||
selectedSymptoms: [] |
|||
}); |
|||
this.closeMoreMenu(); |
|||
} |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
// 导出记录
|
|||
exportChat() { |
|||
wx.showToast({ |
|||
title: '记录已保存到本地', |
|||
icon: 'success' |
|||
}); |
|||
this.closeMoreMenu(); |
|||
}, |
|||
|
|||
// 联系兽医
|
|||
contactDoctor() { |
|||
wx.showModal({ |
|||
title: '联系兽医', |
|||
content: '确定要拨打兽医热线吗?', |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
wx.makePhoneCall({ |
|||
phoneNumber: '400-123-4567' |
|||
}); |
|||
} |
|||
} |
|||
}); |
|||
this.closeMoreMenu(); |
|||
}, |
|||
|
|||
// 显示使用说明
|
|||
showInstructions() { |
|||
wx.showModal({ |
|||
title: '使用说明', |
|||
content: '1. 描述您或牲畜的症状\n2. AI助手会分析并提供建议\n3. 可使用快捷症状选择\n4. 诊断结果仅供参考,请及时咨询专业兽医', |
|||
showCancel: false |
|||
}); |
|||
this.closeMoreMenu(); |
|||
} |
|||
}); |
|||
@ -0,0 +1,5 @@ |
|||
{ |
|||
"navigationBarTitleText":"AI问诊", |
|||
"navigationStyle": "custom", |
|||
"usingComponents": {} |
|||
} |
|||
@ -0,0 +1,196 @@ |
|||
<view class="diagnosis-container"> |
|||
<!-- 自定义导航栏 --> |
|||
<view class="custom-navbar"> |
|||
<view class="nav-left"> |
|||
<view class="back-btn" bindtap="goBack"> |
|||
<text class="back-icon">←</text> |
|||
</view> |
|||
</view> |
|||
<view class="nav-center"> |
|||
<text class="nav-title">AI智能问诊</text> |
|||
<text class="nav-subtitle">与牧健康助手</text> |
|||
</view> |
|||
<view class="nav-right"> |
|||
<view class="more-btn" bindtap="showMoreMenu">···</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 医生信息卡片 --> |
|||
<view class="doctor-card"> |
|||
<view class="doctor-avatar"> |
|||
<image class="avatar-img" src="/pages/images/aiwz.png" mode="aspectFit"></image> |
|||
</view> |
|||
<view class="doctor-info"> |
|||
<text class="doctor-name">AI健康助手</text> |
|||
<text class="doctor-title">智能诊断专家</text> |
|||
<view class="doctor-tags"> |
|||
<view class="tag">24小时在线</view> |
|||
<view class="tag">专业诊断</view> |
|||
<view class="tag">快速响应</view> |
|||
</view> |
|||
</view> |
|||
<view class="online-status online">在线</view> |
|||
</view> |
|||
|
|||
<!-- 聊天区域 --> |
|||
<scroll-view |
|||
class="chat-container" |
|||
scroll-y |
|||
scroll-into-view="{{'msg-' + (messages.length - 1)}}" |
|||
scroll-with-animation="true" |
|||
> |
|||
<!-- 欢迎消息 --> |
|||
<view class="message-wrapper assistant"> |
|||
<view class="message-avatar"> |
|||
<image class="avatar" src="/pages/images/aiwz.png" mode="aspectFit"></image> |
|||
</view> |
|||
<view class="message-content"> |
|||
<view class="message-bubble assistant-bubble"> |
|||
<text class="message-text">您好!我是AI健康助手,有什么可以帮您?\n\n请描述你的牲畜的健康状况,我会为你提供专业的分析和建议。</text> |
|||
</view> |
|||
<view class="message-time">{{currentTime}}</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 消息列表 --> |
|||
<view wx:for="{{messages}}" wx:key="id" id="msg-{{index}}"> |
|||
<!-- 用户消息 --> |
|||
<view wx:if="{{item.type === 'user'}}" class="message-wrapper user"> |
|||
<view class="message-content"> |
|||
<view class="message-bubble user-bubble"> |
|||
<text class="message-text">{{item.content}}</text> |
|||
</view> |
|||
<view class="message-time">{{item.time}}</view> |
|||
</view> |
|||
<view class="message-avatar"> |
|||
<image class="avatar" src="/pages/images/tx.png" mode="aspectFit"></image> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- AI助手消息 --> |
|||
<view wx:if="{{item.type === 'assistant'}}" class="message-wrapper assistant"> |
|||
<view class="message-avatar"> |
|||
<image class="avatar" src="/pages/images/aiwz.png" mode="aspectFit"></image> |
|||
</view> |
|||
<view class="message-content"> |
|||
<view class="message-bubble assistant-bubble"> |
|||
<text class="message-text">{{item.content}}</text> |
|||
<!-- 诊断结果卡片 --> |
|||
<view wx:if="{{item.diagnosis}}" class="diagnosis-card"> |
|||
<view class="diagnosis-header"> |
|||
<text class="diagnosis-title">🤖 智能诊断结果</text> |
|||
</view> |
|||
<view class="diagnosis-item"> |
|||
<text class="diagnosis-label">可能病症:</text> |
|||
<text class="diagnosis-value">{{item.diagnosis.disease}}</text> |
|||
</view> |
|||
<view class="diagnosis-item"> |
|||
<text class="diagnosis-label">严重程度:</text> |
|||
<view class="severity-level {{item.diagnosis.severity}}"> |
|||
{{item.diagnosis.severityText}} |
|||
</view> |
|||
</view> |
|||
<view class="diagnosis-item"> |
|||
<text class="diagnosis-label">建议措施:</text> |
|||
<text class="diagnosis-value">{{item.diagnosis.suggestion}}</text> |
|||
</view> |
|||
<view class="diagnosis-footer"> |
|||
<text class="disclaimer">* 本结果仅供参考,请及时咨询专业兽医</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="message-time">{{item.time}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- AI正在输入 --> |
|||
<view wx:if="{{isAIThinking}}" class="message-wrapper assistant" style="justify-content: center;"> |
|||
<view class="message-content"> |
|||
<view class="message-bubble assistant-bubble typing"> |
|||
<view class="typing-indicator"> |
|||
<view class="typing-dot"></view> |
|||
<view class="typing-dot"></view> |
|||
<view class="typing-dot"></view> |
|||
<text class="typing-text">AI正在思考中...</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
|
|||
<!-- 快捷症状选择 --> |
|||
<view class="symptom-quick-select"> |
|||
<text class="section-title">快速选择症状</text> |
|||
<scroll-view class="symptom-tags" scroll-x> |
|||
<view class="symptom-tag" wx:for="{{quickSymptoms}}" wx:key="id" bindtap="selectQuickSymptom" data-symptom="{{item}}"> |
|||
<text class="tag-text">{{item}}</text> |
|||
</view> |
|||
</scroll-view> |
|||
</view> |
|||
|
|||
<!-- 输入区域 --> |
|||
<view class="input-area"> |
|||
<view class="input-wrapper"> |
|||
<input |
|||
class="message-input" |
|||
value="{{inputValue}}" |
|||
placeholder="描述您或牲畜的症状..." |
|||
placeholder-class="placeholder" |
|||
bindinput="onInput" |
|||
bindconfirm="sendMessage" |
|||
confirm-type="send" |
|||
focus="{{autoFocus}}" |
|||
/> |
|||
|
|||
</view> |
|||
<button class="send-btn" bindtap="sendMessage" hover-class="send-btn-hover"> |
|||
<text class="send-icon">↑</text> |
|||
</button> |
|||
</view> |
|||
|
|||
<!-- 症状选择器组件 --> |
|||
<symptom-selector |
|||
id="symptomSelector" |
|||
show="{{showSymptomSelector}}" |
|||
symptoms="{{symptoms}}" |
|||
selectedSymptoms="{{selectedSymptoms}}" |
|||
bind:select="onSymptomSelect" |
|||
bind:confirm="confirmSymptoms" |
|||
bind:close="closeSymptomSelector" |
|||
/> |
|||
|
|||
<!-- 更多菜单弹窗 --> |
|||
<view class="modal-overlay" wx:if="{{showMoreMenu}}" bindtap="closeMoreMenu"> |
|||
<view class="more-menu" catchtap="stopPropagation"> |
|||
<view class="menu-item" bindtap="clearHistory"> |
|||
<text class="menu-icon">🗑️</text> |
|||
<text class="menu-text">清空记录</text> |
|||
</view> |
|||
<view class="menu-item" bindtap="exportChat"> |
|||
<text class="menu-icon">📤</text> |
|||
<text class="menu-text">导出记录</text> |
|||
</view> |
|||
<view class="menu-item" bindtap="contactDoctor"> |
|||
<text class="menu-icon">👨⚕️</text> |
|||
<text class="menu-text">联系兽医</text> |
|||
</view> |
|||
<view class="menu-item" bindtap="showInstructions"> |
|||
<text class="menu-icon">❓</text> |
|||
<text class="menu-text">使用说明</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 加载动画 --> |
|||
<view class="loading-overlay" wx:if="{{isLoading}}"> |
|||
<view class="loading-content"> |
|||
<view class="pulse-animation"> |
|||
<view class="pulse-circle"></view> |
|||
<view class="pulse-circle"></view> |
|||
<view class="pulse-circle"></view> |
|||
</view> |
|||
<text class="loading-text">{{loadingText}}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
@ -0,0 +1,530 @@ |
|||
|
|||
.diagnosis-container { |
|||
min-height: 100vh; |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
background: linear-gradient(180deg, #f8fafc 0%, #f0f9ff 100%); |
|||
} |
|||
|
|||
/* 自定义导航栏 */ |
|||
.custom-navbar { |
|||
height: 120rpx; |
|||
padding-top: 40rpx; |
|||
background: linear-gradient(135deg, #86D8D0 0%, #6BC4BC 100%); |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 40rpx 32rpx 20rpx; |
|||
box-shadow: 0 2rpx 12rpx rgba(134, 216, 208, 0.2); |
|||
} |
|||
|
|||
.nav-left, .nav-right { |
|||
width: 80rpx; |
|||
} |
|||
|
|||
.nav-center { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
} |
|||
|
|||
.nav-title { |
|||
font-size: 36rpx; |
|||
font-weight: 600; |
|||
color: white; |
|||
margin-bottom: 4rpx; |
|||
} |
|||
|
|||
.nav-subtitle { |
|||
font-size: 22rpx; |
|||
color: rgba(255, 255, 255, 0.8); |
|||
} |
|||
|
|||
.back-btn { |
|||
width: 64rpx; |
|||
height: 64rpx; |
|||
border-radius: 50%; |
|||
background: rgba(255, 255, 255, 0.2); |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.back-icon { |
|||
color: white; |
|||
font-size: 36rpx; |
|||
font-weight: 300; |
|||
} |
|||
|
|||
.more-btn { |
|||
width: 64rpx; |
|||
height: 64rpx; |
|||
border-radius: 50%; |
|||
background: rgba(255, 255, 255, 0.2); |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
color: white; |
|||
font-size: 36rpx; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
/* 医生信息卡片 */ |
|||
.doctor-card { |
|||
background: white; |
|||
margin: 24rpx 32rpx; |
|||
padding: 32rpx; |
|||
border-radius: 20rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06); |
|||
position: relative; |
|||
} |
|||
|
|||
.doctor-avatar { |
|||
width: 120rpx; |
|||
height: 120rpx; |
|||
border-radius: 50%; |
|||
background: linear-gradient(135deg, #86D8D0 0%, #A8E6CF 100%); |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
margin-right: 24rpx; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.avatar-img { |
|||
width: 100rpx; |
|||
height: 100rpx; |
|||
} |
|||
|
|||
.doctor-info { |
|||
flex: 1; |
|||
} |
|||
|
|||
.doctor-name { |
|||
display: block; |
|||
font-size: 32rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
margin-bottom: 8rpx; |
|||
} |
|||
|
|||
.doctor-title { |
|||
display: block; |
|||
font-size: 24rpx; |
|||
color: #86D8D0; |
|||
margin-bottom: 16rpx; |
|||
} |
|||
|
|||
.doctor-tags { |
|||
display: flex; |
|||
gap: 12rpx; |
|||
} |
|||
|
|||
.tag { |
|||
font-size: 20rpx; |
|||
padding: 6rpx 12rpx; |
|||
background: #E8F4F3; |
|||
color: #6BC4BC; |
|||
border-radius: 20rpx; |
|||
} |
|||
|
|||
.online-status { |
|||
position: absolute; |
|||
right: 32rpx; |
|||
bottom: 32rpx; |
|||
font-size: 22rpx; |
|||
padding: 4rpx 12rpx; |
|||
border-radius: 12rpx; |
|||
} |
|||
|
|||
.online-status.online { |
|||
background: #e8f1f4; |
|||
color: #6b8fc4; |
|||
} |
|||
|
|||
/* 聊天容器 */ |
|||
.chat-container { |
|||
flex: 1; |
|||
/* padding: 0 32rpx; */ |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
/* 消息样式 */ |
|||
.message-wrapper { |
|||
display: flex; |
|||
margin: 40rpx 0; |
|||
animation: fadeIn 0.3s ease; |
|||
} |
|||
|
|||
@keyframes fadeIn { |
|||
from { opacity: 0; transform: translateY(20rpx); } |
|||
to { opacity: 1; transform: translateY(0); } |
|||
} |
|||
|
|||
.message-wrapper.user { |
|||
justify-content: flex-end; |
|||
} |
|||
|
|||
.message-content { |
|||
max-width: 70%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.message-wrapper.user .message-content { |
|||
align-items: flex-end; |
|||
} |
|||
|
|||
.message-wrapper.assistant .message-content { |
|||
align-items: flex-start; |
|||
} |
|||
|
|||
.message-avatar { |
|||
width: 80rpx; |
|||
height: 80rpx; |
|||
border-radius: 50%; |
|||
overflow: hidden; |
|||
margin: 0 20rpx; |
|||
align-self: flex-end; |
|||
} |
|||
|
|||
.avatar { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
/* 消息气泡 */ |
|||
.message-bubble { |
|||
padding: 24rpx; |
|||
border-radius: 24rpx; |
|||
position: relative; |
|||
line-height: 1.5; |
|||
} |
|||
|
|||
.assistant-bubble { |
|||
background: #E8F4F3; |
|||
border-radius: 0 24rpx 24rpx 24rpx; |
|||
} |
|||
|
|||
.user-bubble { |
|||
background: #86D8D0; |
|||
border-radius: 24rpx 0 24rpx 24rpx; |
|||
} |
|||
|
|||
.message-text { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
} |
|||
|
|||
.user-bubble .message-text { |
|||
color: white; |
|||
} |
|||
|
|||
/* 消息时间 */ |
|||
.message-time { |
|||
font-size: 22rpx; |
|||
color: #999; |
|||
margin-top: 8rpx; |
|||
} |
|||
|
|||
/* 诊断结果卡片 */ |
|||
.diagnosis-card { |
|||
background: white; |
|||
border-radius: 16rpx; |
|||
padding: 24rpx; |
|||
margin-top: 20rpx; |
|||
border-left: 6rpx solid #86D8D0; |
|||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08); |
|||
} |
|||
|
|||
.diagnosis-header { |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.diagnosis-title { |
|||
font-size: 28rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
} |
|||
|
|||
.diagnosis-item { |
|||
display: flex; |
|||
margin-bottom: 16rpx; |
|||
align-items: flex-start; |
|||
} |
|||
|
|||
.diagnosis-label { |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
width: 140rpx; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
.diagnosis-value { |
|||
font-size: 26rpx; |
|||
color: #333; |
|||
flex: 1; |
|||
line-height: 1.4; |
|||
} |
|||
|
|||
.severity-level { |
|||
padding: 4rpx 16rpx; |
|||
border-radius: 20rpx; |
|||
font-size: 24rpx; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.severity-level.low { |
|||
background: #E8F4F3; |
|||
color: #6BC4BC; |
|||
} |
|||
|
|||
.severity-level.moderate { |
|||
background: #FFF3E0; |
|||
color: #FF9800; |
|||
} |
|||
|
|||
.severity-level.high { |
|||
background: #FFEBEE; |
|||
color: #F44336; |
|||
} |
|||
|
|||
.diagnosis-footer { |
|||
margin-top: 20rpx; |
|||
padding-top: 16rpx; |
|||
border-top: 1rpx solid #eee; |
|||
} |
|||
|
|||
.disclaimer { |
|||
font-size: 22rpx; |
|||
color: #999; |
|||
font-style: italic; |
|||
} |
|||
|
|||
/* AI正在输入 */ |
|||
.typing { |
|||
min-width: 200rpx; |
|||
} |
|||
|
|||
.typing-indicator { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 8rpx; |
|||
} |
|||
|
|||
.typing-dot { |
|||
width: 12rpx; |
|||
height: 12rpx; |
|||
background: #86D8D0; |
|||
border-radius: 50%; |
|||
animation: typingAnimation 1.4s infinite ease-in-out; |
|||
} |
|||
|
|||
.typing-dot:nth-child(1) { animation-delay: -0.32s; } |
|||
.typing-dot:nth-child(2) { animation-delay: -0.16s; } |
|||
|
|||
@keyframes typingAnimation { |
|||
0%, 80%, 100% { transform: scale(0.8); opacity: 0.5; } |
|||
40% { transform: scale(1); opacity: 1; } |
|||
} |
|||
|
|||
.typing-text { |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
margin-left: 12rpx; |
|||
} |
|||
|
|||
/* 快捷症状选择 */ |
|||
.symptom-quick-select { |
|||
padding: 0 32rpx 20rpx; |
|||
} |
|||
|
|||
.section-title { |
|||
display: block; |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.symptom-tags { |
|||
white-space: nowrap; |
|||
display: flex; |
|||
gap: 20rpx; |
|||
} |
|||
|
|||
.symptom-tag { |
|||
display: inline-block; |
|||
padding: 16rpx 24rpx; |
|||
background: white; |
|||
border-radius: 24rpx; |
|||
border: 1rpx solid #E8F4F3; |
|||
box-shadow: 0 2rpx 8rpx rgba(134, 216, 208, 0.1); |
|||
transition: all 0.2s ease; |
|||
} |
|||
|
|||
.symptom-tag:active { |
|||
transform: scale(0.95); |
|||
background: #E8F4F3; |
|||
} |
|||
|
|||
.tag-text { |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
} |
|||
|
|||
/* 输入区域 */ |
|||
.input-area { |
|||
background: white; |
|||
padding: 20rpx 32rpx 40rpx; |
|||
border-top: 1rpx solid #f0f0f0; |
|||
display: flex; |
|||
align-items: flex-end; |
|||
gap: 20rpx; |
|||
} |
|||
|
|||
.input-wrapper { |
|||
flex: 1; |
|||
background: #f8fafc; |
|||
border-radius: 24rpx; |
|||
padding: 16rpx 24rpx; |
|||
border: 1rpx solid #E8F4F3; |
|||
} |
|||
|
|||
.message-input { |
|||
font-size: 28rpx; |
|||
min-height: 60rpx; |
|||
line-height: 1.5; |
|||
} |
|||
|
|||
.placeholder { |
|||
color: #aaa; |
|||
} |
|||
|
|||
|
|||
.send-btn { |
|||
width: 80rpx; |
|||
height: 80rpx; |
|||
border-radius: 50%; |
|||
background: #86D8D0; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
box-shadow: 0 4rpx 12rpx rgba(134, 216, 208, 0.3); |
|||
transition: all 0.2s ease; |
|||
} |
|||
|
|||
.send-btn-hover { |
|||
background: #6BC4BC; |
|||
transform: translateY(-2rpx); |
|||
box-shadow: 0 6rpx 16rpx rgba(134, 216, 208, 0.4); |
|||
} |
|||
|
|||
.send-icon { |
|||
color: white; |
|||
font-size: 36rpx; |
|||
font-weight: 300; |
|||
} |
|||
|
|||
/* 更多菜单 */ |
|||
.modal-overlay { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
z-index: 1000; |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
align-items: flex-start; |
|||
padding-top: 120rpx; |
|||
padding-right: 32rpx; |
|||
} |
|||
|
|||
.more-menu { |
|||
background: white; |
|||
border-radius: 16rpx; |
|||
padding: 16rpx 0; |
|||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.15); |
|||
min-width: 240rpx; |
|||
animation: slideIn 0.3s ease; |
|||
} |
|||
|
|||
@keyframes slideIn { |
|||
from { opacity: 0; transform: translateY(-20rpx); } |
|||
to { opacity: 1; transform: translateY(0); } |
|||
} |
|||
|
|||
.menu-item { |
|||
display: flex; |
|||
align-items: center; |
|||
padding: 24rpx 32rpx; |
|||
gap: 16rpx; |
|||
} |
|||
|
|||
.menu-item:active { |
|||
background: #f8fafc; |
|||
} |
|||
|
|||
.menu-icon { |
|||
font-size: 28rpx; |
|||
} |
|||
|
|||
.menu-text { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
} |
|||
|
|||
/* 加载动画 */ |
|||
.loading-overlay { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background: rgba(255, 255, 255, 0.9); |
|||
z-index: 1001; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.loading-content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
} |
|||
|
|||
.pulse-animation { |
|||
position: relative; |
|||
width: 120rpx; |
|||
height: 120rpx; |
|||
} |
|||
|
|||
.pulse-circle { |
|||
position: absolute; |
|||
width: 100%; |
|||
height: 100%; |
|||
border: 4rpx solid #86D8D0; |
|||
border-radius: 50%; |
|||
animation: pulse 2s infinite ease-in-out; |
|||
} |
|||
|
|||
.pulse-circle:nth-child(2) { animation-delay: 0.5s; } |
|||
.pulse-circle:nth-child(3) { animation-delay: 1s; } |
|||
|
|||
@keyframes pulse { |
|||
0% { transform: scale(0.8); opacity: 1; } |
|||
100% { transform: scale(1.5); opacity: 0; } |
|||
} |
|||
|
|||
.loading-text { |
|||
margin-top: 40rpx; |
|||
font-size: 28rpx; |
|||
color: #666; |
|||
} |
|||
@ -1,13 +1,39 @@ |
|||
//在这里面定义所有接口,一个文件管理所有接口,易于维护
|
|||
import { http } from './http'; // 引入刚刚封装好的http模块,import属于ES6的语法,微信开发者工具必须打开ES6转ES5选项
|
|||
|
|||
function login(params) { // 请求登录接口
|
|||
http('/login', 'post', params) // 接口请求的路由地址以及请求方法在此处传递
|
|||
// 授权登录接口
|
|||
function login(params) { |
|||
http('/auth/wechat/login', 'post', params) |
|||
} |
|||
|
|||
// 获取手机号接口
|
|||
function getPhoneNumber(params) { |
|||
http('/auth/wechat/bind', 'post', params) |
|||
} |
|||
|
|||
|
|||
// 轮播
|
|||
function carousel(params) { |
|||
http('/muhu/ads/list', 'get', params) |
|||
} |
|||
|
|||
// 通知公告
|
|||
function disaster(params) { |
|||
http('/muhu/warning/list', 'get', params) |
|||
} |
|||
|
|||
// 地图导航药店诊所
|
|||
function pharmacy(params) { |
|||
http('/muhu/info/list', 'get', params) |
|||
} |
|||
|
|||
// 办事指南
|
|||
function guidance(params) { |
|||
http('/muhu/guide/list', 'get', params) |
|||
} |
|||
|
|||
|
|||
|
|||
export default { // 暴露接口
|
|||
login |
|||
login,carousel,disaster,pharmacy,guidance,getPhoneNumber |
|||
} |
|||
@ -1,4 +1,4 @@ |
|||
//url: 'https://wxamp.chenhaitech.com/tglzw' + url, // 就是拼接上前缀,此接口域名是开放接口,可访问
|
|||
var baseUrl = 'https://wx.chenhaitech.com/guoziwei-prod-api' |
|||
// var baseUrl = 'http://192.168.101.111:8080'
|
|||
// var baseUrl = 'https://wx.chenhaitech.com/guoziwei-prod-api'
|
|||
var baseUrl = 'http://192.168.101.109:8080' |
|||
// var baseUrl = 'http://192.168.101.111:8081'
|
|||
module.exports = baseUrl |
|||