|
@@ -0,0 +1,427 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="container">
|
|
|
|
|
+ <div class="processing-photo-task">
|
|
|
|
|
+ <div class="top">
|
|
|
|
|
+ <div class="nav-bar">
|
|
|
|
|
+ <van-nav-bar
|
|
|
|
|
+ title="加工拍照任务"
|
|
|
|
|
+ left-arrow
|
|
|
|
|
+ @click-left="goBack"
|
|
|
|
|
+ @click-right="onRefresh"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #left>
|
|
|
|
|
+ <van-icon name="arrow-left" size="25" />
|
|
|
|
|
+ <div
|
|
|
|
|
+ style="
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ height: 46px;
|
|
|
|
|
+ padding-right: 20px;
|
|
|
|
|
+ line-height: 46px;
|
|
|
|
|
+ "
|
|
|
|
|
+ >
|
|
|
|
|
+ 返回
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template #right>
|
|
|
|
|
+ <div class="nav-right" style="color: #fff">刷新</div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </van-nav-bar>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="context">
|
|
|
|
|
+ <van-pull-refresh
|
|
|
|
|
+ v-model="loading"
|
|
|
|
|
+ @refresh="onRefresh"
|
|
|
|
|
+ :style="{
|
|
|
|
|
+ 'max-height': computedMaxHeight,
|
|
|
|
|
+ 'min-height': computedMaxHeight,
|
|
|
|
|
+ overflow: 'auto',
|
|
|
|
|
+ }"
|
|
|
|
|
+ >
|
|
|
|
|
+ <table class="photo-task-table">
|
|
|
|
|
+ <thead>
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <th style="width: 25%">货主</th>
|
|
|
|
|
+ <th style="width: 35%">加工单号</th>
|
|
|
|
|
+ <th style="width: 15%">状态</th>
|
|
|
|
|
+ <th style="width: 12.5%">查看</th>
|
|
|
|
|
+ <th style="width: 12.5%">操作</th>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ </thead>
|
|
|
|
|
+ <tbody>
|
|
|
|
|
+ <tr v-for="(row, rowIndex) in photoTasks" :key="rowIndex">
|
|
|
|
|
+ <td>
|
|
|
|
|
+ <span class="text-compact">{{ row.ownerName }}</span>
|
|
|
|
|
+ </td>
|
|
|
|
|
+ <td>
|
|
|
|
|
+ <span class="text-sm code-link" @click="showNotes(row)">{{ row.code }}</span>
|
|
|
|
|
+ </td>
|
|
|
|
|
+ <td>
|
|
|
|
|
+ <span class="text-compact">{{ row.status }}</span>
|
|
|
|
|
+ </td>
|
|
|
|
|
+ <td>
|
|
|
|
|
+ <van-button type="primary" plain size="small" @click="showPhotos(row)" class="compact-button"
|
|
|
|
|
+ >查看
|
|
|
|
|
+ </van-button>
|
|
|
|
|
+ </td>
|
|
|
|
|
+ <td>
|
|
|
|
|
+ <van-button v-if="row.status !== '完成'" type="primary" size="small" @click="toPhoto(row)" class="compact-button"
|
|
|
|
|
+ >拍摄
|
|
|
|
|
+ </van-button>
|
|
|
|
|
+ </td>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ </tbody>
|
|
|
|
|
+ </table>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 分页控件 -->
|
|
|
|
|
+ <van-pagination
|
|
|
|
|
+ v-model="paginate.page"
|
|
|
|
|
+ :page-size="paginate.size"
|
|
|
|
|
+ :total-items="paginate.total"
|
|
|
|
|
+ :page-count="paginate.pages"
|
|
|
|
|
+ :show-page-size="5"
|
|
|
|
|
+ model="simple"
|
|
|
|
|
+ forced="true"
|
|
|
|
|
+ @change="onPageChange"
|
|
|
|
|
+ class="pagination"
|
|
|
|
|
+ />
|
|
|
|
|
+ </van-pull-refresh>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 图片上传弹窗 -->
|
|
|
|
|
+ <van-popup v-model:show="showUpload" position="bottom" :style="{ height: '80%' }">
|
|
|
|
|
+ <div class="upload-popup">
|
|
|
|
|
+ <van-nav-bar
|
|
|
|
|
+ title="图片上传"
|
|
|
|
|
+ left-arrow
|
|
|
|
|
+ @click-left="showUpload = false"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #left>
|
|
|
|
|
+ <van-icon name="arrow-left" size="25" />
|
|
|
|
|
+ <div style="color: #fff; height: 46px; padding-right: 20px; line-height: 46px;">
|
|
|
|
|
+ 返回
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </van-nav-bar>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="upload-content">
|
|
|
|
|
+ <van-uploader
|
|
|
|
|
+ v-model="uploadImages"
|
|
|
|
|
+ :max-count="9"
|
|
|
|
|
+ :max-size="15 * 1024 * 1024"
|
|
|
|
|
+ :before-read="beforeReadImage"
|
|
|
|
|
+ :after-read="afterReadImage"
|
|
|
|
|
+ multiple
|
|
|
|
|
+ preview-full-image
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <div class="upload-footer">
|
|
|
|
|
+ <van-button
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ block
|
|
|
|
|
+ :loading="uploading"
|
|
|
|
|
+ @click="submitUpload"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ uploading ? '上传中...' : '提交上传' }}
|
|
|
|
|
+ </van-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </van-popup>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup>
|
|
|
|
|
+import { ref, computed, onMounted } from 'vue'
|
|
|
|
|
+import { useRoute } from 'vue-router'
|
|
|
|
|
+import { showNotify, showImagePreview, showFailToast, showLoadingToast, closeToast, showDialog } from 'vant'
|
|
|
|
|
+import {
|
|
|
|
|
+ getProcessingPhotoTask,
|
|
|
|
|
+ processingPhotoTaskItems,
|
|
|
|
|
+ uploadPhoto
|
|
|
|
|
+} from '@/api/processing/index'
|
|
|
|
|
+import { goBack } from '@/utils/android'
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+const route = useRoute()
|
|
|
|
|
+const loading = ref(false)
|
|
|
|
|
+const photoTasks = ref([])
|
|
|
|
|
+const showUpload = ref(false)
|
|
|
|
|
+const uploadImages = ref([])
|
|
|
|
|
+const uploading = ref(false)
|
|
|
|
|
+const currentTaskId = ref(null)
|
|
|
|
|
+
|
|
|
|
|
+const paginate = ref({
|
|
|
|
|
+ page: 1,
|
|
|
|
|
+ size: 20,
|
|
|
|
|
+ total: 0,
|
|
|
|
|
+ pages: 0,
|
|
|
|
|
+})
|
|
|
|
|
+const reviewImages = ref([])
|
|
|
|
|
+
|
|
|
|
|
+// 计算最大高度适配手持设备
|
|
|
|
|
+const computedMaxHeight = computed(() => {
|
|
|
|
|
+ return window.innerHeight - 46 - 20 + 'px'
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 获取从其他页面传递的参数
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ // 可以从route.query或route.params中获取参数
|
|
|
|
|
+ if (route.query.id) {
|
|
|
|
|
+ // 如果有传入id参数,可以做特殊处理
|
|
|
|
|
+ console.log('接收到参数id:', route.query.id)
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 显示notes信息 - 改为弹框方式
|
|
|
|
|
+function showNotes(row) {
|
|
|
|
|
+ const notes = row.notes || '暂无备注信息'
|
|
|
|
|
+ showDialog({
|
|
|
|
|
+ title: '任务备注',
|
|
|
|
|
+ message: notes,
|
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
|
+ messageAlign: 'left'
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function onRefresh() {
|
|
|
|
|
+ // 刷新时重置到第一页
|
|
|
|
|
+ paginate.value.page = 1
|
|
|
|
|
+ listProcessingPhoto()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function listProcessingPhoto() {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ getProcessingPhotoTask(paginate.value).then((res) => {
|
|
|
|
|
+ photoTasks.value = res?.data?.records || []
|
|
|
|
|
+ // 更新分页信息
|
|
|
|
|
+ if (res?.data) {
|
|
|
|
|
+ paginate.value.size = res.data.size || 0
|
|
|
|
|
+ paginate.value.total = res.data.total || 0
|
|
|
|
|
+ paginate.value.page = res.data.current || 0
|
|
|
|
|
+ paginate.value.pages = res.data.pages || 0
|
|
|
|
|
+ }
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 分页变更处理
|
|
|
|
|
+function onPageChange(page) {
|
|
|
|
|
+ paginate.value.page = page
|
|
|
|
|
+ listProcessingPhoto()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function showPhotos(row) {
|
|
|
|
|
+ processingPhotoTaskItems(row.id).then((res) => {
|
|
|
|
|
+ const items = res.data
|
|
|
|
|
+ console.log(res)
|
|
|
|
|
+ if (!items || items.length === 0) {
|
|
|
|
|
+ showNotify({ type: 'warning', message: '没有对应的拍摄' })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ console.log(import.meta.env.VITE_APP_BASE_API)
|
|
|
|
|
+ const baseUrl = import.meta.env.VITE_APP_BASE_API + 'statics/storage/'
|
|
|
|
|
+ const paths = baseUrl.split('.')
|
|
|
|
|
+ paths[1] = 'swms'
|
|
|
|
|
+ const base = paths.join('.')
|
|
|
|
|
+ // 解构图片url
|
|
|
|
|
+ reviewImages.value = items.map(item => {
|
|
|
|
|
+ const {path,module} = item
|
|
|
|
|
+ return `${base}${module}/${path}`
|
|
|
|
|
+ }).filter(url => url)
|
|
|
|
|
+
|
|
|
|
|
+ console.log(reviewImages.value)
|
|
|
|
|
+ // 预览图片
|
|
|
|
|
+ if (reviewImages.value.length > 0) {
|
|
|
|
|
+ showImagePreview({
|
|
|
|
|
+ images: reviewImages.value,
|
|
|
|
|
+ closeable: true,
|
|
|
|
|
+ })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showNotify({ type: 'warning', message: '没有可预览的图片' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(err => {
|
|
|
|
|
+ showNotify({ type: 'danger', message: '获取图片失败' })
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function toPhoto(row) {
|
|
|
|
|
+ currentTaskId.value = row.id
|
|
|
|
|
+ uploadImages.value = []
|
|
|
|
|
+ showUpload.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 检查图片格式和大小
|
|
|
|
|
+const beforeReadImage = (file) => {
|
|
|
|
|
+ const files = Array.isArray(file) ? file : [file]
|
|
|
|
|
+ for (const f of files) {
|
|
|
|
|
+ // 检查文件格式
|
|
|
|
|
+ if (f.name.toLowerCase().endsWith('.heic') || f.name.toLowerCase().endsWith('.heif')) {
|
|
|
|
|
+ showFailToast('不支持HEIC/HEIF格式的图片')
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查文件类型
|
|
|
|
|
+ const isImage = /^image\//.test(f.type)
|
|
|
|
|
+ if (!isImage) {
|
|
|
|
|
+ showFailToast('请上传图片文件')
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查文件大小 (15MB)
|
|
|
|
|
+ if (f.size > 15 * 1024 * 1024) {
|
|
|
|
|
+ showFailToast('图片大小不能超过15MB')
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 图片读取完成后处理
|
|
|
|
|
+const afterReadImage = (file) => {
|
|
|
|
|
+ // file 是上传的文件信息,可以在这里进行额外处理
|
|
|
|
|
+ console.log('文件读取完成:', file)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 提交上传
|
|
|
|
|
+const submitUpload = async () => {
|
|
|
|
|
+ if (!uploadImages.value.length) {
|
|
|
|
|
+ showFailToast('请先选择图片')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!currentTaskId.value) {
|
|
|
|
|
+ showFailToast('任务ID无效')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ uploading.value = true
|
|
|
|
|
+ const toast = showLoadingToast('上传中...')
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 逐个上传图片
|
|
|
|
|
+ for (const image of uploadImages.value) {
|
|
|
|
|
+ const formData = new FormData()
|
|
|
|
|
+ formData.append('file', image.file)
|
|
|
|
|
+ // 调用上传API
|
|
|
|
|
+ await uploadPhoto(currentTaskId.value, formData)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ closeToast()
|
|
|
|
|
+ showNotify({ type: 'success', message: '上传成功' })
|
|
|
|
|
+
|
|
|
|
|
+ // 关闭弹窗并刷新列表
|
|
|
|
|
+ showUpload.value = false
|
|
|
|
|
+ uploadImages.value = []
|
|
|
|
|
+ onRefresh()
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ closeToast()
|
|
|
|
|
+ showNotify({ type: 'danger', message: '上传失败: ' + (err.message || '未知错误') })
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ uploading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 初始化加载数据
|
|
|
|
|
+onRefresh()
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+.photo-task-table {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ border-collapse: collapse;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ table-layout: fixed;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+
|
|
|
|
|
+ thead {
|
|
|
|
|
+ tr {
|
|
|
|
|
+ background-color: #f5f5f5;
|
|
|
|
|
+
|
|
|
|
|
+ th {
|
|
|
|
|
+ padding: 6px 2px;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tbody {
|
|
|
|
|
+ tr {
|
|
|
|
|
+ height: 36px;
|
|
|
|
|
+ border-bottom: 1px solid #e0e0e0;
|
|
|
|
|
+
|
|
|
|
|
+ &:last-child {
|
|
|
|
|
+ border-bottom: none;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ td {
|
|
|
|
|
+ padding: 3px 2px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+
|
|
|
|
|
+ .text-compact {
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ line-height: 1.2;
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .text-sm {
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ line-height: 1.2;
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .compact-button {
|
|
|
|
|
+ height: 24px;
|
|
|
|
|
+ line-height: 22px;
|
|
|
|
|
+ padding: 0 6px;
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ min-width: 36px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.pagination {
|
|
|
|
|
+ padding: 10px 0;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.upload-popup {
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+
|
|
|
|
|
+ .upload-content {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ padding: 10px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+
|
|
|
|
|
+ .upload-footer {
|
|
|
|
|
+ padding: 10px 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.code-link {
|
|
|
|
|
+ color: #1989fa;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ text-decoration: underline;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ color: #0570db;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|