|
@@ -5,8 +5,14 @@
|
|
|
|
|
|
|
|
<van-loading v-if="loading" vertical class="page-loading">加载中...</van-loading>
|
|
<van-loading v-if="loading" vertical class="page-loading">加载中...</van-loading>
|
|
|
<van-empty v-else-if="errorMessage" :description="errorMessage" />
|
|
<van-empty v-else-if="errorMessage" :description="errorMessage" />
|
|
|
- <van-empty v-else-if="page?.voided" description="单据已作废" />
|
|
|
|
|
<template v-else-if="page">
|
|
<template v-else-if="page">
|
|
|
|
|
+ <van-notice-bar
|
|
|
|
|
+ v-if="isReadOnly"
|
|
|
|
|
+ left-icon="info-o"
|
|
|
|
|
+ color="#92400e"
|
|
|
|
|
+ background="#fffbeb"
|
|
|
|
|
+ text="单据已作废,仅可查看"
|
|
|
|
|
+ />
|
|
|
<van-cell-group inset class="section-card">
|
|
<van-cell-group inset class="section-card">
|
|
|
<van-cell title="业务类型" :value="page.businessType || '—'" />
|
|
<van-cell title="业务类型" :value="page.businessType || '—'" />
|
|
|
<van-cell title="日期" :value="page.planDate || '—'" />
|
|
<van-cell title="日期" :value="page.planDate || '—'" />
|
|
@@ -105,6 +111,7 @@
|
|
|
class="actual-box__field"
|
|
class="actual-box__field"
|
|
|
placeholder="请输入"
|
|
placeholder="请输入"
|
|
|
:border="false"
|
|
:border="false"
|
|
|
|
|
+ :readonly="isReadOnly"
|
|
|
/>
|
|
/>
|
|
|
<span class="actual-box__unit">{{ item.unit || '吨' }}</span>
|
|
<span class="actual-box__unit">{{ item.unit || '吨' }}</span>
|
|
|
</div>
|
|
</div>
|
|
@@ -118,12 +125,24 @@
|
|
|
v-model="uploaderFiles"
|
|
v-model="uploaderFiles"
|
|
|
multiple
|
|
multiple
|
|
|
:max-count="9"
|
|
:max-count="9"
|
|
|
|
|
+ :deletable="!isReadOnly"
|
|
|
|
|
+ :show-upload="!isReadOnly"
|
|
|
:after-read="handleAfterRead"
|
|
:after-read="handleAfterRead"
|
|
|
:before-delete="handleBeforeDelete"
|
|
:before-delete="handleBeforeDelete"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
</van-cell-group>
|
|
</van-cell-group>
|
|
|
|
|
|
|
|
|
|
+ <van-cell-group v-if="!isReadOnly" inset class="section-card" title="单据状态">
|
|
|
|
|
+ <div class="status-radio-wrap">
|
|
|
|
|
+ <van-radio-group v-model="selectedStatus" direction="horizontal">
|
|
|
|
|
+ <van-radio name="in_progress">进行中</van-radio>
|
|
|
|
|
+ <van-radio name="completed">已完成</van-radio>
|
|
|
|
|
+ <van-radio name="voided">已作废</van-radio>
|
|
|
|
|
+ </van-radio-group>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </van-cell-group>
|
|
|
|
|
+
|
|
|
<van-cell-group inset class="section-card" title="现场备注">
|
|
<van-cell-group inset class="section-card" title="现场备注">
|
|
|
<van-field
|
|
<van-field
|
|
|
v-model="feedbackRemark"
|
|
v-model="feedbackRemark"
|
|
@@ -133,6 +152,7 @@
|
|
|
maxlength="500"
|
|
maxlength="500"
|
|
|
show-word-limit
|
|
show-word-limit
|
|
|
placeholder="填写现场备注"
|
|
placeholder="填写现场备注"
|
|
|
|
|
+ :readonly="isReadOnly"
|
|
|
/>
|
|
/>
|
|
|
</van-cell-group>
|
|
</van-cell-group>
|
|
|
|
|
|
|
@@ -140,7 +160,7 @@
|
|
|
<van-cell title="上次保存" :value="formatDateTime(page.siteFeedbackTime)" />
|
|
<van-cell title="上次保存" :value="formatDateTime(page.siteFeedbackTime)" />
|
|
|
</van-cell-group>
|
|
</van-cell-group>
|
|
|
|
|
|
|
|
- <footer class="page-footer">
|
|
|
|
|
|
|
+ <footer v-if="!isReadOnly" class="page-footer">
|
|
|
<van-button type="primary" block round :loading="saving" @click="handleSave">
|
|
<van-button type="primary" block round :loading="saving" @click="handleSave">
|
|
|
提交
|
|
提交
|
|
|
</van-button>
|
|
</van-button>
|
|
@@ -152,7 +172,7 @@
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
import type { UploaderFileListItem } from 'vant'
|
|
import type { UploaderFileListItem } from 'vant'
|
|
|
- import { showFailToast, showSuccessToast } from 'vant'
|
|
|
|
|
|
|
+ import { showConfirmDialog, showFailToast, showSuccessToast } from 'vant'
|
|
|
import {
|
|
import {
|
|
|
createPublicIoOrderApi,
|
|
createPublicIoOrderApi,
|
|
|
type PublicIoOrderItem,
|
|
type PublicIoOrderItem,
|
|
@@ -161,9 +181,12 @@
|
|
|
import PublicMobileShell from '@/layouts/PublicMobileShell.vue'
|
|
import PublicMobileShell from '@/layouts/PublicMobileShell.vue'
|
|
|
import { buildAmapNavigationUrl } from '@/utils/amap/navigation'
|
|
import { buildAmapNavigationUrl } from '@/utils/amap/navigation'
|
|
|
|
|
|
|
|
|
|
+ import 'vant/es/dialog/style'
|
|
|
import 'vant/es/toast/style'
|
|
import 'vant/es/toast/style'
|
|
|
import '@/styles/public-mobile-vant.scss'
|
|
import '@/styles/public-mobile-vant.scss'
|
|
|
|
|
|
|
|
|
|
+ type IoOrderStatus = 'in_progress' | 'completed' | 'voided'
|
|
|
|
|
+
|
|
|
const props = defineProps<{ kind: 'inbound' | 'outbound' }>()
|
|
const props = defineProps<{ kind: 'inbound' | 'outbound' }>()
|
|
|
const api = createPublicIoOrderApi(props.kind)
|
|
const api = createPublicIoOrderApi(props.kind)
|
|
|
const route = useRoute()
|
|
const route = useRoute()
|
|
@@ -180,6 +203,8 @@
|
|
|
const feedbackImages = ref<string[]>([])
|
|
const feedbackImages = ref<string[]>([])
|
|
|
const uploaderFiles = ref<UploaderFileListItem[]>([])
|
|
const uploaderFiles = ref<UploaderFileListItem[]>([])
|
|
|
const editableItems = ref<(PublicIoOrderItem & { actualQtyText: string })[]>([])
|
|
const editableItems = ref<(PublicIoOrderItem & { actualQtyText: string })[]>([])
|
|
|
|
|
+ const selectedStatus = ref<IoOrderStatus>('in_progress')
|
|
|
|
|
+ const isReadOnly = computed(() => Boolean(page.value?.voided))
|
|
|
|
|
|
|
|
const deliveryAddressDisplay = computed(() => {
|
|
const deliveryAddressDisplay = computed(() => {
|
|
|
if (!page.value) return '—'
|
|
if (!page.value) return '—'
|
|
@@ -258,6 +283,11 @@
|
|
|
...it,
|
|
...it,
|
|
|
actualQtyText: it.actualQty != null ? String(it.actualQty) : ''
|
|
actualQtyText: it.actualQty != null ? String(it.actualQty) : ''
|
|
|
}))
|
|
}))
|
|
|
|
|
+ selectedStatus.value = (
|
|
|
|
|
+ ['in_progress', 'completed', 'voided'].includes(data.status || '')
|
|
|
|
|
+ ? data.status
|
|
|
|
|
+ : 'in_progress'
|
|
|
|
|
+ ) as IoOrderStatus
|
|
|
syncUploaderFromImages()
|
|
syncUploaderFromImages()
|
|
|
} catch (e: any) {
|
|
} catch (e: any) {
|
|
|
errorMessage.value = e?.message || '链接无效或已失效'
|
|
errorMessage.value = e?.message || '链接无效或已失效'
|
|
@@ -268,6 +298,7 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async function handleAfterRead(item: UploaderFileListItem | UploaderFileListItem[]) {
|
|
async function handleAfterRead(item: UploaderFileListItem | UploaderFileListItem[]) {
|
|
|
|
|
+ if (isReadOnly.value) return
|
|
|
const files = Array.isArray(item) ? item : [item]
|
|
const files = Array.isArray(item) ? item : [item]
|
|
|
for (const fileItem of files) {
|
|
for (const fileItem of files) {
|
|
|
if (!fileItem.file) continue
|
|
if (!fileItem.file) continue
|
|
@@ -290,6 +321,7 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function handleBeforeDelete(item: UploaderFileListItem) {
|
|
function handleBeforeDelete(item: UploaderFileListItem) {
|
|
|
|
|
+ if (isReadOnly.value) return false
|
|
|
const fileUrl = (item as UploaderFileListItem & { fileUrl?: string }).fileUrl
|
|
const fileUrl = (item as UploaderFileListItem & { fileUrl?: string }).fileUrl
|
|
|
if (fileUrl) {
|
|
if (fileUrl) {
|
|
|
feedbackImages.value = feedbackImages.value.filter(u => u !== fileUrl)
|
|
feedbackImages.value = feedbackImages.value.filter(u => u !== fileUrl)
|
|
@@ -298,9 +330,21 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async function handleSave() {
|
|
async function handleSave() {
|
|
|
|
|
+ if (isReadOnly.value) return
|
|
|
|
|
+ if (selectedStatus.value === 'voided') {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await showConfirmDialog({
|
|
|
|
|
+ title: '确认作废',
|
|
|
|
|
+ message: '确认作废本出入库单?作废后不可再提交。'
|
|
|
|
|
+ })
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
saving.value = true
|
|
saving.value = true
|
|
|
try {
|
|
try {
|
|
|
await api.saveFeedback(token.value, {
|
|
await api.saveFeedback(token.value, {
|
|
|
|
|
+ status: selectedStatus.value,
|
|
|
remark: feedbackRemark.value,
|
|
remark: feedbackRemark.value,
|
|
|
images: feedbackImages.value,
|
|
images: feedbackImages.value,
|
|
|
items: editableItems.value.map(it => ({
|
|
items: editableItems.value.map(it => ({
|
|
@@ -350,6 +394,10 @@
|
|
|
padding: 8px 14px 12px;
|
|
padding: 8px 14px 12px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ .status-radio-wrap {
|
|
|
|
|
+ padding: 12px 16px 16px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.page-footer {
|
|
.page-footer {
|
|
|
padding: 16px;
|
|
padding: 16px;
|
|
|
}
|
|
}
|