| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- <template>
- <view class="sub-page">
- <TopBar title="任务提醒" show-back />
- <view class="px-4 pt-3">
- <view v-if="taskStore.loading" class="py-10 text-center">
- <text class="empty-text">加载中...</text>
- </view>
- <view v-else-if="reminderTasks.length === 0">
- <EmptyState message="暂无任务提醒" />
- </view>
- <view v-else class="glass-card">
- <view
- v-for="task in reminderTasks"
- :key="task.id"
- class="task-row"
- hover-class="row-hover"
- :hover-start-time="0"
- :hover-stay-time="120"
- @click="goToDetail(task.id)"
- >
- <view class="flex items-center justify-between mb-2">
- <view class="flex items-center flex-1 min-w-0 mr-2">
- <view class="icon-chip mr-3">
- <text class="uni-icons uniui-notification-filled chip-glyph"></text>
- </view>
- <text class="row-title truncate">{{ task.projectName }}</text>
- </view>
- <text class="pending-tag flex-shrink-0">待确认</text>
- </view>
- <view class="meta-line mb-1">
- <text class="uni-icons uniui-location-filled meta-icon mr-1"></text>
- <text class="meta-text truncate">{{ task.address }}</text>
- </view>
- <view class="meta-line mb-3">
- <text class="uni-icons uniui-calendar-filled meta-icon mr-1"></text>
- <text class="meta-text">预计: {{ task.scheduleDate }} {{ task.scheduleTime }}</text>
- </view>
- <view class="flex gap-3">
- <view class="action-btn action-btn-confirm" hover-class="action-btn-hover" :hover-start-time="0" :hover-stay-time="120" @click.stop="confirmTask(task.id)">
- 确认
- </view>
- <view class="action-btn action-btn-reject" hover-class="action-btn-hover" :hover-start-time="0" :hover-stay-time="120" @click.stop="rejectTask(task.id)">
- 拒绝
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script setup lang="ts">
- import { computed, onMounted } from 'vue'
- import { useTaskStore } from '../../stores/task'
- import TopBar from '../../components/common/TopBar.vue'
- import EmptyState from '../../components/common/EmptyState.vue'
- const taskStore = useTaskStore()
- const reminderTasks = computed(() => {
- return taskStore.tasks.filter(t => t.status === 'pending')
- })
- function goToDetail(taskId: string) {
- taskStore.setCurrentTask(taskId)
- uni.navigateTo({ url: `/subPackages/pages-common/taskDetail?id=${taskId}` })
- }
- function confirmTask(taskId: string) {
- uni.showModal({
- title: '确认任务',
- content: '确认接受此任务吗?',
- success: (res) => {
- if (res.confirm) {
- uni.showToast({ title: '已确认', icon: 'success' })
- }
- },
- })
- }
- function rejectTask(taskId: string) {
- uni.showModal({
- title: '拒绝任务',
- content: '确定要拒绝此任务吗?',
- success: (res) => {
- if (res.confirm) {
- uni.showToast({ title: '已拒绝', icon: 'none' })
- }
- },
- })
- }
- onMounted(() => {
- taskStore.fetchTasks()
- })
- </script>
- <style scoped>
- .sub-page {
- max-width: 430px;
- margin: 0 auto;
- min-height: 100vh;
- background-color: #f6fbf9;
- padding-bottom: 24px;
- }
- .glass-card {
- background-color: rgba(255, 255, 255, 0.85);
- backdrop-filter: blur(14px);
- -webkit-backdrop-filter: blur(14px);
- border: 1px solid rgba(164, 216, 152, 0.35);
- border-radius: 24px;
- box-shadow: 0 18px 50px -12px rgba(54, 143, 111, 0.28);
- overflow: hidden;
- margin-bottom: 12px;
- }
- .task-row {
- padding: 14px 16px;
- border-top: 1px solid rgba(164, 216, 152, 0.18);
- }
- .task-row:first-child {
- border-top: none;
- }
- .row-hover {
- background-color: rgba(164, 216, 152, 0.1);
- }
- .icon-chip {
- width: 42px;
- height: 42px;
- border-radius: 12px;
- flex-shrink: 0;
- display: flex;
- align-items: center;
- justify-content: center;
- background-color: rgba(164, 216, 152, 0.2);
- }
- .chip-glyph {
- font-size: 20px;
- color: #368f6f;
- }
- .row-title {
- font-size: 14px;
- font-weight: 600;
- color: #1f2937;
- }
- .pending-tag {
- padding: 2px 10px;
- border-radius: 999px;
- font-size: 11px;
- font-weight: 600;
- color: #b7791f;
- background-color: rgba(251, 211, 141, 0.25);
- }
- .meta-line {
- display: flex;
- align-items: center;
- padding-left: 54px;
- }
- .meta-icon {
- font-size: 13px;
- color: #9ca3af;
- }
- .meta-text {
- font-size: 12px;
- color: #9ca3af;
- }
- .action-btn {
- flex: 1;
- padding: 8px 0;
- border-radius: 10px;
- text-align: center;
- font-size: 13px;
- font-weight: 600;
- }
- .action-btn-hover {
- opacity: 0.88;
- }
- .action-btn-confirm {
- color: #ffffff;
- background: linear-gradient(135deg, #368f6f 0%, #4ba98a 100%);
- }
- .action-btn-reject {
- color: #6b7280;
- background-color: #f3f4f6;
- }
- .empty-text {
- font-size: 13px;
- color: #9ca3af;
- }
- </style>
|