Browse Source

问诊列表页,详情页,接口联调。个人中心实名认证问题

master
ZhaoYang 2 months ago
parent
commit
0b7eb1e6ad
  1. 4
      app.json
  2. 10
      pages/home/home.js
  3. 271
      pages/personal/personal.js
  4. 23
      pages/personal/personal.wxml
  5. 49
      pages/personal/personal.wxss
  6. 246
      pagesA/pages/askingSyDetails/askingSyDetails.js
  7. 260
      pagesA/pages/askingSyDetails/askingSyDetails.wxml
  8. 81
      pagesA/pages/askingSyDetails/askingSyDetails.wxss
  9. 2
      pagesA/pages/attestation/attestation.wxss
  10. 161
      pagesA/pages/carouselDetail/carouselDetail.js
  11. 4
      pagesA/pages/carouselDetail/carouselDetail.json
  12. 112
      pagesA/pages/carouselDetail/carouselDetail.wxml
  13. 284
      pagesA/pages/carouselDetail/carouselDetail.wxss
  14. 4
      pagesA/pages/expertChat/expertChat.wxss
  15. 120
      pagesA/pages/todayInquiry/todayInquiry.js
  16. 4
      pagesA/pages/todayInquiry/todayInquiry.json
  17. 59
      pagesA/pages/todayInquiry/todayInquiry.wxml
  18. 156
      pagesA/pages/todayInquiry/todayInquiry.wxss
  19. 13
      utils/api.js

4
app.json

