与牧同行-兽医端小程序
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.

593 lines
14 KiB

  1. import http from '../../../utils/api'
  2. const baseUrl = require('../../../utils/baseUrl')
  3. Page({
  4. data: {
  5. baseUrl,
  6. currentTab: 'article',
  7. // 文章相关
  8. articleForm: {
  9. title: '',
  10. subtitle: '',
  11. category: '',
  12. content: '',
  13. coverImage: '' // 这里存储服务器返回的文件名
  14. },
  15. articleCoverTemp: '', // 本地临时路径,用于预览
  16. articleCategory: null,
  17. articleCategories: [],
  18. // 视频相关
  19. videoForm: {
  20. title: '',
  21. description: '',
  22. category: '',
  23. videoUrl: '', // 这里存储服务器返回的视频文件名
  24. coverImage: '' // 这里存储服务器返回的封面文件名
  25. },
  26. videoCoverTemp: '', // 本地临时路径,用于预览
  27. videoUrlTemp: '', // 本地临时路径,用于显示
  28. videoCategory: null,
  29. videoCategories: [],
  30. // UI状态
  31. submitting: false,
  32. isUploading: false, // 防止重复上传
  33. showLoadingMask: false, // 显示加载遮罩层
  34. loadingText: '发布中...', // 加载提示文字
  35. // 表单验证状态
  36. articleFormValid: false,
  37. videoFormValid: false,
  38. },
  39. onLoad() {
  40. this.getArticleCategories()
  41. this.getVideoCategories()
  42. },
  43. /**
  44. * 生命周期函数--监听页面卸载
  45. */
  46. onUnload() {
  47. // 页面卸载时重置状态
  48. this.setData({
  49. submitting: false,
  50. showLoadingMask: false
  51. });
  52. },
  53. // 获取文章分类
  54. getArticleCategories() {
  55. http.articleZd({
  56. data: {
  57. dictType: 'article_category'
  58. },
  59. success: res => {
  60. if (res.rows) {
  61. this.setData({
  62. articleCategories: res.rows
  63. })
  64. }
  65. }
  66. })
  67. },
  68. // 获取视频分类
  69. getVideoCategories() {
  70. http.videoZd({
  71. data: {
  72. dictType: 'video_category'
  73. },
  74. success: res => {
  75. if (res.rows) {
  76. this.setData({
  77. videoCategories: res.rows
  78. })
  79. }
  80. }
  81. })
  82. },
  83. // 切换标签
  84. switchTab(e) {
  85. const type = e.currentTarget.dataset.type
  86. if (type === this.data.currentTab) return
  87. this.setData({ currentTab: type })
  88. },
  89. // 验证文章表单
  90. validateArticleForm() {
  91. const { articleForm } = this.data
  92. const isValid = !!(articleForm.title?.trim() && articleForm.category && articleForm.content?.trim())
  93. this.setData({ articleFormValid: isValid })
  94. return isValid
  95. },
  96. // 验证视频表单
  97. validateVideoForm() {
  98. const { videoForm } = this.data
  99. const isValid = !!(videoForm.title?.trim() && videoForm.category && videoForm.videoUrl)
  100. this.setData({ videoFormValid: isValid })
  101. return isValid
  102. },
  103. // 文章输入处理
  104. onArticleInput(e) {
  105. const field = e.currentTarget.dataset.field
  106. const value = e.detail.value
  107. this.setData({
  108. [`articleForm.${field}`]: value
  109. }, () => {
  110. this.validateArticleForm()
  111. })
  112. },
  113. // 视频输入处理
  114. onVideoInput(e) {
  115. const field = e.currentTarget.dataset.field
  116. const value = e.detail.value
  117. this.setData({
  118. [`videoForm.${field}`]: value
  119. }, () => {
  120. this.validateVideoForm()
  121. })
  122. },
  123. // 文章分类选择
  124. onArticleCategoryChange(e) {
  125. const index = e.detail.value
  126. const category = this.data.articleCategories[index]
  127. this.setData({
  128. 'articleForm.category': category.dictValue,
  129. articleCategory: category
  130. }, () => {
  131. this.validateArticleForm()
  132. })
  133. },
  134. // 视频分类选择
  135. onVideoCategoryChange(e) {
  136. const index = e.detail.value
  137. const category = this.data.videoCategories[index]
  138. this.setData({
  139. 'videoForm.category': category.dictValue,
  140. videoCategory: category
  141. }, () => {
  142. this.validateVideoForm()
  143. })
  144. },
  145. // 选择封面图片(文章或视频)
  146. chooseCover(e) {
  147. if (this.data.isUploading) {
  148. wx.showToast({
  149. title: '正在上传中,请稍候',
  150. icon: 'none'
  151. });
  152. return;
  153. }
  154. const type = e.currentTarget.dataset.type
  155. wx.chooseMedia({
  156. count: 1,
  157. mediaType: ['image'],
  158. sourceType: ['album', 'camera'],
  159. sizeType: ['compressed'],
  160. success: (res) => {
  161. if (res.tempFiles && res.tempFiles.length > 0) {
  162. this.setData({
  163. isUploading: true
  164. });
  165. // 显示加载提示
  166. wx.showLoading({
  167. title: '上传图片中...',
  168. mask: true
  169. });
  170. // 上传图片
  171. this.uploadImage(res.tempFiles[0].tempFilePath, type);
  172. }
  173. }
  174. });
  175. },
  176. // 上传单张图片
  177. uploadImage(tempPath, type) {
  178. wx.uploadFile({
  179. url: baseUrl + '/common/upload',
  180. header: {
  181. 'Authorization': 'Bearer ' + wx.getStorageSync('token')
  182. },
  183. filePath: tempPath,
  184. name: 'file',
  185. success: (uploadRes) => {
  186. try {
  187. const result = JSON.parse(uploadRes.data);
  188. if (result.code === 200 || result.fileName) {
  189. const serverPath = result.fileName || result.url;
  190. if (type === 'article') {
  191. // 文章封面
  192. this.setData({
  193. articleCoverTemp: tempPath,
  194. 'articleForm.coverImage': serverPath,
  195. isUploading: false
  196. }, () => {
  197. this.validateArticleForm();
  198. });
  199. } else {
  200. // 视频封面
  201. this.setData({
  202. videoCoverTemp: tempPath,
  203. 'videoForm.coverImage': serverPath,
  204. isUploading: false
  205. }, () => {
  206. this.validateVideoForm();
  207. });
  208. }
  209. wx.hideLoading();
  210. wx.showToast({
  211. title: '上传成功',
  212. icon: 'success'
  213. });
  214. } else {
  215. throw new Error(result.msg || '上传失败');
  216. }
  217. } catch (error) {
  218. wx.hideLoading();
  219. this.setData({
  220. isUploading: false
  221. });
  222. wx.showToast({
  223. title: error.message || '上传失败',
  224. icon: 'none'
  225. });
  226. }
  227. },
  228. fail: (error) => {
  229. wx.hideLoading();
  230. this.setData({
  231. isUploading: false
  232. });
  233. wx.showToast({
  234. title: '网络请求失败',
  235. icon: 'none'
  236. });
  237. }
  238. });
  239. },
  240. // 选择视频
  241. chooseVideo() {
  242. if (this.data.isUploading) {
  243. wx.showToast({
  244. title: '正在上传中,请稍候',
  245. icon: 'none'
  246. });
  247. return;
  248. }
  249. wx.chooseMedia({
  250. count: 1,
  251. mediaType: ['video'],
  252. sourceType: ['album', 'camera'],
  253. maxDuration: 300,
  254. success: (res) => {
  255. if (res.tempFiles && res.tempFiles.length > 0) {
  256. const tempFilePath = res.tempFiles[0].tempFilePath;
  257. this.setData({
  258. isUploading: true,
  259. videoUrlTemp: tempFilePath // 先显示本地路径
  260. });
  261. // 显示加载提示
  262. wx.showLoading({
  263. title: '上传视频中...',
  264. mask: true
  265. });
  266. console.log(111,tempFilePath);
  267. // 上传视频
  268. this.uploadVideo(tempFilePath);
  269. }
  270. },
  271. fail: (error) => {
  272. console.error('选择视频失败:', error);
  273. wx.showToast({
  274. title: '选择视频失败',
  275. icon: 'none'
  276. });
  277. }
  278. });
  279. },
  280. // 上传视频
  281. uploadVideo(tempPath) {
  282. wx.uploadFile({
  283. url: baseUrl + '/common/upload',
  284. header: {
  285. 'Authorization': 'Bearer ' + wx.getStorageSync('token')
  286. },
  287. filePath: tempPath,
  288. name: 'file',
  289. success: (uploadRes) => {
  290. try {
  291. const result = JSON.parse(uploadRes.data);
  292. console.log(333,result)
  293. if (result.code === 200 || result.fileName) {
  294. const serverPath = result.fileName
  295. this.setData({
  296. 'videoForm.videoUrl': serverPath,
  297. isUploading: false
  298. }, () => {
  299. this.validateVideoForm();
  300. });
  301. wx.hideLoading();
  302. wx.showToast({
  303. title: '上传成功',
  304. icon: 'success'
  305. });
  306. } else {
  307. throw new Error(result.msg || '上传失败');
  308. }
  309. } catch (error) {
  310. wx.hideLoading();
  311. this.setData({
  312. videoUrlTemp: '', // 上传失败清空临时路径
  313. isUploading: false
  314. });
  315. wx.showToast({
  316. title: error.message || '上传失败',
  317. icon: 'none'
  318. });
  319. }
  320. },
  321. fail: (error) => {
  322. wx.hideLoading();
  323. this.setData({
  324. videoUrlTemp: '', // 上传失败清空临时路径
  325. isUploading: false
  326. });
  327. wx.showToast({
  328. title: '网络请求失败',
  329. icon: 'none'
  330. });
  331. }
  332. });
  333. },
  334. // 提交文章
  335. submitArticle() {
  336. const { articleForm, submitting, isUploading } = this.data
  337. if (submitting) return
  338. // 检查是否还有图片正在上传
  339. if (isUploading) {
  340. wx.showToast({
  341. title: '图片正在上传中,请稍后提交',
  342. icon: 'none'
  343. });
  344. return;
  345. }
  346. // 表单验证
  347. if (!this.validateArticleForm()) {
  348. if (!articleForm.title?.trim()) {
  349. this.showError('请输入文章标题')
  350. } else if (!articleForm.category) {
  351. this.showError('请选择文章分类')
  352. } else if (!articleForm.content?.trim()) {
  353. this.showError('请输入文章内容')
  354. }
  355. return
  356. }
  357. // 显示加载遮罩层
  358. this.setData({
  359. submitting: true,
  360. showLoadingMask: true,
  361. loadingText: '发布中...'
  362. });
  363. // 构建提交数据
  364. const submitData = {
  365. title: articleForm.title.trim(),
  366. subtitle: articleForm.subtitle?.trim() || '',
  367. content: articleForm.content.trim(),
  368. coverImage: articleForm.coverImage || '',
  369. category: articleForm.category
  370. }
  371. // 调用接口
  372. http.articleAdd({
  373. data: submitData,
  374. success: (res) => {
  375. if (res.code == 200) {
  376. this.setData({
  377. loadingText: '发布成功'
  378. });
  379. setTimeout(() => {
  380. this.setData({
  381. submitting: false,
  382. showLoadingMask: false
  383. });
  384. wx.showToast({
  385. title: '发布成功',
  386. icon: 'success',
  387. duration: 1500,
  388. success: () => {
  389. setTimeout(() => {
  390. wx.navigateBack()
  391. }, 1500);
  392. }
  393. });
  394. }, 1000);
  395. } else {
  396. this.setData({
  397. loadingText: '发布失败'
  398. });
  399. setTimeout(() => {
  400. this.setData({
  401. submitting: false,
  402. showLoadingMask: false
  403. });
  404. wx.showToast({
  405. title: res.msg || '发布失败,请重试',
  406. icon: 'none',
  407. duration: 2000
  408. });
  409. }, 1000);
  410. }
  411. },
  412. fail: (err) => {
  413. this.setData({
  414. loadingText: '网络错误'
  415. });
  416. setTimeout(() => {
  417. this.setData({
  418. submitting: false,
  419. showLoadingMask: false
  420. });
  421. wx.showToast({
  422. title: '网络异常,请检查网络后重试',
  423. icon: 'none',
  424. duration: 2000
  425. });
  426. }, 1000);
  427. }
  428. })
  429. },
  430. // 提交视频
  431. submitVideo() {
  432. const { videoForm, submitting, isUploading } = this.data
  433. if (submitting) return
  434. // 检查是否还有图片或视频正在上传
  435. if (isUploading) {
  436. wx.showToast({
  437. title: '文件正在上传中,请稍后提交',
  438. icon: 'none'
  439. });
  440. return;
  441. }
  442. // 表单验证
  443. if (!this.validateVideoForm()) {
  444. if (!videoForm.title?.trim()) {
  445. this.showError('请输入视频标题')
  446. } else if (!videoForm.category) {
  447. this.showError('请选择视频分类')
  448. } else if (!videoForm.videoUrl) {
  449. this.showError('请选择视频')
  450. }
  451. return
  452. }
  453. // 显示加载遮罩层
  454. this.setData({
  455. submitting: true,
  456. showLoadingMask: true,
  457. loadingText: '发布中...'
  458. });
  459. // 构建提交数据
  460. const submitData = {
  461. title: videoForm.title.trim(),
  462. description: videoForm.description?.trim() || '',
  463. videoUrl: videoForm.videoUrl,
  464. coverImage: videoForm.coverImage || '',
  465. category: videoForm.category
  466. }
  467. // 调用接口
  468. http.videoAdd({
  469. data: submitData,
  470. success: (res) => {
  471. if (res.code == 200) {
  472. this.setData({
  473. loadingText: '发布成功'
  474. });
  475. setTimeout(() => {
  476. this.setData({
  477. submitting: false,
  478. showLoadingMask: false
  479. });
  480. wx.showToast({
  481. title: '发布成功',
  482. icon: 'success',
  483. duration: 1500,
  484. success: () => {
  485. setTimeout(() => {
  486. wx.navigateBack()
  487. }, 1500);
  488. }
  489. });
  490. }, 1000);
  491. } else {
  492. this.setData({
  493. loadingText: '发布失败'
  494. });
  495. setTimeout(() => {
  496. this.setData({
  497. submitting: false,
  498. showLoadingMask: false
  499. });
  500. wx.showToast({
  501. title: res.msg || '发布失败,请重试',
  502. icon: 'none',
  503. duration: 2000
  504. });
  505. }, 1000);
  506. }
  507. },
  508. fail: (err) => {
  509. this.setData({
  510. loadingText: '网络错误'
  511. });
  512. setTimeout(() => {
  513. this.setData({
  514. submitting: false,
  515. showLoadingMask: false
  516. });
  517. wx.showToast({
  518. title: '网络异常,请检查网络后重试',
  519. icon: 'none',
  520. duration: 2000
  521. });
  522. }, 1000);
  523. }
  524. })
  525. },
  526. // 显示错误提示
  527. showError(msg) {
  528. wx.showToast({
  529. title: msg,
  530. icon: 'none',
  531. duration: 2000
  532. });
  533. }
  534. })