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.

362 lines
9.0 KiB

  1. <template>
  2. <view class="task-upload">
  3. <!-- 任务头部信息 -->
  4. <view class="task-header">
  5. <view class="task-title">{{taskInfo.title}}</view>
  6. <view class="task-deadline">请于{{taskInfo.taskEndTime ? formatDate(taskInfo.taskEndTime) : ''}}之前上传任务超时将自动取消</view>
  7. </view>
  8. <!-- 驳回原因提示(如果任务被驳回) -->
  9. <view class="reject-box" v-if="isRejected">
  10. <view class="reject-title">审核未通过原因</view>
  11. <view class="reject-reason">{{taskInfo.examineText || '暂无驳回原因'}}</view>
  12. </view>
  13. <!-- 上传表单 -->
  14. <view class="upload-form">
  15. <!-- 链接输入 -->
  16. <view class="form-item">
  17. <view class="form-label">笔记/视频链接</view>
  18. <view class="form-input">
  19. <u-input v-model="formData.examineText" placeholder="请输入小红书/抖音等平台的笔记链接" />
  20. </view>
  21. </view>
  22. <!-- 图片上传 -->
  23. <view class="form-item">
  24. <view class="form-label">证明截图</view>
  25. <view class="form-notice">请上传任务完成的截图证明例如发布成功的截图</view>
  26. <view class="upload-box">
  27. <u-upload
  28. :fileList="fileList"
  29. @afterRead="afterRead"
  30. @delete="deletePic"
  31. name="examineImage"
  32. multiple
  33. :maxCount="3"
  34. ></u-upload>
  35. </view>
  36. </view>
  37. <!-- 提交按钮 -->
  38. <view class="submit-btn">
  39. <u-button type="primary" color="#ffaa48" shape="circle" @click="submitTaskHandler">提交审核</u-button>
  40. </view>
  41. </view>
  42. </view>
  43. </template>
  44. <script>
  45. import { getTaskDetail, submitTask } from "@/api/order/task.js"
  46. export default {
  47. data() {
  48. return {
  49. taskId: null,
  50. taskStatus: '',
  51. isRejected: false,
  52. taskInfo: {
  53. id: 0,
  54. title: '',
  55. taskEndTime: '',
  56. examineText: '',
  57. taskState: 0,
  58. examineState: 0
  59. },
  60. formData: {
  61. taskId: 0,
  62. examineImage: [],
  63. examineText: '',
  64. },
  65. fileList: []
  66. }
  67. },
  68. onLoad(options) {
  69. if (options.id) {
  70. this.taskId = options.id
  71. this.formData.taskId = options.id
  72. this.taskStatus = options.status || ''
  73. this.isRejected = this.taskStatus === 'REJECTED'
  74. this.getTaskDetail()
  75. } else {
  76. uni.showToast({
  77. title: '任务ID不存在',
  78. icon: 'none'
  79. })
  80. setTimeout(() => {
  81. uni.navigateBack()
  82. }, 1500)
  83. }
  84. },
  85. methods: {
  86. getTaskDetail() {
  87. // 获取任务详情
  88. getTaskDetail(this.taskId).then(res => {
  89. if (res && res.code === 200) {
  90. this.taskInfo = res.data
  91. // 如果任务已有审核文本,填充到表单
  92. if (res.data.examineText) {
  93. this.formData.examineText = res.data.examineText;
  94. }
  95. // 如果任务已有图片,添加到文件列表显示
  96. if (res.data.examineImage) {
  97. const imageUrls = res.data.examineImage.split(',');
  98. imageUrls.forEach(url => {
  99. if (url) {
  100. this.fileList.push({
  101. url: url,
  102. status: 'success',
  103. message: '已上传',
  104. isImage: true
  105. });
  106. // 同时更新formData中的图片数组
  107. this.formData.examineImage.push(url);
  108. }
  109. });
  110. }
  111. }
  112. })
  113. },
  114. uploadFilePromise(url) {
  115. return new Promise((resolve, reject) => {
  116. let uploadTask = uni.uploadFile({
  117. url: 'https://store-test.catmdogd.com/test-api/h5/oss/upload',
  118. filePath: url,
  119. name: 'file',
  120. formData: {
  121. user: 'test'
  122. },
  123. success: (res) => {
  124. if(res && res.data) {
  125. try {
  126. let resData = JSON.parse(res.data);
  127. if(resData.url) {
  128. resolve(resData.url);
  129. } else {
  130. reject("上传失败: 未获取到图片URL");
  131. }
  132. } catch(e) {
  133. reject("上传失败: 解析响应数据错误");
  134. }
  135. } else {
  136. reject("上传失败: 响应数据为空");
  137. }
  138. },
  139. fail: (err) => {
  140. reject("上传失败: " + (err.errMsg || JSON.stringify(err)));
  141. }
  142. });
  143. // 监听上传进度
  144. uploadTask.onProgressUpdate((res) => {
  145. // 查找当前正在上传的文件
  146. const index = this.fileList.findIndex(file => file.status === 'uploading');
  147. if(index !== -1) {
  148. // 更新上传进度信息
  149. this.fileList[index].message = '上传中 ' + res.progress + '%';
  150. }
  151. });
  152. })
  153. },
  154. formatDate(dateStr) {
  155. if (!dateStr) return '';
  156. let date = new Date(dateStr);
  157. let year = date.getFullYear();
  158. let month = (date.getMonth() + 1).toString().padStart(2, '0');
  159. let day = date.getDate().toString().padStart(2, '0');
  160. return `${year}-${month}-${day}`;
  161. },
  162. afterRead(event) {
  163. // 读取文件后的处理
  164. const { file } = event
  165. // 处理文件数组
  166. const fileList = Array.isArray(file) ? file : [file]
  167. // 遍历处理每个文件
  168. fileList.forEach(item => {
  169. // 更新UI显示上传中状态
  170. const fileListItem = {
  171. ...item,
  172. status: 'uploading',
  173. message: '上传中'
  174. }
  175. this.fileList.push(fileListItem)
  176. const currentIndex = this.fileList.length - 1
  177. // 使用Promise上传图片
  178. this.uploadFilePromise(item.url)
  179. .then(url => {
  180. // 上传成功,更新状态和URL
  181. this.fileList[currentIndex].status = 'success'
  182. this.fileList[currentIndex].message = '上传成功'
  183. this.fileList[currentIndex].url = url
  184. // 保存上传后的URL
  185. this.formData.examineImage.push(url)
  186. })
  187. .catch(err => {
  188. // 上传失败
  189. this.fileList[currentIndex].status = 'failed'
  190. this.fileList[currentIndex].message = '上传失败'
  191. uni.showToast({
  192. title: '图片上传失败',
  193. icon: 'none'
  194. })
  195. })
  196. })
  197. },
  198. deletePic(event) {
  199. // 删除图片
  200. const index = event.index
  201. this.fileList.splice(index, 1)
  202. this.formData.examineImage.splice(index, 1)
  203. },
  204. submitTaskHandler() {
  205. // 表单验证
  206. if (!this.formData.examineText) {
  207. uni.showToast({
  208. title: '请输入笔记链接',
  209. icon: 'none'
  210. })
  211. return
  212. }
  213. if (this.formData.examineImage.length === 0) {
  214. uni.showToast({
  215. title: '请上传至少一张截图',
  216. icon: 'none'
  217. })
  218. return
  219. }
  220. // 检查是否有正在上传的图片
  221. const isUploading = this.fileList.some(file => file.status === 'uploading')
  222. if (isUploading) {
  223. uni.showToast({
  224. title: '图片正在上传中,请稍候',
  225. icon: 'none'
  226. })
  227. return
  228. }
  229. // 显示提交中提示
  230. uni.showLoading({
  231. title: '提交中...'
  232. })
  233. // 提交任务
  234. submitTask({
  235. id: this.taskId,
  236. taskId: this.formData.taskId,
  237. examineText: this.formData.examineText,
  238. examineImage: this.formData.examineImage.join(',')
  239. }).then(res => {
  240. uni.hideLoading()
  241. if (res && res.code === 200) {
  242. uni.showToast({
  243. title: '提交成功',
  244. icon: 'success'
  245. })
  246. // 返回任务详情页
  247. setTimeout(() => {
  248. uni.navigateBack()
  249. }, 1500)
  250. } else {
  251. uni.showToast({
  252. title: res.msg || '提交失败',
  253. icon: 'none'
  254. })
  255. }
  256. }).catch(err => {
  257. uni.hideLoading()
  258. uni.showToast({
  259. title: '提交失败',
  260. icon: 'none'
  261. })
  262. console.error('提交任务失败:', err)
  263. })
  264. }
  265. }
  266. }
  267. </script>
  268. <style lang="scss">
  269. .task-upload {
  270. background-color: #f5f5f7;
  271. min-height: 100vh;
  272. .task-header {
  273. background-color: #FFFFFF;
  274. padding: 30rpx;
  275. .task-title {
  276. font-size: 36rpx;
  277. font-weight: bold;
  278. color: #333;
  279. margin-bottom: 20rpx;
  280. }
  281. .task-deadline {
  282. font-size: 24rpx;
  283. color: #999;
  284. }
  285. }
  286. .reject-box {
  287. background-color: #FFF1F0;
  288. margin-top: 20rpx;
  289. padding: 30rpx;
  290. .reject-title {
  291. font-size: 28rpx;
  292. font-weight: bold;
  293. color: #F5222D;
  294. margin-bottom: 10rpx;
  295. }
  296. .reject-reason {
  297. font-size: 26rpx;
  298. color: #F5222D;
  299. }
  300. }
  301. .upload-form {
  302. background-color: #FFFFFF;
  303. margin-top: 20rpx;
  304. padding: 30rpx;
  305. .form-item {
  306. margin-bottom: 40rpx;
  307. .form-label {
  308. font-size: 30rpx;
  309. font-weight: bold;
  310. color: #333;
  311. margin-bottom: 20rpx;
  312. }
  313. .form-notice {
  314. font-size: 24rpx;
  315. color: #999;
  316. margin-bottom: 20rpx;
  317. }
  318. .form-input {
  319. background-color: #F8F8F8;
  320. border-radius: 8rpx;
  321. padding: 10rpx;
  322. }
  323. .upload-box {
  324. margin-top: 20rpx;
  325. }
  326. }
  327. .submit-btn {
  328. margin-top: 60rpx;
  329. padding: 0 40rpx;
  330. }
  331. }
  332. }
  333. </style>