Browse Source

远程诊疗,回复

master
ZhaoYang 2 months ago
parent
commit
2aa2d00033
  1. 4
      app.json
  2. 7
      pages/home/home.js
  3. 2
      pages/home/home.wxml
  4. BIN
      pagesA/images/kzt.png
  5. 66
      pagesA/pages/askingSy/askingSy.js
  6. 4
      pagesA/pages/askingSy/askingSy.json
  7. 98
      pagesA/pages/askingSy/askingSy.wxml
  8. 428
      pagesA/pages/askingSy/askingSy.wxss
  9. 569
      pagesA/pages/askingSyDetails/askingSyDetails.js
  10. 4
      pagesA/pages/askingSyDetails/askingSyDetails.json
  11. 243
      pagesA/pages/askingSyDetails/askingSyDetails.wxml
  12. 1067
      pagesA/pages/askingSyDetails/askingSyDetails.wxss
  13. 16
      utils/api.js

4
app.json

@ -9,7 +9,9 @@
{ {
"root": "pagesA", "root": "pagesA",
"pages": [ "pages": [
"pages/carouselDetail/carouselDetail"
"pages/carouselDetail/carouselDetail",
"pages/askingSy/askingSy",
"pages/askingSyDetails/askingSyDetails"
] ]
}, },
{ {

7
pages/home/home.js

@ -40,6 +40,13 @@ Page({
}) })
}, },
// 远程诊疗
bindYczl() {
wx.navigateTo({
url: '/pagesA/pages/askingSy/askingSy',
})
},
// 在线问答列表 // 在线问答列表
getforumList() { getforumList() {

2
pages/home/home.wxml

@ -53,7 +53,7 @@
<view class="card2_1">快捷回复</view> <view class="card2_1">快捷回复</view>
</view> </view>
<view class="card3"> <view class="card3">
<view class="card3_1 card3_kp" bind:tap="bindZj">
<view class="card3_1 card3_kp" bind:tap="bindYczl">
<view>远程诊疗</view> <view>远程诊疗</view>
<view>足不出户方便快捷</view> <view>足不出户方便快捷</view>
</view> </view>

BIN
pagesA/images/kzt.png

After

Width: 320  |  Height: 320  |  Size: 8.5 KiB

66
pagesA/pages/askingSy/askingSy.js

@ -0,0 +1,66 @@
import http from '../../../utils/api'
Page({
data: {
diagnosisList: []
},
onLoad: function () {
},
onShow:function(){
this.getwzd()
},
// 问诊单
getwzd() {
http.wzd({
data: {},
success: res => {
console.log(1111, res);
this.setData({
diagnosisList: res.rows
})
}
})
},
// 格式化日期显示
formatDate: function (dateString) {
const date = new Date(dateString);
const now = new Date();
const diff = now - date;
const diffDays = Math.floor(diff / (1000 * 60 * 60 * 24));
const diffHours = Math.floor(diff / (1000 * 60 * 60));
const diffMinutes = Math.floor(diff / (1000 * 60));
if (diffMinutes < 60) {
return `${diffMinutes}分钟前`;
} else if (diffHours < 24) {
return `${diffHours}小时前`;
} else if (diffDays === 1) {
return '昨天';
} else if (diffDays === 2) {
return '前天';
} else if (diffDays < 7) {
return `${diffDays}天前`;
} else {
const month = date.getMonth() + 1;
const day = date.getDate();
return `${month}${day}`;
}
},
// 查看详情
viewDetail: function (e) {
const data = e.currentTarget.dataset.value
wx.navigateTo({
url: `/pagesA/pages/askingSyDetails/askingSyDetails?data=${encodeURIComponent(JSON.stringify(data))}`,
});
},
});

4
pagesA/pages/askingSy/askingSy.json

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

98
pagesA/pages/askingSy/askingSy.wxml

@ -0,0 +1,98 @@
<view class="wzbox">
<!-- 顶部标题栏 -->
<view class="header">
<view class="header-content">
<view class="title-section">
<text class="title">远程诊疗</text>
<text class="subtitle">专业兽医在线解答</text>
</view>
</view>
<view class="header-decoration">
<view class="decoration-circle circle-1"></view>
<view class="decoration-circle circle-2"></view>
</view>
</view>
<!-- 问诊记录列表 -->
<scroll-view class="record-list" scroll-y enable-back-to-top>
<!-- 空状态 -->
<view wx:if="{{diagnosisList.length === 0}}" class="empty-state">
<image class="empty-icon" src="/pagesA/images/kzt.png" mode="widthFix"></image>
<text class="empty-text">暂无问诊记录</text>
<text class="empty-tip">开始您的第一次问诊吧</text>
</view>
<!-- 问诊记录卡片 -->
<view wx:else class="records-container">
<view class="section-header">
<text class="section-title">问诊记录</text>
<text class="section-count">{{diagnosisList.length}}条</text>
</view>
<view wx:for="{{diagnosisList}}" wx:key="id" class="record-card" bindtap="viewDetail" data-value="{{item}}">
<!-- 卡片头部:用户信息 + 状态 -->
<view class="card-header">
<view class="user-section">
<image class="user-avatar" src="{{item.userInfo.avatar || '/pages/images/tx.png'}}"></image>
<text class="user-name">{{item.farmerName || '用户'}}</text>
</view>
<view class="status-tag {{item.status === '已回复' ? 'status-replied' : 'status-pending'}}">
{{item.status}}
</view>
</view>
<!-- 牲畜信息 -->
<view class="livestock-section">
<view class="livestock-title-wrapper">
<view class="livestock-title-line"></view>
<view class="livestock-title-content">
<text class="livestock-title-text">牲畜信息</text>
</view>
<view class="livestock-title-line"></view>
</view>
<view class="livestock-tags">
<view class="livestock-tag type-tag">
<text class="tag-text">{{item.animalType}}</text>
</view>
<view class="livestock-tag age-tag">
<text class="tag-text">{{item.animalAge}}</text>
</view>
<view class="livestock-tag gender-tag">
<text class="tag-text">{{item.animalGender}}</text>
</view>
</view>
</view>
<!-- 症状描述 -->
<view class="symptom-section">
<view class="symptom-content">
<text class="symptom-text">{{item.description}}</text>
</view>
</view>
<!-- 卡片底部 -->
<view class="card-footer">
<view class="footer-left">
<view class="time-info">
<text class="time-text">{{item.createdTime}}</text>
</view>
</view>
<view class="footer-right">
<view class="reply-info">
<text class="reply-count">{{item.replyCount}}条回复</text>
</view>
</view>
</view>
</view>
</view>
<!-- 列表底部提示 -->
<view wx:if="{{diagnosisList.length > 0}}" class="list-footer">
<text class="footer-text">已显示全部记录</text>
</view>
</scroll-view>
</view>

428
pagesA/pages/askingSy/askingSy.wxss

@ -0,0 +1,428 @@
/* 全局样式 */
.wzbox{
min-height: 100vh;
position: relative;
background: linear-gradient(180deg, #F8FBFF 0%, #F0F7FF 100%);
}
/* 头部样式优化 */
.header {
padding: 20rpx 40rpx 20rpx;
background: linear-gradient(135deg, #6D9EFF 0%, #4A7CFF 100%);
border-radius: 0 0 36rpx 36rpx;
box-shadow: 0 4rpx 20rpx rgba(74, 144, 226, 0.15);
position: relative;
overflow: hidden;
}
.header-content {
position: relative;
z-index: 2;
}
.title-section {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.title {
font-size: 44rpx;
font-weight: 700;
color: #FFFFFF;
letter-spacing: 0.5rpx;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.subtitle {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.9);
font-weight: 400;
}
/* 头部装饰元素 */
.header-decoration {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
z-index: 1;
}
.decoration-circle {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.08);
}
.circle-1 {
width: 200rpx;
height: 200rpx;
top: -80rpx;
right: -40rpx;
}
.circle-2 {
width: 120rpx;
height: 120rpx;
bottom: -40rpx;
left: -20rpx;
}
/* 问诊记录列表 */
.record-list {
height: calc(100vh - 200rpx);
padding: 0 32rpx 20rpx;
box-sizing: border-box;
}
.records-container {
padding-top: 24rpx;
}
/* 列表头部 */
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
padding: 0 4rpx;
}
.section-title {
font-size: 32rpx;
font-weight: 700;
color: #1A1A1A;
position: relative;
padding-left: 16rpx;
}
.section-title::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 4rpx;
height: 20rpx;
background: linear-gradient(180deg, #6D9EFF 0%, #4A7CFF 100%);
border-radius: 2rpx;
}
.section-count {
font-size: 26rpx;
color: #666;
background: #F0F7FF;
padding: 6rpx 16rpx;
border-radius: 16rpx;
font-weight: 500;
}
/* 问诊记录卡片 */
.record-card {
background: #FFFFFF;
border-radius: 24rpx;
margin-bottom: 24rpx;
box-shadow: 0 6rpx 24rpx rgba(74, 144, 226, 0.08);
position: relative;
overflow: hidden;
transition: all 0.3s cubic-bezier(0.2, 0, 0.2, 1);
border: 1rpx solid #F0F7FF;
}
.record-card:active {
transform: translateY(-2rpx);
box-shadow: 0 10rpx 30rpx rgba(74, 144, 226, 0.15);
}
/* 卡片头部 */
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 28rpx;
border-bottom: 1rpx solid #F5F9FF;
}
.user-section {
display: flex;
align-items: center;
gap: 16rpx;
flex: 1;
}
.user-avatar {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
border: 2rpx solid rgba(255, 255, 255, 0.8);
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
}
.user-name {
font-size: 28rpx;
color: #1A1A1A;
font-weight: 600;
}
/* 状态标签 */
.status-tag {
padding: 8rpx 20rpx;
border-radius: 20rpx;
font-size: 22rpx;
font-weight: 600;
min-width: 80rpx;
text-align: center;
flex-shrink: 0;
}
.status-replied {
background: linear-gradient(135deg, rgba(76, 217, 100, 0.12) 0%, rgba(46, 204, 113, 0.12) 100%);
color: #2ECC71;
border: 1rpx solid rgba(46, 204, 113, 0.2);
}
.status-pending {
background: linear-gradient(135deg, rgba(255, 149, 0, 0.12) 0%, rgba(255, 127, 0, 0.12) 100%);
color: #FF9500;
border: 1rpx solid rgba(255, 149, 0, 0.2);
}
/* 牲畜信息 */
.livestock-section {
padding: 20rpx 28rpx;
}
/* 牲畜信息标题优化 */
.livestock-title-wrapper {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
position: relative;
}
.livestock-title-line {
flex: 1;
height: 2rpx;
background: linear-gradient(90deg, transparent, #4A7CFF 50%, transparent);
opacity: 0.3;
}
.livestock-title-content {
display: flex;
align-items: center;
gap: 12rpx;
padding: 0 20rpx;
position: relative;
}
.livestock-title-text {
font-size: 30rpx;
font-weight: 700;
color: #333;
background: linear-gradient(135deg, #4A7CFF 0%, #8CB4FF 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-shadow: 0 2rpx 4rpx rgba(74, 124, 255, 0.1);
letter-spacing: 1rpx;
}
@keyframes cowPulse {
0%, 100% {
transform: scale(1) rotate(0deg);
}
50% {
transform: scale(1.1) rotate(5deg);
}
}
.livestock-tags {
display: flex;
gap: 16rpx;
flex-wrap: wrap;
}
.livestock-tag {
padding: 5rpx 20rpx;
border-radius: 20rpx;
font-size: 26rpx;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.type-tag {
background: linear-gradient(135deg, #6D9EFF 0%, #4A7CFF 100%);
color: #FFFFFF;
border: 2rpx solid rgba(255, 255, 255, 0.3);
}
.age-tag {
background: linear-gradient(135deg, #FFB347 0%, #FFA033 100%);
color: #FFFFFF;
border: 2rpx solid rgba(255, 255, 255, 0.3);
}
.gender-tag {
background: linear-gradient(135deg, #42E695 0%, #3BB2B8 100%);
color: #FFFFFF;
border: 2rpx solid rgba(255, 255, 255, 0.3);
}
.tag-text {
font-size: 26rpx;
font-weight: 600;
color: #FFFFFF;
}
/* 症状描述 */
.symptom-section {
padding: 24rpx 28rpx 28rpx;
}
.symptom-content {
background: #F9FAFF;
padding: 20rpx 24rpx;
border-radius: 16rpx;
border: 1rpx solid #E6ECFF;
position: relative;
}
.symptom-content::before {
content: '症状描述';
position: absolute;
top: -12rpx;
left: 24rpx;
background: #FFFFFF;
padding: 0 12rpx;
font-size: 24rpx;
font-weight: 600;
color: #4A7CFF;
z-index: 1;
}
.symptom-text {
font-size: 28rpx;
color: #333;
line-height: 1.6;
font-weight: 400;
}
/* 卡片底部 */
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 28rpx;
border-top: 1rpx solid #F5F9FF;
}
.time-info {
display: flex;
align-items: center;
gap: 8rpx;
}
.time-text {
font-size: 24rpx;
color: #999;
font-weight: 400;
}
.reply-info {
display: flex;
align-items: center;
gap: 8rpx;
padding: 8rpx 16rpx;
background: #F0F7FF;
border-radius: 16rpx;
border: 1rpx solid #E5EFFF;
}
.reply-count {
font-size: 24rpx;
font-weight: 500;
color: #4A7CFF;
}
/* 空状态优化 */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 120rpx;
text-align: center;
}
.empty-icon {
width: 400rpx;
margin-bottom: 32rpx;
opacity: 0.5;
}
.empty-text {
font-size: 32rpx;
color: #666;
margin-bottom: 12rpx;
font-weight: 600;
}
.empty-tip {
font-size: 26rpx;
color: #999;
margin-bottom: 40rpx;
line-height: 1.4;
}
/* 列表底部 */
.list-footer {
text-align: center;
padding: 40rpx 0;
color: #999;
font-size: 24rpx;
}
.footer-text {
opacity: 0.6;
letter-spacing: 1rpx;
}
/* 卡片入场动画 */
@keyframes cardSlideIn {
from {
opacity: 0;
transform: translateY(30rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.record-card {
animation: cardSlideIn 0.4s ease-out forwards;
opacity: 0;
}
.record-card:nth-child(1) { animation-delay: 0.1s; }
.record-card:nth-child(2) { animation-delay: 0.15s; }
.record-card:nth-child(3) { animation-delay: 0.2s; }
.record-card:nth-child(4) { animation-delay: 0.25s; }
.record-card:nth-child(5) { animation-delay: 0.3s; }
/* 响应式适配 */
@media screen and (min-width: 768px) {
.record-card {
max-width: 600rpx;
margin-left: auto;
margin-right: auto;
}
}

569
pagesA/pages/askingSyDetails/askingSyDetails.js

@ -0,0 +1,569 @@
// 第一个页面的完整JS代码 - pages/diagnosisDetail/diagnosisDetail.js
import http from '../../../utils/api'
const baseUrl = require('../../../utils/baseUrl')
Page({
/**
* 页面的初始数据
*/
data: {
diagnosisData: {},
replies: [],
baseUrl: baseUrl,
refreshing: false,
// 新增回复相关数据
showReplyInput: true,
replyContent: '',
replyImages: [],
replyImagesTemp: [], // 本地临时路径,用于预览
uploadingImage: false,
submittingReply: false,
isUploading: false // 防止重复上传
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
if (options.data) {
// 根据id加载兽医回复数据
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({
diagnosisData: data,
})
this.loadDiagnosisData(data.formId);
}
},
/**
* 加载问诊数据兽医回复
* @param {string} id - 问诊ID
*/
loadDiagnosisData(id) {
console.log('加载问诊数据:', id);
wx.showLoading({
title: '加载中...',
mask: true
});
http.wzdxq({
data: {
consultationId: id
},
success: res => {
wx.hideLoading();
// 处理兽医回复的图片
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 => {
wx.hideLoading();
console.error('加载回复失败:', err);
wx.showToast({
title: '加载失败',
icon: 'none'
});
}
})
},
/**
* 回复内容输入
*/
onReplyContentInput(e) {
this.setData({
replyContent: e.detail.value
});
},
/**
* 清空所有图片
*/
clearAllImages() {
if (this.data.replyImages.length === 0) return;
wx.showModal({
title: '提示',
content: '确定要清空所有已选图片吗?',
success: (res) => {
if (res.confirm) {
this.setData({
replyImages: [],
replyImagesTemp: []
});
}
}
});
},
/**
* 选择回复图片 - 优化后的版本
*/
chooseReplyImage() {
if (this.data.isUploading) {
wx.showToast({
title: '正在上传中,请稍候',
icon: 'none'
});
return;
}
if (this.data.replyImages.length >= 9) {
wx.showToast({
title: '最多上传9张图片',
icon: 'none'
});
return;
}
wx.chooseMedia({
count: 9 - this.data.replyImages.length,
mediaType: ['image'],
sourceType: ['album', 'camera'],
sizeType: ['compressed'],
success: (res) => {
if (res.tempFiles && res.tempFiles.length > 0) {
this.setData({
isUploading: true
});
// 显示加载提示
wx.showLoading({
title: '上传图片中...',
mask: true
});
// 获取临时文件路径列表
const tempPaths = res.tempFiles.map(file => file.tempFilePath);
// 保存临时路径用于预览
const newTempPaths = [...this.data.replyImagesTemp, ...tempPaths];
this.setData({
replyImagesTemp: newTempPaths
});
// 逐张上传图片
this.uploadImages(tempPaths);
}
}
});
},
/**
* 上传多张图片 - 优化后的版本
*/
uploadImages(filePaths) {
const uploadTasks = filePaths.map(path => {
return new Promise((resolve, reject) => {
wx.uploadFile({
url: baseUrl + '/common/upload',
filePath: path,
name: 'file',
header: {
'Authorization': 'Bearer ' + wx.getStorageSync('token')
},
success: (res) => {
try {
const data = JSON.parse(res.data);
if (data.code === 200 || data.fileName) {
const imagePath = data.fileName || data.url;
resolve(imagePath);
} else {
reject(new Error(data.msg || '上传失败'));
}
} catch (e) {
reject(e);
}
},
fail: (err) => {
reject(err);
}
});
});
});
Promise.all(uploadTasks)
.then((imagePaths) => {
wx.hideLoading();
// 将新上传的图片添加到现有图片数组中
const newReplyImages = [...this.data.replyImages, ...imagePaths];
this.setData({
replyImages: newReplyImages,
isUploading: false
});
wx.showToast({
title: '上传成功',
icon: 'success'
});
})
.catch((err) => {
wx.hideLoading();
console.error('上传失败:', err);
// 上传失败时,移除对应的临时预览图片
const failedCount = filePaths.length;
const currentTempPaths = [...this.data.replyImagesTemp];
for (let i = 0; i < failedCount; i++) {
currentTempPaths.pop();
}
this.setData({
replyImagesTemp: currentTempPaths,
isUploading: false
});
wx.showToast({
title: '上传失败,请重试',
icon: 'none'
});
});
},
/**
* 移除单张回复图片
*/
removeReplyImage(e) {
const index = e.currentTarget.dataset.index;
const replyImages = this.data.replyImages.filter((_, i) => i !== index);
const replyImagesTemp = this.data.replyImagesTemp.filter((_, i) => i !== index);
this.setData({
replyImages: replyImages,
replyImagesTemp: replyImagesTemp
});
},
/**
* 提交回复 - 优化后的版本
*/
submitReply() {
const content = this.data.replyContent.trim();
const images = this.data.replyImages;
// 检查内容
if (!content && images.length === 0) {
wx.showToast({
title: '请输入回复内容或上传图片',
icon: 'none'
});
return;
}
if (this.data.submittingReply || this.data.isUploading) {
wx.showToast({
title: this.data.isUploading ? '图片上传中,请稍后' : '提交中,请稍后',
icon: 'none'
});
return;
}
this.setData({ submittingReply: true });
// 显示加载提示
wx.showLoading({
title: '发送中...',
mask: true
});
// 准备提交数据
const submitData = {
consultationId: this.data.diagnosisData.formId,
content: content
};
// 如果有图片,将图片数组转为逗号分隔的字符串
if (images.length > 0) {
submitData.images = images.join(',');
}
console.log('提交回复数据:', submitData);
// 调用回复接口
http.wzdAdd({
data: submitData,
success: res => {
wx.hideLoading();
if (res.code === 200 || res.success) {
// 清空输入
this.setData({
replyContent: '',
replyImages: [],
replyImagesTemp: [],
submittingReply: false
});
wx.showToast({
title: '回复成功',
icon: 'success'
});
// 重新加载回复列表
this.loadDiagnosisData(this.data.diagnosisData.formId);
// 滚动到底部
setTimeout(() => {
wx.createSelectorQuery().select('.page-content').boundingClientRect(rect => {
wx.pageScrollTo({
scrollTop: rect.height,
duration: 300
});
}).exec();
}, 500);
} else {
this.setData({ submittingReply: false });
wx.showToast({
title: res.message || '回复失败',
icon: 'none'
});
}
},
fail: err => {
wx.hideLoading();
this.setData({ submittingReply: false });
console.error('回复失败:', err);
wx.showToast({
title: '网络错误,请重试',
icon: 'none'
});
}
});
},
/**
* 返回上一页
*/
goBack() {
wx.navigateBack();
},
/**
* 分享
*/
onShare() {
wx.showActionSheet({
itemList: ['分享给好友', '保存到相册'],
success: (res) => {
if (res.tapIndex === 0) {
wx.showToast({
title: '已分享',
icon: 'success'
});
}
}
});
},
/**
* 下拉刷新
*/
onRefresh() {
this.setData({
refreshing: true
});
if (this.data.diagnosisData && this.data.diagnosisData.formId) {
this.loadDiagnosisData(this.data.diagnosisData.formId)
}
setTimeout(() => {
this.setData({
refreshing: false
});
wx.showToast({
title: '刷新成功',
icon: 'success'
});
}, 1000);
},
/**
* 预览用户图片
*/
previewImage(e) {
const dataset = e.currentTarget.dataset;
const current = dataset.url;
const urls = dataset.urls || [];
// 构建完整URL数组
const urlsArray = urls.map(item => {
if (typeof item === 'string' && (item.startsWith('http://') || item.startsWith('https://'))) {
return item;
}
return baseUrl + item;
});
console.log('预览用户图片:', urlsArray);
wx.previewImage({
current: current,
urls: urlsArray
});
},
/**
* 预览兽医回复图片
*/
previewReplyImage(e) {
const dataset = e.currentTarget.dataset;
const currentFileName = dataset.url;
const currentFullUrl = dataset.fullurl;
const urlsArray = dataset.urls || [];
const currentIndex = dataset.currentIndex || 0;
const replyIndex = dataset.replyIndex;
console.log('预览兽医图片 - 数据集:', dataset);
// 从replies数据中获取当前回复的图片列表
let targetUrls = [];
let targetCurrentUrl = '';
if (replyIndex !== undefined && this.data.replies[replyIndex]) {
const reply = this.data.replies[replyIndex];
if (reply.images && reply.images.length > 0) {
targetUrls = reply.images;
const fullUrls = targetUrls.map(img => {
if (typeof img === 'string' && (img.startsWith('http://') || img.startsWith('https://'))) {
return img;
}
return baseUrl + img;
});
if (currentIndex < fullUrls.length) {
targetCurrentUrl = fullUrls[currentIndex];
} else if (currentFullUrl) {
targetCurrentUrl = currentFullUrl;
} else if (currentFileName) {
targetCurrentUrl = baseUrl + currentFileName;
}
console.log('预览兽医回复图片:', fullUrls, '当前:', targetCurrentUrl);
wx.previewImage({
current: targetCurrentUrl,
urls: fullUrls
});
return;
}
}
// 使用dataset中的数据
if (urlsArray && urlsArray.length > 0) {
const fullUrls = urlsArray.map(item => {
if (typeof item === 'string' && (item.startsWith('http://') || item.startsWith('https://'))) {
return item;
}
return baseUrl + item;
});
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;
}
// 预览单张图片
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'
});
}
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
// 如果已经有数据,刷新列表
if (this.data.diagnosisData && this.data.diagnosisData.formId) {
this.loadDiagnosisData(this.data.diagnosisData.formId);
}
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
// 页面卸载时重置状态
this.setData({
submittingReply: false,
isUploading: false
});
}
});

4
pagesA/pages/askingSyDetails/askingSyDetails.json

@ -0,0 +1,4 @@
{
"navigationBarTitleText":"问诊详情",
"usingComponents": {}
}

243
pagesA/pages/askingSyDetails/askingSyDetails.wxml

@ -0,0 +1,243 @@
<view class="xqbox">
<!-- 页面内容 -->
<scroll-view class="page-content" scroll-y refresher-enabled refresher-triggered="{{refreshing}}" bindrefresherrefresh="onRefresh" scroll-with-animation="{{true}}">
<!-- 用户问诊卡片 -->
<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 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>
</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>
<!-- 相关图片 -->
<view class="image-section" wx:if="{{diagnosisData.images && diagnosisData.images.length > 0}}">
<view class="section-header">
<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>
</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 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 class="vet-meta">
<view class="meta-item" wx:if="{{item.hospital}}">
<text class="vet-hospital">{{item.hospital}}</text>
</view>
<view class="meta-item" wx:if="{{item.experience}}">
<text class="vet-experience">{{item.experience}}</text>
</view>
</view>
</view>
</view>
<!-- 回复内容 -->
<view class="reply-content">
<view class="reply-bubble">
<text class="reply-text">{{item.content}}</text>
</view>
<!-- 兽医回复图片 - 优化后的图片网格布局,支持预览 -->
<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 class="reply-footer">
<view class="reply-time">
<text class="time-text">{{item.createdAt || item.createTime || ''}}</text>
</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 class="bottom-placeholder" wx:if="{{showReplyInput}}"></view>
</scroll-view>
<!-- 回复输入区域 - 固定在底部 -->
<view class="reply-input-section {{showReplyInput ? 'show' : ''}}" wx:if="{{showReplyInput}}">
<view class="reply-input-container">
<!-- 图片预览区 - 添加删除全部图标 -->
<view class="reply-image-preview" wx:if="{{replyImagesTemp.length > 0}}">
<view class="preview-header">
<text class="preview-title">已选图片 ({{replyImagesTemp.length}}/9)</text>
<view class="clear-all-btn" bindtap="clearAllImages" wx:if="{{replyImagesTemp.length > 0}}">
<text class="clear-icon">🗑️</text>
<text class="clear-text">清空全部</text>
</view>
</view>
<scroll-view class="preview-scroll" scroll-x>
<view class="preview-list">
<block wx:for="{{replyImagesTemp}}" wx:key="index" wx:for-index="imgIndex">
<view class="preview-item">
<image class="preview-img" src="{{item}}" mode="aspectFill"></image>
<view class="preview-remove" bindtap="removeReplyImage" data-index="{{imgIndex}}">
<text class="remove-icon">×</text>
</view>
</view>
</block>
</view>
</scroll-view>
</view>
<!-- 输入工具栏 -->
<view class="input-toolbar">
<textarea
class="reply-textarea"
placeholder="请输入回复内容..."
placeholder-class="textarea-placeholder"
value="{{replyContent}}"
bindinput="onReplyContentInput"
auto-height
maxlength="{{500}}"
show-confirm-bar="{{false}}"
></textarea>
<view class="toolbar-actions">
<view class="action-left">
<view class="action-item" bindtap="chooseReplyImage">
<text class="action-icon">📷</text>
<text class="action-text">图片</text>
</view>
<view class="image-count-badge" wx:if="{{replyImagesTemp.length > 0}}">
<text class="count-text">{{replyImagesTemp.length}}</text>
</view>
</view>
<view class="action-right">
<button class="submit-reply-btn {{replyContent || replyImages.length > 0 ? 'active' : ''}}"
bindtap="submitReply"
disabled="{{!replyContent && replyImages.length === 0}}">
发送回复
</button>
</view>
</view>
</view>
</view>
</view>
<!-- 未登录或非兽医时显示的提示 -->
<view class="no-reply-permission" wx:elif="{{!isVet}}">
<text class="no-permission-text">仅兽医可回复</text>
</view>
</view>

1067
pagesA/pages/askingSyDetails/askingSyDetails.wxss
File diff suppressed because it is too large
View File

16
utils/api.js

@ -77,8 +77,20 @@ function videoZd(params) {
http('/system/dict/data/list', 'get', params) http('/system/dict/data/list', 'get', params)
} }
// 问诊列表
function wzd(params) {
http('/muhu/consultation/list', 'get', params)
}
// 问诊单回复列表
function wzdxq(params) {
http('/vet/comments/list', 'get', params)
}
// 新增问诊单回复
function wzdAdd(params) {
http('/vet/comments', 'post', params)
}
@ -150,8 +162,8 @@ function today(params) {
export default { // 暴露接口 export default { // 暴露接口
login,carousel,getPhoneNumber,article,articleDetails,articleZd,
login,carousel,getPhoneNumber,article,articleDetails,articleZd,wzd,wzdAdd,
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,
today,carouselDetail,videoAdd,articleAdd
today,carouselDetail,videoAdd,articleAdd,wzdxq
} }
Loading…
Cancel
Save