解决登录显示、首页显示bug
This commit is contained in:
258
pages/mall/delivery/orders/execute.uvue
Normal file
258
pages/mall/delivery/orders/execute.uvue
Normal file
@@ -0,0 +1,258 @@
|
||||
<template>
|
||||
<ServicePageScaffold title="服务执行" fallback-url="/pages/mall/delivery/orders/detail">
|
||||
<ServicePanel title="执行计时" subtitle="服务开始后持续计时,提交前可暂存。">
|
||||
<text class="timer-text">已服务时长:{{ elapsedText }}</text>
|
||||
<text class="info-text">备注:{{ progressNote }}</text>
|
||||
</ServicePanel>
|
||||
|
||||
<ServicePanel title="服务项目打卡" subtitle="未完成项必须填写原因。">
|
||||
<view v-for="item in serviceItems" :key="item.id" class="item-card">
|
||||
<view class="item-header">
|
||||
<text class="item-title">{{ item.name }}</text>
|
||||
<switch :checked="item.completed" color="#0f766e" @change="toggleItem(item.id, $event)" />
|
||||
</view>
|
||||
<input class="note-input" v-model="item.remark" placeholder="服务备注,例如监测结果、陪护说明" />
|
||||
<input v-if="item.completed == false" class="note-input" v-model="item.incompleteReason" placeholder="未完成原因,必填" />
|
||||
</view>
|
||||
</ServicePanel>
|
||||
|
||||
<ServicePanel title="过程留痕" subtitle="服务中可补充备注、证据和异常上报。">
|
||||
<input class="note-input" v-model="progressNote" placeholder="请输入服务过程备注" />
|
||||
<input class="note-input" v-model="serviceSummary" placeholder="请输入服务总结,完成提交时会带入" />
|
||||
<view class="action-row">
|
||||
<view class="secondary-btn" @click="goEvidence"><text class="btn-text secondary-text">证据上传</text></view>
|
||||
<view class="secondary-btn" @click="goException"><text class="btn-text secondary-text">异常上报</text></view>
|
||||
</view>
|
||||
</ServicePanel>
|
||||
|
||||
<view class="bottom-space"></view>
|
||||
<view class="fixed-bar">
|
||||
<view class="bar-btn secondary-btn" @click="saveDraft"><text class="btn-text secondary-text">暂存</text></view>
|
||||
<view class="bar-btn primary-btn" @click="goFinish"><text class="btn-text">完成服务</text></view>
|
||||
</view>
|
||||
</ServicePageScaffold>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onUnload } from '@dcloudio/uni-app'
|
||||
import ServicePageScaffold from '@/components/homeService/ServicePageScaffold.uvue'
|
||||
import ServicePanel from '@/components/homeService/ServicePanel.uvue'
|
||||
import { getDeliveryOrderDetail, saveServiceProgress, startService } from '@/services/deliveryService.uts'
|
||||
import type { DeliveryOrderType, DeliveryServiceItemType } from '@/types/delivery.uts'
|
||||
import { requireDeliveryAuth } from '@/utils/deliveryAuth.uts'
|
||||
import { getDeliveryRouteParam } from '@/utils/deliveryRoute.uts'
|
||||
|
||||
const orderId = ref('')
|
||||
const order = ref<DeliveryOrderType | null>(null)
|
||||
const serviceItems = ref([] as Array<DeliveryServiceItemType>)
|
||||
const progressNote = ref('')
|
||||
const serviceSummary = ref('')
|
||||
const elapsedText = ref('00:00')
|
||||
let timerId: number | null = null
|
||||
|
||||
function formatElapsed() {
|
||||
if (order.value == null || order.value.actualStartTime == '') {
|
||||
elapsedText.value = '00:00'
|
||||
return
|
||||
}
|
||||
const start = new Date(order.value.actualStartTime.replace(' ', 'T')).getTime()
|
||||
const diffMinutes = Math.floor((Date.now() - start) / 60000)
|
||||
const hours = Math.floor(diffMinutes / 60)
|
||||
const minutes = diffMinutes % 60
|
||||
const hourText = hours < 10 ? '0' + String(hours) : String(hours)
|
||||
const minuteText = minutes < 10 ? '0' + String(minutes) : String(minutes)
|
||||
elapsedText.value = hourText + ':' + minuteText
|
||||
}
|
||||
|
||||
function startTimer() {
|
||||
formatElapsed()
|
||||
if (timerId != null) {
|
||||
clearInterval(timerId)
|
||||
}
|
||||
timerId = setInterval(() => {
|
||||
formatElapsed()
|
||||
}, 60000)
|
||||
}
|
||||
|
||||
function toggleItem(itemId: string, event: any) {
|
||||
for (let i = 0; i < serviceItems.value.length; i++) {
|
||||
if (serviceItems.value[i].id == itemId) {
|
||||
const checked = event.detail.value === true
|
||||
serviceItems.value[i].completed = checked
|
||||
serviceItems.value[i].updatedAt = new Date().toISOString().replace('T', ' ').substring(0, 19)
|
||||
if (checked) {
|
||||
serviceItems.value[i].incompleteReason = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function ensureStarted(orderData: DeliveryOrderType) {
|
||||
if (orderData.status == 'checked_in' || orderData.status == 'arrived') {
|
||||
order.value = await startService(orderId.value)
|
||||
} else {
|
||||
order.value = orderData
|
||||
}
|
||||
if (order.value != null) {
|
||||
serviceItems.value = order.value.serviceItems
|
||||
progressNote.value = order.value.progressNote
|
||||
serviceSummary.value = order.value.serviceSummary
|
||||
startTimer()
|
||||
}
|
||||
}
|
||||
|
||||
async function loadData() {
|
||||
const authResult = await requireDeliveryAuth({ redirectOnFail: true, toastOnFail: true })
|
||||
if (!authResult.ok || orderId.value == '') {
|
||||
return
|
||||
}
|
||||
const detail = await getDeliveryOrderDetail(orderId.value)
|
||||
if (detail != null) {
|
||||
await ensureStarted(detail)
|
||||
}
|
||||
}
|
||||
|
||||
function validateItems(): boolean {
|
||||
for (let i = 0; i < serviceItems.value.length; i++) {
|
||||
const item = serviceItems.value[i]
|
||||
if (item.completed == false && item.incompleteReason == '') {
|
||||
uni.showToast({ title: '未完成项目必须填写原因', icon: 'none' })
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
async function saveDraft() {
|
||||
if (!validateItems()) {
|
||||
return
|
||||
}
|
||||
await saveServiceProgress(orderId.value, { items: serviceItems.value, progressNote: progressNote.value, serviceSummary: serviceSummary.value })
|
||||
uni.showToast({ title: '已暂存服务记录', icon: 'success' })
|
||||
loadData()
|
||||
}
|
||||
|
||||
async function goFinish() {
|
||||
if (!validateItems()) {
|
||||
return
|
||||
}
|
||||
await saveServiceProgress(orderId.value, { items: serviceItems.value, progressNote: progressNote.value, serviceSummary: serviceSummary.value })
|
||||
uni.navigateTo({ url: '/pages/mall/delivery/orders/finish?id=' + orderId.value })
|
||||
}
|
||||
|
||||
function goEvidence() {
|
||||
uni.navigateTo({ url: '/pages/mall/delivery/orders/evidence?id=' + orderId.value })
|
||||
}
|
||||
|
||||
function goException() {
|
||||
uni.navigateTo({ url: '/pages/mall/delivery/orders/exception?id=' + orderId.value })
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
if (options != null) {
|
||||
orderId.value = getDeliveryRouteParam(options as UTSJSONObject, 'id')
|
||||
}
|
||||
loadData()
|
||||
})
|
||||
|
||||
onUnload(() => {
|
||||
if (timerId != null) {
|
||||
clearInterval(timerId)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.timer-text {
|
||||
font-size: 38rpx;
|
||||
font-weight: 700;
|
||||
color: #0f766e;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
margin-top: 12rpx;
|
||||
font-size: 24rpx;
|
||||
line-height: 36rpx;
|
||||
color: #5e758c;
|
||||
}
|
||||
|
||||
.item-card {
|
||||
padding: 20rpx;
|
||||
margin-bottom: 16rpx;
|
||||
border-radius: 18rpx;
|
||||
background: #f8fbfc;
|
||||
}
|
||||
|
||||
.item-header,
|
||||
.action-row {
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #16324f;
|
||||
}
|
||||
|
||||
.note-input {
|
||||
height: 84rpx;
|
||||
padding: 0 24rpx;
|
||||
margin-top: 14rpx;
|
||||
border-radius: 18rpx;
|
||||
background: #f2f7f6;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.action-row {
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
|
||||
.secondary-btn,
|
||||
.primary-btn,
|
||||
.bar-btn {
|
||||
flex: 1;
|
||||
padding: 20rpx 0;
|
||||
border-radius: 18rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.secondary-btn {
|
||||
background: #eaf2f0;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.primary-btn {
|
||||
background: #0f766e;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.secondary-text {
|
||||
color: #0f766e;
|
||||
}
|
||||
|
||||
.bottom-space {
|
||||
height: 140rpx;
|
||||
}
|
||||
|
||||
.fixed-bar {
|
||||
position: fixed;
|
||||
left: 24rpx;
|
||||
right: 24rpx;
|
||||
bottom: 24rpx;
|
||||
padding: 16rpx;
|
||||
flex-direction: row;
|
||||
background: #ffffff;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 12rpx 24rpx rgba(15, 118, 110, 0.08);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user