Browse Source

YT-302: 纳入受领书并对比代码

intex_online20241111
ljlong_2630 2 weeks ago
parent
commit
5b56b38f80
  1. 251
      src/components/ImportForm/src/ImportFormStep.vue
  2. 81
      src/views/wms/deliversettlementManage/inducedProduct/deliverRecordMain/deliverRecordMain.data.ts
  3. 22
      src/views/wms/deliversettlementManage/inducedProduct/deliverRecordMain/index.vue

251
src/components/ImportForm/src/ImportFormStep.vue

@ -18,14 +18,10 @@
<el-upload <el-upload
ref="uploadRef" ref="uploadRef"
v-model:file-list="fileList" v-model:file-list="fileList"
:action="importUrl"
:auto-upload="false" :auto-upload="false"
:disabled="formLoading" :disabled="formLoading"
:headers="uploadHeaders"
:limit="1" :limit="1"
:on-error="submitFormError"
:on-exceed="handleExceed" :on-exceed="handleExceed"
:on-success="submitFormSuccess"
:accept="accept" :accept="accept"
drag drag
style="width: 300px; margin: 0px auto 0px" style="width: 300px; margin: 0px auto 0px"
@ -51,13 +47,14 @@
</template> </template>
</el-upload> </el-upload>
</div> </div>
<div v-else-if="active == 1"> <div v-if="active == 1">
<div class="red"> <div class="red">
<el-icon color="#E44033" size="18" style="margin-right: 6px;"><WarningFilled /></el-icon> <el-icon color="#E44033" size="18" style="margin-right: 6px;"><WarningFilled /></el-icon>
纳入受领书数量与顺引发货记录数量不一致无法导入以下是差异数据 纳入受领书数量与顺引发货记录数量不一致无法导入以下是差异数据
</div> </div>
<!-- <Table v-clientTable
:columns="tableColumns" <Table v-clientTable
:columns="Array.isArray(currentColumns) ? currentColumns : []"
:data="tableObject.tableList" :data="tableObject.tableList"
:loading="tableObject.loading" :loading="tableObject.loading"
:pagination="{ :pagination="{
@ -66,7 +63,7 @@
v-model:pageSize="tableObject.pageSize" v-model:pageSize="tableObject.pageSize"
v-model:currentPage="tableObject.currentPage" v-model:currentPage="tableObject.currentPage"
v-model:sort="tableObject.sort" v-model:sort="tableObject.sort"
/> --> />
</div> </div>
<div v-else-if="active == 2" class="success"> <div v-else-if="active == 2" class="success">
<el-icon color="#409eff" size="60"><CircleCheckFilled /></el-icon> <el-icon color="#409eff" size="60"><CircleCheckFilled /></el-icon>
@ -77,7 +74,7 @@
<template #footer> <template #footer>
<div class="flex items-center"> <div class="flex items-center">
<div class="flex-1 text-left"> <div class="flex-1 text-left">
<el-button type="primary" plain @click="importTemplate" v-if="active == 0"> <el-button type="primary" plain @click="importTemplate" v-if="active == 0 && isShowDownloadBtn">
<Icon icon="ep:download" /> <Icon icon="ep:download" />
{{ t('ts.下载模板') }} {{ t('ts.下载模板') }}
</el-button> </el-button>
@ -93,17 +90,18 @@
</template> </template>
</Dialog> </Dialog>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { getAccessToken, getTenantId } from '@/utils/auth' import { getAccessToken, getTenantId } from '@/utils/auth'
import download from '@/utils/download' import download from '@/utils/download'
import { getBaseUrl } from '@/utils/systemParam' import { getBaseUrl } from '@/utils/systemParam'
import { UploadFilled, List, CircleCheckFilled,WarningFilled } from '@element-plus/icons-vue' import { UploadFilled, List, CircleCheckFilled,WarningFilled } from '@element-plus/icons-vue'
import { waitForDebugger } from 'node:inspector/promises'
defineOptions({ name: 'ImportForm' }) defineOptions({ name: 'ImportForm' })
const { t } = useI18n()
const { t } = useI18n()
const message = useMessage() // const message = useMessage() //
const dialogVisible = ref(false) // const dialogVisible = ref(false) //
const formLoading = ref(false) // const formLoading = ref(false) //
const uploadRef = ref() const uploadRef = ref()
@ -145,38 +143,78 @@ const props = defineProps({
active: { active: {
type: Number, type: Number,
required: false, required: false,
default: 1 default: 0
}, },
tableColumns: { successTableColumns: {
type: Array, type: Array,
required: false, required: false,
default: () => [] default: () => [],
validator: (value: any) => Array.isArray(value)
},
errorTableColumns: {
type: Array,
required: false,
default: () => [],
validator: (value: any) => Array.isArray(value)
}, },
tableObject: { tableObject: {
type: Object, type: Object,
required: false, required: false,
default: null default: () => ({
tableList: [],
loading: false,
total: 0,
pageSize: 10,
currentPage: 1,
sort: {}
})
},
//
isShowDownloadBtn: {
type: Boolean,
required: false,
default: true
}, },
}) })
// tableObject
const tableObject = computed(() => props.tableObject)
const importTemplateData = ref(props.importTemplateData) const importTemplateData = ref(props.importTemplateData)
const accept = ref(props.accept) const accept = ref(props.accept)
const formSchema = ref(props.formSchema) const formSchema = ref(props.formSchema)
const rules = ref(props.rules) const rules = ref(props.rules)
const importUrl = ref('') const importUrl = ref('')
const active = ref(props.active)
/** 打开弹窗 */ /** 打开弹窗 */
const open = () => { const open = () => {
dialogVisible.value = true dialogVisible.value = true
resetForm() resetForm()
active.value = 0 //
//
if (props.tableObject) {
props.tableObject.tableList = []
props.tableObject.total = 0
props.tableObject.currentPage = 1
}
} }
defineExpose({ open }) // open defineExpose({ open }) // open
const formRef = ref() const formRef = ref()
/** 提交表单 */ /** 提交表单 */
const submitForm = async () => { const submitForm = async () => {
const elForm = unref(formRef)?.getElFormRef() //
if (active.value === 1) {
active.value = 2
return
}
const elForm = unref(formRef)?.getElFormRef()
// //
if (!elForm) return if (!elForm) return
const valid = await elForm.validate() const valid = await elForm.validate()
if (!valid) return if (!valid) return
const data = unref(formRef)?.formModel const data = unref(formRef)?.formModel
@ -184,18 +222,47 @@ const submitForm = async () => {
message.error('请上传文件') message.error('请上传文件')
return return
} }
file.value = fileList.value[0].name //
importUrl.value = getBaseUrl() + import.meta.env.VITE_API_URL + props.url + '?file=' + file.value const fileReader = new FileReader()
formSchema.value.forEach(item => { const originalFile = fileList.value[0].raw
importUrl.value += `&${item.field}=${data[item.field]||''}` fileReader.onload = async () => {
}) try {
// //
uploadHeaders.value = { const arrayBuffer = fileReader.result as ArrayBuffer
Authorization: 'Bearer ' + getAccessToken(), // FormData
'tenant-id': getTenantId() const formData = new FormData()
// BlobFormData
const blob = new Blob([arrayBuffer], { type: originalFile.type })
formData.append('file', blob, originalFile.name)
//
formSchema.value.forEach(item => {
formData.append(item.field, data[item.field] || '')
})
//
const headers = {
Authorization: 'Bearer ' + getAccessToken(),
'tenant-id': getTenantId()
}
formLoading.value = true
//
const response = await fetch(getBaseUrl() + import.meta.env.VITE_API_URL + props.url, {
method: 'POST',
headers: headers,
body: formData
})
const result = await response.json()
submitFormSuccess(result)
} catch (error) {
submitFormError()
console.error('上传失败:', error)
}
}
fileReader.onerror = () => {
message.error('文件读取失败')
formLoading.value = false
} }
formLoading.value = true //
uploadRef.value!.submit() fileReader.readAsArrayBuffer(originalFile)
} }
/** 文件上传成功 */ /** 文件上传成功 */
@ -212,57 +279,84 @@ const submitFormSuccess = (response: any) => {
} else if (response.code == 0) { } else if (response.code == 0) {
if (response.data.errorCount > 0) { if (response.data.errorCount > 0) {
message.confirm('文件中有部分数据导入失败,是否下载失败数据?').then(() => { message.confirm('文件中有部分数据导入失败,是否下载失败数据?').then(() => {
// download.excel(file, 'file_' + new Date().getTime()) fetch(getBaseUrl() + '/admin-api' + response.data.errorFile)
// url .then(res => res.blob())
// const downloadElement = document.createElement('a') .then(blob => {
// console.log(172, getBaseUrl() + import.meta.env.VITE_API_URL + '/' + response.data.errorFile) const url = window.URL.createObjectURL(blob);
// console.log(172, getBaseUrl() + '/admin-api/opt/profile/' + response.data.errorFile) const a = document.createElement('a');
window.open( a.style.display = 'none';
getBaseUrl() + '/admin-api' + response.data.errorFile, a.href = url;
'222' if(response.data.errorFileName&&response.data.errorFileName!=''){
) a.download = response.data.errorFileName;
// downloadElement.setAttribute('href', getBaseUrl() + import.meta.env.VITE_API_URL + response.data.errorFile ) }else{
// a.download = 'error_file.txt';
// downloadElement.click() }
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
});
}) })
} else { } else {
message.success('导入成功') message.success('导入成功')
if(response.data?.successData?.failList&&response.data?.successData?.failList.length>0) {
console.log('设置差异数据:', response.data.successData.failList);
console.log('使用的列定义:', props.errorTableColumns);
props.tableObject.tableList = response.data.successData.failList;
props.tableObject.total = response.data.successData.failList.length;
active.value = 1;
} else {
console.log('设置成功数据:', response.data.successData.successList);
console.log('使用的列定义:', props.successTableColumns);
props.tableObject.tableList = response.data.successData.successList;
props.tableObject.total = response.data.successData.successList.length;
active.value = 1;
}
} }
}else if(response.data == null){ } else if(response.data == null) {
message.error(response.msg) message.error(response.msg)
} }
} }
// if (response.code !== 0) {
// message.error(response.msg)
// formLoading.value = false
// return
// }
// //
// const data = response.data
// const create = response.data.importResult[0]
// const update = response.data.importResult[1]
// const failure = response.data.importResult[2]
// let text = '' + data[create].length + ';'
// for (let name of data[create]) {
// text += '< ' + name + ' >'
// }
// text += '' + data[update].length + ';'
// for (const name of data[update]) {
// text += '< ' + name + ' >'
// }
// text += '' + Object.keys(data[failure]).length + ';'
// for (const name in data[failure]) {
// text += '< ' + name + ': ' + data[failure][name] + ' >'
// }
// message.alert(text)
//
formLoading.value = false formLoading.value = false
emits('success') emits('success')
dialogVisible.value = false
} }
//
const currentColumns = computed(() => {
console.log('当前 active:', active.value);
console.log('tableList:', props.tableObject?.tableList);
console.log('errorTableColumns:', props.errorTableColumns);
console.log('successTableColumns:', props.successTableColumns);
// active === 1
if (active.value !== 1) {
return [];
}
//
const hasFailData = props.tableObject?.tableList?.some(item =>
// difference
item.hasOwnProperty('difference')
);
let columns = [];
if (hasFailData) {
// 使
columns = Array.isArray(props.errorTableColumns?.allSchemas?.tableColumns)
? props.errorTableColumns?.allSchemas?.tableColumns
: [];
console.log('使用错误数据列');
} else {
// 使
columns = Array.isArray(props.successTableColumns?.allSchemas?.tableColumns)
? props.successTableColumns?.allSchemas?.tableColumns
: [];
console.log('使用成功数据列');
}
console.log('最终使用的列:', columns);
return columns;
});
/** 上传错误提示 */ /** 上传错误提示 */
const submitFormError = (): void => { const submitFormError = (): void => {
message.error('上传失败,请您重新上传!') message.error('上传失败,请您重新上传!')
@ -282,6 +376,20 @@ const handleExceed = (): void => {
message.error('最多只能上传一个文件!') message.error('最多只能上传一个文件!')
} }
//
watch(() => props.tableObject?.tableList, (newVal) => {
console.log('tableList 发生变化:', newVal);
}, { deep: true });
//
watch(() => props.errorTableColumns, (newVal) => {
console.log('errorTableColumns 发生变化:', newVal);
}, { deep: true });
watch(() => props.successTableColumns, (newVal) => {
console.log('successTableColumns 发生变化:', newVal);
}, { deep: true });
/** 下载模板操作 */ /** 下载模板操作 */
const importTemplate = () => { const importTemplate = () => {
const res = importTemplateData.value.templateUrl const res = importTemplateData.value.templateUrl
@ -297,7 +405,6 @@ const importTemplate = () => {
div { div {
position: relative; position: relative;
padding-left: 22px; padding-left: 22px;
&::before { &::before {
width: 4px; width: 4px;
height: 4px; height: 4px;

81
src/views/wms/deliversettlementManage/inducedProduct/deliverRecordMain/deliverRecordMain.data.ts

@ -884,7 +884,7 @@ export const DeliverRecordImport = useCrudSchemas(reactive<CrudSchema[]>([
}, },
{ {
label: '开始日期', label: '开始日期',
field: 'startData', field: 'startDate',
sort: 'custom', sort: 'custom',
form: { form: {
component: 'DatePicker', component: 'DatePicker',
@ -898,7 +898,7 @@ export const DeliverRecordImport = useCrudSchemas(reactive<CrudSchema[]>([
}, },
{ {
label: '结束日期', label: '结束日期',
field: 'finishData', field: 'endDate',
sort: 'custom', sort: 'custom',
form: { form: {
component: 'DatePicker', component: 'DatePicker',
@ -924,7 +924,7 @@ export const DeliverRecordImport = useCrudSchemas(reactive<CrudSchema[]>([
}, },
{ {
label: '结束序号', label: '结束序号',
field: 'finishNo', field: 'endNo',
sort: 'custom', sort: 'custom',
form: { form: {
component: 'InputNumber', component: 'InputNumber',
@ -935,41 +935,51 @@ export const DeliverRecordImport = useCrudSchemas(reactive<CrudSchema[]>([
}, },
}, },
])) ]))
//导入表单校验 // 导入表单校验
export const DeliverRecordImportRules = reactive({ export const DeliverRecordImportRules = reactive({
customerOrderNumber: [ incorporationNumber: [
{ required: true, message: '请输入单号', trigger: 'blur' } { required: true, message: '请输入纳入受领书单号', trigger: 'blur' }
], ],
startData: [ orderNumber: [
{ required: true, message: '请选择开始日期', trigger: 'change' } { required: true, message: '请输入订单号', trigger: 'blur' }
], ],
finishData: [ type: [
{ required: true, message: '请选择结束日期', trigger: 'change' } { required: true, message: '请选择类型', trigger: 'change' }
], ],
startNo: [ materialCode: [
{ required: true, message: '请输入开始序号', trigger: 'change' } { required: true, message: '请输入物料代码', trigger: 'blur' }
], ],
finishNo: [ backNumber: [
{ required: true, message: '请输入结束序号', trigger: 'change' } { required: true, message: '请输入背番', trigger: 'blur' }
], ],
quantity: [
{ required: true, message: '请输入数量', trigger: 'change' },
{ type: 'number', message: '数量必须为数字', trigger: 'blur' }
]
}) })
/** /**
* @returns {Array} * @returns {Array}
*/ */
export const DeliverRecordImportData = useCrudSchemas(reactive<CrudSchema[]>([ export const ImportLeadershipDocTempData = useCrudSchemas(reactive<CrudSchema[]>([
{ {
label: '纳入受领书单号', label: '纳入受领书单号',
field: 'customerOrderNumber', field: 'incorporationNumber',
sort: 'custom',
},
{
label: '类型',
field: 'type',
sort: 'custom', sort: 'custom',
}, },
{ {
label: '订单号', label: '订单号',
field: 'customerOrderNumber', field: 'orderNumber',
sort: 'custom', sort: 'custom',
}, },
{ {
label: '物料代码', label: '物料代码',
field: 'itemCode', field: 'materialCode',
sort: 'custom', sort: 'custom',
}, },
{ {
@ -979,7 +989,38 @@ export const DeliverRecordImportData = useCrudSchemas(reactive<CrudSchema[]>([
}, },
{ {
label: '数量', label: '数量',
field: 'qty', field: 'quantity',
sort: 'custom',
}
]))
/**
* @returns {Array}
*/
export const ImportLeadershipDocErrorData = useCrudSchemas(reactive<CrudSchema[]>([
{
label: '物料代码',
field: 'materialCode',
sort: 'custom',
},
{
label: '背番',
field: 'backNumber',
sort: 'custom', sort: 'custom',
}, },
{
label: '纳入数量',
field: 'incorporationQuantity',
sort: 'custom',
},
{
label: '发货数量',
field: 'shippedQuantity',
sort: 'custom',
},
{
label: '差异数量',
field: 'difference',
sort: 'custom',
}
])) ]))

22
src/views/wms/deliversettlementManage/inducedProduct/deliverRecordMain/index.vue

@ -61,18 +61,22 @@
/> />
<!-- 导入 --> <!-- 导入 -->
<ImportFormStep <ImportFormStep
ref="importFormRef" ref="importFormRef"
url="/wms/deliver-record-main/import-parse-file" url="/wms/deliver-record-main/import-parse-file"
:importTemplateData="importTemplateData" :importTemplateData="importTemplateData"
:formSchema="DeliverRecordImport.allSchemas.formSchema" :formSchema="DeliverRecordImport.allSchemas.formSchema"
:rules="DeliverRecordImportRules" :rules="DeliverRecordImportRules"
:tableColumns="DeliverRecordImportData.allSchemas.tableColumns" :successTableColumns="ImportLeadershipDocTempData"
@success="importSuccess" /> :errorTableColumns="ImportLeadershipDocErrorData"
@success="importSuccess"
accept=".txt"
:isShowDownloadBtn="false"
/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import download from '@/utils/download' import download from '@/utils/download'
import { getAccessToken } from '@/utils/auth' import { getAccessToken } from '@/utils/auth'
import { DeliverRecordMain,DeliverRecordMainRules,DeliverRecordDetail,DeliverRecordDetailRules,DeliverRecordImport,DeliverRecordImportRules,DeliverRecordImportData } from './deliverRecordMain.data' import { DeliverRecordMain,DeliverRecordMainRules,DeliverRecordDetail,DeliverRecordDetailRules,DeliverRecordImport,DeliverRecordImportRules,ImportLeadershipDocErrorData,ImportLeadershipDocTempData } from './deliverRecordMain.data'
import * as DeliverRecordMainApi from '@/api/wms/deliverRecordMain' import * as DeliverRecordMainApi from '@/api/wms/deliverRecordMain'
import * as DeliverRecordDetailApi from '@/api/wms/deliverRecordDetail' import * as DeliverRecordDetailApi from '@/api/wms/deliverRecordDetail'
import * as defaultButtons from '@/utils/disposition/defaultButtons' import * as defaultButtons from '@/utils/disposition/defaultButtons'
@ -254,7 +258,7 @@ onMounted(async () => {
tableObject.params.businessType = 'inducedProduct' tableObject.params.businessType = 'inducedProduct'
getList() getList()
if(routeName.value == 'InducedProduct'){ if(routeName.value == 'InducedProduct'){
importTemplateData.templateUrl = await DeliverRecordMainApi.importInducedProductTemplate() // importTemplateData.templateUrl = await DeliverRecordMainApi.importInducedProductTemplate()
} }
}) })
</script> </script>

Loading…
Cancel
Save