与牧同行-兽医端小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

568 lines
14 KiB

  1. // 第一个页面的完整JS代码 - pages/diagnosisDetail/diagnosisDetail.js
  2. import http from '../../../utils/api'
  3. const baseUrl = require('../../../utils/baseUrl')
  4. Page({
  5. /**
  6. * 页面的初始数据
  7. */
  8. data: {
  9. diagnosisData: {},
  10. replies: [],
  11. baseUrl: baseUrl,
  12. refreshing: false,
  13. // 新增回复相关数据
  14. showReplyInput: true,
  15. replyContent: '',
  16. replyImages: [],
  17. replyImagesTemp: [], // 本地临时路径,用于预览
  18. uploadingImage: false,
  19. submittingReply: false,
  20. isUploading: false // 防止重复上传
  21. },
  22. /**
  23. * 生命周期函数--监听页面加载
  24. */
  25. onLoad(options) {
  26. if (options.data) {
  27. // 根据id加载兽医回复数据
  28. const data = JSON.parse(decodeURIComponent(options.data));
  29. // 处理用户图片 - 确保是数组格式
  30. if (data.images) {
  31. if (typeof data.images === 'string') {
  32. data.images = data.images.split(',')
  33. }
  34. console.log('用户图片:', data.images);
  35. } else {
  36. data.images = [];
  37. }
  38. this.setData({
  39. diagnosisData: data,
  40. })
  41. this.loadDiagnosisData(data.formId);
  42. }
  43. },
  44. /**
  45. * 加载问诊数据兽医回复
  46. * @param {string} id - 问诊ID
  47. */
  48. loadDiagnosisData(id) {
  49. console.log('加载问诊数据:', id);
  50. wx.showLoading({
  51. title: '加载中...',
  52. mask: true
  53. });
  54. http.wzdxq({
  55. data: {
  56. consultationId: id
  57. },
  58. success: res => {
  59. wx.hideLoading();
  60. // 处理兽医回复的图片
  61. let replies = [];
  62. if (res && res.rows) {
  63. replies = res.rows || [];
  64. // 遍历每个回复,处理图片字段
  65. for (let i = 0; i < replies.length; i++) {
  66. const item = replies[i];
  67. // 处理图片 - 确保是数组格式
  68. if (item.images) {
  69. if (typeof item.images === 'string') {
  70. // 如果是空字符串,设为空数组
  71. if (item.images.trim() === '') {
  72. item.images = [];
  73. } else {
  74. // 按逗号分割字符串
  75. item.images = item.images.split(',');
  76. }
  77. } else if (Array.isArray(item.images)) {
  78. // 已经是数组,但需要过滤空值
  79. item.images = item.images.filter(img => img && img.trim() !== '');
  80. } else {
  81. item.images = [];
  82. }
  83. } else {
  84. item.images = [];
  85. }
  86. console.log(`兽医回复[${i}]图片:`, item.images);
  87. }
  88. }
  89. console.log('兽医回复数据:', replies);
  90. this.setData({
  91. replies: replies
  92. })
  93. },
  94. fail: err => {
  95. wx.hideLoading();
  96. console.error('加载回复失败:', err);
  97. wx.showToast({
  98. title: '加载失败',
  99. icon: 'none'
  100. });
  101. }
  102. })
  103. },
  104. /**
  105. * 回复内容输入
  106. */
  107. onReplyContentInput(e) {
  108. this.setData({
  109. replyContent: e.detail.value
  110. });
  111. },
  112. /**
  113. * 清空所有图片
  114. */
  115. clearAllImages() {
  116. if (this.data.replyImages.length === 0) return;
  117. wx.showModal({
  118. title: '提示',
  119. content: '确定要清空所有已选图片吗?',
  120. success: (res) => {
  121. if (res.confirm) {
  122. this.setData({
  123. replyImages: [],
  124. replyImagesTemp: []
  125. });
  126. }
  127. }
  128. });
  129. },
  130. /**
  131. * 选择回复图片 - 优化后的版本
  132. */
  133. chooseReplyImage() {
  134. if (this.data.isUploading) {
  135. wx.showToast({
  136. title: '正在上传中,请稍候',
  137. icon: 'none'
  138. });
  139. return;
  140. }
  141. if (this.data.replyImages.length >= 9) {
  142. wx.showToast({
  143. title: '最多上传9张图片',
  144. icon: 'none'
  145. });
  146. return;
  147. }
  148. wx.chooseMedia({
  149. count: 9 - this.data.replyImages.length,
  150. mediaType: ['image'],
  151. sourceType: ['album', 'camera'],
  152. sizeType: ['compressed'],
  153. success: (res) => {
  154. if (res.tempFiles && res.tempFiles.length > 0) {
  155. this.setData({
  156. isUploading: true
  157. });
  158. // 显示加载提示
  159. wx.showLoading({
  160. title: '上传图片中...',
  161. mask: true
  162. });
  163. // 获取临时文件路径列表
  164. const tempPaths = res.tempFiles.map(file => file.tempFilePath);
  165. // 保存临时路径用于预览
  166. const newTempPaths = [...this.data.replyImagesTemp, ...tempPaths];
  167. this.setData({
  168. replyImagesTemp: newTempPaths
  169. });
  170. // 逐张上传图片
  171. this.uploadImages(tempPaths);
  172. }
  173. }
  174. });
  175. },
  176. /**
  177. * 上传多张图片 - 优化后的版本
  178. */
  179. uploadImages(filePaths) {
  180. const uploadTasks = filePaths.map(path => {
  181. return new Promise((resolve, reject) => {
  182. wx.uploadFile({
  183. url: baseUrl + '/common/upload',
  184. filePath: path,
  185. name: 'file',
  186. header: {
  187. 'Authorization': 'Bearer ' + wx.getStorageSync('token')
  188. },
  189. success: (res) => {
  190. try {
  191. const data = JSON.parse(res.data);
  192. if (data.code === 200 || data.fileName) {
  193. const imagePath = data.fileName || data.url;
  194. resolve(imagePath);
  195. } else {
  196. reject(new Error(data.msg || '上传失败'));
  197. }
  198. } catch (e) {
  199. reject(e);
  200. }
  201. },
  202. fail: (err) => {
  203. reject(err);
  204. }
  205. });
  206. });
  207. });
  208. Promise.all(uploadTasks)
  209. .then((imagePaths) => {
  210. wx.hideLoading();
  211. // 将新上传的图片添加到现有图片数组中
  212. const newReplyImages = [...this.data.replyImages, ...imagePaths];
  213. this.setData({
  214. replyImages: newReplyImages,
  215. isUploading: false
  216. });
  217. wx.showToast({
  218. title: '上传成功',
  219. icon: 'success'
  220. });
  221. })
  222. .catch((err) => {
  223. wx.hideLoading();
  224. console.error('上传失败:', err);
  225. // 上传失败时,移除对应的临时预览图片
  226. const failedCount = filePaths.length;
  227. const currentTempPaths = [...this.data.replyImagesTemp];
  228. for (let i = 0; i < failedCount; i++) {
  229. currentTempPaths.pop();
  230. }
  231. this.setData({
  232. replyImagesTemp: currentTempPaths,
  233. isUploading: false
  234. });
  235. wx.showToast({
  236. title: '上传失败,请重试',
  237. icon: 'none'
  238. });
  239. });
  240. },
  241. /**
  242. * 移除单张回复图片
  243. */
  244. removeReplyImage(e) {
  245. const index = e.currentTarget.dataset.index;
  246. const replyImages = this.data.replyImages.filter((_, i) => i !== index);
  247. const replyImagesTemp = this.data.replyImagesTemp.filter((_, i) => i !== index);
  248. this.setData({
  249. replyImages: replyImages,
  250. replyImagesTemp: replyImagesTemp
  251. });
  252. },
  253. /**
  254. * 提交回复 - 优化后的版本
  255. */
  256. submitReply() {
  257. const content = this.data.replyContent.trim();
  258. const images = this.data.replyImages;
  259. // 检查内容
  260. if (!content && images.length === 0) {
  261. wx.showToast({
  262. title: '请输入回复内容或上传图片',
  263. icon: 'none'
  264. });
  265. return;
  266. }
  267. if (this.data.submittingReply || this.data.isUploading) {
  268. wx.showToast({
  269. title: this.data.isUploading ? '图片上传中,请稍后' : '提交中,请稍后',
  270. icon: 'none'
  271. });
  272. return;
  273. }
  274. this.setData({ submittingReply: true });
  275. // 显示加载提示
  276. wx.showLoading({
  277. title: '发送中...',
  278. mask: true
  279. });
  280. // 准备提交数据
  281. const submitData = {
  282. consultationId: this.data.diagnosisData.formId,
  283. content: content
  284. };
  285. // 如果有图片,将图片数组转为逗号分隔的字符串
  286. if (images.length > 0) {
  287. submitData.images = images.join(',');
  288. }
  289. console.log('提交回复数据:', submitData);
  290. // 调用回复接口
  291. http.wzdAdd({
  292. data: submitData,
  293. success: res => {
  294. wx.hideLoading();
  295. if (res.code === 200 || res.success) {
  296. // 清空输入
  297. this.setData({
  298. replyContent: '',
  299. replyImages: [],
  300. replyImagesTemp: [],
  301. submittingReply: false
  302. });
  303. wx.showToast({
  304. title: '回复成功',
  305. icon: 'success'
  306. });
  307. // 重新加载回复列表
  308. this.loadDiagnosisData(this.data.diagnosisData.formId);
  309. // 滚动到底部
  310. setTimeout(() => {
  311. wx.createSelectorQuery().select('.page-content').boundingClientRect(rect => {
  312. wx.pageScrollTo({
  313. scrollTop: rect.height,
  314. duration: 300
  315. });
  316. }).exec();
  317. }, 500);
  318. } else {
  319. this.setData({ submittingReply: false });
  320. wx.showToast({
  321. title: res.message || '回复失败',
  322. icon: 'none'
  323. });
  324. }
  325. },
  326. fail: err => {
  327. wx.hideLoading();
  328. this.setData({ submittingReply: false });
  329. console.error('回复失败:', err);
  330. wx.showToast({
  331. title: '网络错误,请重试',
  332. icon: 'none'
  333. });
  334. }
  335. });
  336. },
  337. /**
  338. * 返回上一页
  339. */
  340. goBack() {
  341. wx.navigateBack();
  342. },
  343. /**
  344. * 分享
  345. */
  346. onShare() {
  347. wx.showActionSheet({
  348. itemList: ['分享给好友', '保存到相册'],
  349. success: (res) => {
  350. if (res.tapIndex === 0) {
  351. wx.showToast({
  352. title: '已分享',
  353. icon: 'success'
  354. });
  355. }
  356. }
  357. });
  358. },
  359. /**
  360. * 下拉刷新
  361. */
  362. onRefresh() {
  363. this.setData({
  364. refreshing: true
  365. });
  366. if (this.data.diagnosisData && this.data.diagnosisData.formId) {
  367. this.loadDiagnosisData(this.data.diagnosisData.formId)
  368. }
  369. setTimeout(() => {
  370. this.setData({
  371. refreshing: false
  372. });
  373. wx.showToast({
  374. title: '刷新成功',
  375. icon: 'success'
  376. });
  377. }, 1000);
  378. },
  379. /**
  380. * 预览用户图片
  381. */
  382. previewImage(e) {
  383. const dataset = e.currentTarget.dataset;
  384. const current = dataset.url;
  385. const urls = dataset.urls || [];
  386. // 构建完整URL数组
  387. const urlsArray = urls.map(item => {
  388. if (typeof item === 'string' && (item.startsWith('http://') || item.startsWith('https://'))) {
  389. return item;
  390. }
  391. return baseUrl + item;
  392. });
  393. console.log('预览用户图片:', urlsArray);
  394. wx.previewImage({
  395. current: current,
  396. urls: urlsArray
  397. });
  398. },
  399. /**
  400. * 预览兽医回复图片
  401. */
  402. previewReplyImage(e) {
  403. const dataset = e.currentTarget.dataset;
  404. const currentFileName = dataset.url;
  405. const currentFullUrl = dataset.fullurl;
  406. const urlsArray = dataset.urls || [];
  407. const currentIndex = dataset.currentIndex || 0;
  408. const replyIndex = dataset.replyIndex;
  409. console.log('预览兽医图片 - 数据集:', dataset);
  410. // 从replies数据中获取当前回复的图片列表
  411. let targetUrls = [];
  412. let targetCurrentUrl = '';
  413. if (replyIndex !== undefined && this.data.replies[replyIndex]) {
  414. const reply = this.data.replies[replyIndex];
  415. if (reply.images && reply.images.length > 0) {
  416. targetUrls = reply.images;
  417. const fullUrls = targetUrls.map(img => {
  418. if (typeof img === 'string' && (img.startsWith('http://') || img.startsWith('https://'))) {
  419. return img;
  420. }
  421. return baseUrl + img;
  422. });
  423. if (currentIndex < fullUrls.length) {
  424. targetCurrentUrl = fullUrls[currentIndex];
  425. } else if (currentFullUrl) {
  426. targetCurrentUrl = currentFullUrl;
  427. } else if (currentFileName) {
  428. targetCurrentUrl = baseUrl + currentFileName;
  429. }
  430. console.log('预览兽医回复图片:', fullUrls, '当前:', targetCurrentUrl);
  431. wx.previewImage({
  432. current: targetCurrentUrl,
  433. urls: fullUrls
  434. });
  435. return;
  436. }
  437. }
  438. // 使用dataset中的数据
  439. if (urlsArray && urlsArray.length > 0) {
  440. const fullUrls = urlsArray.map(item => {
  441. if (typeof item === 'string' && (item.startsWith('http://') || item.startsWith('https://'))) {
  442. return item;
  443. }
  444. return baseUrl + item;
  445. });
  446. let currentUrl = '';
  447. if (currentFullUrl) {
  448. currentUrl = currentFullUrl;
  449. } else if (currentIndex < fullUrls.length) {
  450. currentUrl = fullUrls[currentIndex];
  451. } else if (currentFileName) {
  452. currentUrl = baseUrl + currentFileName;
  453. }
  454. console.log('预览兽医回复图片(从dataset):', fullUrls, '当前:', currentUrl);
  455. wx.previewImage({
  456. current: currentUrl,
  457. urls: fullUrls
  458. });
  459. return;
  460. }
  461. // 预览单张图片
  462. if (currentFullUrl) {
  463. console.log('预览单张兽医图片:', [currentFullUrl]);
  464. wx.previewImage({
  465. current: currentFullUrl,
  466. urls: [currentFullUrl]
  467. });
  468. } else if (currentFileName) {
  469. const fullUrl = baseUrl + currentFileName;
  470. console.log('预览单张兽医图片(拼接后):', [fullUrl]);
  471. wx.previewImage({
  472. current: fullUrl,
  473. urls: [fullUrl]
  474. });
  475. } else {
  476. wx.showToast({
  477. title: '图片预览失败',
  478. icon: 'none'
  479. });
  480. }
  481. },
  482. /**
  483. * 生命周期函数--监听页面显示
  484. */
  485. onShow() {
  486. // 如果已经有数据,刷新列表
  487. if (this.data.diagnosisData && this.data.diagnosisData.formId) {
  488. this.loadDiagnosisData(this.data.diagnosisData.formId);
  489. }
  490. },
  491. /**
  492. * 生命周期函数--监听页面卸载
  493. */
  494. onUnload() {
  495. // 页面卸载时重置状态
  496. this.setData({
  497. submittingReply: false,
  498. isUploading: false
  499. });
  500. }
  501. });