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.

539 lines
15 KiB

  1. <template>
  2. <view class="task-center">
  3. <u-subsection :list="tabList"
  4. active-color="#ffaa48"
  5. bg-color="#fff"
  6. inactive-color="#aaaaaa"
  7. font-size="16"
  8. :current="curNow"
  9. @change="sectionChange"></u-subsection>
  10. <!-- <view class="container-tabs">
  11. <up-tabs :list="tabList" lineWidth="68rpx" :activeStyle="{
  12. color: '#ffaa48',
  13. fontWeight: 'bold',
  14. transform: 'scale(1.05)'
  15. }" :inactiveStyle="{
  16. color: '#555',
  17. transform: 'scale(1)'
  18. }" :itemStyle="{height:'88rpx',padding:'0 52rpx'}" lineColor="#ffaa48" @click="sectionChange"></up-tabs>
  19. </view> -->
  20. <!-- 待接受任务列表 -->
  21. <view v-if="curNow === 0">
  22. <view v-for="(item,index) in pendingTasks" style="padding:28rpx 36rpx 0;" :key="index">
  23. <view class="task-card">
  24. <view class="task-header">
  25. <view class="task-image">
  26. <image src="https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png" mode="heightFix"></image>
  27. </view>
  28. <view class="task-type">{{item.taskType}}</view>
  29. <view class="task-reward">酬劳 <text> ¥{{item.reward}}</text> </view>
  30. </view>
  31. <view class="task-content">
  32. <view class="task-icon">
  33. <image :src="item.icon" style="width: 120rpx; height: 120rpx;" mode="aspectFill"></image>
  34. </view>
  35. <view class="task-info">
  36. <view class="task-title">{{item.title}}</view>
  37. <view class="task-desc">{{item.description}}</view>
  38. <view class="task-deadline">任务截止日期: {{item.deadline}}</view>
  39. </view>
  40. </view>
  41. <view class="task-footer">
  42. <u-button shape="circle" plain text="查看详情" @click="viewTaskDetail(item)"></u-button>
  43. <u-button shape="circle" color="#ffaa48" text="立即接受" @click="acceptTaskHandler(item)"></u-button>
  44. </view>
  45. </view>
  46. </view>
  47. <view v-if="pendingTasks.length === 0" class="empty-tip">
  48. <text>暂无待接受任务</text>
  49. </view>
  50. </view>
  51. <!-- 已接收任务列表 -->
  52. <view v-else>
  53. <view v-for="(item,index) in acceptedTasks" style="padding:28rpx 36rpx 0;" :key="index">
  54. <view class="task-card">
  55. <view class="task-header">
  56. <view class="task-image">
  57. <image src="https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png" mode="heightFix"></image>
  58. </view>
  59. <view class="task-type">{{item.taskType}}</view>
  60. <view class="task-reward">酬劳 <text> ¥{{item.reward}}</text> </view>
  61. </view>
  62. <view class="task-content">
  63. <view class="task-icon">
  64. <image :src="item.icon" style="width: 120rpx; height: 120rpx;" mode="aspectFill"></image>
  65. </view>
  66. <view class="task-info">
  67. <view class="task-title">{{item.title}}</view>
  68. <view class="task-desc">{{item.description}}</view>
  69. <view class="task-deadline">任务截止日期: {{item.deadline}}</view>
  70. <view class="task-status-tag" :class="{'status-pending': item.status === 'ACCEPTED', 'status-reviewing': item.status === 'SUBMITTED', 'status-rejected': item.status === 'REJECTED', 'status-approved': item.status === 'APPROVED'}">{{getStatusText(item.status)}}</view>
  71. </view>
  72. </view>
  73. <view class="task-footer">
  74. <u-button shape="circle" plain text="查看详情" @click="viewTaskDetail(item)"></u-button>
  75. <u-button v-if="item.status === 'REJECTED'" shape="circle" type="error" text="驳回原因" @click="showRejectReason(item)"></u-button>
  76. <u-button v-if="item.status === 'ACCEPTED'" shape="circle" color="#ffaa48" text="立即上传" @click="uploadTask(item)"></u-button>
  77. <u-button v-if="item.status === 'SUBMITTED'" shape="circle" disabled text="审核中"></u-button>
  78. <u-button v-if="item.status === 'REJECTED'" shape="circle" color="#ffaa48" text="重新上传" @click="uploadTask(item)"></u-button>
  79. <view v-if="item.status === 'APPROVED'" class="task-status task-status-approved">已通过</view>
  80. </view>
  81. </view>
  82. </view>
  83. <view v-if="acceptedTasks.length === 0" class="empty-tip">
  84. <text>暂无已接收任务</text>
  85. </view>
  86. </view>
  87. </view>
  88. </template>
  89. <script>
  90. import {
  91. getTaskList,
  92. acceptTask,
  93. submitTask,
  94. getTaskDetail
  95. } from "@/api/system/task.js"
  96. export default {
  97. data() {
  98. return {
  99. tabList: [
  100. {
  101. name: '待接受',
  102. badge: {
  103. value: 1,
  104. }
  105. },
  106. {
  107. name: '已接受',
  108. badge: {
  109. value: 0,
  110. }
  111. },
  112. ],
  113. curNow: 0,
  114. pendingTasks: [{
  115. id: 1,
  116. taskType: '悬赏任务',
  117. reward: '2',
  118. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  119. title: '发布小红书宣传笔记',
  120. description: '主题: 猫狗狗食使用感受&体验',
  121. deadline: '2025-03-28'
  122. },
  123. {
  124. id: 2,
  125. taskType: '体验任务',
  126. reward: '3',
  127. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  128. title: '狗狗玩具测评',
  129. description: '测试新款狗狗玩具并提供使用反馈',
  130. deadline: '2025-04-05'
  131. },
  132. {
  133. id: 3,
  134. taskType: '推广任务',
  135. reward: '5',
  136. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  137. title: '抖音短视频拍摄',
  138. description: '拍摄宠物使用产品的有趣短视频',
  139. deadline: '2025-04-10'
  140. },
  141. {
  142. id: 13,
  143. taskType: '问卷调查',
  144. reward: '1',
  145. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  146. title: '宠物食品偏好调查',
  147. description: '完成一份关于宠物食品偏好的问卷调查',
  148. deadline: '2025-03-30'
  149. },
  150. {
  151. id: 14,
  152. taskType: '社区任务',
  153. reward: '4',
  154. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  155. title: '宠物社区话题讨论',
  156. description: '在指定宠物社区参与话题讨论并获得5个以上回复',
  157. deadline: '2025-04-15'
  158. }
  159. ],
  160. acceptedTasks: [
  161. {
  162. id: 4,
  163. taskType: '悬赏任务',
  164. reward: '3',
  165. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  166. title: '发布小红书宣传笔记',
  167. description: '主题: 猫狗狗食使用感受&体验',
  168. deadline: '2025-03-28',
  169. status: 'ACCEPTED' // 已接受,待上传
  170. },
  171. {
  172. id: 5,
  173. taskType: '悬赏任务',
  174. reward: '3',
  175. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  176. title: '发布小红书宣传笔记',
  177. description: '主题: 猫狗狗食使用感受&体验',
  178. deadline: '2025-03-28',
  179. status: 'SUBMITTED' // 已提交,审核中
  180. },
  181. {
  182. id: 6,
  183. taskType: '悬赏任务',
  184. reward: '3',
  185. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  186. title: '发布小红书宣传笔记',
  187. description: '主题: 猫狗狗食使用感受&体验',
  188. deadline: '2025-03-28',
  189. status: 'REJECTED', // 已驳回
  190. rejectReason: '图片不清晰,请重新上传高清图片'
  191. },
  192. {
  193. id: 7,
  194. taskType: '悬赏任务',
  195. reward: '3',
  196. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  197. title: '发布小红书宣传笔记',
  198. description: '主题: 猫狗狗食使用感受&体验',
  199. deadline: '2025-03-28',
  200. status: 'APPROVED' // 已通过
  201. },
  202. {
  203. id: 8,
  204. taskType: '体验任务',
  205. reward: '5',
  206. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  207. title: '猫咪零食体验测评',
  208. description: '体验新品猫咪零食并提供详细测评报告',
  209. deadline: '2025-04-15',
  210. status: 'ACCEPTED', // 已接受,待上传
  211. receiveTime: '2025-03-10'
  212. },
  213. {
  214. id: 9,
  215. taskType: '推广任务',
  216. reward: '8',
  217. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  218. title: '朋友圈分享宠物用品',
  219. description: '在朋友圈分享指定宠物用品并获取5个以上点赞',
  220. deadline: '2025-03-25',
  221. status: 'SUBMITTED', // 已提交,审核中
  222. submitTime: '2025-03-20'
  223. },
  224. {
  225. id: 10,
  226. taskType: '视频任务',
  227. reward: '10',
  228. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  229. title: '拍摄宠物使用产品视频',
  230. description: '拍摄15秒宠物使用我们产品的有趣视频',
  231. deadline: '2025-04-10',
  232. status: 'REJECTED', // 已驳回
  233. rejectReason: '视频时长不足,请确保视频至少15秒且清晰可见'
  234. },
  235. {
  236. id: 11,
  237. taskType: '问卷调查',
  238. reward: '2',
  239. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  240. title: '宠物主人消费习惯调查',
  241. description: '完成一份关于宠物主人消费习惯的问卷调查',
  242. deadline: '2025-03-30',
  243. status: 'APPROVED', // 已通过
  244. approveTime: '2025-03-18'
  245. },
  246. {
  247. id: 12,
  248. taskType: '社区任务',
  249. reward: '6',
  250. icon: 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  251. title: '参与线下宠物活动',
  252. description: '参加指定城市的线下宠物主题活动并拍照记录',
  253. deadline: '2025-05-01',
  254. status: 'SUBMITTED', // 已提交,审核中
  255. submitTime: '2025-04-25'
  256. }
  257. ]
  258. }
  259. },
  260. onLoad() {
  261. // 加载任务列表数据
  262. this.getTaskList()
  263. // 更新标签页的徽标数量
  264. this.updateBadgeCount()
  265. },
  266. methods: {
  267. sectionChange(index) {
  268. this.curNow = index;
  269. },
  270. getTaskList() {
  271. // 调用API获取任务列表
  272. // 由于后端API可能尚未实现,这里先使用模拟数据
  273. // 实际项目中取消注释下面的代码
  274. /*
  275. getTaskList().then(res=>{
  276. if (res && res.code === 200) {
  277. let rows = res.rows || []
  278. console.log(rows)
  279. this.pendingTasks = rows.filter(item=>item.status=="PENDING")
  280. this.acceptedTasks = rows.filter(item=>item.status!="PENDING")
  281. this.updateBadgeCount()
  282. }
  283. })
  284. */
  285. // 使用模拟数据
  286. console.log('加载任务列表')
  287. // 更新标签页的徽标数量
  288. this.updateBadgeCount()
  289. },
  290. updateBadgeCount() {
  291. // 更新标签页的徽标数量
  292. this.tabList[0].badge.value = this.pendingTasks.length
  293. this.tabList[1].badge.value = this.acceptedTasks.length
  294. },
  295. viewTaskDetail(task) {
  296. // 查看任务详情,跳转到任务详情页面
  297. uni.navigateTo({
  298. url: `/pages_order/task/taskDetail?id=${task.id}`
  299. });
  300. },
  301. acceptTaskHandler(task) {
  302. // 接受任务
  303. uni.showModal({
  304. title: '接受任务',
  305. content: `确定接受任务: ${task.title}`,
  306. success: res => {
  307. if (res.confirm) {
  308. // 实际项目中取消注释下面的代码
  309. /*
  310. acceptTask(task.id).then(res => {
  311. if (res && res.code === 200) {
  312. uni.showToast({
  313. title: '任务接受成功',
  314. icon: 'success'
  315. });
  316. // 刷新任务列表
  317. this.getTaskList();
  318. }
  319. });
  320. */
  321. // 模拟接受任务
  322. const index = this.pendingTasks.findIndex(item => item.id === task.id);
  323. if (index !== -1) {
  324. const acceptedTask = {
  325. ...this.pendingTasks[index],
  326. status: 'ACCEPTED'
  327. };
  328. this.acceptedTasks.push(acceptedTask);
  329. this.pendingTasks.splice(index, 1);
  330. this.updateBadgeCount();
  331. uni.showToast({
  332. title: '任务接受成功',
  333. icon: 'success'
  334. });
  335. }
  336. }
  337. }
  338. });
  339. },
  340. uploadTask(task) {
  341. // 上传任务
  342. uni.navigateTo({
  343. url: `/pages_order/task/taskUpload?id=${task.id}&status=${task.status}`
  344. });
  345. },
  346. showRejectReason(task) {
  347. // 显示驳回原因
  348. if (task.rejectReason) {
  349. uni.showModal({
  350. title: '驳回原因',
  351. content: task.rejectReason,
  352. showCancel: false
  353. });
  354. } else {
  355. uni.showToast({
  356. title: '暂无驳回原因',
  357. icon: 'none'
  358. });
  359. }
  360. },
  361. getStatusText(status) {
  362. // 获取状态文本
  363. const statusMap = {
  364. 'ACCEPTED': '待上传',
  365. 'SUBMITTED': '审核中',
  366. 'REJECTED': '未通过',
  367. 'APPROVED': '已通过'
  368. };
  369. return statusMap[status] || status;
  370. },
  371. getStatusClass(status) {
  372. // 获取状态样式类
  373. const classMap = {
  374. 'ACCEPTED': 'status-pending',
  375. 'SUBMITTED': 'status-reviewing',
  376. 'REJECTED': 'status-rejected',
  377. 'APPROVED': 'status-approved'
  378. };
  379. return classMap[status] || '';
  380. }
  381. }
  382. }
  383. </script>
  384. <style lang="scss">
  385. .task-center {
  386. background-color: #f5f5f7;
  387. min-height: 100vh;
  388. .task-card {
  389. background-color: #FFFFFF;
  390. border-radius: 16rpx;
  391. margin-bottom: 30rpx;
  392. overflow: hidden;
  393. .task-header {
  394. display: flex;
  395. align-items: center;
  396. margin-bottom: 20rpx;
  397. background-color: #FFF4E599;
  398. padding: 15rpx;
  399. .task-image {
  400. margin-right: 30rpx;
  401. display: flex;
  402. align-items: center;
  403. image {
  404. height: 50rpx;
  405. width: 50rpx;
  406. }
  407. }
  408. .task-type {
  409. color: #A94F20;
  410. font-size: 26rpx;
  411. background-color: #FFF4E5;
  412. padding: 10rpx 30rpx;
  413. border-radius: 30rpx;
  414. }
  415. .task-reward {
  416. font-size: 26rpx;
  417. margin-left: auto;
  418. text {
  419. color: #FF5722;
  420. font-weight: bold;
  421. margin-left: 10rpx;
  422. font-size: 30rpx;
  423. }
  424. }
  425. }
  426. .task-content {
  427. display: flex;
  428. margin-bottom: 30rpx;
  429. padding: 0 30rpx 0 30rpx;
  430. .task-icon {
  431. margin-right: 30rpx;
  432. }
  433. .task-info {
  434. flex: 1;
  435. position: relative;
  436. .task-title {
  437. font-size: 32rpx;
  438. font-weight: bold;
  439. color: #333;
  440. margin-bottom: 10rpx;
  441. }
  442. .task-desc {
  443. font-size: 28rpx;
  444. color: #666;
  445. margin-bottom: 10rpx;
  446. }
  447. .task-deadline {
  448. font-size: 24rpx;
  449. color: #999;
  450. margin-bottom: 10rpx;
  451. }
  452. .task-status-tag {
  453. display: inline-block;
  454. font-size: 24rpx;
  455. padding: 6rpx 20rpx;
  456. border-radius: 20rpx;
  457. margin-top: 10rpx;
  458. &.status-pending {
  459. background-color: #E6F7FF;
  460. color: #1890FF;
  461. }
  462. &.status-reviewing {
  463. background-color: #FFF7E6;
  464. color: #FA8C16;
  465. }
  466. &.status-rejected {
  467. background-color: #FFF1F0;
  468. color: #F5222D;
  469. }
  470. &.status-approved {
  471. background-color: #F6FFED;
  472. color: #52C41A;
  473. }
  474. }
  475. }
  476. }
  477. .task-footer {
  478. padding-bottom: 30rpx;
  479. display: flex;
  480. justify-content: center;
  481. align-items: flex-end;
  482. gap: 20rpx;
  483. flex-wrap: wrap;
  484. .u-button {
  485. width: 200rpx;
  486. height: 60rpx;
  487. font-size: 28rpx;
  488. }
  489. .task-status {
  490. height: 60rpx;
  491. display: flex;
  492. align-items: center;
  493. justify-content: center;
  494. width: 200rpx;
  495. font-size: 28rpx;
  496. &.task-status-approved {
  497. color: #52C41A;
  498. }
  499. }
  500. }
  501. }
  502. .empty-tip {
  503. text-align: center;
  504. padding: 60rpx 0;
  505. color: #999;
  506. font-size: 28rpx;
  507. }
  508. }
  509. </style>