feat: lock dialog and disable close actions during image upload to prevent orphan files and state errors
This commit is contained in:
@ -323,6 +323,9 @@
|
|||||||
width="700px"
|
width="700px"
|
||||||
append-to-body
|
append-to-body
|
||||||
@close="cancel"
|
@close="cancel"
|
||||||
|
:close-on-click-modal="!isUploading"
|
||||||
|
:close-on-press-escape="!isUploading"
|
||||||
|
:show-close="!isUploading"
|
||||||
>
|
>
|
||||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
|
||||||
|
|
||||||
@ -477,8 +480,8 @@
|
|||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="cancel">取 消</el-button>
|
<el-button @click="cancel" :disabled="isUploading">取 消</el-button>
|
||||||
<el-button type="primary" @click="submitForm" :loading="submitLoading">确 定</el-button>
|
<el-button type="primary" @click="submitForm" :loading="submitLoading || isUploading">确 定</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -596,6 +599,10 @@ const total = ref(0);
|
|||||||
const tableData = ref<MaterialBaseVO[]>([]);
|
const tableData = ref<MaterialBaseVO[]>([]);
|
||||||
const tableRef = ref<InstanceType<typeof ElTable>>();
|
const tableRef = ref<InstanceType<typeof ElTable>>();
|
||||||
const submitLoading = ref(false);
|
const submitLoading = ref(false);
|
||||||
|
|
||||||
|
// 上传锁定状态
|
||||||
|
const isUploading = ref(false);
|
||||||
|
|
||||||
const tableSize = ref<'large' | 'default' | 'small'>('large');
|
const tableSize = ref<'large' | 'default' | 'small'>('large');
|
||||||
const advancedFilterVisible = ref(false);
|
const advancedFilterVisible = ref(false);
|
||||||
const advancedConditions = ref([{ field: '', operator: '', value: '' }]);
|
const advancedConditions = ref([{ field: '', operator: '', value: '' }]);
|
||||||
@ -1278,6 +1285,7 @@ const customUpload = async (options: any, targetField: 'generalImage' | 'general
|
|||||||
const { file, onSuccess, onError } = options
|
const { file, onSuccess, onError } = options
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
|
isUploading.value = true
|
||||||
try {
|
try {
|
||||||
const res: any = await uploadFile(formData)
|
const res: any = await uploadFile(formData)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
@ -1293,6 +1301,7 @@ const customUpload = async (options: any, targetField: 'generalImage' | 'general
|
|||||||
ElMessage.error('网络错误');
|
ElMessage.error('网络错误');
|
||||||
onError(e)
|
onError(e)
|
||||||
}
|
}
|
||||||
|
finally { isUploading.value = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRemoveImage = async (uploadFile: any, targetField: 'generalImage' | 'generalManual') => {
|
const handleRemoveImage = async (uploadFile: any, targetField: 'generalImage' | 'generalManual') => {
|
||||||
|
|||||||
@ -251,7 +251,9 @@
|
|||||||
:width="'min(1000px, 95vw)'"
|
:width="'min(1000px, 95vw)'"
|
||||||
top="4vh"
|
top="4vh"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="!isUploading"
|
||||||
|
:close-on-press-escape="!isUploading"
|
||||||
|
:show-close="!isUploading"
|
||||||
class="stylish-dialog compact-layout"
|
class="stylish-dialog compact-layout"
|
||||||
>
|
>
|
||||||
<div class="dialog-scroll-container">
|
<div class="dialog-scroll-container">
|
||||||
@ -618,8 +620,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="visible = false" size="large">取消</el-button>
|
<el-button @click="visible = false" size="large" :disabled="isUploading">取消</el-button>
|
||||||
<el-button type="primary" :loading="submitting" @click="submitForm" size="large" class="confirm-btn">{{ dialogStatus === 'create' ? '确认入库并打印' : '保存修改' }}</el-button>
|
<el-button type="primary" :loading="submitting || isUploading" @click="submitForm" size="large" class="confirm-btn">{{ dialogStatus === 'create' ? '确认入库并打印' : '保存修改' }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -782,6 +784,9 @@ const tableData = ref([])
|
|||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
|
|
||||||
|
// 上传锁定状态
|
||||||
|
const isUploading = ref(false)
|
||||||
|
|
||||||
const categoryOptions = ref<string[]>([])
|
const categoryOptions = ref<string[]>([])
|
||||||
const typeOptions = ref<string[]>([])
|
const typeOptions = ref<string[]>([])
|
||||||
const companyOptions = ref<string[]>([])
|
const companyOptions = ref<string[]>([])
|
||||||
@ -1423,6 +1428,7 @@ const customUpload = async (options: any, targetField: 'arrival_photo' | 'inspec
|
|||||||
const { file, onSuccess, onError } = options
|
const { file, onSuccess, onError } = options
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
|
isUploading.value = true
|
||||||
try {
|
try {
|
||||||
const res: any = await uploadFile(formData)
|
const res: any = await uploadFile(formData)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
@ -1448,6 +1454,8 @@ const customUpload = async (options: any, targetField: 'arrival_photo' | 'inspec
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
ElMessage.error('网络错误')
|
ElMessage.error('网络错误')
|
||||||
onError(e)
|
onError(e)
|
||||||
|
} finally {
|
||||||
|
isUploading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -231,7 +231,7 @@
|
|||||||
|
|
||||||
<el-pagination class="pagination-bar" v-model:current-page="queryParams.page" v-model:page-size="queryParams.pageSize" :total="total" layout="total, sizes, prev, pager, next" background @change="fetchData" />
|
<el-pagination class="pagination-bar" v-model:current-page="queryParams.page" v-model:page-size="queryParams.pageSize" :total="total" layout="total, sizes, prev, pager, next" background @change="fetchData" />
|
||||||
|
|
||||||
<el-dialog v-model="visible" :title="dialogStatus === 'create' ? '成品入库' : '编辑成品'" width="min(1000px, 95vw)" top="5vh" :close-on-click-modal="false" class="stylish-dialog compact-layout">
|
<el-dialog v-model="visible" :title="dialogStatus === 'create' ? '成品入库' : '编辑成品'" width="min(1000px, 95vw)" top="5vh" :close-on-click-modal="!isUploading" :close-on-press-escape="!isUploading" :show-close="!isUploading" class="stylish-dialog compact-layout">
|
||||||
<div class="dialog-scroll-container">
|
<div class="dialog-scroll-container">
|
||||||
<el-form :model="form" label-width="110px" ref="formRef" :rules="rules" size="default" class="stylish-form">
|
<el-form :model="form" label-width="110px" ref="formRef" :rules="rules" size="default" class="stylish-form">
|
||||||
|
|
||||||
@ -488,8 +488,8 @@
|
|||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="visible = false" size="large">取消</el-button>
|
<el-button @click="visible = false" size="large" :disabled="isUploading">取消</el-button>
|
||||||
<el-button type="primary" :loading="submitting" @click="submitForm" size="large" class="confirm-btn">
|
<el-button type="primary" :loading="submitting || isUploading" @click="submitForm" size="large" class="confirm-btn">
|
||||||
{{ dialogStatus === 'create' ? '提交并打印' : '保存修改' }}
|
{{ dialogStatus === 'create' ? '提交并打印' : '保存修改' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -599,6 +599,10 @@ const dialogStatus = ref<'create' | 'update'>('create')
|
|||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
|
|
||||||
|
// 上传锁定状态
|
||||||
|
const isUploading = ref(false)
|
||||||
|
|
||||||
const queryParams = reactive({ page: 1, pageSize: 50, keyword: '', searchField: 'all', sku: '', category: '', material_type: '', statuses: ['在库', '借库'], company: '', orderByColumn: '', isAsc: '', advancedFilters: [] })
|
const queryParams = reactive({ page: 1, pageSize: 50, keyword: '', searchField: 'all', sku: '', category: '', material_type: '', statuses: ['在库', '借库'], company: '', orderByColumn: '', isAsc: '', advancedFilters: [] })
|
||||||
const categoryOptions = ref<string[]>([])
|
const categoryOptions = ref<string[]>([])
|
||||||
const typeOptions = ref<string[]>([])
|
const typeOptions = ref<string[]>([])
|
||||||
@ -1137,12 +1141,14 @@ const beforeAvatarUpload = (rawFile: any) => { if (rawFile.type !== 'image/jpeg'
|
|||||||
const customUpload = async (options: any, targetField: 'product_photo' | 'quality_report_link' | 'inspection_report_link') => {
|
const customUpload = async (options: any, targetField: 'product_photo' | 'quality_report_link' | 'inspection_report_link') => {
|
||||||
const { file, onSuccess, onError } = options
|
const { file, onSuccess, onError } = options
|
||||||
const formData = new FormData(); formData.append('file', file)
|
const formData = new FormData(); formData.append('file', file)
|
||||||
|
isUploading.value = true
|
||||||
try {
|
try {
|
||||||
const res: any = await uploadFile(formData)
|
const res: any = await uploadFile(formData)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
const newUrl = res.data.url; form[targetField].push(newUrl); ElMessage.success('上传成功'); onSuccess(res)
|
const newUrl = res.data.url; form[targetField].push(newUrl); ElMessage.success('上传成功'); onSuccess(res)
|
||||||
} else { ElMessage.error(res.msg || '上传失败'); onError(new Error(res.msg)) }
|
} else { ElMessage.error(res.msg || '上传失败'); onError(new Error(res.msg)) }
|
||||||
} catch (e) { ElMessage.error('网络错误'); onError(e) }
|
} catch (e) { ElMessage.error('网络错误'); onError(e) }
|
||||||
|
finally { isUploading.value = false }
|
||||||
}
|
}
|
||||||
const handleRemoveImage = async (uploadFile: any, targetField: 'product_photo' | 'quality_report_link' | 'inspection_report_link') => {
|
const handleRemoveImage = async (uploadFile: any, targetField: 'product_photo' | 'quality_report_link' | 'inspection_report_link') => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -275,7 +275,9 @@
|
|||||||
width="min(1000px, 95vw)"
|
width="min(1000px, 95vw)"
|
||||||
top="5vh"
|
top="5vh"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="!isUploading"
|
||||||
|
:close-on-press-escape="!isUploading"
|
||||||
|
:show-close="!isUploading"
|
||||||
class="stylish-dialog compact-layout"
|
class="stylish-dialog compact-layout"
|
||||||
>
|
>
|
||||||
<div class="dialog-scroll-container">
|
<div class="dialog-scroll-container">
|
||||||
@ -562,8 +564,8 @@
|
|||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="visible = false" size="large">取消</el-button>
|
<el-button @click="visible = false" size="large" :disabled="isUploading">取消</el-button>
|
||||||
<el-button type="primary" :loading="submitting" @click="submitForm" size="large" class="confirm-btn">
|
<el-button type="primary" :loading="submitting || isUploading" @click="submitForm" size="large" class="confirm-btn">
|
||||||
{{ dialogStatus === 'create' ? '提交并打印' : '保存修改' }}
|
{{ dialogStatus === 'create' ? '提交并打印' : '保存修改' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -666,6 +668,10 @@ const dialogStatus = ref<'create' | 'update'>('create')
|
|||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
|
|
||||||
|
// 上传锁定状态
|
||||||
|
const isUploading = ref(false)
|
||||||
|
|
||||||
const queryParams = reactive({ page: 1, pageSize: 50, keyword: '', searchField: 'all', sku: '', category: '', material_type: '', statuses: ['在库', '借库'], company: '', orderByColumn: '', isAsc: '', advancedFilters: [] })
|
const queryParams = reactive({ page: 1, pageSize: 50, keyword: '', searchField: 'all', sku: '', category: '', material_type: '', statuses: ['在库', '借库'], company: '', orderByColumn: '', isAsc: '', advancedFilters: [] })
|
||||||
const categoryOptions = ref<string[]>([])
|
const categoryOptions = ref<string[]>([])
|
||||||
const typeOptions = ref<string[]>([])
|
const typeOptions = ref<string[]>([])
|
||||||
@ -1269,12 +1275,14 @@ const beforeAvatarUpload = (rawFile: any) => {
|
|||||||
const customUpload = async (options: any, targetField: 'arrival_photo' | 'quality_report_link') => {
|
const customUpload = async (options: any, targetField: 'arrival_photo' | 'quality_report_link') => {
|
||||||
const { file, onSuccess, onError } = options
|
const { file, onSuccess, onError } = options
|
||||||
const formData = new FormData(); formData.append('file', file)
|
const formData = new FormData(); formData.append('file', file)
|
||||||
|
isUploading.value = true
|
||||||
try {
|
try {
|
||||||
const res: any = await uploadFile(formData)
|
const res: any = await uploadFile(formData)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
const newUrl = res.data.url; form[targetField].push(newUrl); ElMessage.success('上传成功'); onSuccess(res)
|
const newUrl = res.data.url; form[targetField].push(newUrl); ElMessage.success('上传成功'); onSuccess(res)
|
||||||
} else { ElMessage.error(res.msg || '上传失败'); onError(new Error(res.msg)) }
|
} else { ElMessage.error(res.msg || '上传失败'); onError(new Error(res.msg)) }
|
||||||
} catch (e) { ElMessage.error('网络错误'); onError(e) }
|
} catch (e) { ElMessage.error('网络错误'); onError(e) }
|
||||||
|
finally { isUploading.value = false }
|
||||||
}
|
}
|
||||||
const handleRemoveImage = async (uploadFile: any, targetField: 'arrival_photo' | 'quality_report_link') => {
|
const handleRemoveImage = async (uploadFile: any, targetField: 'arrival_photo' | 'quality_report_link') => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user