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.

392 lines
10 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. getTaskDetail,
  93. acceptTask
  94. } from "@/api/order/task.js"
  95. export default {
  96. data() {
  97. return {
  98. tabList: [
  99. {
  100. name: '待接受',
  101. badge: {
  102. value: 1,
  103. }
  104. },
  105. {
  106. name: '已接受',
  107. badge: {
  108. value: 0,
  109. }
  110. },
  111. ],
  112. curNow: 0,
  113. pendingTasks: [],
  114. acceptedTasks: []
  115. }
  116. },
  117. onShow() {
  118. // 加载任务列表数据
  119. this.getTaskList()
  120. },
  121. methods: {
  122. sectionChange(index) {
  123. this.curNow = index;
  124. this.getTaskList()
  125. },
  126. getTaskList() {
  127. // 调用API获取任务列表
  128. getTaskList({
  129. status : this.curNow
  130. }).then(res=>{
  131. if (res && res.code === 200) {
  132. let rows = res.rows || []
  133. console.log(rows)
  134. // 根据status字段分类:0为待接受,1为已接受
  135. this.pendingTasks = rows.filter(item => item.status === 0).map(item => this.formatTaskItem(item))
  136. this.acceptedTasks = rows.filter(item => item.status === 1).map(item => this.formatTaskItem(item))
  137. this.updateBadgeCount()
  138. }
  139. })
  140. },
  141. // 格式化任务项
  142. formatTaskItem(item) {
  143. return {
  144. id: item.id,
  145. taskType: item.taskName || '任务',
  146. reward: item.taskMoney || '0',
  147. icon: item.taskIcon || 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png',
  148. title: item.title || '',
  149. description: item.theme || '',
  150. deadline: item.taskEndTime ? this.formatDate(item.taskEndTime) : '',
  151. status: this.getTaskStatus(item.taskState, item.examineState),
  152. rejectReason: item.examineText || ''
  153. }
  154. },
  155. // 根据任务进度和审核状态获取任务状态
  156. getTaskStatus(taskState, examineState) {
  157. // taskState: 任务进度,examineState: 审核状态
  158. if (taskState === 0) return 'ACCEPTED'; // 待上传
  159. if (taskState === 1 && examineState === 0) return 'SUBMITTED'; // 审核中
  160. if (taskState === 1 && examineState === 1) return 'APPROVED'; // 已通过
  161. if (taskState === 1 && examineState === 2) return 'REJECTED'; // 驳回
  162. return 'ACCEPTED'; // 默认状态
  163. },
  164. // 格式化日期
  165. formatDate(dateStr) {
  166. if (!dateStr) return '';
  167. let date = new Date(dateStr);
  168. let year = date.getFullYear();
  169. let month = (date.getMonth() + 1).toString().padStart(2, '0');
  170. let day = date.getDate().toString().padStart(2, '0');
  171. return `${year}-${month}-${day}`;
  172. },
  173. updateBadgeCount() {
  174. // 更新标签页的徽标数量
  175. this.tabList[0].badge.value = this.pendingTasks.length
  176. this.tabList[1].badge.value = this.acceptedTasks.length
  177. },
  178. viewTaskDetail(task) {
  179. // 查看任务详情,跳转到任务详情页面
  180. uni.navigateTo({
  181. url: `/pages_order/task/taskDetail?id=${task.id}`
  182. });
  183. },
  184. acceptTaskHandler(task) {
  185. // 接受任务
  186. uni.showModal({
  187. title: '接受任务',
  188. content: `确定接受任务: ${task.title}`,
  189. success: res => {
  190. if (res.confirm) {
  191. acceptTask({id : task.id}).then(res => {
  192. if (res && res.code === 200) {
  193. uni.showToast({
  194. title: '任务接受成功',
  195. icon: 'success'
  196. });
  197. // 刷新任务列表
  198. this.getTaskList();
  199. }
  200. });
  201. }
  202. }
  203. });
  204. },
  205. uploadTask(task) {
  206. // 上传任务
  207. uni.navigateTo({
  208. url: `/pages_order/task/taskUpload?id=${task.id}&status=${task.status}`
  209. });
  210. },
  211. showRejectReason(task) {
  212. // 显示驳回原因
  213. if (task.rejectReason) {
  214. uni.showModal({
  215. title: '驳回原因',
  216. content: task.rejectReason,
  217. showCancel: false
  218. });
  219. } else {
  220. uni.showToast({
  221. title: '暂无驳回原因',
  222. icon: 'none'
  223. });
  224. }
  225. },
  226. getStatusText(status) {
  227. // 获取状态文本
  228. const statusMap = {
  229. 'ACCEPTED': '待上传',
  230. 'SUBMITTED': '审核中',
  231. 'REJECTED': '未通过',
  232. 'APPROVED': '已通过'
  233. };
  234. return statusMap[status] || status;
  235. }
  236. }
  237. }
  238. </script>
  239. <style lang="scss">
  240. .task-center {
  241. background-color: #f5f5f7;
  242. min-height: 100vh;
  243. .task-card {
  244. background-color: #FFFFFF;
  245. border-radius: 16rpx;
  246. margin-bottom: 30rpx;
  247. overflow: hidden;
  248. .task-header {
  249. display: flex;
  250. align-items: center;
  251. margin-bottom: 20rpx;
  252. background-color: #FFF4E599;
  253. padding: 15rpx;
  254. .task-image {
  255. margin-right: 30rpx;
  256. display: flex;
  257. align-items: center;
  258. image {
  259. height: 50rpx;
  260. width: 50rpx;
  261. }
  262. }
  263. .task-type {
  264. color: #A94F20;
  265. font-size: 26rpx;
  266. background-color: #FFF4E5;
  267. padding: 10rpx 30rpx;
  268. border-radius: 30rpx;
  269. }
  270. .task-reward {
  271. font-size: 26rpx;
  272. margin-left: auto;
  273. text {
  274. color: #FF5722;
  275. font-weight: bold;
  276. margin-left: 10rpx;
  277. font-size: 30rpx;
  278. }
  279. }
  280. }
  281. .task-content {
  282. display: flex;
  283. margin-bottom: 30rpx;
  284. padding: 0 30rpx 0 30rpx;
  285. .task-icon {
  286. margin-right: 30rpx;
  287. }
  288. .task-info {
  289. flex: 1;
  290. position: relative;
  291. .task-title {
  292. font-size: 32rpx;
  293. font-weight: bold;
  294. color: #333;
  295. margin-bottom: 10rpx;
  296. }
  297. .task-desc {
  298. font-size: 28rpx;
  299. color: #666;
  300. margin-bottom: 10rpx;
  301. }
  302. .task-deadline {
  303. font-size: 24rpx;
  304. color: #999;
  305. margin-bottom: 10rpx;
  306. }
  307. .task-status-tag {
  308. display: inline-block;
  309. font-size: 24rpx;
  310. padding: 6rpx 20rpx;
  311. border-radius: 20rpx;
  312. margin-top: 10rpx;
  313. &.status-pending {
  314. background-color: #E6F7FF;
  315. color: #1890FF;
  316. }
  317. &.status-reviewing {
  318. background-color: #FFF7E6;
  319. color: #FA8C16;
  320. }
  321. &.status-rejected {
  322. background-color: #FFF1F0;
  323. color: #F5222D;
  324. }
  325. &.status-approved {
  326. background-color: #F6FFED;
  327. color: #52C41A;
  328. }
  329. }
  330. }
  331. }
  332. .task-footer {
  333. padding-bottom: 30rpx;
  334. display: flex;
  335. justify-content: center;
  336. align-items: flex-end;
  337. gap: 20rpx;
  338. flex-wrap: wrap;
  339. .u-button {
  340. width: 200rpx;
  341. height: 60rpx;
  342. font-size: 28rpx;
  343. }
  344. .task-status {
  345. height: 60rpx;
  346. display: flex;
  347. align-items: center;
  348. justify-content: center;
  349. width: 200rpx;
  350. font-size: 28rpx;
  351. &.task-status-approved {
  352. color: #52C41A;
  353. }
  354. }
  355. }
  356. }
  357. .empty-tip {
  358. text-align: center;
  359. padding: 60rpx 0;
  360. color: #999;
  361. font-size: 28rpx;
  362. }
  363. }
  364. </style>