- 新增新用户专享页面,包含优惠券领取功能 - 优化任务模块接口和页面逻辑 - 重构登录页面样式和交互流程 - 新增图片资源及上传功能 - 优化Vuex状态管理,新增配置映射 - 完善任务上传和详情页面的状态展示master
| @ -1,120 +1,151 @@ | |||||
| <template> | <template> | ||||
| <view class="new-user-coupon" v-if="showPopup"> | |||||
| <view class="mask" @click="closePopup"></view> | |||||
| <view class="coupon-container"> | |||||
| <view class="coupon-content"> | |||||
| <image class="coupon-image" src="https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/coupon/new-user-coupon.png" mode="widthFix"></image> | |||||
| <view class="coupon-btn" @click="getCoupon">立即领取</view> | |||||
| </view> | |||||
| <view class="close-btn" @click="closePopup"> | |||||
| <text class="close-icon">×</text> | |||||
| </view> | |||||
| <view class="new-user-coupon" v-if="showPopup"> | |||||
| <view class="mask" @click="closePopup"></view> | |||||
| <view class="coupon-container"> | |||||
| <view class="coupon-content"> | |||||
| <view style="position: relative;"> | |||||
| <image class="coupon-image" | |||||
| style="height: 800rpx;" | |||||
| src="http://wxa.mp.video.tencent-cloud.com/271/20304/stodownload?m=e32f5f803d62036cc76c2de769355081&filekey=30340201010420301e0202010f040253480410e32f5f803d62036cc76c2de76935508102020d9e040d00000004627466730000000132&hy=SH&storeid=2689416ee0007c1f4000000000000010f00004f50534805aab171568b33d14&bizid=1023" | |||||
| mode="aspectFill"></image> | |||||
| <image | |||||
| style="width: 280rpx;height: 70rpx; | |||||
| position: absolute; | |||||
| left: 50%; | |||||
| top: 20rpx; | |||||
| transform: translate(-50%, 0%);" | |||||
| mode="aspectFill" | |||||
| src="https://image.hhlm1688.com/2025/08/07767f2fc0a686433bb9e3f90bc6e60990Group%201000001612@3x.png"/> | |||||
| <image class="coupon-image" | |||||
| style="position: absolute;left: 50%;top: 50%; | |||||
| width: 80%; | |||||
| transform: translate(-50%, -50%);" | |||||
| :src="NewUserCoupon.couponPoster || image" | |||||
| mode="widthFix"></image> | |||||
| </view> | |||||
| <view class="coupon-btn" @click="getCoupon">立即领取</view> | |||||
| </view> | |||||
| <view class="close-btn" @click="closePopup"> | |||||
| <text class="close-icon">×</text> | |||||
| </view> | |||||
| </view> | |||||
| </view> | </view> | ||||
| </view> | |||||
| </template> | </template> | ||||
| <script> | <script> | ||||
| import { getToken } from '@/utils/auth' | import { getToken } from '@/utils/auth' | ||||
| import { mapState } from 'vuex' | |||||
| export default { | export default { | ||||
| name: 'NewUserCoupon', | |||||
| data() { | |||||
| return { | |||||
| showPopup: true | |||||
| } | |||||
| }, | |||||
| methods: { | |||||
| closePopup() { | |||||
| this.showPopup = false | |||||
| this.$emit('close') | |||||
| name: 'NewUserCoupon', | |||||
| data() { | |||||
| return { | |||||
| showPopup: true, | |||||
| image : 'https://img.teyizhao.com/2025-08-07/a7535f42-6726-4630-9552-6940331ddb8b.png', | |||||
| } | |||||
| }, | }, | ||||
| getCoupon() { | |||||
| // 检查用户是否已登录 | |||||
| if (!getToken()) { | |||||
| // 未登录,跳转到登录页面 | |||||
| uni.navigateTo({ | |||||
| url: '/pages_order/auth/login' | |||||
| }) | |||||
| } else { | |||||
| // 已登录,触发领券事件 | |||||
| this.$emit('getCoupon') | |||||
| this.closePopup() | |||||
| } | |||||
| computed : { | |||||
| ...mapState(['NewUserCoupon']), | |||||
| }, | |||||
| methods: { | |||||
| closePopup() { | |||||
| this.showPopup = false | |||||
| this.$emit('close') | |||||
| }, | |||||
| getCoupon() { | |||||
| // 检查用户是否已登录 | |||||
| if (!getToken() || !this.userInfo.phone) { | |||||
| // 未登录,跳转到登录页面 | |||||
| uni.navigateTo({ | |||||
| url: '/pages_order/auth/login?url=/pages_order/newUser/index' | |||||
| }) | |||||
| } else { | |||||
| // 已登录,跳转到新用户优惠券页面 | |||||
| this.closePopup() | |||||
| uni.navigateTo({ | |||||
| url: '/pages_order/newUser/index' | |||||
| }) | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| </script> | </script> | ||||
| <style lang="scss"> | <style lang="scss"> | ||||
| .new-user-coupon { | .new-user-coupon { | ||||
| position: fixed; | |||||
| top: 0; | |||||
| left: 0; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| z-index: 999; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| .mask { | |||||
| position: absolute; | |||||
| position: fixed; | |||||
| top: 0; | top: 0; | ||||
| left: 0; | left: 0; | ||||
| width: 100%; | width: 100%; | ||||
| height: 100%; | height: 100%; | ||||
| background-color: rgba(0, 0, 0, 0.6); | |||||
| } | |||||
| .coupon-container { | |||||
| position: relative; | |||||
| width: 560rpx; | |||||
| z-index: 1000; | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| } | |||||
| .coupon-content { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| } | |||||
| .coupon-image { | |||||
| width: 560rpx; | |||||
| border-radius: 20rpx; | |||||
| } | |||||
| .coupon-btn { | |||||
| margin-top: -80rpx; | |||||
| width: 300rpx; | |||||
| height: 80rpx; | |||||
| background: #FFB13F; | |||||
| color: #FFFFFF; | |||||
| font-size: 32rpx; | |||||
| font-weight: bold; | |||||
| border-radius: 40rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| } | |||||
| .close-btn { | |||||
| margin-top: 40rpx; | |||||
| width: 60rpx; | |||||
| height: 60rpx; | |||||
| background: rgba(255, 255, 255, 0.8); | |||||
| border-radius: 50%; | |||||
| z-index: 999; | |||||
| display: flex; | display: flex; | ||||
| align-items: center; | align-items: center; | ||||
| justify-content: center; | justify-content: center; | ||||
| .close-icon { | |||||
| color: #666; | |||||
| font-size: 40rpx; | |||||
| font-weight: bold; | |||||
| .mask { | |||||
| position: absolute; | |||||
| top: 0; | |||||
| left: 0; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| background-color: rgba(0, 0, 0, 0.6); | |||||
| } | |||||
| .coupon-container { | |||||
| position: relative; | |||||
| width: 560rpx; | |||||
| z-index: 1000; | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| } | |||||
| .coupon-content { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| } | |||||
| .coupon-image { | |||||
| width: 560rpx; | |||||
| border-radius: 20rpx; | |||||
| } | |||||
| .coupon-btn { | |||||
| position: relative; | |||||
| margin-top: -100rpx; | |||||
| width: 300rpx; | |||||
| height: 80rpx; | |||||
| background: #FFB13F; | |||||
| color: #FFFFFF; | |||||
| font-size: 32rpx; | |||||
| font-weight: bold; | |||||
| border-radius: 40rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| } | |||||
| .close-btn { | |||||
| position: relative; | |||||
| margin-top: 40rpx; | |||||
| width: 60rpx; | |||||
| height: 60rpx; | |||||
| background: rgba(255, 255, 255, 0.8); | |||||
| border-radius: 50%; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| .close-icon { | |||||
| color: #666; | |||||
| font-size: 40rpx; | |||||
| font-weight: bold; | |||||
| } | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| </style> | </style> | ||||
| @ -0,0 +1,208 @@ | |||||
| <template> | |||||
| <uni-popup ref="popup" type="bottom" background-color="#fff" border-radius="20rpx 20rpx 0 0"> | |||||
| <view class="popup-content"> | |||||
| <!-- 标题 --> | |||||
| <view class="popup-title"> | |||||
| <text>选择下单方式</text> | |||||
| <view class="close-btn" @click="close"> | |||||
| <uni-icons type="closeempty" size="20" color="#999"></uni-icons> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 选项列表 --> | |||||
| <view class="option-list"> | |||||
| <!-- 系统下单 --> | |||||
| <view class="option-item" @click="selectOption('system')"> | |||||
| <view class="option-left"> | |||||
| <image class="option-icon" | |||||
| src="https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/petServiceOrder/SystemOrderCircle.png" /> | |||||
| <view class="option-info"> | |||||
| <text class="option-title">系统下单</text> | |||||
| <text class="option-desc">系统自动为您匹配合适的伴宠师</text> | |||||
| </view> | |||||
| </view> | |||||
| <uni-icons type="arrowright" size="16" color="#ccc"></uni-icons> | |||||
| </view> | |||||
| <!-- 指定伴宠师 --> | |||||
| <view class="option-item" @click="selectOption('companion')"> | |||||
| <view class="option-left"> | |||||
| <image class="option-icon" | |||||
| src="https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/petServiceOrder/OrderIcon.png" /> | |||||
| <view class="option-info"> | |||||
| <text class="option-title">指定伴宠师</text> | |||||
| <text class="option-desc">选择您信任的伴宠师为您服务</text> | |||||
| </view> | |||||
| </view> | |||||
| <uni-icons type="arrowright" size="16" color="#ccc"></uni-icons> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| </uni-popup> | |||||
| </template> | |||||
| <script> | |||||
| export default { | |||||
| name: 'OrderTypeSelectPopup', | |||||
| methods: { | |||||
| // 打开弹窗 | |||||
| open() { | |||||
| this.$refs.popup.open('bottom') | |||||
| }, | |||||
| // 关闭弹窗 | |||||
| close() { | |||||
| this.$refs.popup.close() | |||||
| }, | |||||
| // 选择下单方式 | |||||
| selectOption(type) { | |||||
| this.close() | |||||
| setTimeout(() => { | |||||
| if (type === 'system') { | |||||
| // 系统下单 - 跳转到新订单页面 | |||||
| uni.navigateTo({ | |||||
| url: '/pages/newOrder/serviceNew' | |||||
| }) | |||||
| } else if (type === 'companion') { | |||||
| // 指定伴宠师 - 先选择定位 | |||||
| this.selectLocation() | |||||
| } | |||||
| }, 300) | |||||
| }, | |||||
| // 选择定位 | |||||
| selectLocation() { | |||||
| wx.chooseLocation({ | |||||
| type: 'gcj02', | |||||
| success: (res) => { | |||||
| console.log('选择的位置:', res); | |||||
| // 构建位置信息对象 | |||||
| const allInfo = { | |||||
| isCheckLocation: true, | |||||
| locationName: res.address, | |||||
| locationLongitude: res.longitude, | |||||
| locationLatitude: res.latitude, | |||||
| locationAddress: res.address, | |||||
| selectedDate: [], | |||||
| isCheckTime: false, | |||||
| selectedDateShowText: '', | |||||
| }; | |||||
| this.$store.commit('setPosition', { | |||||
| address: res.address, | |||||
| longitude: res.longitude, | |||||
| latitude: res.latitude, | |||||
| date : [], | |||||
| }) | |||||
| // 跳转到伴宠师列表页面,传递位置信息 | |||||
| uni.navigateTo({ | |||||
| url: `/pages_order/companionPetList/companionPetList?info=` + encodeURIComponent(JSON.stringify(allInfo)) | |||||
| }) | |||||
| }, | |||||
| fail: (err) => { | |||||
| console.error('选择位置失败:', err); | |||||
| uni.showToast({ | |||||
| title: '选择位置失败,请重试', | |||||
| icon: 'none', | |||||
| duration: 2000 | |||||
| }) | |||||
| } | |||||
| }); | |||||
| } | |||||
| } | |||||
| } | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| .popup-content { | |||||
| padding: 40rpx 30rpx 60rpx; | |||||
| background: #fff; | |||||
| border-radius: 20rpx 20rpx 0 0; | |||||
| } | |||||
| .popup-title { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| margin-bottom: 40rpx; | |||||
| text { | |||||
| font-size: 32rpx; | |||||
| font-weight: bold; | |||||
| color: #333; | |||||
| } | |||||
| .close-btn { | |||||
| width: 60rpx; | |||||
| height: 60rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| border-radius: 50%; | |||||
| background: #f5f5f5; | |||||
| &:active { | |||||
| background: #e5e5e5; | |||||
| } | |||||
| } | |||||
| } | |||||
| .option-list { | |||||
| .option-item { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| padding: 30rpx 20rpx; | |||||
| margin-bottom: 20rpx; | |||||
| background: #f8f9fa; | |||||
| border-radius: 16rpx; | |||||
| border: 2rpx solid transparent; | |||||
| transition: all 0.3s ease; | |||||
| &:active { | |||||
| background: #e9ecef; | |||||
| border-color: #FFB13F; | |||||
| transform: scale(0.98); | |||||
| } | |||||
| &:last-child { | |||||
| margin-bottom: 0; | |||||
| } | |||||
| .option-left { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| flex: 1; | |||||
| .option-icon { | |||||
| width: 60rpx; | |||||
| height: 60rpx; | |||||
| margin-right: 20rpx; | |||||
| border-radius: 8rpx; | |||||
| } | |||||
| .option-info { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| .option-title { | |||||
| font-size: 30rpx; | |||||
| font-weight: 600; | |||||
| color: #333; | |||||
| margin-bottom: 8rpx; | |||||
| } | |||||
| .option-desc { | |||||
| font-size: 24rpx; | |||||
| color: #666; | |||||
| line-height: 1.4; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| </style> | |||||
| @ -0,0 +1,170 @@ | |||||
| <template> | |||||
| <view class="new-user-page"> | |||||
| <!-- 背景图片 --> | |||||
| <image class="bg-image" | |||||
| src="http://wxa.mp.video.tencent-cloud.com/271/20304/stodownload?m=e32f5f803d62036cc76c2de769355081&filekey=30340201010420301e0202010f040253480410e32f5f803d62036cc76c2de76935508102020d9e040d00000004627466730000000132&hy=SH&storeid=2689416ee0007c1f4000000000000010f00004f50534805aab171568b33d14&bizid=1023" | |||||
| mode="aspectFill" /> | |||||
| <!-- 顶部标题图片 --> | |||||
| <image class="title-image" src="https://image.hhlm1688.com/2025/08/07767f2fc0a686433bb9e3f90bc6e60990Group%201000001612@3x.png" | |||||
| mode="widthFix" /> | |||||
| <!-- 优惠券内容图片 --> | |||||
| <image class="coupon-content-image" | |||||
| :src="NewUserCoupon.couponPoster || image" mode="widthFix" /> | |||||
| <!-- 立即领取/立即使用按钮 --> | |||||
| <view class="receive-btn" @click="handleButtonClick"> | |||||
| {{ isReceived ? '立即使用' : '立即领取' }} | |||||
| </view> | |||||
| <!-- 下单方式选择弹窗 --> | |||||
| <order-type-select-popup ref="orderTypeSelectPopup" /> | |||||
| </view> | |||||
| </template> | |||||
| <script> | |||||
| import { getToken } from '@/utils/auth' | |||||
| import OrderTypeSelectPopup from '@/pages_order/components/OrderTypeSelectPopup.vue' | |||||
| import { mapState } from 'vuex' | |||||
| import { receiveCoupon } from "@/api/system/user" | |||||
| export default { | |||||
| name: 'NewUserCouponPage', | |||||
| components: { | |||||
| OrderTypeSelectPopup | |||||
| }, | |||||
| data() { | |||||
| return { | |||||
| isReceived: false, // 优惠券是否已领取 | |||||
| image : 'https://img.teyizhao.com/2025-08-07/a7535f42-6726-4630-9552-6940331ddb8b.png', | |||||
| } | |||||
| }, | |||||
| computed : { | |||||
| ...mapState(['NewUserCoupon']), | |||||
| }, | |||||
| methods: { | |||||
| // 处理按钮点击 | |||||
| handleButtonClick() { | |||||
| if (this.isReceived) { | |||||
| // 已领取,点击立即使用,打开选择下单方式弹窗 | |||||
| this.openOrderTypePopup() | |||||
| } else { | |||||
| // 未领取,点击立即领取 | |||||
| this.receiveCoupon() | |||||
| } | |||||
| }, | |||||
| // 领取优惠券 | |||||
| receiveCoupon() { | |||||
| let data = { | |||||
| stockId: this.NewUserCoupon.id, | |||||
| } | |||||
| receiveCoupon(data).then(res => { | |||||
| if (res.code == 200) { | |||||
| uni.showToast({ | |||||
| title: '领取成功!', | |||||
| icon: 'success', | |||||
| duration: 2000 | |||||
| }) | |||||
| // 更新状态为已领取 | |||||
| this.isReceived = true | |||||
| } | |||||
| }).catch(err => { | |||||
| uni.showToast({ | |||||
| title: '领取优惠券失败', | |||||
| icon: 'none' | |||||
| }) | |||||
| }) | |||||
| }, | |||||
| // 打开下单方式选择弹窗 | |||||
| openOrderTypePopup() { | |||||
| this.$refs.orderTypeSelectPopup.open() | |||||
| }, | |||||
| // 暂不领取 | |||||
| skipReceive() { | |||||
| uni.navigateBack() | |||||
| } | |||||
| } | |||||
| } | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| .new-user-page { | |||||
| position: relative; | |||||
| width: 100vw; | |||||
| height: 100vh; | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| overflow: hidden; | |||||
| } | |||||
| .bg-image { | |||||
| position: absolute; | |||||
| top: 0; | |||||
| left: 0; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| z-index: 1; | |||||
| } | |||||
| .title-image { | |||||
| position: relative; | |||||
| z-index: 2; | |||||
| width: 280rpx; | |||||
| margin-bottom: 40rpx; | |||||
| margin-top: -200rpx; | |||||
| } | |||||
| .coupon-content-image { | |||||
| position: relative; | |||||
| z-index: 2; | |||||
| width: 600rpx; | |||||
| margin-bottom: 80rpx; | |||||
| } | |||||
| .receive-btn { | |||||
| position: relative; | |||||
| z-index: 2; | |||||
| width: 600rpx; | |||||
| height: 80rpx; | |||||
| background: linear-gradient(135deg, #FFB13F 0%, #FF8C00 100%); | |||||
| color: #FFFFFF; | |||||
| font-size: 32rpx; | |||||
| font-weight: bold; | |||||
| border-radius: 40rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| box-shadow: 0 8rpx 20rpx rgba(255, 177, 63, 0.4); | |||||
| margin-bottom: 40rpx; | |||||
| &:active { | |||||
| transform: scale(0.95); | |||||
| transition: transform 0.1s; | |||||
| } | |||||
| } | |||||
| .skip-btn { | |||||
| position: relative; | |||||
| z-index: 2; | |||||
| width: 200rpx; | |||||
| height: 60rpx; | |||||
| background: rgba(255, 255, 255, 0.8); | |||||
| color: #666; | |||||
| font-size: 28rpx; | |||||
| border-radius: 30rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| &:active { | |||||
| background: rgba(255, 255, 255, 0.6); | |||||
| transition: background 0.1s; | |||||
| } | |||||
| } | |||||
| </style> | |||||
| @ -1,430 +1,422 @@ | |||||
| <template> | <template> | ||||
| <view class="task-detail"> | |||||
| <!-- 任务头部信息 --> | |||||
| <view class="task-header"> | |||||
| <view class="header-content"> | |||||
| <view class="header-top-row"> | |||||
| <view class="task-title">{{ getStatusText() }}</view> | |||||
| <view class="task-type">{{taskInfo.taskName || ''}}</view> | |||||
| <view class="task-reward">酬劳 <text> ¥{{taskInfo.taskMoney}}</text> </view> | |||||
| </view> | |||||
| <view class="task-deadline">请于 | |||||
| <text style="color: #FF5722;">{{taskInfo.taskEndTime ? formatDate(taskInfo.taskEndTime) : ''}}</text> | |||||
| 之前上传任务,超时将自动取消</view> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 任务进度 --> | |||||
| <view class="task-progress"> | |||||
| <view class="progress-title">任务进度</view> | |||||
| <uni-steps :options="stepsList" :active="currentStep" active-icon="checkbox-filled" | |||||
| active-color="#ffaa48"></uni-steps> | |||||
| </view> | |||||
| <!-- 任务说明 --> | |||||
| <view class="task-instruction"> | |||||
| <!-- <view class="instruction-header"> | |||||
| <view class="task-detail"> | |||||
| <!-- 任务头部信息 --> | |||||
| <view class="task-header"> | |||||
| <view class="header-content"> | |||||
| <view class="header-top-row"> | |||||
| <view class="task-status-tag" | |||||
| :class="{ 'status-pending': taskInfo.status === 0, 'status-reviewing': taskInfo.status === 1, 'status-rejected': taskInfo.status === 3, 'status-approved': taskInfo.status === 2 }"> | |||||
| <text v-if="taskInfo.status === 0">待上传</text> | |||||
| <text v-else-if="taskInfo.status === 1">待审核</text> | |||||
| <text v-else-if="taskInfo.status === 2">审核通过</text> | |||||
| <text v-else-if="taskInfo.status === 3">已驳回</text> | |||||
| </view> | |||||
| <view class="task-type">悬赏任务</view> | |||||
| <view class="task-reward" v-if="taskInfo.type == 0">酬劳 <text>{{ taskInfo.taskCouponTitle }}</text> | |||||
| </view> | |||||
| <view class="task-reward" v-if="taskInfo.type == 1">酬劳 <text> ¥{{ taskInfo.taskMoney }}</text></view> | |||||
| </view> | |||||
| <view class="task-deadline">请于 | |||||
| <text style="color: #FF5722;">{{ taskInfo.endTime ? formatDate(taskInfo.endTime) : '' }}</text> | |||||
| 之前上传任务,超时将自动取消 | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 任务进度 --> | |||||
| <view class="task-progress"> | |||||
| <view class="progress-title">任务进度</view> | |||||
| <uni-steps :options="stepsList" :active="currentStep" active-icon="checkbox-filled" | |||||
| active-color="#ffaa48"></uni-steps> | |||||
| </view> | |||||
| <!-- 任务说明 --> | |||||
| <view class="task-instruction"> | |||||
| <!-- <view class="instruction-header"> | |||||
| <image class="instruction-icon" | <image class="instruction-icon" | ||||
| :src="taskInfo.taskIcon || 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png'"> | :src="taskInfo.taskIcon || 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png'"> | ||||
| </image> | </image> | ||||
| <view class="instruction-title">{{taskInfo.taskName || '任务说明'}}</view> | <view class="instruction-title">{{taskInfo.taskName || '任务说明'}}</view> | ||||
| </view> --> | </view> --> | ||||
| <view class="instruction-content"> | |||||
| <!-- <view class="instruction-main"> | |||||
| <!-- <view class="instruction-content"> --> | |||||
| <!-- <view class="instruction-main"> | |||||
| <text>{{taskInfo.theme || '暂无任务说明'}}</text> | <text>{{taskInfo.theme || '暂无任务说明'}}</text> | ||||
| </view> --> | </view> --> | ||||
| <!-- 审核未通过时显示驳回原因 --> | |||||
| <!-- <view class="requirement-section" v-if="taskInfo.examineState === 2"> | |||||
| <!-- 审核未通过时显示驳回原因 --> | |||||
| <!-- <view class="requirement-section" v-if="taskInfo.examineState === 2"> | |||||
| <view class="requirement-title">驳回原因</view> | <view class="requirement-title">驳回原因</view> | ||||
| <view class="other-requirements"> | <view class="other-requirements"> | ||||
| <view class="requirement-item"> | <view class="requirement-item"> | ||||
| <view class="requirement-tag">!</view> | <view class="requirement-tag">!</view> | ||||
| <view class="requirement-text">{{taskInfo.examineText || '未提供驳回原因'}}</view> | |||||
| <view class="requirement-text">{{taskInfo.rejectTxt || '未提供驳回原因'}}</view> | |||||
| </view> | </view> | ||||
| </view> | </view> | ||||
| </view> --> | </view> --> | ||||
| <!-- 任务图片 --> | |||||
| <view class="task-images" v-if="taskInfo.image"> | |||||
| <image :src="taskInfo.image" mode="widthFix" style="width: 100%;"></image> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 底部按钮 --> | |||||
| <view class="footer-buttons"> | |||||
| <u-button shape="circle" plain @click="cancelTask">取消</u-button> | |||||
| <u-button shape="circle" color="#ffaa48" v-if="taskInfo.status == 0" | |||||
| @click="acceptTaskHandler">接受任务</u-button> | |||||
| <u-button shape="circle" color="#ffaa48" v-else-if="taskInfo.taskState == 1 || taskInfo.examineState == 2" | |||||
| @click="uploadTask">{{taskInfo.examineState === 2 ? '重新上传' : '立即上传'}}</u-button> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 任务图片 --> | |||||
| <view class="task-images" v-if="taskInfo.image"> | |||||
| <image :src="taskInfo.image" mode="widthFix" style="width: 100%;border-radius: 20rpx;"></image> | |||||
| </view> | |||||
| <!-- </view> --> | |||||
| </view> | |||||
| <!-- 底部按钮 --> | |||||
| <view class="footer-buttons"> | |||||
| <u-button shape="circle" plain @click="cancelTask">取消</u-button> | |||||
| <u-button shape="circle" color="#ffaa48" v-if="taskInfo.status == 0" @click="uploadTask">立即上传</u-button> | |||||
| <u-button shape="circle" disabled v-else-if="taskInfo.status == 1" text="审核中"></u-button> | |||||
| <u-button shape="circle" color="#ffaa48" v-else-if="taskInfo.status == 3" | |||||
| @click="uploadTask">重新上传</u-button> | |||||
| <u-button v-if="taskInfo.status === 3" shape="circle" type="error" text="驳回原因" | |||||
| @click="showRejectReason"></u-button> | |||||
| <view v-if="taskInfo.status == 2" class="task-status task-status-approved">已通过</view> | |||||
| </view> | |||||
| </view> | |||||
| </template> | </template> | ||||
| <script> | <script> | ||||
| import { | |||||
| getTaskDetail | |||||
| } from "@/api/order/task.js" | |||||
| import { | |||||
| getTaskList, | |||||
| acceptTask | |||||
| } from "@/api/order/task.js" | |||||
| export default { | |||||
| data() { | |||||
| return { | |||||
| taskInfo: { | |||||
| id: 0, | |||||
| title: '', | |||||
| theme: '', | |||||
| taskEndTime: '', | |||||
| taskName: '', | |||||
| taskMoney: 0, | |||||
| taskState: 0, | |||||
| examineState: 0, | |||||
| examineText: '', | |||||
| image: '', | |||||
| taskIcon: '' | |||||
| }, | |||||
| stepsList: [{ | |||||
| title: '接受任务' | |||||
| }, | |||||
| { | |||||
| title: '上传任务' | |||||
| }, | |||||
| { | |||||
| title: '平台审核' | |||||
| }, | |||||
| { | |||||
| title: '酬劳到账' | |||||
| } | |||||
| ], | |||||
| currentStep: 0, | |||||
| id : 0, | |||||
| } | |||||
| }, | |||||
| onLoad(options) { | |||||
| if (options.id) { | |||||
| this.id = options.id | |||||
| this.loadTaskDetail(options.id); | |||||
| } | |||||
| }, | |||||
| methods: { | |||||
| acceptTaskHandler(task) { | |||||
| // 接受任务 | |||||
| uni.showModal({ | |||||
| title: '接受任务', | |||||
| content: `确定接受任务: ${task.title}?`, | |||||
| success: res => { | |||||
| if (res.confirm) { | |||||
| acceptTask({id : task.id}).then(res => { | |||||
| if (res && res.code === 200) { | |||||
| uni.showToast({ | |||||
| title: '任务接受成功', | |||||
| icon: 'success' | |||||
| }); | |||||
| // 刷新任务 | |||||
| this.loadTaskDetail(this.id); | |||||
| } | |||||
| }); | |||||
| } | |||||
| } | |||||
| }); | |||||
| }, | |||||
| loadTaskDetail(taskId) { | |||||
| getTaskDetail(taskId).then(res => { | |||||
| if (res && res.code === 200) { | |||||
| this.taskInfo = res.data; | |||||
| // 根据任务状态设置当前步骤 | |||||
| this.updateCurrentStep(); | |||||
| } | |||||
| }); | |||||
| }, | |||||
| updateCurrentStep() { | |||||
| // 根据任务状态和审核状态设置当前步骤 | |||||
| if (this.taskInfo.status === 0) { | |||||
| this.currentStep = 0; // 待接受 | |||||
| } else if (this.taskInfo.taskState === 0) { | |||||
| this.currentStep = 1; // 已接受,待上传 | |||||
| } else if (this.taskInfo.taskState === 1) { | |||||
| if (this.taskInfo.examineState === 0) { | |||||
| this.currentStep = 2; // 已提交,待审核 | |||||
| } else if (this.taskInfo.examineState === 1) { | |||||
| this.currentStep = 3; // 已审核通过 | |||||
| } else if (this.taskInfo.examineState === 2) { | |||||
| this.currentStep = 1; // 审核未通过,重新上传 | |||||
| } | |||||
| } | |||||
| }, | |||||
| formatDate(dateStr) { | |||||
| if (!dateStr) return ''; | |||||
| let date = new Date(dateStr); | |||||
| let year = date.getFullYear(); | |||||
| let month = (date.getMonth() + 1).toString().padStart(2, '0'); | |||||
| let day = date.getDate().toString().padStart(2, '0'); | |||||
| return `${year}-${month}-${day}`; | |||||
| }, | |||||
| cancelTask() { | |||||
| uni.showModal({ | |||||
| title: '取消任务', | |||||
| content: '确定要取消此任务吗?', | |||||
| success: (res) => { | |||||
| if (res.confirm) { | |||||
| uni.navigateBack(); | |||||
| } | |||||
| } | |||||
| }); | |||||
| }, | |||||
| uploadTask() { | |||||
| uni.navigateTo({ | |||||
| url: `/pages_order/task/taskUpload?id=${this.taskInfo.id}&status=${this.taskInfo.examineState === 2 ? 'REJECTED' : 'ACCEPTED'}` | |||||
| }); | |||||
| }, | |||||
| getStatusText() { | |||||
| if (this.taskInfo.status === 0) { | |||||
| return '待接受'; | |||||
| } else if (this.taskInfo.taskState === 0) { | |||||
| return '待上传'; | |||||
| } else if (this.taskInfo.taskState === 1) { | |||||
| if (this.taskInfo.examineState === 0) { | |||||
| return '待审核'; | |||||
| } else if (this.taskInfo.examineState === 1) { | |||||
| return '审核通过'; | |||||
| } else if (this.taskInfo.examineState === 2) { | |||||
| return '审核未通过'; | |||||
| } | |||||
| } | |||||
| return ''; | |||||
| } | |||||
| } | |||||
| } | |||||
| import { | |||||
| getTaskDetail, | |||||
| getTaskDetailUser, | |||||
| } from "@/api/order/task.js" | |||||
| export default { | |||||
| data() { | |||||
| return { | |||||
| taskInfo: { | |||||
| id: 0, | |||||
| title: '', | |||||
| theme: '', | |||||
| endTime: '', | |||||
| type: 0, | |||||
| taskCouponTitle: '', | |||||
| taskMoney: 0, | |||||
| status: 0, | |||||
| rejectTxt: '', | |||||
| taskIcon: '' | |||||
| }, | |||||
| stepsList: [{ | |||||
| title: '接受任务' | |||||
| }, | |||||
| { | |||||
| title: '上传任务' | |||||
| }, | |||||
| { | |||||
| title: '平台审核' | |||||
| }, | |||||
| { | |||||
| title: '酬劳到账' | |||||
| } | |||||
| ], | |||||
| currentStep: 0, | |||||
| id: 0, | |||||
| status: 0, | |||||
| } | |||||
| }, | |||||
| onLoad(options) { | |||||
| if (options.status) { | |||||
| this.status = options.status || 0 | |||||
| } | |||||
| if (options.id) { | |||||
| this.id = options.id | |||||
| this.loadTaskDetail(options.id); | |||||
| } | |||||
| }, | |||||
| methods: { | |||||
| showRejectReason() { | |||||
| uni.showModal({ | |||||
| title: '驳回原因', | |||||
| content: this.taskInfo.rejectTxt || '未提供驳回原因', | |||||
| showCancel: false | |||||
| }); | |||||
| }, | |||||
| loadTaskDetail(taskId) { | |||||
| if (this.status == 0) { | |||||
| getTaskDetail(taskId).then(res => { | |||||
| if (res && res.code === 200) { | |||||
| this.taskInfo = res.data; | |||||
| // 根据任务状态设置当前步骤 | |||||
| this.updateCurrentStep(); | |||||
| } | |||||
| }); | |||||
| }else{ | |||||
| getTaskDetailUser(taskId).then(res => { | |||||
| if (res && res.code === 200) { | |||||
| this.taskInfo = res.data; | |||||
| // 根据任务状态设置当前步骤 | |||||
| this.updateCurrentStep(); | |||||
| } | |||||
| }); | |||||
| } | |||||
| }, | |||||
| updateCurrentStep() { | |||||
| // 根据任务状态设置当前步骤 | |||||
| if (this.taskInfo.status === 0) { | |||||
| this.currentStep = 1; // 待上传 | |||||
| } else if (this.taskInfo.status === 1) { | |||||
| this.currentStep = 2; // 待审核 | |||||
| } else if (this.taskInfo.status === 2) { | |||||
| this.currentStep = 3; // 审核通过 | |||||
| } else if (this.taskInfo.status === 3) { | |||||
| this.currentStep = 1; // 已驳回,重新上传 | |||||
| } | |||||
| }, | |||||
| formatDate(dateStr) { | |||||
| if (!dateStr) return ''; | |||||
| let date = new Date(dateStr); | |||||
| let year = date.getFullYear(); | |||||
| let month = (date.getMonth() + 1).toString().padStart(2, '0'); | |||||
| let day = date.getDate().toString().padStart(2, '0'); | |||||
| return `${year}-${month}-${day}`; | |||||
| }, | |||||
| cancelTask() { | |||||
| uni.showModal({ | |||||
| title: '取消任务', | |||||
| content: '确定要取消此任务吗?', | |||||
| success: (res) => { | |||||
| if (res.confirm) { | |||||
| uni.navigateBack(); | |||||
| } | |||||
| } | |||||
| }); | |||||
| }, | |||||
| uploadTask() { | |||||
| uni.navigateTo({ | |||||
| url: `/pages_order/task/taskUpload?id=${this.taskInfo.id}&status=${this.taskInfo.status}` | |||||
| }); | |||||
| }, | |||||
| } | |||||
| } | |||||
| </script> | </script> | ||||
| <style lang="scss"> | <style lang="scss"> | ||||
| .task-detail { | |||||
| background-color: #f5f5f7; | |||||
| min-height: 100vh; | |||||
| padding-bottom: 120rpx; | |||||
| .task-header { | |||||
| background-color: #FFFFFF; | |||||
| padding: 30rpx; | |||||
| margin: 20rpx; | |||||
| border-radius: 20rpx; | |||||
| background: linear-gradient(to bottom, #FFE4BB66, #fff, #fff, #fff); | |||||
| .header-content { | |||||
| .header-top-row { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| margin-bottom: 20rpx; | |||||
| .task-title { | |||||
| font-size: 30rpx; | |||||
| flex-shrink: 0; | |||||
| font-weight: 900; | |||||
| } | |||||
| .task-type { | |||||
| color: #C68C5B; | |||||
| font-size: 26rpx; | |||||
| background-color: #FFE4BB; | |||||
| padding: 10rpx 30rpx; | |||||
| border-radius: 30rpx; | |||||
| text-align: center; | |||||
| margin: 0 10rpx; | |||||
| width: fit-content; | |||||
| } | |||||
| .task-reward { | |||||
| font-size: 26rpx; | |||||
| color: #333; | |||||
| flex-shrink: 0; | |||||
| margin-left: auto; | |||||
| text { | |||||
| color: #FF5722; | |||||
| font-weight: bold; | |||||
| margin-left: 10rpx; | |||||
| font-size: 30rpx; | |||||
| } | |||||
| } | |||||
| } | |||||
| .task-deadline { | |||||
| font-size: 24rpx; | |||||
| color: #999; | |||||
| } | |||||
| } | |||||
| } | |||||
| .task-progress { | |||||
| background-color: #FFFFFF; | |||||
| margin: 20rpx; | |||||
| border-radius: 20rpx; | |||||
| padding: 30rpx; | |||||
| .progress-title { | |||||
| font-size: 30rpx; | |||||
| font-weight: bold; | |||||
| color: #333; | |||||
| margin-bottom: 30rpx; | |||||
| } | |||||
| } | |||||
| .task-instruction { | |||||
| background-color: #FFFFFF; | |||||
| margin: 20rpx; | |||||
| border-radius: 20rpx; | |||||
| padding: 30rpx; | |||||
| .instruction-header { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| margin-bottom: 30rpx; | |||||
| .instruction-icon { | |||||
| width: 60rpx; | |||||
| height: 60rpx; | |||||
| margin-right: 20rpx; | |||||
| } | |||||
| .instruction-title { | |||||
| font-size: 32rpx; | |||||
| font-weight: bold; | |||||
| color: #A94F20; | |||||
| } | |||||
| } | |||||
| .instruction-content { | |||||
| .instruction-main { | |||||
| padding: 20rpx 0; | |||||
| border-bottom: 1px solid #EEEEEE; | |||||
| margin-bottom: 20rpx; | |||||
| text { | |||||
| font-size: 28rpx; | |||||
| color: #666; | |||||
| line-height: 1.6; | |||||
| } | |||||
| } | |||||
| .requirement-section { | |||||
| margin-bottom: 30rpx; | |||||
| .requirement-title { | |||||
| font-size: 28rpx; | |||||
| font-weight: bold; | |||||
| color: #333; | |||||
| margin-bottom: 20rpx; | |||||
| } | |||||
| .requirement-content { | |||||
| padding: 20rpx; | |||||
| background-color: #FFF4E5; | |||||
| border-radius: 10rpx; | |||||
| text { | |||||
| display: block; | |||||
| font-size: 26rpx; | |||||
| color: #A94F20; | |||||
| line-height: 1.8; | |||||
| } | |||||
| } | |||||
| .title-examples { | |||||
| background-color: #FFF4E5; | |||||
| padding: 20rpx; | |||||
| border-radius: 10rpx; | |||||
| .example-item { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| margin-bottom: 15rpx; | |||||
| .example-tag { | |||||
| width: 50rpx; | |||||
| height: 50rpx; | |||||
| background-color: #ffaa48; | |||||
| color: #FFFFFF; | |||||
| border-radius: 25rpx; | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| font-size: 24rpx; | |||||
| margin-right: 20rpx; | |||||
| } | |||||
| .example-text { | |||||
| font-size: 26rpx; | |||||
| color: #A94F20; | |||||
| } | |||||
| } | |||||
| } | |||||
| .other-requirements { | |||||
| background-color: #FFF4E5; | |||||
| padding: 20rpx; | |||||
| border-radius: 10rpx; | |||||
| .requirement-item { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| margin-bottom: 15rpx; | |||||
| .requirement-tag { | |||||
| width: 40rpx; | |||||
| height: 40rpx; | |||||
| color: #A94F20; | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| font-size: 24rpx; | |||||
| margin-right: 20rpx; | |||||
| } | |||||
| .requirement-text { | |||||
| font-size: 26rpx; | |||||
| color: #A94F20; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| .note-text { | |||||
| text-align: center; | |||||
| margin-top: 20rpx; | |||||
| text { | |||||
| font-size: 24rpx; | |||||
| color: #FF5722; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| .footer-buttons { | |||||
| position: fixed; | |||||
| bottom: 0; | |||||
| left: 0; | |||||
| right: 0; | |||||
| background-color: #FFFFFF; | |||||
| padding: 20rpx 30rpx; | |||||
| display: flex; | |||||
| justify-content: space-around; | |||||
| align-items: center; | |||||
| box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05); | |||||
| .u-button { | |||||
| width: 300rpx; | |||||
| height: 80rpx; | |||||
| font-size: 28rpx; | |||||
| } | |||||
| } | |||||
| } | |||||
| .task-detail { | |||||
| background-color: #f5f5f7; | |||||
| min-height: 100vh; | |||||
| padding-bottom: 120rpx; | |||||
| .task-header { | |||||
| background-color: #FFFFFF; | |||||
| padding: 30rpx; | |||||
| margin: 20rpx; | |||||
| border-radius: 20rpx; | |||||
| background: linear-gradient(to bottom, #FFE4BB66, #fff, #fff, #fff); | |||||
| .header-content { | |||||
| .header-top-row { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| margin-bottom: 20rpx; | |||||
| .task-title { | |||||
| font-size: 30rpx; | |||||
| flex-shrink: 0; | |||||
| font-weight: 900; | |||||
| } | |||||
| .task-type { | |||||
| color: #C68C5B; | |||||
| font-size: 26rpx; | |||||
| background-color: #FFE4BB; | |||||
| padding: 10rpx 30rpx; | |||||
| border-radius: 30rpx; | |||||
| text-align: center; | |||||
| margin: 0 10rpx; | |||||
| width: fit-content; | |||||
| } | |||||
| .task-reward { | |||||
| font-size: 26rpx; | |||||
| color: #333; | |||||
| flex-shrink: 0; | |||||
| margin-left: auto; | |||||
| text { | |||||
| color: #FF5722; | |||||
| font-weight: bold; | |||||
| margin-left: 10rpx; | |||||
| font-size: 30rpx; | |||||
| } | |||||
| } | |||||
| } | |||||
| .task-deadline { | |||||
| font-size: 24rpx; | |||||
| color: #999; | |||||
| } | |||||
| } | |||||
| } | |||||
| .task-progress { | |||||
| background-color: #FFFFFF; | |||||
| margin: 20rpx; | |||||
| border-radius: 20rpx; | |||||
| padding: 30rpx; | |||||
| .progress-title { | |||||
| font-size: 30rpx; | |||||
| font-weight: bold; | |||||
| color: #333; | |||||
| margin-bottom: 30rpx; | |||||
| } | |||||
| } | |||||
| .task-instruction { | |||||
| // background-color: #FFFFFF; | |||||
| margin: 20rpx; | |||||
| border-radius: 20rpx; | |||||
| // padding: 30rpx; | |||||
| .instruction-header { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| margin-bottom: 30rpx; | |||||
| .instruction-icon { | |||||
| width: 60rpx; | |||||
| height: 60rpx; | |||||
| margin-right: 20rpx; | |||||
| } | |||||
| .instruction-title { | |||||
| font-size: 32rpx; | |||||
| font-weight: bold; | |||||
| color: #A94F20; | |||||
| } | |||||
| } | |||||
| .instruction-content { | |||||
| .instruction-main { | |||||
| // padding: 20rpx 0; | |||||
| border-bottom: 1px solid #EEEEEE; | |||||
| margin-bottom: 20rpx; | |||||
| text { | |||||
| font-size: 28rpx; | |||||
| color: #666; | |||||
| line-height: 1.6; | |||||
| } | |||||
| } | |||||
| .requirement-section { | |||||
| margin-bottom: 30rpx; | |||||
| .requirement-title { | |||||
| font-size: 28rpx; | |||||
| font-weight: bold; | |||||
| color: #333; | |||||
| margin-bottom: 20rpx; | |||||
| } | |||||
| .requirement-content { | |||||
| padding: 20rpx; | |||||
| background-color: #FFF4E5; | |||||
| border-radius: 10rpx; | |||||
| text { | |||||
| display: block; | |||||
| font-size: 26rpx; | |||||
| color: #A94F20; | |||||
| line-height: 1.8; | |||||
| } | |||||
| } | |||||
| .title-examples { | |||||
| background-color: #FFF4E5; | |||||
| padding: 20rpx; | |||||
| border-radius: 10rpx; | |||||
| .example-item { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| margin-bottom: 15rpx; | |||||
| .example-tag { | |||||
| width: 50rpx; | |||||
| height: 50rpx; | |||||
| background-color: #ffaa48; | |||||
| color: #FFFFFF; | |||||
| border-radius: 25rpx; | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| font-size: 24rpx; | |||||
| margin-right: 20rpx; | |||||
| } | |||||
| .example-text { | |||||
| font-size: 26rpx; | |||||
| color: #A94F20; | |||||
| } | |||||
| } | |||||
| } | |||||
| .other-requirements { | |||||
| background-color: #FFF4E5; | |||||
| padding: 20rpx; | |||||
| border-radius: 10rpx; | |||||
| .requirement-item { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| margin-bottom: 15rpx; | |||||
| .requirement-tag { | |||||
| width: 40rpx; | |||||
| height: 40rpx; | |||||
| color: #A94F20; | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| font-size: 24rpx; | |||||
| margin-right: 20rpx; | |||||
| } | |||||
| .requirement-text { | |||||
| font-size: 26rpx; | |||||
| color: #A94F20; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| .note-text { | |||||
| text-align: center; | |||||
| margin-top: 20rpx; | |||||
| text { | |||||
| font-size: 24rpx; | |||||
| color: #FF5722; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| .footer-buttons { | |||||
| position: fixed; | |||||
| bottom: 0; | |||||
| left: 0; | |||||
| right: 0; | |||||
| background-color: #FFFFFF; | |||||
| padding: 20rpx 30rpx; | |||||
| display: flex; | |||||
| justify-content: space-around; | |||||
| align-items: center; | |||||
| box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05); | |||||
| .u-button { | |||||
| width: 300rpx; | |||||
| height: 80rpx; | |||||
| font-size: 28rpx; | |||||
| } | |||||
| } | |||||
| } | |||||
| </style> | </style> | ||||
| @ -1,407 +1,394 @@ | |||||
| <template> | <template> | ||||
| <view class="task-center"> | |||||
| <view class="task-center"> | |||||
| <!-- <u-subsection :list="tabList" | |||||
| <!-- <u-subsection :list="tabList" | |||||
| active-color="#ffaa48" | active-color="#ffaa48" | ||||
| bg-color="#fff" | bg-color="#fff" | ||||
| inactive-color="#aaaaaa" | inactive-color="#aaaaaa" | ||||
| font-size="16" | font-size="16" | ||||
| :current="curNow" | :current="curNow" | ||||
| @change="sectionChange"></u-subsection> --> | @change="sectionChange"></u-subsection> --> | ||||
| <!-- <u-tabs :list="list1" @click="sectionChange"></u-tabs> --> | |||||
| <view class="container-tabs"> | |||||
| <u-tabs :list="tabList" | |||||
| :scrollable="false" | |||||
| lineWidth="68rpx" :activeStyle="{ | |||||
| color: '#fff', | |||||
| fontWeight: 'bold', | |||||
| transform: 'scale(1.05)' | |||||
| }" :inactiveStyle="{ | |||||
| color: '#eee', | |||||
| transform: 'scale(1)' | |||||
| }" :itemStyle="{height:'88rpx',padding:'0 52rpx'}" lineColor="#fff" @click="sectionChange"></u-tabs> | |||||
| </view> | |||||
| <!-- 待接受任务列表 --> | |||||
| <view v-if="curNow === 0"> | |||||
| <view v-for="(item,index) in pendingTasks" style="padding:28rpx 36rpx 0;" :key="index"> | |||||
| <view class="task-card"> | |||||
| <view class="task-header"> | |||||
| <view class="task-image"> | |||||
| <image src="https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png" mode="heightFix"></image> | |||||
| </view> | |||||
| <view class="task-type">{{item.taskType}}</view> | |||||
| <view class="task-reward">酬劳 <text> ¥{{item.reward}}</text> </view> | |||||
| </view> | |||||
| <view class="task-content"> | |||||
| <view class="task-icon"> | |||||
| <image :src="item.icon" style="width: 150rpx; height: 150rpx;" mode="aspectFill"></image> | |||||
| </view> | |||||
| <view class="task-info"> | |||||
| <view class="task-title">{{item.title}}</view> | |||||
| <view class="task-desc">{{item.description}}</view> | |||||
| <view class="task-deadline">任务截止日期: {{item.deadline}}</view> | |||||
| </view> | |||||
| </view> | |||||
| <view class="task-footer"> | |||||
| <u-button shape="circle" plain text="查看详情" @click="viewTaskDetail(item)"></u-button> | |||||
| <u-button shape="circle" color="#ffaa48" text="立即接受" @click="acceptTaskHandler(item)"></u-button> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| <view v-if="pendingTasks.length === 0" class="empty-tip"> | |||||
| <text>暂无待接受任务</text> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 已接收任务列表 --> | |||||
| <view v-else> | |||||
| <view v-for="(item,index) in acceptedTasks" style="padding:28rpx 36rpx 0;" :key="index"> | |||||
| <view class="task-card"> | |||||
| <view class="task-header"> | |||||
| <view class="task-image"> | |||||
| <image src="https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png" mode="heightFix"></image> | |||||
| </view> | |||||
| <view class="task-type">{{item.taskType}}</view> | |||||
| <!-- <view class="task-reward">酬劳 <text> ¥{{item.reward}}</text> </view> --> | |||||
| <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> | |||||
| </view> | |||||
| <view class="task-content"> | |||||
| <view class="task-icon"> | |||||
| <image :src="item.icon" style="width: 150rpx; height: 150rpx;" mode="aspectFill"></image> | |||||
| </view> | |||||
| <view class="task-info"> | |||||
| <view class="task-title">{{item.title}}</view> | |||||
| <view class="task-desc">{{item.description}}</view> | |||||
| <view class="task-deadline">任务截止日期: {{item.deadline}}</view> | |||||
| <!-- <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> --> | |||||
| </view> | |||||
| </view> | |||||
| <view class="task-footer"> | |||||
| <u-button shape="circle" plain text="查看详情" @click="viewTaskDetail(item)"></u-button> | |||||
| <u-button v-if="item.status === 'REJECTED'" shape="circle" type="error" text="驳回原因" @click="showRejectReason(item)"></u-button> | |||||
| <u-button v-if="item.status === 'ACCEPTED'" shape="circle" color="#ffaa48" text="立即上传" @click="uploadTask(item)"></u-button> | |||||
| <u-button v-if="item.status === 'SUBMITTED'" shape="circle" disabled text="审核中"></u-button> | |||||
| <u-button v-if="item.status === 'REJECTED'" shape="circle" color="#ffaa48" text="重新上传" @click="uploadTask(item)"></u-button> | |||||
| <view v-if="item.status === 'APPROVED'" class="task-status task-status-approved">已通过</view> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| <view v-if="acceptedTasks.length === 0" class="empty-tip"> | |||||
| <text>暂无已接收任务</text> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| <!-- <u-tabs :list="list1" @click="sectionChange"></u-tabs> --> | |||||
| <view class="container-tabs"> | |||||
| <u-tabs :list="tabList" :scrollable="false" lineWidth="68rpx" :activeStyle="{ | |||||
| color: '#fff', | |||||
| fontWeight: 'bold', | |||||
| transform: 'scale(1.05)' | |||||
| }" :inactiveStyle="{ | |||||
| color: '#eee', | |||||
| transform: 'scale(1)' | |||||
| }" :itemStyle="{ height: '88rpx', padding: '0 52rpx' }" lineColor="#fff" @click="sectionChange"></u-tabs> | |||||
| </view> | |||||
| <!-- 待接受任务列表 --> | |||||
| <view v-if="curNow === 0"> | |||||
| <view v-for="(item, index) in pendingTasks" style="padding:28rpx 36rpx 0;" :key="index"> | |||||
| <view class="task-card"> | |||||
| <view class="task-header"> | |||||
| <view class="task-image"> | |||||
| <image | |||||
| src="https://image.hhlm1688.com/2025/08/07767f2fc0a686433bb9e3f90bc6e60990Group%201000001612@3x.png" | |||||
| mode="heightFix"></image> | |||||
| </view> | |||||
| <view class="task-type">悬赏任务</view> | |||||
| <view class="task-reward" v-if="item.type == 0">酬劳 <text>{{ item.taskCouponTitle }}</text></view> | |||||
| <view class="task-reward" v-if="item.type == 1">酬劳 <text> ¥{{ item.taskMoney }}</text></view> | |||||
| </view> | |||||
| <view class="task-content"> | |||||
| <view class="task-icon"> | |||||
| <image :src="item.taskIcon" style="width: 150rpx; height: 150rpx;" mode="aspectFill"> | |||||
| </image> | |||||
| </view> | |||||
| <view class="task-info"> | |||||
| <view class="task-title">{{ item.title }}</view> | |||||
| <view class="task-desc">主题:{{ item.theme }}</view> | |||||
| <view class="task-deadline">任务截止日期: {{ item.endTime }}</view> | |||||
| </view> | |||||
| </view> | |||||
| <view class="task-footer"> | |||||
| <u-button shape="circle" plain text="查看详情" @click="viewTaskDetail(item, 0)"></u-button> | |||||
| <u-button shape="circle" color="#ffaa48" text="立即接受" | |||||
| @click="acceptTaskHandler(item)"></u-button> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| <view v-if="pendingTasks.length === 0" class="empty-tip"> | |||||
| <text>暂无待接受任务</text> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 已接收任务列表 --> | |||||
| <view v-else> | |||||
| <view v-for="(item, index) in acceptedTasks" style="padding:28rpx 36rpx 0;" :key="index"> | |||||
| <view class="task-card"> | |||||
| <view class="task-header"> | |||||
| <view class="task-image"> | |||||
| <image | |||||
| src="https://image.hhlm1688.com/2025/08/07767f2fc0a686433bb9e3f90bc6e60990Group%201000001612@3x.png" | |||||
| mode="heightFix"></image> | |||||
| </view> | |||||
| <view class="task-type">悬赏任务</view> | |||||
| <!-- <template v-if="item.status == 0"> | |||||
| <view class="task-reward" v-if="item.type == 0">酬劳 <text>{{ item.taskCouponTitle }}</text></view> | |||||
| <view class="task-reward" v-if="item.type == 1">酬劳 <text> ¥{{ item.taskMoney }}</text></view> | |||||
| </template> --> | |||||
| <view class="task-status-tag" | |||||
| :class="{ 'status-pending': item.status === 0, 'status-reviewing': item.status === 1, 'status-rejected': item.status === 3, 'status-approved': item.status === 2 }"> | |||||
| <text v-if="item.status === 0">待上传</text> | |||||
| <text v-else-if="item.status === 1">待审核</text> | |||||
| <text v-else-if="item.status === 2">审核通过</text> | |||||
| <text v-else-if="item.status === 3">已驳回</text> | |||||
| </view> | |||||
| </view> | |||||
| <view class="task-content"> | |||||
| <view class="task-icon"> | |||||
| <image :src="item.taskIcon" style="width: 150rpx; height: 150rpx;" mode="aspectFill"> | |||||
| </image> | |||||
| </view> | |||||
| <view class="task-info"> | |||||
| <view class="task-title">{{ item.title }}</view> | |||||
| <view class="task-desc">主题:{{ item.theme }}</view> | |||||
| <view class="task-deadline">任务截止日期: {{ item.endTime }}</view> | |||||
| </view> | |||||
| </view> | |||||
| <view class="task-footer"> | |||||
| <u-button shape="circle" plain text="查看详情" @click="viewTaskDetail(item, 1)"></u-button> | |||||
| <u-button v-if="item.status === 3" shape="circle" type="error" text="驳回原因" | |||||
| @click="showRejectReason(item)"></u-button> | |||||
| <u-button v-if="item.status === 0" shape="circle" color="#ffaa48" text="立即上传" | |||||
| @click="uploadTask(item)"></u-button> | |||||
| <u-button v-if="item.status === 1" shape="circle" disabled text="审核中"></u-button> | |||||
| <u-button v-if="item.status === 3" shape="circle" color="#ffaa48" text="重新上传" | |||||
| @click="uploadTask(item)"></u-button> | |||||
| <view v-if="item.status === 2" class="task-status task-status-approved">已通过</view> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| <view v-if="acceptedTasks.length === 0" class="empty-tip"> | |||||
| <text>暂无已接收任务</text> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| </template> | </template> | ||||
| <script> | <script> | ||||
| import { | |||||
| getTaskList, | |||||
| getTaskDetail, | |||||
| acceptTask | |||||
| } from "@/api/order/task.js" | |||||
| export default { | |||||
| data() { | |||||
| return { | |||||
| tabList: [ | |||||
| { | |||||
| name: '待接受', | |||||
| badge: { | |||||
| value: 1, | |||||
| } | |||||
| }, | |||||
| { | |||||
| name: '已接受', | |||||
| badge: { | |||||
| value: 0, | |||||
| } | |||||
| }, | |||||
| ], | |||||
| curNow: 0, | |||||
| pendingTasks: [], | |||||
| acceptedTasks: [] | |||||
| } | |||||
| }, | |||||
| onShow() { | |||||
| // 加载任务列表数据 | |||||
| this.getTaskList() | |||||
| }, | |||||
| methods: { | |||||
| sectionChange({index}) { | |||||
| this.curNow = index; | |||||
| this.getTaskList() | |||||
| }, | |||||
| getTaskList() { | |||||
| // 调用API获取任务列表 | |||||
| getTaskList({ | |||||
| status : this.curNow | |||||
| }).then(res=>{ | |||||
| if (res && res.code === 200) { | |||||
| let rows = res.rows || [] | |||||
| console.log(rows) | |||||
| // 根据status字段分类:0为待接受,1为已接受 | |||||
| this.pendingTasks = rows.filter(item => item.status === 0).map(item => this.formatTaskItem(item)) | |||||
| this.acceptedTasks = rows.filter(item => item.status === 1).map(item => this.formatTaskItem(item)) | |||||
| this.updateBadgeCount() | |||||
| } | |||||
| }) | |||||
| }, | |||||
| // 格式化任务项 | |||||
| formatTaskItem(item) { | |||||
| return { | |||||
| id: item.id, | |||||
| taskType: item.taskName || '任务', | |||||
| reward: item.taskMoney || '0', | |||||
| icon: item.taskIcon || 'https://catmdogf.oss-cn-shanghai.aliyuncs.com/CMDF/front/personal/index/point.png', | |||||
| title: item.title || '', | |||||
| description: item.theme || '', | |||||
| deadline: item.taskEndTime ? this.formatDate(item.taskEndTime) : '', | |||||
| status: this.getTaskStatus(item.taskState, item.examineState), | |||||
| rejectReason: item.examineText || '' | |||||
| } | |||||
| }, | |||||
| // 根据任务进度和审核状态获取任务状态 | |||||
| getTaskStatus(taskState, examineState) { | |||||
| // taskState: 任务进度,examineState: 审核状态 | |||||
| if (taskState === 0) return 'ACCEPTED'; // 待上传 | |||||
| if (taskState === 1 && examineState === 0) return 'SUBMITTED'; // 审核中 | |||||
| if (taskState === 1 && examineState === 1) return 'APPROVED'; // 已通过 | |||||
| if (taskState === 1 && examineState === 2) return 'REJECTED'; // 驳回 | |||||
| return 'ACCEPTED'; // 默认状态 | |||||
| }, | |||||
| // 格式化日期 | |||||
| formatDate(dateStr) { | |||||
| if (!dateStr) return ''; | |||||
| let date = new Date(dateStr); | |||||
| let year = date.getFullYear(); | |||||
| let month = (date.getMonth() + 1).toString().padStart(2, '0'); | |||||
| let day = date.getDate().toString().padStart(2, '0'); | |||||
| return `${year}-${month}-${day}`; | |||||
| }, | |||||
| updateBadgeCount() { | |||||
| // 更新标签页的徽标数量 | |||||
| this.tabList[0].badge.value = this.pendingTasks.length | |||||
| this.tabList[1].badge.value = this.acceptedTasks.length | |||||
| }, | |||||
| viewTaskDetail(task) { | |||||
| // 查看任务详情,跳转到任务详情页面 | |||||
| uni.navigateTo({ | |||||
| url: `/pages_order/task/taskDetail?id=${task.id}` | |||||
| }); | |||||
| }, | |||||
| acceptTaskHandler(task) { | |||||
| // 接受任务 | |||||
| uni.showModal({ | |||||
| title: '接受任务', | |||||
| content: `确定接受任务: ${task.title}?`, | |||||
| success: res => { | |||||
| if (res.confirm) { | |||||
| acceptTask({id : task.id}).then(res => { | |||||
| if (res && res.code === 200) { | |||||
| uni.showToast({ | |||||
| title: '任务接受成功', | |||||
| icon: 'success' | |||||
| }); | |||||
| // 刷新任务列表 | |||||
| this.getTaskList(); | |||||
| } | |||||
| }); | |||||
| } | |||||
| } | |||||
| }); | |||||
| }, | |||||
| uploadTask(task) { | |||||
| // 上传任务 | |||||
| uni.navigateTo({ | |||||
| url: `/pages_order/task/taskUpload?id=${task.id}&status=${task.status}` | |||||
| }); | |||||
| }, | |||||
| showRejectReason(task) { | |||||
| // 显示驳回原因 | |||||
| if (task.rejectReason) { | |||||
| uni.showModal({ | |||||
| title: '驳回原因', | |||||
| content: task.rejectReason, | |||||
| showCancel: false | |||||
| }); | |||||
| } else { | |||||
| uni.showToast({ | |||||
| title: '暂无驳回原因', | |||||
| icon: 'none' | |||||
| }); | |||||
| } | |||||
| }, | |||||
| getStatusText(status) { | |||||
| // 获取状态文本 | |||||
| const statusMap = { | |||||
| 'ACCEPTED': '待上传', | |||||
| 'SUBMITTED': '审核中', | |||||
| 'REJECTED': '未通过', | |||||
| 'APPROVED': '已通过' | |||||
| }; | |||||
| return statusMap[status] || status; | |||||
| } | |||||
| } | |||||
| } | |||||
| import { | |||||
| getTaskList, | |||||
| getTaskDetail, | |||||
| acceptTask, | |||||
| getTaskListByUser, | |||||
| getTaskDetailUser | |||||
| } from "@/api/order/task.js" | |||||
| export default { | |||||
| data() { | |||||
| return { | |||||
| tabList: [ | |||||
| { | |||||
| name: '待接受', | |||||
| badge: { | |||||
| value: 0, | |||||
| } | |||||
| }, | |||||
| { | |||||
| name: '已接受', | |||||
| badge: { | |||||
| value: 0, | |||||
| } | |||||
| }, | |||||
| ], | |||||
| curNow: 0, | |||||
| pendingTasks: [], | |||||
| acceptedTasks: [] | |||||
| } | |||||
| }, | |||||
| onShow() { | |||||
| // 加载任务列表数据 | |||||
| this.getTaskList() | |||||
| }, | |||||
| methods: { | |||||
| sectionChange({ index }) { | |||||
| this.curNow = index; | |||||
| this.getTaskList() | |||||
| }, | |||||
| getTaskList() { | |||||
| if (this.curNow == 0) { | |||||
| getTaskList().then(res => { | |||||
| if (res && res.code === 200) { | |||||
| let rows = res.rows || [] | |||||
| this.pendingTasks = rows | |||||
| } | |||||
| }) | |||||
| }else{ | |||||
| getTaskListByUser().then(res => { | |||||
| if (res && res.code === 200) { | |||||
| let rows = res.rows || [] | |||||
| this.acceptedTasks = rows | |||||
| } | |||||
| }) | |||||
| } | |||||
| }, | |||||
| // 格式化日期 | |||||
| formatDate(dateStr) { | |||||
| if (!dateStr) return ''; | |||||
| let date = new Date(dateStr); | |||||
| let year = date.getFullYear(); | |||||
| let month = (date.getMonth() + 1).toString().padStart(2, '0'); | |||||
| let day = date.getDate().toString().padStart(2, '0'); | |||||
| return `${year}-${month}-${day}`; | |||||
| }, | |||||
| viewTaskDetail(task, status) { | |||||
| // 查看任务详情,跳转到任务详情页面 | |||||
| uni.navigateTo({ | |||||
| url: `/pages_order/task/taskDetail?id=${task.id}&status=${status}` | |||||
| }); | |||||
| }, | |||||
| acceptTaskHandler(task) { | |||||
| // 接受任务 | |||||
| uni.showModal({ | |||||
| title: '接受任务', | |||||
| content: `确定接受任务: ${task.title}?`, | |||||
| success: res => { | |||||
| if (res.confirm) { | |||||
| acceptTask({ id: task.id }).then(res => { | |||||
| if (res && res.code === 200) { | |||||
| uni.showToast({ | |||||
| title: '任务接受成功', | |||||
| icon: 'success' | |||||
| }); | |||||
| // 刷新任务列表 | |||||
| this.getTaskList(); | |||||
| } | |||||
| }); | |||||
| } | |||||
| } | |||||
| }); | |||||
| }, | |||||
| uploadTask(task) { | |||||
| // 上传任务 | |||||
| uni.navigateTo({ | |||||
| url: `/pages_order/task/taskUpload?id=${task.id}` | |||||
| }); | |||||
| }, | |||||
| showRejectReason(task) { | |||||
| // 显示驳回原因 | |||||
| if (task.rejectTxt) { | |||||
| uni.showModal({ | |||||
| title: '驳回原因', | |||||
| content: task.rejectTxt, | |||||
| showCancel: false | |||||
| }); | |||||
| } else { | |||||
| uni.showToast({ | |||||
| title: '暂无驳回原因', | |||||
| icon: 'none' | |||||
| }); | |||||
| } | |||||
| }, | |||||
| } | |||||
| } | |||||
| </script> | </script> | ||||
| <style lang="scss"> | <style lang="scss"> | ||||
| .task-center { | |||||
| background-color: #f5f5f7; | |||||
| min-height: 100vh; | |||||
| .container-tabs{ | |||||
| background-color: #FFBF60; | |||||
| } | |||||
| .task-status-tag { | |||||
| display: inline-block; | |||||
| font-size: 24rpx; | |||||
| padding: 6rpx 20rpx; | |||||
| border-radius: 20rpx; | |||||
| margin-top: 10rpx; | |||||
| margin-left: auto; | |||||
| &.status-pending { | |||||
| // background-color: #E6F7FF; | |||||
| color: #1890FF; | |||||
| } | |||||
| &.status-reviewing { | |||||
| // background-color: #FFF7E6; | |||||
| color: #FA8C16; | |||||
| } | |||||
| &.status-rejected { | |||||
| // background-color: #FFF1F0; | |||||
| color: #F5222D; | |||||
| } | |||||
| &.status-approved { | |||||
| // background-color: #F6FFED; | |||||
| color: #52C41A; | |||||
| } | |||||
| } | |||||
| .task-card { | |||||
| background-color: #FFFFFF; | |||||
| border-radius: 16rpx; | |||||
| margin-bottom: 30rpx; | |||||
| overflow: hidden; | |||||
| .task-header { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| margin-bottom: 20rpx; | |||||
| background-color: #FFF4E599; | |||||
| padding: 15rpx; | |||||
| .task-image { | |||||
| margin-right: 30rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| image { | |||||
| height: 50rpx; | |||||
| width: 50rpx; | |||||
| } | |||||
| } | |||||
| .task-type { | |||||
| color: #C68C5B; | |||||
| font-size: 26rpx; | |||||
| background-color: #FFE4BB; | |||||
| padding: 10rpx 30rpx; | |||||
| border-radius: 30rpx; | |||||
| } | |||||
| .task-reward { | |||||
| font-size: 26rpx; | |||||
| margin-left: auto; | |||||
| text { | |||||
| color: #FF5722; | |||||
| font-weight: bold; | |||||
| margin-left: 10rpx; | |||||
| font-size: 30rpx; | |||||
| } | |||||
| } | |||||
| } | |||||
| .task-content { | |||||
| display: flex; | |||||
| margin-bottom: 30rpx; | |||||
| padding: 0 30rpx 0 30rpx; | |||||
| .task-icon { | |||||
| margin-right: 30rpx; | |||||
| } | |||||
| .task-info { | |||||
| flex: 1; | |||||
| position: relative; | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| gap: 10rpx; | |||||
| .task-title { | |||||
| font-size: 32rpx; | |||||
| font-weight: bold; | |||||
| color: #333; | |||||
| margin-bottom: 10rpx; | |||||
| } | |||||
| .task-desc { | |||||
| font-size: 28rpx; | |||||
| color: #666; | |||||
| margin-bottom: 10rpx; | |||||
| color: #FFC673; | |||||
| } | |||||
| .task-deadline { | |||||
| font-size: 24rpx; | |||||
| color: #999; | |||||
| margin-bottom: 10rpx; | |||||
| } | |||||
| } | |||||
| } | |||||
| .task-footer { | |||||
| padding-bottom: 30rpx; | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| align-items: flex-end; | |||||
| gap: 20rpx; | |||||
| flex-wrap: wrap; | |||||
| .u-button { | |||||
| width: 200rpx; | |||||
| height: 60rpx; | |||||
| font-size: 28rpx; | |||||
| } | |||||
| .task-status { | |||||
| height: 60rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| width: 200rpx; | |||||
| font-size: 28rpx; | |||||
| &.task-status-approved { | |||||
| color: #52C41A; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| .empty-tip { | |||||
| text-align: center; | |||||
| padding: 60rpx 0; | |||||
| color: #999; | |||||
| font-size: 28rpx; | |||||
| } | |||||
| } | |||||
| .task-center { | |||||
| background-color: #f5f5f7; | |||||
| min-height: 100vh; | |||||
| .container-tabs { | |||||
| background-color: #FFBF60; | |||||
| } | |||||
| .task-status-tag { | |||||
| display: inline-block; | |||||
| font-size: 24rpx; | |||||
| padding: 6rpx 20rpx; | |||||
| border-radius: 20rpx; | |||||
| margin-top: 10rpx; | |||||
| margin-left: auto; | |||||
| &.status-pending { | |||||
| // background-color: #E6F7FF; | |||||
| color: #1890FF; | |||||
| } | |||||
| &.status-reviewing { | |||||
| // background-color: #FFF7E6; | |||||
| color: #FA8C16; | |||||
| } | |||||
| &.status-rejected { | |||||
| // background-color: #FFF1F0; | |||||
| color: #F5222D; | |||||
| } | |||||
| &.status-approved { | |||||
| // background-color: #F6FFED; | |||||
| color: #52C41A; | |||||
| } | |||||
| } | |||||
| .task-card { | |||||
| background-color: #FFFFFF; | |||||
| border-radius: 16rpx; | |||||
| margin-bottom: 30rpx; | |||||
| overflow: hidden; | |||||
| .task-header { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| margin-bottom: 20rpx; | |||||
| background-color: #FFF4E599; | |||||
| padding: 15rpx; | |||||
| .task-image { | |||||
| margin-right: 30rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| image { | |||||
| height: 60rpx; | |||||
| width: 50rpx; | |||||
| } | |||||
| } | |||||
| .task-type { | |||||
| color: #C68C5B; | |||||
| font-size: 26rpx; | |||||
| background-color: #FFE4BB; | |||||
| padding: 10rpx 30rpx; | |||||
| border-radius: 30rpx; | |||||
| flex-shrink: 0; | |||||
| } | |||||
| .task-reward { | |||||
| font-size: 26rpx; | |||||
| margin-left: auto; | |||||
| flex-shrink: 0; | |||||
| text { | |||||
| color: #FF5722; | |||||
| font-weight: bold; | |||||
| margin-left: 10rpx; | |||||
| font-size: 30rpx; | |||||
| } | |||||
| } | |||||
| } | |||||
| .task-content { | |||||
| display: flex; | |||||
| margin-bottom: 30rpx; | |||||
| padding: 0 30rpx 0 30rpx; | |||||
| .task-icon { | |||||
| margin-right: 30rpx; | |||||
| } | |||||
| .task-info { | |||||
| flex: 1; | |||||
| position: relative; | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| gap: 10rpx; | |||||
| .task-title { | |||||
| font-size: 32rpx; | |||||
| font-weight: bold; | |||||
| color: #333; | |||||
| margin-bottom: 10rpx; | |||||
| } | |||||
| .task-desc { | |||||
| font-size: 28rpx; | |||||
| color: #666; | |||||
| margin-bottom: 10rpx; | |||||
| color: #FFC673; | |||||
| } | |||||
| .task-deadline { | |||||
| font-size: 24rpx; | |||||
| color: #999; | |||||
| margin-bottom: 10rpx; | |||||
| } | |||||
| } | |||||
| } | |||||
| .task-footer { | |||||
| padding-bottom: 30rpx; | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| align-items: flex-end; | |||||
| gap: 20rpx; | |||||
| flex-wrap: wrap; | |||||
| .u-button { | |||||
| width: 200rpx; | |||||
| height: 60rpx; | |||||
| font-size: 28rpx; | |||||
| } | |||||
| .task-status { | |||||
| height: 60rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| width: 200rpx; | |||||
| font-size: 28rpx; | |||||
| &.task-status-approved { | |||||
| color: #52C41A; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| .empty-tip { | |||||
| text-align: center; | |||||
| padding: 60rpx 0; | |||||
| color: #999; | |||||
| font-size: 28rpx; | |||||
| } | |||||
| } | |||||
| </style> | </style> | ||||
| @ -1,363 +1,431 @@ | |||||
| <template> | <template> | ||||
| <view class="task-upload"> | |||||
| <!-- 任务头部信息 --> | |||||
| <view class="task-header"> | |||||
| <view class="task-title">{{taskInfo.title}}</view> | |||||
| <view class="task-deadline">请于{{taskInfo.taskEndTime ? formatDate(taskInfo.taskEndTime) : ''}}之前上传任务,超时将自动取消</view> | |||||
| </view> | |||||
| <!-- 驳回原因提示(如果任务被驳回) --> | |||||
| <view class="reject-box" v-if="isRejected"> | |||||
| <view class="reject-title">审核未通过原因:</view> | |||||
| <view class="reject-reason">{{taskInfo.examineText || '暂无驳回原因'}}</view> | |||||
| </view> | |||||
| <!-- 上传表单 --> | |||||
| <view class="upload-form"> | |||||
| <!-- 链接输入 --> | |||||
| <view class="form-item"> | |||||
| <view class="form-label">笔记/视频链接</view> | |||||
| <view class="form-input"> | |||||
| <u-input v-model="formData.examineText" placeholder="请输入小红书/抖音等平台的笔记链接" /> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 图片上传 --> | |||||
| <view class="form-item"> | |||||
| <view class="form-label">证明截图</view> | |||||
| <view class="form-notice">请上传任务完成的截图证明,例如发布成功的截图</view> | |||||
| <view class="upload-box"> | |||||
| <u-upload | |||||
| :fileList="fileList" | |||||
| @afterRead="afterRead" | |||||
| @delete="deletePic" | |||||
| name="examineImage" | |||||
| multiple | |||||
| :maxCount="3" | |||||
| ></u-upload> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 提交按钮 --> | |||||
| <view class="submit-btn"> | |||||
| <u-button type="primary" color="#ffaa48" shape="circle" @click="submitTaskHandler">提交审核</u-button> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| <view class="task-upload"> | |||||
| <!-- 任务状态提示 --> | |||||
| <view class="status-box" v-if="taskInfo.status != 0"> | |||||
| <!-- 驳回状态 --> | |||||
| <view class="reject-box" v-if="taskInfo.status == 3"> | |||||
| <view class="reject-icon">⚠</view> | |||||
| <view class="reject-content"> | |||||
| <view class="reject-title">拒绝原因:{{taskInfo.rejectTxt}}</view> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 审核中状态 --> | |||||
| <view class="reviewing-box" v-if="taskInfo.status == 1"> | |||||
| <view class="reviewing-icon">⏳</view> | |||||
| <view class="reviewing-content"> | |||||
| <view class="reviewing-title">任务审核中,请耐心等待审核结果</view> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 已通过状态 --> | |||||
| <view class="approved-box" v-if="taskInfo.status == 2"> | |||||
| <view class="approved-icon">✅</view> | |||||
| <view class="approved-content"> | |||||
| <view class="approved-title">任务已审核通过</view> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 上传表单 --> | |||||
| <view class="upload-form"> | |||||
| <!-- 链接输入 --> | |||||
| <view class="form-item"> | |||||
| <view class="form-label">笔记链接</view> | |||||
| <view class="form-input"> | |||||
| <u-textarea v-model="formData.proveTxt" | |||||
| :border="false" | |||||
| height="300rpx" | |||||
| :disabled="taskInfo.status == 1 || taskInfo.status == 2" | |||||
| placeholder="请输入笔记链接" :maxlength="300" count /> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 图片上传 --> | |||||
| <view class="form-item"> | |||||
| <view class="form-label">笔记截图</view> | |||||
| <view class="upload-box"> | |||||
| <u-upload :fileList="fileList" @afterRead="afterRead" @delete="deletePic" name="proveImage" | |||||
| multiple :maxCount="3" :disabled="taskInfo.status == 1 || taskInfo.status == 2"></u-upload> | |||||
| </view> | |||||
| </view> | |||||
| <!-- 提交按钮 --> | |||||
| <view class="submit-btn" v-if="taskInfo.status == 0 || taskInfo.status == 3"> | |||||
| <u-button type="primary" color="#ffaa48" shape="circle" @click="submitTaskHandler">提交审核</u-button> | |||||
| </view> | |||||
| </view> | |||||
| </view> | |||||
| </template> | </template> | ||||
| <script> | <script> | ||||
| import { getTaskDetail, submitTask } from "@/api/order/task.js" | |||||
| export default { | |||||
| data() { | |||||
| return { | |||||
| taskId: null, | |||||
| taskStatus: '', | |||||
| isRejected: false, | |||||
| taskInfo: { | |||||
| id: 0, | |||||
| title: '', | |||||
| taskEndTime: '', | |||||
| examineText: '', | |||||
| taskState: 0, | |||||
| examineState: 0 | |||||
| }, | |||||
| formData: { | |||||
| taskId: 0, | |||||
| examineImage: [], | |||||
| examineText: '', | |||||
| }, | |||||
| fileList: [] | |||||
| } | |||||
| }, | |||||
| onLoad(options) { | |||||
| if (options.id) { | |||||
| this.taskId = options.id | |||||
| this.formData.taskId = options.id | |||||
| this.taskStatus = options.status || '' | |||||
| this.isRejected = this.taskStatus === 'REJECTED' | |||||
| this.getTaskDetail() | |||||
| } else { | |||||
| uni.showToast({ | |||||
| title: '任务ID不存在', | |||||
| icon: 'none' | |||||
| }) | |||||
| setTimeout(() => { | |||||
| uni.navigateBack() | |||||
| }, 1500) | |||||
| } | |||||
| }, | |||||
| methods: { | |||||
| getTaskDetail() { | |||||
| // 获取任务详情 | |||||
| getTaskDetail(this.taskId).then(res => { | |||||
| if (res && res.code === 200) { | |||||
| this.taskInfo = res.data | |||||
| // 如果任务已有审核文本,填充到表单 | |||||
| if (res.data.examineText) { | |||||
| this.formData.examineText = res.data.examineText; | |||||
| } | |||||
| // 如果任务已有图片,添加到文件列表显示 | |||||
| if (res.data.examineImage) { | |||||
| const imageUrls = res.data.examineImage.split(','); | |||||
| imageUrls.forEach(url => { | |||||
| if (url) { | |||||
| this.fileList.push({ | |||||
| url: url, | |||||
| status: 'success', | |||||
| message: '已上传', | |||||
| isImage: true | |||||
| }); | |||||
| // 同时更新formData中的图片数组 | |||||
| this.formData.examineImage.push(url); | |||||
| import { getTaskDetailUser, submitTask } from "@/api/order/task.js" | |||||
| export default { | |||||
| data() { | |||||
| return { | |||||
| taskId: null, | |||||
| taskStatus: 0, | |||||
| taskInfo: { | |||||
| id: 0, | |||||
| title: '', | |||||
| taskEndTime: '', | |||||
| rejectTxt: '', | |||||
| proveTxt: '', | |||||
| status: 0 | |||||
| }, | |||||
| formData: { | |||||
| taskId: 0, | |||||
| proveImage: [], | |||||
| rejectTxt: '', | |||||
| proveTxt: '', | |||||
| }, | |||||
| fileList: [] | |||||
| } | |||||
| }, | |||||
| onLoad(options) { | |||||
| if (options.id) { | |||||
| this.taskId = options.id | |||||
| this.formData.taskId = options.id | |||||
| this.getTaskDetail() | |||||
| } else { | |||||
| uni.showToast({ | |||||
| title: '任务ID不存在', | |||||
| icon: 'none' | |||||
| }) | |||||
| setTimeout(() => { | |||||
| uni.navigateBack() | |||||
| }, 1500) | |||||
| } | |||||
| }, | |||||
| methods: { | |||||
| getTaskDetail() { | |||||
| // 获取任务详情 | |||||
| getTaskDetailUser(this.taskId).then(res => { | |||||
| if (res && res.code == 200) { | |||||
| this.taskInfo = res.data | |||||
| // 如果任务已有审核文本,填充到表单 | |||||
| if (res.data.proveTxt) { | |||||
| this.formData.proveTxt = res.data.proveTxt; | |||||
| } | |||||
| // 如果任务已有图片,添加到文件列表显示 | |||||
| if (res.data.proveImage) { | |||||
| const imageUrls = res.data.proveImage.split(','); | |||||
| imageUrls.forEach(url => { | |||||
| if (url) { | |||||
| this.fileList.push({ | |||||
| url: url, | |||||
| status: 'success', | |||||
| message: '已上传', | |||||
| isImage: true | |||||
| }); | |||||
| // 同时更新formData中的图片数组 | |||||
| this.formData.proveImage.push(url); | |||||
| } | |||||
| }); | |||||
| } | |||||
| } | |||||
| }) | |||||
| }, | |||||
| uploadFilePromise(url) { | |||||
| return new Promise((resolve, reject) => { | |||||
| let uploadTask = uni.uploadFile({ | |||||
| url: 'https://store-test.catmdogd.com/test-api/h5/oss/upload', | |||||
| filePath: url, | |||||
| name: 'file', | |||||
| formData: { | |||||
| user: 'test' | |||||
| }, | |||||
| success: (res) => { | |||||
| if (res && res.data) { | |||||
| try { | |||||
| let resData = JSON.parse(res.data); | |||||
| if (resData.url) { | |||||
| resolve(resData.url); | |||||
| } else { | |||||
| reject("上传失败: 未获取到图片URL"); | |||||
| } | } | ||||
| }); | |||||
| } catch (e) { | |||||
| reject("上传失败: 解析响应数据错误"); | |||||
| } | |||||
| } else { | |||||
| reject("上传失败: 响应数据为空"); | |||||
| } | } | ||||
| } | |||||
| }) | |||||
| }, | |||||
| uploadFilePromise(url) { | |||||
| return new Promise((resolve, reject) => { | |||||
| let uploadTask = uni.uploadFile({ | |||||
| url: 'https://store-test.catmdogd.com/test-api/h5/oss/upload', | |||||
| filePath: url, | |||||
| name: 'file', | |||||
| formData: { | |||||
| user: 'test' | |||||
| }, | |||||
| success: (res) => { | |||||
| if(res && res.data) { | |||||
| try { | |||||
| let resData = JSON.parse(res.data); | |||||
| if(resData.url) { | |||||
| resolve(resData.url); | |||||
| } else { | |||||
| reject("上传失败: 未获取到图片URL"); | |||||
| } | |||||
| } catch(e) { | |||||
| reject("上传失败: 解析响应数据错误"); | |||||
| } | |||||
| } else { | |||||
| reject("上传失败: 响应数据为空"); | |||||
| } | |||||
| }, | |||||
| fail: (err) => { | |||||
| reject("上传失败: " + (err.errMsg || JSON.stringify(err))); | |||||
| } | |||||
| }); | |||||
| // 监听上传进度 | |||||
| uploadTask.onProgressUpdate((res) => { | |||||
| // 查找当前正在上传的文件 | |||||
| const index = this.fileList.findIndex(file => file.status === 'uploading'); | |||||
| if(index !== -1) { | |||||
| // 更新上传进度信息 | |||||
| this.fileList[index].message = '上传中 ' + res.progress + '%'; | |||||
| } | |||||
| }); | |||||
| }) | |||||
| }, | |||||
| formatDate(dateStr) { | |||||
| if (!dateStr) return ''; | |||||
| let date = new Date(dateStr); | |||||
| let year = date.getFullYear(); | |||||
| let month = (date.getMonth() + 1).toString().padStart(2, '0'); | |||||
| let day = date.getDate().toString().padStart(2, '0'); | |||||
| return `${year}-${month}-${day}`; | |||||
| }, | |||||
| afterRead(event) { | |||||
| // 读取文件后的处理 | |||||
| const { file } = event | |||||
| // 处理文件数组 | |||||
| const fileList = Array.isArray(file) ? file : [file] | |||||
| // 遍历处理每个文件 | |||||
| fileList.forEach(item => { | |||||
| // 更新UI显示上传中状态 | |||||
| const fileListItem = { | |||||
| ...item, | |||||
| status: 'uploading', | |||||
| message: '上传中' | |||||
| } | |||||
| this.fileList.push(fileListItem) | |||||
| const currentIndex = this.fileList.length - 1 | |||||
| // 使用Promise上传图片 | |||||
| this.uploadFilePromise(item.url) | |||||
| .then(url => { | |||||
| // 上传成功,更新状态和URL | |||||
| this.fileList[currentIndex].status = 'success' | |||||
| this.fileList[currentIndex].message = '上传成功' | |||||
| this.fileList[currentIndex].url = url | |||||
| // 保存上传后的URL | |||||
| this.formData.examineImage.push(url) | |||||
| }) | |||||
| .catch(err => { | |||||
| // 上传失败 | |||||
| this.fileList[currentIndex].status = 'failed' | |||||
| this.fileList[currentIndex].message = '上传失败' | |||||
| uni.showToast({ | |||||
| title: '图片上传失败', | |||||
| icon: 'none' | |||||
| }) | |||||
| }) | |||||
| }) | |||||
| }, | |||||
| deletePic(event) { | |||||
| // 删除图片 | |||||
| const index = event.index | |||||
| this.fileList.splice(index, 1) | |||||
| this.formData.examineImage.splice(index, 1) | |||||
| }, | |||||
| submitTaskHandler() { | |||||
| // 表单验证 | |||||
| if (!this.formData.examineText) { | |||||
| uni.showToast({ | |||||
| title: '请输入笔记链接', | |||||
| icon: 'none' | |||||
| }) | |||||
| return | |||||
| } | |||||
| if (this.formData.examineImage.length === 0) { | |||||
| uni.showToast({ | |||||
| title: '请上传至少一张截图', | |||||
| icon: 'none' | |||||
| }) | |||||
| return | |||||
| } | |||||
| // 检查是否有正在上传的图片 | |||||
| const isUploading = this.fileList.some(file => file.status === 'uploading') | |||||
| if (isUploading) { | |||||
| uni.showToast({ | |||||
| title: '图片正在上传中,请稍候', | |||||
| icon: 'none' | |||||
| }) | |||||
| return | |||||
| } | |||||
| // 显示提交中提示 | |||||
| uni.showLoading({ | |||||
| title: '提交中...' | |||||
| }) | |||||
| // 提交任务 | |||||
| submitTask({ | |||||
| id: this.taskId, | |||||
| taskId: this.formData.taskId, | |||||
| examineText: this.formData.examineText, | |||||
| examineImage: this.formData.examineImage.join(',') | |||||
| }).then(res => { | |||||
| uni.hideLoading() | |||||
| if (res && res.code === 200) { | |||||
| uni.showToast({ | |||||
| title: '提交成功', | |||||
| icon: 'success' | |||||
| }) | |||||
| // 返回任务详情页 | |||||
| setTimeout(() => { | |||||
| uni.navigateBack() | |||||
| }, 1500) | |||||
| } else { | |||||
| uni.showToast({ | |||||
| title: res.msg || '提交失败', | |||||
| icon: 'none' | |||||
| }) | |||||
| } | |||||
| }).catch(err => { | |||||
| uni.hideLoading() | |||||
| uni.showToast({ | |||||
| title: '提交失败', | |||||
| icon: 'none' | |||||
| }) | |||||
| console.error('提交任务失败:', err) | |||||
| }) | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| fail: (err) => { | |||||
| reject("上传失败: " + (err.errMsg || JSON.stringify(err))); | |||||
| } | |||||
| }); | |||||
| // 监听上传进度 | |||||
| uploadTask.onProgressUpdate((res) => { | |||||
| // 查找当前正在上传的文件 | |||||
| const index = this.fileList.findIndex(file => file.status == 'uploading'); | |||||
| if (index != -1) { | |||||
| // 更新上传进度信息 | |||||
| this.fileList[index].message = '上传中 ' + res.progress + '%'; | |||||
| } | |||||
| }); | |||||
| }) | |||||
| }, | |||||
| formatDate(dateStr) { | |||||
| if (!dateStr) return ''; | |||||
| let date = new Date(dateStr); | |||||
| let year = date.getFullYear(); | |||||
| let month = (date.getMonth() + 1).toString().padStart(2, '0'); | |||||
| let day = date.getDate().toString().padStart(2, '0'); | |||||
| return `${year}-${month}-${day}`; | |||||
| }, | |||||
| afterRead(event) { | |||||
| // 读取文件后的处理 | |||||
| const { file } = event | |||||
| // 处理文件数组 | |||||
| const fileList = Array.isArray(file) ? file : [file] | |||||
| // 遍历处理每个文件 | |||||
| fileList.forEach(item => { | |||||
| // 更新UI显示上传中状态 | |||||
| const fileListItem = { | |||||
| ...item, | |||||
| status: 'uploading', | |||||
| message: '上传中' | |||||
| } | |||||
| this.fileList.push(fileListItem) | |||||
| const currentIndex = this.fileList.length - 1 | |||||
| // 使用Promise上传图片 | |||||
| this.uploadFilePromise(item.url) | |||||
| .then(url => { | |||||
| // 上传成功,更新状态和URL | |||||
| this.fileList[currentIndex].status = 'success' | |||||
| this.fileList[currentIndex].message = '上传成功' | |||||
| this.fileList[currentIndex].url = url | |||||
| // 保存上传后的URL | |||||
| this.formData.proveImage.push(url) | |||||
| }) | |||||
| .catch(err => { | |||||
| // 上传失败 | |||||
| this.fileList[currentIndex].status = 'failed' | |||||
| this.fileList[currentIndex].message = '上传失败' | |||||
| uni.showToast({ | |||||
| title: '图片上传失败', | |||||
| icon: 'none' | |||||
| }) | |||||
| }) | |||||
| }) | |||||
| }, | |||||
| deletePic(event) { | |||||
| // 删除图片 | |||||
| const index = event.index | |||||
| this.fileList.splice(index, 1) | |||||
| this.formData.proveImage.splice(index, 1) | |||||
| }, | |||||
| submitTaskHandler() { | |||||
| // 表单验证 | |||||
| if (!this.formData.proveTxt) { | |||||
| uni.showToast({ | |||||
| title: '请输入笔记链接', | |||||
| icon: 'none' | |||||
| }) | |||||
| return | |||||
| } | |||||
| if (this.formData.proveImage.length == 0) { | |||||
| uni.showToast({ | |||||
| title: '请上传至少一张截图', | |||||
| icon: 'none' | |||||
| }) | |||||
| return | |||||
| } | |||||
| // 检查是否有正在上传的图片 | |||||
| const isUploading = this.fileList.some(file => file.status == 'uploading') | |||||
| if (isUploading) { | |||||
| uni.showToast({ | |||||
| title: '图片正在上传中,请稍候', | |||||
| icon: 'none' | |||||
| }) | |||||
| return | |||||
| } | |||||
| // 显示提交中提示 | |||||
| uni.showLoading({ | |||||
| title: '提交中...' | |||||
| }) | |||||
| // 提交任务 | |||||
| submitTask({ | |||||
| id: this.taskId, | |||||
| taskId: this.formData.taskId, | |||||
| proveTxt: this.formData.proveTxt, | |||||
| proveImage: this.formData.proveImage.join(',') | |||||
| }).then(res => { | |||||
| uni.hideLoading() | |||||
| if (res && res.code == 200) { | |||||
| uni.showToast({ | |||||
| title: '提交成功', | |||||
| icon: 'success' | |||||
| }) | |||||
| // 返回任务详情页 | |||||
| setTimeout(() => { | |||||
| uni.navigateBack() | |||||
| }, 1500) | |||||
| } else { | |||||
| uni.showToast({ | |||||
| title: res.msg || '提交失败', | |||||
| icon: 'none' | |||||
| }) | |||||
| } | |||||
| }).catch(err => { | |||||
| uni.hideLoading() | |||||
| uni.showToast({ | |||||
| title: '提交失败', | |||||
| icon: 'none' | |||||
| }) | |||||
| console.error('提交任务失败:', err) | |||||
| }) | |||||
| } | |||||
| } | |||||
| } | |||||
| </script> | </script> | ||||
| <style lang="scss"> | |||||
| .task-upload { | |||||
| background-color: #f5f5f7; | |||||
| min-height: 100vh; | |||||
| .task-header { | |||||
| background-color: #FFFFFF; | |||||
| padding: 30rpx; | |||||
| .task-title { | |||||
| font-size: 36rpx; | |||||
| font-weight: bold; | |||||
| color: #333; | |||||
| margin-bottom: 20rpx; | |||||
| } | |||||
| .task-deadline { | |||||
| font-size: 24rpx; | |||||
| color: #999; | |||||
| } | |||||
| } | |||||
| .reject-box { | |||||
| background-color: #FFF1F0; | |||||
| margin-top: 20rpx; | |||||
| padding: 30rpx; | |||||
| .reject-title { | |||||
| font-size: 28rpx; | |||||
| font-weight: bold; | |||||
| color: #F5222D; | |||||
| margin-bottom: 10rpx; | |||||
| } | |||||
| .reject-reason { | |||||
| font-size: 26rpx; | |||||
| color: #F5222D; | |||||
| } | |||||
| } | |||||
| .upload-form { | |||||
| background-color: #FFFFFF; | |||||
| margin-top: 20rpx; | |||||
| padding: 30rpx; | |||||
| .form-item { | |||||
| margin-bottom: 40rpx; | |||||
| .form-label { | |||||
| font-size: 30rpx; | |||||
| font-weight: bold; | |||||
| color: #333; | |||||
| margin-bottom: 20rpx; | |||||
| } | |||||
| .form-notice { | |||||
| font-size: 24rpx; | |||||
| color: #999; | |||||
| margin-bottom: 20rpx; | |||||
| } | |||||
| .form-input { | |||||
| background-color: #F8F8F8; | |||||
| border-radius: 8rpx; | |||||
| padding: 10rpx; | |||||
| } | |||||
| .upload-box { | |||||
| margin-top: 20rpx; | |||||
| } | |||||
| } | |||||
| .submit-btn { | |||||
| margin-top: 60rpx; | |||||
| padding: 0 40rpx; | |||||
| } | |||||
| } | |||||
| } | |||||
| <style lang="scss" scoped> | |||||
| .task-upload { | |||||
| padding: 20rpx; | |||||
| background-color: #f5f5f5; | |||||
| min-height: 100vh; | |||||
| .status-box { | |||||
| margin-bottom: 20rpx; | |||||
| } | |||||
| .reject-box { | |||||
| background-color: #fff2e8; | |||||
| border-radius: 10rpx; | |||||
| padding: 20rpx 30rpx; | |||||
| margin-bottom: 20rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| .reject-icon { | |||||
| font-size: 32rpx; | |||||
| color: #ff8800; | |||||
| margin-right: 15rpx; | |||||
| font-weight: bold; | |||||
| } | |||||
| .reject-content { | |||||
| flex: 1; | |||||
| } | |||||
| .reject-title { | |||||
| font-size: 28rpx; | |||||
| color: #ff8800; | |||||
| font-weight: 500; | |||||
| } | |||||
| } | |||||
| .reviewing-box { | |||||
| background-color: #fff7e6; | |||||
| border-radius: 10rpx; | |||||
| padding: 20rpx 30rpx; | |||||
| margin-bottom: 20rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| .reviewing-icon { | |||||
| font-size: 32rpx; | |||||
| color: #fa8c16; | |||||
| margin-right: 15rpx; | |||||
| font-weight: bold; | |||||
| } | |||||
| .reviewing-content { | |||||
| flex: 1; | |||||
| } | |||||
| .reviewing-title { | |||||
| font-size: 28rpx; | |||||
| color: #fa8c16; | |||||
| font-weight: 500; | |||||
| } | |||||
| } | |||||
| .approved-box { | |||||
| background-color: #f6ffed; | |||||
| border-radius: 10rpx; | |||||
| padding: 20rpx 30rpx; | |||||
| margin-bottom: 20rpx; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| .approved-icon { | |||||
| font-size: 32rpx; | |||||
| color: #52c41a; | |||||
| margin-right: 15rpx; | |||||
| font-weight: bold; | |||||
| } | |||||
| .approved-content { | |||||
| flex: 1; | |||||
| } | |||||
| .approved-title { | |||||
| font-size: 28rpx; | |||||
| color: #52c41a; | |||||
| font-weight: 500; | |||||
| } | |||||
| } | |||||
| .upload-form { | |||||
| border-radius: 10rpx; | |||||
| padding: 10rpx; | |||||
| .form-item { | |||||
| margin-bottom: 40rpx; | |||||
| background-color: #fff; | |||||
| padding: 30rpx; | |||||
| border-radius: 10rpx; | |||||
| &:last-child { | |||||
| margin-bottom: 0; | |||||
| } | |||||
| .form-label { | |||||
| font-size: 28rpx; | |||||
| color: #333; | |||||
| font-weight: 500; | |||||
| margin-bottom: 20rpx; | |||||
| position: relative; | |||||
| &::before { | |||||
| content: ''; | |||||
| width: 6rpx; | |||||
| height: 28rpx; | |||||
| background-color: #ff8800; | |||||
| position: absolute; | |||||
| left: -20rpx; | |||||
| top: 50%; | |||||
| transform: translateY(-50%); | |||||
| border-radius: 3rpx; | |||||
| } | |||||
| } | |||||
| .form-input { | |||||
| margin-bottom: 10rpx; | |||||
| } | |||||
| .upload-box { | |||||
| margin-top: 20rpx; | |||||
| } | |||||
| } | |||||
| .submit-btn { | |||||
| margin-top: 60rpx; | |||||
| padding: 0 40rpx; | |||||
| } | |||||
| } | |||||
| } | |||||
| </style> | </style> | ||||