@ -20,7 +20,9 @@
"pages/medicineDetails/medicineDetails", "pages/medicineDetails/medicineDetails",
"pages/attestation/attestation", "pages/attestation/attestation",
"pages/noticeList/noticeList", "pages/noticeList/noticeList",
"pages/noticeListDetails/noticeListDetails"
"pages/noticeListDetails/noticeListDetails",
"pages/todayInquiry/todayInquiry",
"pages/carouselDetail/carouselDetail"
] ]
}, },
{ {

10
pages/home/home.js

@ -271,12 +271,10 @@ Page({
// 轮播图点击 // 轮播图点击
onSwiperTap(e) { onSwiperTap(e) {
console.log(1111, e); console.log(1111, e);
var item = e.currentTarget.dataset.value
wx.showToast({
title: `进入${item.adsType}`,
icon: 'none',
duration: 1000
});
var id = e.currentTarget.dataset.value.carouselId
wx.navigateTo({
url: `/pagesA/pages/carouselDetail/carouselDetail?id=${id}`,
})
}, },
// 通知点击 // 通知点击

271
pages/personal/personal.js

@ -4,11 +4,13 @@ const baseUrl = require('../../utils/baseUrl')
Page({ Page({
data: { data: {
// 用户信息 // 用户信息
avatarUrl: '',
avatarUrl: '', // 原始头像路径(相对路径)
avatarFullUrl: '', // 完整的头像URL(用于显示)
userInfo: { userInfo: {
user: {} user: {}
}, },
baseUrl: baseUrl, baseUrl: baseUrl,
displayNickName: '', // 显示用的昵称
// 弹窗状态 // 弹窗状态
showFeedbackModal: false, showFeedbackModal: false,
@ -35,15 +37,56 @@ Page({
// 上传状态 // 上传状态
isUploadingAvatar: false, isUploadingAvatar: false,
isUpdatingNickname: false
isUpdatingNickname: false,
// 消息数字
totalToday: 0
}, },
onLoad() { onLoad() {
this.getUserInfo()
this.gettoday()
// 初始化时从缓存加载用户信息
this.loadUserInfoFromCache()
}, },
onShow() { onShow() {
console.log('个人中心页面显示,重新获取用户信息')
// 每次显示页面都从服务器获取最新数据
this.getUserInfo() this.getUserInfo()
// 刷新消息数
this.gettoday()
},
// 从缓存加载用户信息(用于快速显示)
loadUserInfoFromCache() {
const cachedUserInfo = wx.getStorageSync('userInfo')
if (cachedUserInfo) {
const avatarFullUrl = this.buildAvatarUrl(cachedUserInfo.user?.avatar)
this.setData({
userInfo: cachedUserInfo,
avatarUrl: cachedUserInfo.user?.avatar || '',
avatarFullUrl: avatarFullUrl,
displayNickName: cachedUserInfo.user?.nickName || '微信用户'
})
}
},
// 构建完整的头像URL
buildAvatarUrl(avatarPath) {
if (!avatarPath) {
return '/pages/images/tx.png'
}
// 如果已经是完整URL,直接返回
if (avatarPath.startsWith('http')) {
return avatarPath
}
// 如果是相对路径,拼接baseUrl
// 确保路径格式正确
let cleanPath = avatarPath
if (cleanPath.startsWith('/')) {
cleanPath = cleanPath.substring(1)
}
return baseUrl + '/' + cleanPath
}, },
// 获取用户信息 // 获取用户信息
@ -51,58 +94,52 @@ Page({
http.UserInfo({ http.UserInfo({
data: {}, data: {},
success: (res) => { success: (res) => {
console.log('获取用户信息成功', res)
if (res.data && res.data.user) { if (res.data && res.data.user) {
wx.setStorageSync('userInfo', res.data)
// 构建完整的头像URL
const avatarFullUrl = this.buildAvatarUrl(res.data.user?.avatar)
// 更新数据
this.setData({ this.setData({
userInfo: res.data, userInfo: res.data,
avatarUrl: res.data.user?.avatar ? baseUrl + res.data.user.avatar : ''
avatarUrl: res.data.user?.avatar || '',
avatarFullUrl: avatarFullUrl,
displayNickName: res.data.user?.nickName || '微信用户'
}) })
// 更新缓存
wx.setStorageSync('userInfo', res.data)
} }
}, },
fail: (err) => { fail: (err) => {
console.error('获取用户信息失败:', err) console.error('获取用户信息失败:', err)
// 使用缓存的用户信息 // 使用缓存的用户信息
const cachedUserInfo = wx.getStorageSync('userInfo')
if (cachedUserInfo) {
this.setData({
userInfo: cachedUserInfo,
avatarUrl: cachedUserInfo.user?.avatar ? baseUrl + cachedUserInfo.user.avatar : ''
})
}
this.loadUserInfoFromCache()
} }
}) })
}, },
// 更新用户信息到服务器
updateUserInfo() {
const formData = this.data.formData
// 过滤掉空值
const dataToUpdate = {}
if (formData.avatar) dataToUpdate.avatar = formData.avatar
if (formData.nickName) dataToUpdate.nickName = formData.nickName
if (Object.keys(dataToUpdate).length === 0) return
http.revise({
data: dataToUpdate,
success: (res) => {
// 清空表单数据
this.setData({
'formData.avatar': null,
'formData.nickName': null
})
// 立即刷新用户信息
this.getUserInfo()
// 问诊消息 - 获取今日消息数
gettoday() {
http.today({
data: {},
success: res => {
if (res.rows && res.rows[0]) {
const num = res.rows[0].totalTodayReplyCount || 0
this.setData({
totalToday: num
})
}
}, },
fail: (err) => {
console.error('更新失败:', err)
this.showToast('更新失败,请重试')
fail: err => {
console.error('获取消息数失败', err)
} }
}) })
}, },
// 选择头像 // 选择头像
onChooseAvatar(e) { onChooseAvatar(e) {
// 防止重复上传
if (this.data.isUploadingAvatar) { if (this.data.isUploadingAvatar) {
this.showToast('正在上传中...') this.showToast('正在上传中...')
return return
@ -130,27 +167,62 @@ Page({
filePath: avatarUrl, filePath: avatarUrl,
name: 'file', name: 'file',
success: (uploadRes) => { success: (uploadRes) => {
wx.hideLoading()
try { try {
const result = JSON.parse(uploadRes.data) const result = JSON.parse(uploadRes.data)
console.log('上传结果', result)
if (result && result.fileName) { if (result && result.fileName) {
// 立即更新本地显示
// 获取上传后的文件路径
const uploadedFilePath = result.fileName
// 构建完整的头像URL
const fullAvatarUrl = this.buildAvatarUrl(uploadedFilePath)
console.log('上传成功,新头像路径:', uploadedFilePath)
console.log('完整头像URL:', fullAvatarUrl)
// 1. 立即更新本地显示
this.setData({ this.setData({
avatarUrl: avatarUrl,
'formData.avatar': result.fileName,
'userInfo.user.avatar': result.fileName
avatarUrl: uploadedFilePath,
avatarFullUrl: fullAvatarUrl,
'userInfo.user.avatar': uploadedFilePath
}) })
// 更新到服务器
this.updateUserInfo()
// 2. 更新缓存中的用户信息
const cachedUserInfo = wx.getStorageSync('userInfo') || {}
if (!cachedUserInfo.user) {
cachedUserInfo.user = {}
}
cachedUserInfo.user.avatar = uploadedFilePath
wx.setStorageSync('userInfo', cachedUserInfo)
console.log(3435353,uploadedFilePath);
// 3. 单独调用更新头像的API
http.revise({
data: { avatar: uploadedFilePath },
success: (res) => {
console.log('头像更新成功')
wx.hideLoading()
this.showToast('头像更新成功')
// 4. 重新获取用户信息以确保数据同步
setTimeout(() => {
this.getUserInfo()
}, 500)
},
fail: (err) => {
console.error('头像更新失败:', err)
wx.hideLoading()
this.showToast('头像保存失败,请重试')
}
})
this.showToast('头像更新成功')
} else { } else {
throw new Error('上传失败')
throw new Error('上传失败:返回数据格式错误')
} }
} catch (error) { } catch (error) {
console.error('解析上传结果失败:', error) console.error('解析上传结果失败:', error)
wx.hideLoading()
this.showToast('上传失败,请重试') this.showToast('上传失败,请重试')
} }
}, },
@ -169,7 +241,7 @@ Page({
editNickname() { editNickname() {
this.setData({ this.setData({
showNicknameModal: true, showNicknameModal: true,
newNickname: this.data.userInfo.user?.nickName || ''
newNickname: this.data.userInfo.user?.nickName || this.data.displayNickName || ''
}) })
}, },
@ -195,7 +267,8 @@ Page({
} }
// 如果昵称没有变化,直接关闭弹窗 // 如果昵称没有变化,直接关闭弹窗
if (newNickname === this.data.userInfo.user?.nickName) {
const currentNickName = this.data.userInfo.user?.nickName || this.data.displayNickName
if (newNickname === currentNickName) {
this.hideNicknameModal() this.hideNicknameModal()
return return
} }
@ -205,37 +278,60 @@ Page({
// 立即更新本地显示 // 立即更新本地显示
this.setData({ this.setData({
'userInfo.user.nickName': newNickname, 'userInfo.user.nickName': newNickname,
displayNickName: newNickname,
'formData.nickName': newNickname 'formData.nickName': newNickname
}) })
// 更新到服务器
this.updateUserInfo()
// 更新缓存
const cachedUserInfo = wx.getStorageSync('userInfo') || {}
if (!cachedUserInfo.user) {
cachedUserInfo.user = {}
}
cachedUserInfo.user.nickName = newNickname
wx.setStorageSync('userInfo', cachedUserInfo)
this.setData({
showNicknameModal: false,
isUpdatingNickname: false
// 更新到服务器
http.revise({
data: { nickName: newNickname },
success: (res) => {
console.log('昵称更新成功')
this.setData({
showNicknameModal: false,
isUpdatingNickname: false,
'formData.nickName': null
})
this.showToast('昵称修改成功')
// 重新获取用户信息以确保数据同步
setTimeout(() => {
this.getUserInfo()
}, 500)
},
fail: (err) => {
console.error('昵称更新失败:', err)
this.setData({ isUpdatingNickname: false })
this.showToast('修改失败,请重试')
}
}) })
this.showToast('昵称修改成功')
}, },
// 查看问诊消息 // 查看问诊消息
goToConsultation() { goToConsultation() {
wx.navigateTo({ wx.navigateTo({
url: ''
url: '/pagesA/pages/todayInquiry/todayInquiry'
}) })
}, },
// 查看问答消息 // 查看问答消息
goToQA() { goToQA() {
wx.navigateTo({ wx.navigateTo({
url: ''
url: '' // 请填写实际的问答消息页面路径
}) })
}, },
// 实名认证 // 实名认证
goToAuth() { goToAuth() {
if (this.data.userInfo.authStatus) {
if (this.data.userInfo.authStatus == '已认证') {
this.showToast('您已完成实名认证') this.showToast('您已完成实名认证')
} else { } else {
wx.navigateTo({ wx.navigateTo({
@ -250,12 +346,16 @@ Page({
showFeedbackModal: true, showFeedbackModal: true,
feedbackContent: '', feedbackContent: '',
canSubmit: false, canSubmit: false,
isSubmitting: false
isSubmitting: false,
textareaFocus: true
}) })
}, },
hideFeedback() { hideFeedback() {
this.setData({ showFeedbackModal: false })
this.setData({
showFeedbackModal: false,
textareaFocus: false
})
}, },
// 反馈内容输入 // 反馈内容输入
@ -272,7 +372,6 @@ Page({
// 提交反馈 // 提交反馈
submitFeedback() { submitFeedback() {
if (!this.data.canSubmit || this.data.isSubmitting) return if (!this.data.canSubmit || this.data.isSubmitting) return
const content = this.data.feedbackContent.trim() const content = this.data.feedbackContent.trim()
if (content.length < 5) { if (content.length < 5) {
this.showToast('请填写详细的反馈内容') this.showToast('请填写详细的反馈内容')
@ -281,28 +380,28 @@ Page({
this.setData({ isSubmitting: true }) this.setData({ isSubmitting: true })
// 提交
setTimeout(() => {
console.log('提交反馈:', content)
http.feedback({
data:{
content:content
},
success:res=>{
if(res.code==200){
this.showToast('感谢您的反馈!')
}else{
this.showToast('反馈失败!')
}
this.setData({
isSubmitting: false,
showFeedbackModal: false
})
http.feedback({
data: {
content: content
},
success: res => {
if (res.code == 200) {
this.showToast('感谢您的反馈!')
} else {
this.showToast('反馈失败!')
} }
})
}, 1500)
this.setData({
isSubmitting: false,
showFeedbackModal: false,
textareaFocus: false
})
},
fail: (err) => {
console.error('反馈失败:', err)
this.showToast('反馈失败,请重试')
this.setData({ isSubmitting: false })
}
})
}, },
// 退出登录相关 // 退出登录相关
@ -317,7 +416,7 @@ Page({
doLogout() { doLogout() {
// 清除本地存储 // 清除本地存储
wx.clearStorageSync() wx.clearStorageSync()
// 跳转到登录页 // 跳转到登录页
wx.reLaunch({ wx.reLaunch({
url: '/pages/login/login' url: '/pages/login/login'
@ -340,6 +439,7 @@ Page({
// 下拉刷新 // 下拉刷新
onPullDownRefresh() { onPullDownRefresh() {
this.getUserInfo() this.getUserInfo()
this.gettoday() // 刷新消息数
setTimeout(() => { setTimeout(() => {
wx.stopPullDownRefresh() wx.stopPullDownRefresh()
@ -347,11 +447,4 @@ Page({
}, 1000) }, 1000)
}, },
// 分享
onShareAppMessage() {
return {
title: '健康守护 - 您的个人健康中心',
path: '/pages/personal-center/index'
}
}
}) })

23
pages/personal/personal.wxml

@ -1,23 +1,23 @@
<view class="personal-center"> <view class="personal-center">
<!-- 用户信息区域 -->
<view class="user-section fade-in">
<!-- 用户信息区域 -->
<view class="user-section fade-in">
<view class="user-card"> <view class="user-card">
<!-- 头像 -->
<button class="avatar-btn" open-type="chooseAvatar" bindchooseavatar="onChooseAvatar">
<image class="avatar" src="{{baseUrl + userInfo.user.avatar || '/pages/images/tx.png'}}" mode="aspectFill"></image>
<!-- 头像 - 修复显示问题 -->
<button class="avatar-btn" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
<image class="avatar" src="{{avatarFullUrl || '/pages/images/tx.png'}}" mode="aspectFill"></image>
<view class="avatar-edit-tip">点击修改</view> <view class="avatar-edit-tip">点击修改</view>
</button> </button>
<!-- 用户信息 --> <!-- 用户信息 -->
<view class="user-info"> <view class="user-info">
<view class="nickname-section" bindtap="editNickname"> <view class="nickname-section" bindtap="editNickname">
<text class="nickname">{{userInfo.user.nickName || '微信用户'}}</text>
<text class="nickname">{{displayNickName || '微信用户'}}</text>
<image src="/pages/images/bj.png"></image> <image src="/pages/images/bj.png"></image>
</view> </view>
<view class="user-meta"> <view class="user-meta">
<view class="auth-tag {{userInfo.isVerified ? 'verified' : ''}}" bindtap="goToAuth"> <view class="auth-tag {{userInfo.isVerified ? 'verified' : ''}}" bindtap="goToAuth">
<text>{{userInfo.authStatus ? '已认证' : '未认证'}}</text>
<text>{{userInfo.authStatus}}</text>
</view> </view>
</view> </view>
</view> </view>
@ -34,12 +34,15 @@
<view class="message-item" bindtap="goToConsultation"> <view class="message-item" bindtap="goToConsultation">
<view class="message-icon-wrapper"> <view class="message-icon-wrapper">
<image class="message-icon" src="/pages/images/wz.png" mode=""></image> <image class="message-icon" src="/pages/images/wz.png" mode=""></image>
<!-- 动态数字气泡,有动画效果 -->
<view class="badge" wx:if="{{totalToday > 0}}">
<view class="badge-dot"></view>
<view class="badge-num animation-badge">{{totalToday}}</view>
</view>
</view> </view>
<text class="message-label">问诊消息</text> <text class="message-label">问诊消息</text>
</view> </view>
<view class="divider"></view> <view class="divider"></view>
<view class="message-item" bindtap="goToQA"> <view class="message-item" bindtap="goToQA">
<view class="message-icon-wrapper"> <view class="message-icon-wrapper">
<image class="message-icon" src="/pages/images/wdxx.png" mode=""></image> <image class="message-icon" src="/pages/images/wdxx.png" mode=""></image>
@ -59,7 +62,7 @@
<text class="item-title">实名认证</text> <text class="item-title">实名认证</text>
</view> </view>
<view class="item-status {{userInfo.isVerified ? 'verified' : ''}}"> <view class="item-status {{userInfo.isVerified ? 'verified' : ''}}">
{{userInfo.authStatus ? '已认证' : '去认证'}}
{{userInfo.authStatus}}
</view> </view>
</view> </view>

49
pages/personal/personal.wxss

@ -255,6 +255,55 @@
height: 60rpx; height: 60rpx;
} }
/* 数字气泡 - 定位在顶部 */
.badge {
position: absolute;
top: -10rpx;
right: -10rpx;
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
}
.badge-num {
background: linear-gradient(135deg, #ff6b6b, #ee5253);
border-radius: 36rpx;
color: white;
font-size: 22rpx;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
padding: 0 10rpx;
box-shadow: 0 4rpx 8rpx rgba(238, 82, 83, 0.3);
}
/* 动画效果:跳动+呼吸 */
.animation-badge {
animation: badgeBounce 2.5s ease-in-out infinite;
}
@keyframes badgeBounce {
0%, 100% {
transform: scale(1);
}
30% {
transform: scale(1.2);
}
50% {
transform: scale(1.1);
}
70% {
transform: scale(1.15);
}
}
/* 可选的小红点效果(如果有需要可以保留,当前用的是数字) */
.badge-dot {
display: none; /* 隐藏,用数字替代 */
}
.message-label { .message-label {
font-size: 26rpx; font-size: 26rpx;
color: #475569; color: #475569;

246
pagesA/pages/askingSyDetails/askingSyDetails.js

@ -1,13 +1,14 @@
import http from '../../../utils/api' import http from '../../../utils/api'
const baseUrl = require('../../../utils/baseUrl') const baseUrl = require('../../../utils/baseUrl')
Page({ Page({
/** /**
* 页面的初始数据 * 页面的初始数据
*/ */
data: { data: {
diagnosisData:{},
replies:[],
baseUrl:baseUrl,
diagnosisData: {},
replies: [],
baseUrl: baseUrl,
refreshing: false refreshing: false
}, },
@ -17,45 +18,95 @@ Page({
onLoad(options) { onLoad(options) {
if (options.data) { if (options.data) {
// 根据id加载兽医回复数据 // 根据id加载兽医回复数据
const data = JSON.parse(decodeURIComponent(options.data));
if(data.images){
const images = data.images.split(',')
this.setData({
images:images
})
const data = JSON.parse(decodeURIComponent(options.data));
// 处理用户图片 - 确保是数组格式
if (data.images) {
if (typeof data.images === 'string') {
data.images = data.images.split(',')
}
console.log('用户图片:', data.images);
} else {
data.images = [];
} }
this.setData({ this.setData({
diagnosisData:data,
diagnosisData: data,
}) })
this.loadDiagnosisData(data.formId); this.loadDiagnosisData(data.formId);
} }
}, },
// 加载问诊数据
/**
* 加载问诊数据兽医回复
* @param {string} id - 问诊ID
*/
loadDiagnosisData(id) { loadDiagnosisData(id) {
console.log('加载问诊数据:', id); console.log('加载问诊数据:', id);
http.wzdxq({
data:{
consultationId:id
},
success:res=>{
console.log(111111111,res);
this.setData({
replies:res.rows
})
}
})
http.wzdxq({
data: {
consultationId: id
},
success: res => {
// 处理兽医回复的图片
let replies = [];
if (res && res.rows) {
replies = res.rows || [];
// 遍历每个回复,处理图片字段
for (let i = 0; i < replies.length; i++) {
const item = replies[i];
// 处理图片 - 确保是数组格式
if (item.images) {
if (typeof item.images === 'string') {
// 如果是空字符串,设为空数组
if (item.images.trim() === '') {
item.images = [];
} else {
// 按逗号分割字符串
item.images = item.images.split(',');
}
} else if (Array.isArray(item.images)) {
// 已经是数组,但需要过滤空值
item.images = item.images.filter(img => img && img.trim() !== '');
} else {
item.images = [];
}
} else {
item.images = [];
}
console.log(`兽医回复[${i}]图片:`, item.images);
}
}
console.log('兽医回复数据:', replies);
this.setData({
replies: replies
})
},
fail: err => {
console.error('加载回复失败:', err);
wx.showToast({
title: '加载失败',
icon: 'none'
});
}
})
}, },
// 返回上一页
/**
* 返回上一页
*/
goBack() { goBack() {
wx.navigateBack(); wx.navigateBack();
}, },
// 分享
/**
* 分享
*/
onShare() { onShare() {
wx.showActionSheet({ wx.showActionSheet({
itemList: ['分享给好友', '保存到相册'], itemList: ['分享给好友', '保存到相册'],
@ -70,13 +121,18 @@ Page({
}); });
}, },
// 下拉刷新
/**
* 下拉刷新
*/
onRefresh() { onRefresh() {
this.setData({ this.setData({
refreshing: true refreshing: true
}); });
this.loadDiagnosisData(this.data.diagnosisData.formId)
if (this.data.diagnosisData && this.data.diagnosisData.formId) {
this.loadDiagnosisData(this.data.diagnosisData.formId)
}
setTimeout(() => { setTimeout(() => {
this.setData({ this.setData({
refreshing: false refreshing: false
@ -88,17 +144,131 @@ Page({
}, 1000); }, 1000);
}, },
// 预览图片
/**
* 预览用户图片
*/
previewImage(e) { previewImage(e) {
const current = e.currentTarget.dataset.url;
const urls = e.currentTarget.dataset.urls;
const urlsArray = urls.map(item=>{
return baseUrl+item
})
console.log(666,urlsArray);
const dataset = e.currentTarget.dataset;
const current = dataset.url;
const urls = dataset.urls || [];
// 构建完整URL数组
const urlsArray = urls.map(item => {
// 如果已经是完整URL,直接返回
if (typeof item === 'string' && (item.startsWith('http://') || item.startsWith('https://'))) {
return item;
}
// 否则拼接baseUrl
return baseUrl + item;
});
console.log('预览用户图片:', urlsArray);
wx.previewImage({ wx.previewImage({
current:current,
urls:urlsArray
current: current,
urls: urlsArray
}); });
}, },
/**
* 预览兽医回复图片 - 修复版
*/
previewReplyImage(e) {
const dataset = e.currentTarget.dataset;
// 获取数据 - 使用三种可能的来源
const currentFileName = dataset.url; // 当前点击的图片文件名
const currentFullUrl = dataset.fullurl; // 当前点击的图片完整URL
const urlsArray = dataset.urls || []; // 该回复的所有图片文件名数组
const currentIndex = dataset.currentIndex || 0; // 当前点击图片的索引
const replyIndex = dataset.replyIndex; // 回复在列表中的索引
console.log('预览兽医图片 - 数据集:', dataset);
// 方法1: 从replies数据中获取当前回复的图片列表
let targetUrls = [];
let targetCurrentUrl = '';
if (replyIndex !== undefined && this.data.replies[replyIndex]) {
// 从replies数据中获取完整的图片列表
const reply = this.data.replies[replyIndex];
if (reply.images && reply.images.length > 0) {
targetUrls = reply.images;
// 构建完整URL数组
const fullUrls = targetUrls.map(img => {
if (typeof img === 'string' && (img.startsWith('http://') || img.startsWith('https://'))) {
return img;
}
return baseUrl + img;
});
// 确定当前图片的完整URL
if (currentIndex < fullUrls.length) {
targetCurrentUrl = fullUrls[currentIndex];
} else if (currentFullUrl) {
targetCurrentUrl = currentFullUrl;
} else if (currentFileName) {
targetCurrentUrl = baseUrl + currentFileName;
}
console.log('预览兽医回复图片(从replies数据):', fullUrls, '当前:', targetCurrentUrl);
wx.previewImage({
current: targetCurrentUrl,
urls: fullUrls
});
return;
}
}
// 方法2: 使用dataset中的数据
if (urlsArray && urlsArray.length > 0) {
// 构建完整URL数组
const fullUrls = urlsArray.map(item => {
if (typeof item === 'string' && (item.startsWith('http://') || item.startsWith('https://'))) {
return item;
}
return baseUrl + item;
});
// 确定当前图片的完整URL
let currentUrl = '';
if (currentFullUrl) {
currentUrl = currentFullUrl;
} else if (currentIndex < fullUrls.length) {
currentUrl = fullUrls[currentIndex];
} else if (currentFileName) {
currentUrl = baseUrl + currentFileName;
}
console.log('预览兽医回复图片(从dataset):', fullUrls, '当前:', currentUrl);
wx.previewImage({
current: currentUrl,
urls: fullUrls
});
return;
}
// 方法3: 只预览单张图片
if (currentFullUrl) {
console.log('预览单张兽医图片:', [currentFullUrl]);
wx.previewImage({
current: currentFullUrl,
urls: [currentFullUrl]
});
} else if (currentFileName) {
const fullUrl = baseUrl + currentFileName;
console.log('预览单张兽医图片(拼接后):', [fullUrl]);
wx.previewImage({
current: fullUrl,
urls: [fullUrl]
});
} else {
wx.showToast({
title: '图片预览失败',
icon: 'none'
});
}
}
}); });

260
pagesA/pages/askingSyDetails/askingSyDetails.wxml

@ -1,151 +1,177 @@
<view class="xqbox"> <view class="xqbox">
<!-- 页面内容 -->
<scroll-view class="page-content" scroll-y refresher-enabled refresher-triggered="{{refreshing}}" bindrefresherrefresh="onRefresh">
<!-- 用户问诊卡片 -->
<view class="user-query-card card-enter">
<!-- 用户信息 -->
<view class="user-info-section">
<view class="avatar-wrapper">
<image class="user-avatar" src="/pages/images/tx.png"></image>
<!-- 页面内容 -->
<scroll-view class="page-content" scroll-y refresher-enabled refresher-triggered="{{refreshing}}" bindrefresherrefresh="onRefresh">
<!-- 用户问诊卡片 -->
<view class="user-query-card card-enter">
<!-- 用户信息 -->
<view class="user-info-section">
<view class="avatar-wrapper">
<image class="user-avatar" src="{{diagnosisData.avatar?baseUrl+diagnosisData.avatar:'/pages/images/tx.png'}}"></image>
</view>
<view class="user-details">
<view class="user-name-row">
<text class="user-name">{{diagnosisData.farmerName || '用户'}}</text>
<view class="status-badge {{diagnosisData.status === '已回复' ? 'status-replied' : 'status-pending'}} pulse">
{{diagnosisData.status}}
</view>
</view> </view>
<view class="user-details">
<view class="user-name-row">
<text class="user-name">{{diagnosisData.farmerName || '用户'}}</text>
<view class="status-badge {{diagnosisData.status === '已回复' ? 'status-replied' : 'status-pending'}} pulse">
{{diagnosisData.status}}
</view>
<view class="pet-info">
<view class="pet-info-tags">
<view class="pet-tag gradient-blue">{{diagnosisData.animalType}}</view>
<view class="pet-tag gradient-orange">{{diagnosisData.animalAge}}</view>
<view class="pet-tag gradient-pink">{{diagnosisData.animalGender}}</view>
</view> </view>
<view class="pet-info">
<view class="pet-info-tags">
<view class="pet-tag gradient-blue">{{diagnosisData.animalType}}</view>
<view class="pet-tag gradient-orange">{{diagnosisData.animalAge}}</view>
<view class="pet-tag gradient-pink">{{diagnosisData.animalGender}}</view>
</view>
<view class="time-info">
<text class="time-text">{{diagnosisData.createdTime}}</text>
</view>
<view class="time-info">
<text class="time-text">{{diagnosisData.createdTime}}</text>
</view> </view>
</view> </view>
</view> </view>
</view>
<!-- 症状描述 -->
<view class="symptom-section">
<view class="section-header">
<text class="section-title">症状描述</text>
<view class="title-decoration"></view>
</view>
<view class="symptom-content">
<view class="quote-left">
<text>"</text>
</view>
<text class="symptom-text">{{diagnosisData.description}}</text>
</view>
<!-- 症状描述 -->
<view class="symptom-section">
<view class="section-header">
<text class="section-title">症状描述</text>
<view class="title-decoration"></view>
</view> </view>
<!-- 相关图片 -->
<view class="image-section" wx:if="{{images && images.length > 0}}">
<view class="section-header">
<text class="section-title">相关图片</text>
<text class="image-count gradient-blue">{{images.length}}张</text>
<view class="symptom-content">
<view class="quote-left">
<text>"</text>
</view> </view>
<scroll-view class="images-scroll" scroll-x>
<view class="images-container">
<block wx:for="{{images}}" wx:key="*this" wx:for-index="index">
<view class="image-wrapper">
<image
class="symptom-image"
src="{{baseUrl+item}}"
mode="aspectFill"
bindtap="previewImage"
data-url="{{baseUrl+item}}"
data-urls="{{images}}"
></image>
</view>
</block>
</view>
</scroll-view>
</view>
<!-- 卡片装饰 -->
<view class="card-decoration">
<view class="decoration-dot dot-1"></view>
<view class="decoration-dot dot-2"></view>
<view class="decoration-dot dot-3"></view>
<text class="symptom-text">{{diagnosisData.description}}</text>
</view> </view>
</view> </view>
<!-- 兽医回复区域 -->
<view class="replies-section">
<!-- 相关图片 -->
<view class="image-section" wx:if="{{diagnosisData.images && diagnosisData.images.length > 0}}">
<view class="section-header"> <view class="section-header">
<text class="section-title">兽医回复</text>
<view class="reply-count gradient-purple">
<text class="count-number">{{replies.length}}</text>
<text class="count-text">条回复</text>
<text class="section-title">相关图片</text>
<text class="image-count gradient-blue">{{diagnosisData.images.length}}张</text>
</view>
<scroll-view class="images-scroll" scroll-x>
<view class="images-container">
<block wx:for="{{diagnosisData.images}}" wx:key="*this" wx:for-index="index">
<view class="image-wrapper">
<image
class="symptom-image"
src="{{baseUrl+item}}"
mode="aspectFill"
bindtap="previewImage"
data-url="{{baseUrl+item}}"
data-urls="{{diagnosisData.images}}"
data-type="user"
></image>
</view>
</block>
</view> </view>
</scroll-view>
</view>
<!-- 卡片装饰 -->
<view class="card-decoration">
<view class="decoration-dot dot-1"></view>
<view class="decoration-dot dot-2"></view>
<view class="decoration-dot dot-3"></view>
</view>
</view>
<!-- 兽医回复区域 -->
<view class="replies-section">
<view class="section-header">
<text class="section-title">兽医回复</text>
<view class="reply-count gradient-purple">
<text class="count-number">{{replies.length}}</text>
<text class="count-text">条回复</text>
</view> </view>
</view>
<!-- 回复列表 -->
<view class="replies-list">
<block wx:for="{{replies}}" wx:key="id" wx:for-index="index">
<view class="vet-reply-card fade-in-up" style="animation-delay: {{index * 0.1}}s;">
<!-- 兽医信息 -->
<view class="vet-info">
<view class="avatar-wrapper">
<image class="vet-avatar" src="{{item.avatar?baseUrl+item.avatar:'/pages/images/tx.png'}}"></image>
<view class="vet-verified"></view>
<!-- 回复列表 -->
<view class="replies-list">
<block wx:for="{{replies}}" wx:key="index" wx:for-index="index">
<view class="vet-reply-card fade-in-up" style="animation-delay: {{index * 0.1}}s;">
<!-- 兽医信息 -->
<view class="vet-info">
<view class="avatar-wrapper">
<image class="vet-avatar" src="{{item.avatar?baseUrl+item.avatar:'/pages/images/tx.png'}}"></image>
<view class="vet-verified"></view>
</view>
<view class="vet-details">
<view class="vet-name-row">
<text class="vet-name">{{item.replyName || '兽医'}}</text>
<view class="vet-badge gradient-gold" wx:if="{{item.title}}">
<text class="vet-title">{{item.title}}</text>
</view>
</view> </view>
<view class="vet-details">
<view class="vet-name-row">
<text class="vet-name">{{item.replyName}}</text>
<view class="vet-badge gradient-gold">
<text class="vet-title">{{item.title}}</text>
</view>
<view class="vet-meta">
<view class="meta-item" wx:if="{{item.hospital}}">
<text class="vet-hospital">{{item.hospital}}</text>
</view> </view>
<view class="vet-meta">
<view class="meta-item">
<text class="vet-hospital">{{item.hospital}}</text>
</view>
<view class="meta-item">
<text class="vet-experience">{{item.experience}}</text>
</view>
<view class="meta-item" wx:if="{{item.experience}}">
<text class="vet-experience">{{item.experience}}</text>
</view> </view>
</view> </view>
</view> </view>
</view>
<!-- 回复内容 -->
<view class="reply-content">
<view class="reply-bubble">
<text class="reply-text">{{item.content}}</text>
</view>
<!-- 回复内容 -->
<view class="reply-content">
<view class="reply-bubble">
<text class="reply-text">{{item.content}}</text>
</view> </view>
<!-- 回复底部 -->
<view class="reply-footer">
<view class="reply-time">
<text class="time-text">{{item.createdAt}}</text>
<!-- 兽医回复图片 - 优化后的图片网格布局,支持预览 -->
<view wx:if="{{item.images && item.images.length > 0}}" class="reply-images-section">
<view class="reply-images-grid grid-{{item.images.length}}">
<block wx:for="{{item.images}}" wx:key="this" wx:for-index="imgIndex">
<view class="reply-image-wrapper"
bindtap="previewReplyImage"
data-url="{{item}}"
data-fullurl="{{baseUrl + item}}"
data-urls="{{item.images}}"
data-current-index="{{imgIndex}}"
data-reply-index="{{index}}">
<image
class="reply-image"
src="{{baseUrl + item}}"
mode="aspectFill"
lazy-load
></image>
<!-- 如果图片数量大于4且当前是第4张,显示剩余数量遮罩(仅当图片很多时视觉优化,但预览仍全部可看) -->
<view wx:if="{{item.images.length > 4 && imgIndex === 3}}" class="image-more-mask">
<text class="more-count">+{{item.images.length - 4}}</text>
</view>
</view>
</block>
</view> </view>
</view> </view>
</view> </view>
</block>
<!-- 无回复状态 -->
<view wx:if="{{diagnosisData.replies.length === 0}}" class="no-replies fade-in">
<image class="no-replies-icon" src="/images/waiting.png"></image>
<text class="no-replies-title">等待兽医回复中</text>
<text class="no-replies-desc">专业兽医通常会在24小时内为您解答</text>
<view class="waiting-animation">
<view class="loading-dot dot-1"></view>
<view class="loading-dot dot-2"></view>
<view class="loading-dot dot-3"></view>
<!-- 回复底部 -->
<view class="reply-footer">
<view class="reply-time">
<text class="time-text">{{item.createdAt || item.createTime || ''}}</text>
</view>
</view> </view>
</view>
</block>
<!-- 无回复状态 -->
<view wx:if="{{replies.length === 0}}" class="no-replies fade-in">
<text class="no-replies-title">等待兽医回复中</text>
<text class="no-replies-desc">专业兽医通常会在24小时内为您解答</text>
<view class="waiting-animation">
<view class="loading-dot dot-1"></view>
<view class="loading-dot dot-2"></view>
<view class="loading-dot dot-3"></view>
</view> </view>
</view> </view>
</view> </view>
</view>
<!-- 底部安全区域 -->
<view class="page-bottom"></view>
</scroll-view>
<!-- 底部安全区域 -->
<view class="page-bottom"></view>
</scroll-view>
</view> </view>

81
pagesA/pages/askingSyDetails/askingSyDetails.wxss

@ -252,7 +252,7 @@
font-weight: 500; font-weight: 500;
} }
/* 症状描述区域 - 调整到最左边 */
/* 症状描述区域 */
.symptom-section { .symptom-section {
padding: 32rpx; padding: 32rpx;
position: relative; position: relative;
@ -544,7 +544,6 @@
} }
/* 无回复状态 */ /* 无回复状态 */
.no-replies { .no-replies {
background: #FFFFFF; background: #FFFFFF;
@ -557,13 +556,6 @@
overflow: hidden; overflow: hidden;
} }
.no-replies-icon {
width: 200rpx;
height: 150rpx;
margin-bottom: 32rpx;
opacity: 0.6;
filter: hue-rotate(200deg);
}
.no-replies-title { .no-replies-title {
font-size: 32rpx; font-size: 32rpx;
@ -604,4 +596,75 @@
/* 页面底部安全区域 */ /* 页面底部安全区域 */
.page-bottom { .page-bottom {
height: 60rpx; height: 60rpx;
}
/* 新增兽医回复图片预览 */
.reply-images-section {
margin-top: 24rpx;
padding: 0 8rpx;
}
.reply-images-grid {
display: grid;
gap: 12rpx;
width: 100%;
}
/* 根据图片数量自适应网格 */
.reply-images-grid.grid-1 {
grid-template-columns: repeat(1, minmax(200rpx, 320rpx));
justify-content: start;
}
.reply-images-grid.grid-2 {
grid-template-columns: repeat(2, 1fr);
}
.reply-images-grid.grid-3,
.reply-images-grid.grid-4,
.reply-images-grid:not(.grid-1):not(.grid-2) {
/* 超过2张时显示为2列网格*/
grid-template-columns: repeat(2, 1fr);
}
.reply-image-wrapper {
position: relative;
border-radius: 16rpx;
overflow: hidden;
background-color: #f5f5f5;
aspect-ratio: 1 / 1; /* 保持正方形 */
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
transition: transform 0.2s ease;
}
.reply-image-wrapper:active {
transform: scale(0.98);
}
.reply-image {
width: 100%;
height: 100%;
border-radius: 16rpx;
object-fit: cover;
}
/* 图片数量遮罩(超过4张时显示) */
.image-more-mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
border-radius: 16rpx;
}
.more-count {
color: #fff;
font-size: 36rpx;
font-weight: 700;
text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.3);
} }

2
pagesA/pages/attestation/attestation.wxss

@ -1371,7 +1371,6 @@ page {
visibility: hidden; visibility: hidden;
transition: all 0.3s ease; transition: all 0.3s ease;
z-index: 9999; z-index: 9999;
padding: 40rpx;
} }
.modal-overlay.show { .modal-overlay.show {
@ -1380,7 +1379,6 @@ page {
} }
.modal-container { .modal-container {
width: 600rpx;
max-width: 90vw; max-width: 90vw;
background: #fff; background: #fff;
border-radius: 20rpx; border-radius: 20rpx;

161
pagesA/pages/carouselDetail/carouselDetail.js

@ -0,0 +1,161 @@
import http from '../../../utils/api';
const baseUrl = require('../../../utils/baseUrl');
Page({
/**
* 页面的初始数据
*/
data: {
baseUrl: baseUrl,
detailInfo: {},
id: null,
cardAnimation: {} // 卡片动画数据
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
if (options.id) {
this.setData({ id: options.id });
this.getCarouselDetail(options.id);
this.initAnimation();
} else {
wx.showToast({
title: '参数错误',
icon: 'none'
});
}
},
/**
* 初始化卡片动画
*/
initAnimation() {
const animation = wx.createAnimation({
duration: 600,
timingFunction: 'ease-out',
delay: 100
});
animation.translateY(0).opacity(1).step();
this.setData({
cardAnimation: animation.export()
});
},
/**
* 获取轮播详情
*/
getCarouselDetail(id) {
wx.showLoading({ title: '加载中...', mask: true });
http.carouselDetail({
data: { id: id },
success: (res) => {
wx.hideLoading();
console.log('轮播详情:', res);
if (res && res.code === 200 && res.data) {
this.setData({
detailInfo: res.data
});
// 设置导航栏颜色为主题色
wx.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: res.data.textColor?.replace('#', '') || '2E7D32'
});
wx.setNavigationBarTitle({
title: res.data.title || '轮播详情'
});
} else {
wx.showToast({
title: res?.msg || '数据加载失败',
icon: 'none'
});
}
},
fail: (err) => {
wx.hideLoading();
console.error('请求失败:', err);
wx.showToast({
title: '网络错误',
icon: 'none'
});
}
});
},
/**
* 颜色调整函数用于渐变效果
*/
adjustColor(hex, percent) {
if (!hex) return '#4CAF50';
// 简单实现:如果传入颜色,返回稍浅的版本
// 这里为了简化,直接返回原色稍微变浅,实际项目中可使用颜色处理库
return hex;
},
/**
* 图片加载错误处理
*/
imageLoadError(e) {
console.warn('图片加载失败', e);
},
/**
* 返回上一页
*/
goBack() {
wx.navigateBack({
delta: 1
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {},
/**
* 生命周期函数--监听页面显示
*/
onShow() {},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
const { title, imageUrl } = this.data.detailInfo;
return {
title: title || '轮播详情',
imageUrl: this.data.baseUrl + (imageUrl || ''),
path: `/pages/carousel/detail/detail?id=${this.data.id}`
};
}
});

4
pagesA/pages/carouselDetail/carouselDetail.json

@ -0,0 +1,4 @@
{
"navigationBarTitleText":"轮播详情",
"usingComponents": {}
}

112
pagesA/pages/carouselDetail/carouselDetail.wxml

@ -0,0 +1,112 @@
<view class="carousel-detail-container" style="--bg-color: {{detailInfo.bgColor || '#F8F9FA'}};">
<!-- 沉浸式头部,带渐变遮罩和返回按钮 -->
<view class="hero-section">
<image
class="hero-image"
src="{{baseUrl + detailInfo.imageUrl}}"
mode="aspectFill"
binderror="imageLoadError"
></image>
<view class="hero-overlay" style="background: linear-gradient(to bottom, transparent 30%, {{detailInfo.bgColor || '#F8F9FA'}} 90%);"></view>
<!-- 返回按钮 -->
<view class="nav-back glass" bindtap="goBack">
<text class="iconfont icon-back">←</text>
</view>
<!-- 页面标题 - 仅在需要时显示 -->
<view class="page-title glass" wx:if="{{detailInfo.adsType}}">
<text>{{detailInfo.adsType}}</text>
</view>
</view>
<!-- 主要内容卡片 -->
<view class="content-card" animation="{{cardAnimation}}" style="--text-color: {{detailInfo.textColor || '#2E7D32'}};">
<!-- 标题区域 -->
<view class="title-section">
<text class="main-title" style="color: {{detailInfo.textColor || '#1A1A1A'}};">{{detailInfo.title || '无标题'}}</text>
<text class="sub-title">{{detailInfo.subtitle || '暂无副标题'}}</text>
</view>
<!-- 装饰分割线 -->
<view class="divider">
<view class="divider-line" style="background-color: {{detailInfo.textColor || '#2E7D32'}};"></view>
<view class="divider-dot" style="background-color: {{detailInfo.textColor || '#2E7D32'}};"></view>
<view class="divider-line" style="background-color: {{detailInfo.textColor || '#2E7D32'}};"></view>
</view>
<!-- 信息网格 -->
<view class="info-grid">
<!-- 尺寸信息卡片 -->
<view class="info-item" wx:if="{{detailInfo.imageSize}}">
<view class="info-icon">📐</view>
<view class="info-content">
<text class="info-label">图片尺寸</text>
<text class="info-value">{{detailInfo.imageSize}}</text>
</view>
</view>
<!-- 展示次数卡片 -->
<view class="info-item" wx:if="{{detailInfo.displayCount !== undefined}}">
<view class="info-icon">👁️</view>
<view class="info-content">
<text class="info-label">展示次数</text>
<text class="info-value">{{detailInfo.displayCount}}</text>
</view>
</view>
<!-- 点击次数卡片 -->
<view class="info-item" wx:if="{{detailInfo.clickCount !== undefined}}">
<view class="info-icon">🖱️</view>
<view class="info-content">
<text class="info-label">点击次数</text>
<text class="info-value">{{detailInfo.clickCount}}</text>
</view>
</view>
<!-- 创建时间卡片 -->
<view class="info-item" wx:if="{{detailInfo.createdAt}}">
<view class="info-icon">📅</view>
<view class="info-content">
<text class="info-label">创建时间</text>
<text class="info-value">{{detailInfo.createdAt}}</text>
</view>
</view>
<!-- 更新时间卡片 -->
<view class="info-item" wx:if="{{detailInfo.updatedAt}}">
<view class="info-icon">🔄</view>
<view class="info-content">
<text class="info-label">更新时间</text>
<text class="info-value">{{detailInfo.updatedAt}}</text>
</view>
</view>
<!-- 有效性状态卡片 - 使用优雅的徽章设计 -->
<view class="info-item status-item" wx:if="{{detailInfo.isActive !== undefined}}">
<view class="info-icon">⚡</view>
<view class="info-content">
<text class="info-label">状态</text>
<view class="status-badge" style="background-color: {{detailInfo.isActive === 1 ? '#4CAF50' : '#9E9E9E'}}20; border-color: {{detailInfo.isActive === 1 ? '#4CAF50' : '#9E9E9E'}};">
<text class="status-dot" style="background-color: {{detailInfo.isActive === 1 ? '#4CAF50' : '#9E9E9E'}};"></text>
<text class="status-text" style="color: {{detailInfo.isActive === 1 ? '#4CAF50' : '#9E9E9E'}};">{{detailInfo.isActive === 1 ? '有效' : '无效'}}</text>
</view>
</view>
</view>
</view>
<!-- 描述/备注区域(如果有remark字段) -->
<view class="remark-section" wx:if="{{detailInfo.remark}}">
<view class="remark-icon">📝</view>
<view class="remark-content">{{detailInfo.remark}}</view>
</view>
<!-- 辅助信息:始终有效标识 -->
<view class="always-valid" wx:if="{{detailInfo.isAlwaysValid === 1}}">
<text class="valid-icon">✨</text>
<text class="valid-text">长期有效</text>
</view>
</view>
</view>

284
pagesA/pages/carouselDetail/carouselDetail.wxss

@ -0,0 +1,284 @@
.carousel-detail-container {
min-height: 100vh;
background-color: var(--bg-color, #F8F9FA);
position: relative;
padding-bottom: 40rpx;
}
/* 沉浸式头部 */
.hero-section {
position: relative;
width: 100%;
height: 600rpx;
overflow: hidden;
}
.hero-image {
width: 100%;
height: 100%;
filter: brightness(0.9);
transition: transform 0.3s ease;
}
.hero-image:active {
transform: scale(1.02);
}
.hero-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 200rpx;
pointer-events: none;
}
/* 毛玻璃返回按钮 */
.nav-back {
position: absolute;
top: 60rpx;
left: 30rpx;
width: 72rpx;
height: 72rpx;
border-radius: 36rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 40rpx;
color: #333;
z-index: 10;
}
.glass {
background: rgba(255, 255, 255, 0.25);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1rpx solid rgba(255, 255, 255, 0.3);
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
}
.page-title {
position: absolute;
top: 60rpx;
right: 30rpx;
padding: 16rpx 32rpx;
border-radius: 40rpx;
font-size: 26rpx;
color: #333;
font-weight: 500;
z-index: 10;
letter-spacing: 1rpx;
}
/* 主要内容卡片 */
.content-card {
margin: -100rpx 30rpx 0;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-radius: 48rpx;
padding: 48rpx 32rpx;
box-shadow: 0 30rpx 60rpx rgba(0, 0, 0, 0.1),
0 10rpx 30rpx rgba(0, 0, 0, 0.05);
position: relative;
z-index: 5;
border: 1rpx solid rgba(255, 255, 255, 0.5);
opacity: 0;
transform: translateY(50rpx);
animation: cardFloat 0.6s ease-out forwards;
}
@keyframes cardFloat {
to {
opacity: 1;
transform: translateY(0);
}
}
/* 标题区域 */
.title-section {
margin-bottom: 40rpx;
}
.main-title {
display: block;
font-size: 56rpx;
font-weight: 700;
line-height: 1.3;
margin-bottom: 16rpx;
letter-spacing: -0.5rpx;
}
.sub-title {
display: block;
font-size: 30rpx;
color: #666;
line-height: 1.5;
font-weight: 400;
opacity: 0.8;
}
/* 装饰分割线 */
.divider {
display: flex;
align-items: center;
margin: 30rpx 0 40rpx;
}
.divider-line {
flex: 1;
height: 2rpx;
opacity: 0.2;
}
.divider-dot {
width: 8rpx;
height: 8rpx;
border-radius: 4rpx;
margin: 0 20rpx;
opacity: 0.5;
}
/* 信息网格 */
.info-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 24rpx;
margin-bottom: 40rpx;
}
.info-item {
background: rgba(0, 0, 0, 0.02);
border-radius: 28rpx;
padding: 28rpx 20rpx;
display: flex;
align-items: center;
border: 1rpx solid rgba(0, 0, 0, 0.03);
transition: all 0.3s ease;
}
.info-item:active {
transform: scale(0.98);
background: rgba(0, 0, 0, 0.04);
}
.info-icon {
font-size: 48rpx;
margin-right: 20rpx;
filter: drop-shadow(0 4rpx 8rpx rgba(0, 0, 0, 0.1));
}
.info-content {
flex: 1;
display: flex;
flex-direction: column;
}
.info-label {
font-size: 22rpx;
color: #999;
margin-bottom: 8rpx;
letter-spacing: 0.5rpx;
}
.info-value {
font-size: 28rpx;
font-weight: 600;
color: #333;
word-break: break-all;
}
/* 状态特殊样式 */
.status-item .info-content {
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.status-badge {
display: flex;
align-items: center;
padding: 8rpx 16rpx;
border-radius: 40rpx;
border-width: 1rpx;
border-style: solid;
background-color: rgba(76, 175, 80, 0.1);
}
.status-dot {
width: 16rpx;
height: 16rpx;
border-radius: 8rpx;
margin-right: 8rpx;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
.status-text {
font-size: 24rpx;
font-weight: 500;
}
/* 备注区域 */
.remark-section {
background: rgba(0, 0, 0, 0.02);
border-radius: 28rpx;
padding: 28rpx;
margin-bottom: 40rpx;
display: flex;
border-left: 8rpx solid var(--text-color, #2E7D32);
}
.remark-icon {
font-size: 40rpx;
margin-right: 20rpx;
}
.remark-content {
flex: 1;
font-size: 28rpx;
color: #444;
line-height: 1.6;
}
/* 始终有效标识 */
.always-valid {
display: flex;
align-items: center;
justify-content: center;
margin-top: 30rpx;
padding: 20rpx;
background: linear-gradient(135deg, rgba(255, 215, 0, 0.1), rgba(255, 215, 0, 0.05));
border-radius: 40rpx;
border: 1rpx solid rgba(255, 215, 0, 0.3);
}
.valid-icon {
font-size: 32rpx;
margin-right: 12rpx;
animation: starTwinkle 1.5s infinite;
}
@keyframes starTwinkle {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.7; transform: scale(1.1); }
}
.valid-text {
font-size: 26rpx;
color: #B8860B;
font-weight: 500;
}
/* 响应式调整 */
@media (min-width: 768px) {
.content-card {
max-width: 700rpx;
margin: -100rpx auto 0;
}
}

4
pagesA/pages/expertChat/expertChat.wxss

@ -491,7 +491,7 @@
height: 28rpx; height: 28rpx;
} }
/* 发送按钮 - 美观渐变绿色,完美垂直居中 */
/* 发送按钮 */
.send-btn { .send-btn {
background: linear-gradient(135deg, #07c160 0%, #06ae56 100%); background: linear-gradient(135deg, #07c160 0%, #06ae56 100%);
width: 112rpx; width: 112rpx;
@ -499,7 +499,7 @@
border-radius: 10rpx; border-radius: 10rpx;
border: none; border: none;
display: flex; display: flex;
align-items: center;s
align-items: center;
justify-content: center; justify-content: center;
transition: all 0.3s ease; transition: all 0.3s ease;
padding: 0; padding: 0;

120
pagesA/pages/todayInquiry/todayInquiry.js

@ -0,0 +1,120 @@
import http from '../../../utils/api'
const baseUrl = require('../../../utils/baseUrl')
Page({
/**
* 页面的初始数据
*/
data: {
list: [], // 问诊列表数据
loading: true, // 首次加载loading
hasMore: false, // 是否还有更多数据(根据后端分页逻辑调整,本例简单置false)
pageNum: 1, // 当前页码(若需要分页)
pageSize: 10,
total: 0,
baseUrl: baseUrl || '' // 图片前缀
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.getTodayList()
},
/**
* 获取今日问诊列表第一页
*/
getTodayList() {
this.setData({ loading: false })
http.today({
data: {
pageNum: this.data.pageNum,
pageSize: this.data.pageSize
// 根据接口实际需要可添加其他参数
},
success: (res) => {
console.log('今日问诊接口返回:', res)
if (res && res.code === 200) {
const rows = res.rows || []
const total = res.total || 0
// 处理图片字段可能为空字符串或null
rows.forEach(item => {
if (!item.images) item.images = ''
})
this.setData({
list: rows,
total: total,
hasMore: rows.length < total && rows.length >= this.data.pageSize // 简单判断
})
} else {
wx.showToast({ title: '数据加载失败', icon: 'none' })
}
},
fail: (err) => {
wx.showToast({ title: '网络错误', icon: 'none' })
console.error(err)
},
complete: () => {
this.setData({ loading: false })
}
})
},
/**
* 加载更多上拉触底
*/
loadMore() {
if (!this.data.hasMore) return
// 如果有分页需求,可在此累加pageNum再次请求,并将新数据concat
// 当前根据接口示例无分页参数,故简单提示
wx.showToast({ title: '暂无更多', icon: 'none' })
},
/**
* 跳转详情页
*/
// 查看详情
goDetail: function (e) {
console.log(e);
const data = e.currentTarget.dataset.value
wx.navigateTo({
url: `/pagesA/pages/askingSyDetails/askingSyDetails?data=${encodeURIComponent(JSON.stringify(data))}`,
});
},
/**
* 预览图片
*/
previewImage(e) {
const { src, list } = e.currentTarget.dataset
wx.previewImage({
current: src, // 当前显示图片
urls: list // 所有图片列表
})
},
/**
* 下拉刷新如果需要
*/
onPullDownRefresh() {
this.setData({ pageNum: 1 }, () => {
this.getTodayList()
wx.stopPullDownRefresh()
})
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
return {
title: '今日问诊列表',
path: '/pages/consult/today/today'
}
}
})

4
pagesA/pages/todayInquiry/todayInquiry.json

@ -0,0 +1,4 @@
{
"navigationBarTitleText":"今日问诊列表",
"usingComponents": {}
}

59
pagesA/pages/todayInquiry/todayInquiry.wxml

@ -0,0 +1,59 @@
<view class="container">
<!-- 加载中提示 -->
<view wx:if="{{loading}}" class="loading">
<text>加载中...</text>
</view>
<!-- 空列表提示 -->
<view wx:elif="{{list.length === 0}}" class="empty">
<text>暂无今日问诊</text>
</view>
<!-- 问诊列表 -->
<scroll-view
wx:else
scroll-y
class="scroll-list"
bindscrolltolower="loadMore"
lower-threshold="50"
>
<view class="list">
<view class="card" wx:for="{{list}}" wx:key="formId" data-value="{{item}}" bindtap="goDetail">
<!-- 用户信息行:头像、姓名、时间、状态 -->
<view class="user-row">
<image class="avatar" src="{{baseUrl + item.avatar}}" mode="aspectFill" lazy-load></image>
<view class="user-info">
<text class="name">{{item.farmerName}}</text>
<text class="time">{{item.createdTime}}</text>
</view>
<view class="status" data-status="{{item.status}}">{{item.status}}</view>
</view>
<!-- 病情描述卡片 -->
<view class="content-block">
<view class="desc">{{item.description}}</view>
<!-- 动物标签 -->
<view class="tag-group">
<text class="tag">{{item.animalType}}</text>
<text class="tag">{{item.animalGender}}</text>
<text class="tag">{{item.animalAge}}岁</text>
</view>
</view>
<!-- 底部互动信息 -->
<view class="card-footer">
<text>浏览 {{item.viewCount || 0}}</text>
<text>回复 {{item.replyCount || 0}}</text>
</view>
</view>
</view>
<!-- 加载更多 -->
<view class="load-more" wx:if="{{hasMore}}">
<text>加载更多...</text>
</view>
<view class="no-more" wx:elif="{{list.length > 0}}">
<text>没有更多了</text>
</view>
</scroll-view>
</view>

156
pagesA/pages/todayInquiry/todayInquiry.wxss

@ -0,0 +1,156 @@
.container {
min-height: 100vh;
background-color: #f5f7fa;
padding: 0 20rpx;
box-sizing: border-box;
}
.loading, .empty {
display: flex;
justify-content: center;
align-items: center;
height: 300rpx;
color: #999;
font-size: 28rpx;
}
.scroll-list {
height: 100vh;
}
.list {
padding: 20rpx 0;
}
.card {
background: #fff;
border-radius: 24rpx;
margin-bottom: 30rpx;
padding: 30rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
}
/* 用户行 */
.user-row {
display: flex;
align-items: center;
margin-bottom: 24rpx;
position: relative;
}
.avatar {
width: 72rpx;
height: 72rpx;
border-radius: 50%;
margin-right: 20rpx;
background-color: #eee;
}
.user-info {
flex: 1;
display: flex;
flex-direction: column;
}
.name {
font-size: 28rpx;
font-weight: 500;
color: #333;
margin-bottom: 4rpx;
}
.time {
font-size: 22rpx;
color: #999;
}
.status {
padding: 6rpx 20rpx;
background-color: #fff1f0;
border-radius: 30rpx;
font-size: 24rpx;
color: #f56c6c;
border: 1rpx solid #fbc4c4;
}
/* 根据状态可设置不同颜色,例如 “未回复” 保持红色,“已回复”变绿色 */
.status[data-status="未回复"] {
background-color: #fff1f0;
color: #f56c6c;
border-color: #fbc4c4;
}
.status[data-status="已回复"] {
background-color: #e8f7ef;
color: #2ecc71;
border-color: #a9e0c0;
}
/* 内容块 */
.content-block {
margin-bottom: 20rpx;
}
.desc {
font-size: 30rpx;
color: #333;
line-height: 1.5;
margin-bottom: 20rpx;
word-break: break-word;
}
.tag-group {
display: flex;
flex-wrap: wrap;
margin-bottom: 20rpx;
}
.tag {
background-color: #f0f2f5;
padding: 6rpx 24rpx;
border-radius: 30rpx;
font-size: 24rpx;
color: #666;
margin-right: 16rpx;
margin-bottom: 10rpx;
}
/* 图片九宫格简化版 */
.image-grid {
display: flex;
flex-wrap: wrap;
margin-top: 10rpx;
}
.grid-img {
width: 200rpx;
height: 200rpx;
border-radius: 16rpx;
margin-right: 16rpx;
margin-bottom: 16rpx;
background-color: #eee;
}
/* 底部栏 */
.card-footer {
display: flex;
align-items: center;
font-size: 24rpx;
color: #999;
border-top: 2rpx solid #f0f0f0;
padding-top: 20rpx;
margin-top: 10rpx;
}
.card-footer text {
margin-right: 30rpx;
}
/* 加载更多 */
.load-more, .no-more {
text-align: center;
padding: 30rpx 0 50rpx;
font-size: 26rpx;
color: #aaa;
}

13
utils/api.js

@ -16,6 +16,11 @@ function carousel(params) {
http('/muhu/ads/list', 'get', params) http('/muhu/ads/list', 'get', params)
} }
// 轮播详情
function carouselDetail(params) {
http('/muhu/ads/' + params.data.id, 'get', params)
}
// 通知公告 // 通知公告
function disaster(params) { function disaster(params) {
http('/muhu/warning/list', 'get', params) http('/muhu/warning/list', 'get', params)
@ -196,7 +201,6 @@ function experienceDetails(params) {
http('/vet/article/' + params.data.id, 'get', params) http('/vet/article/' + params.data.id, 'get', params)
} }
// 经验分享分类字典 // 经验分享分类字典
function experiencezd(params) { function experiencezd(params) {
http('/vet/article/options', 'get', params) http('/vet/article/options', 'get', params)
@ -222,7 +226,10 @@ function warningType(params) {
http('/system/dict/data/list', 'get', params) http('/system/dict/data/list', 'get', params)
} }
// 个人中心今日问诊
function today(params) {
http('/muhu/consultation/today', 'get', params)
}
export default { // 暴露接口 export default { // 暴露接口
@ -231,5 +238,5 @@ export default { // 暴露接口
recommendationXq,queryList,tipList,article,articleDetails,articleZd,policyelucidation, recommendationXq,queryList,tipList,article,articleDetails,articleZd,policyelucidation,
areaChildren,userCode,UserInfo,videoList,videoZd,videoDetails,forumList,forumAdd,forumDetails, areaChildren,userCode,UserInfo,videoList,videoZd,videoDetails,forumList,forumAdd,forumDetails,
forumReply,commentReply,experience,experiencezd,experienceDetails,realName,revise,feedback, forumReply,commentReply,experience,experiencezd,experienceDetails,realName,revise,feedback,
warningType,disasterDetail
warningType,disasterDetail,today,carouselDetail
} }
Loading…
Cancel
Save