|
|
@@ -1,4 +1,4 @@
|
|
|
-<template>
|
|
|
+ <template>
|
|
|
<div class="container">
|
|
|
<div class="processing-photo-task">
|
|
|
<div class="top">
|
|
|
@@ -23,12 +23,44 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
<template #right>
|
|
|
- <div class="nav-right" style="color: #fff">刷新</div>
|
|
|
+ <div class="nav-right" style="color: #fff">重置</div>
|
|
|
</template>
|
|
|
</van-nav-bar>
|
|
|
</div>
|
|
|
|
|
|
<div class="context">
|
|
|
+ <!-- 筛选区域 -->
|
|
|
+ <div class="filter-section">
|
|
|
+ <van-row gutter="10">
|
|
|
+ <van-col span="8">
|
|
|
+ <van-field
|
|
|
+ v-model="filterForm.owners"
|
|
|
+ placeholder="请选择货主"
|
|
|
+ readonly
|
|
|
+ clickable
|
|
|
+ clearable
|
|
|
+ clear-trigger="always"
|
|
|
+ @click="showOwnerDialog"
|
|
|
+ @clear="onOwnerClear"
|
|
|
+ />
|
|
|
+ </van-col>
|
|
|
+ <van-col span="8">
|
|
|
+ <van-field
|
|
|
+ v-model="filterForm.status"
|
|
|
+ placeholder="请选择状态"
|
|
|
+ readonly
|
|
|
+ clickable
|
|
|
+ @click="showStatusPicker = true"
|
|
|
+ />
|
|
|
+ </van-col>
|
|
|
+ <van-col span="8">
|
|
|
+ <van-button type="primary" size="small" block @click="onFilterSearch">
|
|
|
+ 搜索
|
|
|
+ </van-button>
|
|
|
+ </van-col>
|
|
|
+ </van-row>
|
|
|
+ </div>
|
|
|
+
|
|
|
<van-pull-refresh
|
|
|
v-model="loading"
|
|
|
@refresh="onRefresh"
|
|
|
@@ -89,6 +121,21 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
+ <!-- 货主选择器弹窗 -->
|
|
|
+ <Owner
|
|
|
+ ref="ownerRef"
|
|
|
+ @onOwner="onOwnerSelect"
|
|
|
+ />
|
|
|
+
|
|
|
+ <!-- 状态选择器弹窗 -->
|
|
|
+ <van-popup v-model:show="showStatusPicker" position="bottom">
|
|
|
+ <van-picker
|
|
|
+ :columns="statusOptions"
|
|
|
+ @confirm="onStatusConfirm"
|
|
|
+ @cancel="showStatusPicker = false"
|
|
|
+ />
|
|
|
+ </van-popup>
|
|
|
+
|
|
|
<!-- 图片上传弹窗 -->
|
|
|
<van-popup v-model:show="showUpload" position="bottom" :style="{ height: '80%' }">
|
|
|
<div class="upload-popup">
|
|
|
@@ -140,9 +187,10 @@ import { showNotify, showImagePreview, showFailToast, showLoadingToast, closeToa
|
|
|
import {
|
|
|
getProcessingPhotoTask,
|
|
|
processingPhotoTaskItems,
|
|
|
- uploadPhoto
|
|
|
+ uploadPhoto,status
|
|
|
} from '@/api/processing/index'
|
|
|
import { getHeader, goBack } from '@/utils/android'
|
|
|
+import Owner from '@/components/Owner.vue'
|
|
|
try {
|
|
|
getHeader()
|
|
|
} catch (error) {
|
|
|
@@ -157,6 +205,7 @@ const showUpload = ref(false)
|
|
|
const uploadImages = ref([])
|
|
|
const uploading = ref(false)
|
|
|
const currentTaskId = ref(null)
|
|
|
+const ownerRef = ref(null)
|
|
|
|
|
|
const paginate = ref({
|
|
|
page: 1,
|
|
|
@@ -166,6 +215,16 @@ const paginate = ref({
|
|
|
})
|
|
|
const reviewImages = ref([])
|
|
|
|
|
|
+// 筛选相关数据
|
|
|
+const filterForm = ref({
|
|
|
+ owners: '',
|
|
|
+ status: '',
|
|
|
+ statusCode: ''
|
|
|
+})
|
|
|
+
|
|
|
+const showStatusPicker = ref(false)
|
|
|
+const statusOptions = ref([])
|
|
|
+
|
|
|
// 计算最大高度适配手持设备
|
|
|
const computedMaxHeight = computed(() => {
|
|
|
return window.innerHeight - 46 - 20 + 'px'
|
|
|
@@ -176,8 +235,15 @@ onMounted(() => {
|
|
|
// 可以从route.query或route.params中获取参数
|
|
|
if (route.query.id) {
|
|
|
// 如果有传入id参数,可以做特殊处理
|
|
|
- console.log('接收到参数id:', route.query.id)
|
|
|
}
|
|
|
+
|
|
|
+ status().then(res=>{
|
|
|
+ if (res.data) {
|
|
|
+ statusOptions.value = res.data.map(item=>{
|
|
|
+ return {text:item.name,value:item.code}
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
// 显示notes信息 - 改为弹框方式
|
|
|
@@ -194,12 +260,21 @@ function showNotes(row) {
|
|
|
function onRefresh() {
|
|
|
// 刷新时重置到第一页
|
|
|
paginate.value.page = 1
|
|
|
+ filterForm.value.owners = null
|
|
|
+ filterForm.value.status = null
|
|
|
+ filterForm.value.statusCode = null
|
|
|
listProcessingPhoto()
|
|
|
}
|
|
|
|
|
|
function listProcessingPhoto() {
|
|
|
loading.value = true
|
|
|
- getProcessingPhotoTask(paginate.value).then((res) => {
|
|
|
+ // 合并筛选条件和分页参数,使用statusCode而不是status
|
|
|
+ const params = {
|
|
|
+ ...paginate.value,
|
|
|
+ owners: filterForm.value.owners,
|
|
|
+ status: filterForm.value.statusCode
|
|
|
+ }
|
|
|
+ getProcessingPhotoTask(params).then((res) => {
|
|
|
photoTasks.value = res?.data?.records || []
|
|
|
// 更新分页信息
|
|
|
if (res?.data) {
|
|
|
@@ -222,12 +297,10 @@ function onPageChange(page) {
|
|
|
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'
|
|
|
@@ -238,7 +311,6 @@ function showPhotos(row) {
|
|
|
return `${base}${module}/${path}`
|
|
|
}).filter(url => url)
|
|
|
|
|
|
- console.log(reviewImages.value)
|
|
|
// 预览图片
|
|
|
if (reviewImages.value.length > 0) {
|
|
|
showImagePreview({
|
|
|
@@ -288,7 +360,6 @@ const beforeReadImage = (file) => {
|
|
|
// 图片读取完成后处理
|
|
|
const afterReadImage = (file) => {
|
|
|
// file 是上传的文件信息,可以在这里进行额外处理
|
|
|
- console.log('文件读取完成:', file)
|
|
|
}
|
|
|
|
|
|
// 提交上传
|
|
|
@@ -307,34 +378,123 @@ const submitUpload = async () => {
|
|
|
const toast = showLoadingToast('上传中...')
|
|
|
|
|
|
try {
|
|
|
+ const totalImages = uploadImages.value.length
|
|
|
+ let successCount = 0
|
|
|
+ let failedImages = []
|
|
|
+
|
|
|
// 逐个上传图片
|
|
|
- for (const image of uploadImages.value) {
|
|
|
- const formData = new FormData()
|
|
|
- formData.append('file', image.file)
|
|
|
- // 调用上传API
|
|
|
- await uploadPhoto(currentTaskId.value, formData)
|
|
|
+ for (let i = 0; i < uploadImages.value.length; i++) {
|
|
|
+ const image = uploadImages.value[i]
|
|
|
+ try {
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('file', image.file)
|
|
|
+ // 调用上传API
|
|
|
+ await uploadPhoto(currentTaskId.value, formData)
|
|
|
+ successCount++
|
|
|
+ } catch (err) {
|
|
|
+ console.error(`第${i + 1}张图片上传失败:`, err)
|
|
|
+ failedImages.push({
|
|
|
+ index: i,
|
|
|
+ image: image,
|
|
|
+ error: err.message || '上传失败'
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
closeToast()
|
|
|
- showNotify({ type: 'success', message: '上传成功' })
|
|
|
|
|
|
- // 关闭弹窗并刷新列表
|
|
|
- showUpload.value = false
|
|
|
- uploadImages.value = []
|
|
|
- onRefresh()
|
|
|
+ if (successCount === totalImages) {
|
|
|
+ // 全部上传成功
|
|
|
+ showNotify({ type: 'success', message: '全部图片上传成功' })
|
|
|
+ // 关闭弹窗并刷新列表
|
|
|
+ showUpload.value = false
|
|
|
+ uploadImages.value = []
|
|
|
+ onRefresh()
|
|
|
+ } else if (successCount > 0) {
|
|
|
+ // 部分上传成功
|
|
|
+ showNotify({
|
|
|
+ type: 'warning',
|
|
|
+ message: `${successCount}/${totalImages}张图片上传成功,${failedImages.length}张失败`
|
|
|
+ })
|
|
|
+ // 移除上传成功的图片,保留失败的图片
|
|
|
+ uploadImages.value = failedImages.map(item => item.image)
|
|
|
+ } else {
|
|
|
+ // 全部上传失败
|
|
|
+ showNotify({
|
|
|
+ type: 'danger',
|
|
|
+ message: '所有图片上传失败,请检查网络连接或重试'
|
|
|
+ })
|
|
|
+ // 保留所有失败的图片,让用户可以重试
|
|
|
+ }
|
|
|
} catch (err) {
|
|
|
closeToast()
|
|
|
- showNotify({ type: 'danger', message: '上传失败: ' + (err.message || '未知错误') })
|
|
|
+ showNotify({ type: 'danger', message: '上传过程发生异常: ' + (err.message || '未知错误') })
|
|
|
+ // 发生异常时保留所有图片,让用户可以重试
|
|
|
} finally {
|
|
|
uploading.value = false
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+function onFilterSearch() {
|
|
|
+ // 搜索时重置到第一页
|
|
|
+ paginate.value.page = 1
|
|
|
+ listProcessingPhoto()
|
|
|
+}
|
|
|
+
|
|
|
+// 显示货主选择弹窗
|
|
|
+function showOwnerDialog() {
|
|
|
+ if (ownerRef.value) {
|
|
|
+ ownerRef.value.show('filter')
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 处理货主选择
|
|
|
+function onOwnerSelect(item, type) {
|
|
|
+ filterForm.value.owners = item.name
|
|
|
+ // 选择货主后自动搜索
|
|
|
+ onFilterSearch()
|
|
|
+}
|
|
|
+
|
|
|
+// 处理货主清空
|
|
|
+function onOwnerClear() {
|
|
|
+ filterForm.value.owners = ''
|
|
|
+ // 清空货主后自动搜索
|
|
|
+ onFilterSearch()
|
|
|
+}
|
|
|
+
|
|
|
+function onStatusConfirm({ selectedOptions }) {
|
|
|
+ filterForm.value.status = selectedOptions[0].text
|
|
|
+ filterForm.value.statusCode = selectedOptions[0].value
|
|
|
+ showStatusPicker.value = false
|
|
|
+ // 选择状态后自动搜索
|
|
|
+ onFilterSearch()
|
|
|
+}
|
|
|
+
|
|
|
// 初始化加载数据
|
|
|
onRefresh()
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
+// 确保van-field的清空按钮样式正确显示
|
|
|
+:deep(.van-field__clear) {
|
|
|
+ display: flex !important;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ color: #c8c9cc;
|
|
|
+ font-size: 16px;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ color: #969799;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 确保van-field右侧区域有足够空间显示清空按钮
|
|
|
+:deep(.van-field__right-icon) {
|
|
|
+ display: flex !important;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
.photo-task-table {
|
|
|
width: 100%;
|
|
|
border-collapse: collapse;
|
|
|
@@ -420,6 +580,12 @@ onRefresh()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+.filter-section {
|
|
|
+ padding: 10px;
|
|
|
+ background: #fff;
|
|
|
+ border-bottom: 1px solid #e0e0e0;
|
|
|
+}
|
|
|
+
|
|
|
.code-link {
|
|
|
color: #1989fa;
|
|
|
cursor: pointer;
|
|
|
@@ -429,4 +595,4 @@ onRefresh()
|
|
|
color: #0570db;
|
|
|
}
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|