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
ref="uploadRef"
v-model:file-list="fileList"
:action="importUrl"
:auto-upload="false"
:disabled="formLoading"
:headers="uploadHeaders"
:limit="1"
:on-error="submitFormError"
:on-exceed="handleExceed"
:on-success="submitFormSuccess"
:accept="accept"
drag
style="width: 300px; margin: 0px auto 0px"
@ -51,13 +47,14 @@
</template>
</el-upload>
</div>
<div v-else-if="active == 1">
<div v-if="active == 1">
<div class="red">
<el-icon color="#E44033" size="18" style="margin-right: 6px;"><WarningFilled /></el-icon>
纳入受领书数量与顺引发货记录数量不一致无法导入以下是差异数据
</div>
<!-- <Table v-clientTable
:columns="tableColumns"
<Table v-clientTable
:columns="Array.isArray(currentColumns) ? currentColumns : []"
:data="tableObject.tableList"
:loading="tableObject.loading"
:pagination="{
@ -66,7 +63,7 @@
v-model:pageSize="tableObject.pageSize"
v-model:currentPage="tableObject.currentPage"
v-model:sort="tableObject.sort"
/> -->
/>
</div>
<div v-else-if="active == 2" class="success">
<el-icon color="#409eff" size="60"><CircleCheckFilled /></el-icon>
@ -77,7 +74,7 @@
<template #footer>
<div class="flex items-center">
<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" />
{{ t('ts.下载模板') }}
</el-button>
@ -93,17 +90,18 @@
</template>
</Dialog>
</template>
<script lang="ts" setup>
import { getAccessToken, getTenantId } from '@/utils/auth'
import download from '@/utils/download'
import { getBaseUrl } from '@/utils/systemParam'
import { UploadFilled, List, CircleCheckFilled,WarningFilled } from '@element-plus/icons-vue'
import { waitForDebugger } from 'node:inspector/promises'
defineOptions({ name: 'ImportForm' })
const { t } = useI18n()
const { t } = useI18n()
const message = useMessage() //
const dialogVisible = ref(false) //
const formLoading = ref(false) //
const uploadRef = ref()
@ -145,38 +143,78 @@ const props = defineProps({
active: {
type: Number,
required: false,
default: 1
default: 0
},
tableColumns: {
successTableColumns: {
type: Array,
required: false,
default: () => []
default: () => [],
validator: (value: any) => Array.isArray(value)
},
errorTableColumns: {
type: Array,
required: false,
default: () => [],
validator: (value: any) => Array.isArray(value)
},
tableObject: {
type: Object,
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 accept = ref(props.accept)
const formSchema = ref(props.formSchema)
const rules = ref(props.rules)
const importUrl = ref('')
const active = ref(props.active)
/** 打开弹窗 */
const open = () => {
dialogVisible.value = true
resetForm()
active.value = 0 //
//
if (props.tableObject) {
props.tableObject.tableList = []
props.tableObject.total = 0
props.tableObject.currentPage = 1
}
}
defineExpose({ open }) // open
const formRef = ref()
/** 提交表单 */
const submitForm = async () => {
const elForm = unref(formRef)?.getElFormRef()
//
if (active.value === 1) {
active.value = 2
return
}
const elForm = unref(formRef)?.getElFormRef()
//
if (!elForm) return
const valid = await elForm.validate()
if (!valid) return
const data = unref(formRef)?.formModel
@ -184,18 +222,47 @@ const submitForm = async () => {
message.error('请上传文件')
return
}
file.value = fileList.value[0].name
importUrl.value = getBaseUrl() + import.meta.env.VITE_API_URL + props.url + '?file=' + file.value
formSchema.value.forEach(item => {
importUrl.value += `&${item.field}=${data[item.field]||''}`
})
//
uploadHeaders.value = {
Authorization: 'Bearer ' + getAccessToken(),
'tenant-id': getTenantId()
//
const fileReader = new FileReader()
const originalFile = fileList.value[0].raw
fileReader.onload = async () => {
try {
//
const arrayBuffer = fileReader.result as ArrayBuffer
// FormData
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) {
if (response.data.errorCount > 0) {
message.confirm('文件中有部分数据导入失败,是否下载失败数据?').then(() => {
// download.excel(file, 'file_' + new Date().getTime())
// url
// const downloadElement = document.createElement('a')
// console.log(172, getBaseUrl() + import.meta.env.VITE_API_URL + '/' + response.data.errorFile)
// console.log(172, getBaseUrl() + '/admin-api/opt/profile/' + response.data.errorFile)
window.open(
getBaseUrl() + '/admin-api' + response.data.errorFile,
'222'
)
// downloadElement.setAttribute('href', getBaseUrl() + import.meta.env.VITE_API_URL + response.data.errorFile )
//
// downloadElement.click()
fetch(getBaseUrl() + '/admin-api' + response.data.errorFile)
.then(res => res.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
if(response.data.errorFileName&&response.data.errorFileName!=''){
a.download = response.data.errorFileName;
}else{
a.download = 'error_file.txt';
}
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
});
})
} else {
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){
message.error(response.msg)
}
} else if(response.data == null) {
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
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 => {
message.error('上传失败,请您重新上传!')
@ -282,6 +376,20 @@ const handleExceed = (): void => {
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 res = importTemplateData.value.templateUrl
@ -297,7 +405,6 @@ const importTemplate = () => {
div {
position: relative;
padding-left: 22px;
&::before {
width: 4px;
height: 4px;

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

@ -884,7 +884,7 @@ export const DeliverRecordImport = useCrudSchemas(reactive<CrudSchema[]>([
},
{
label: '开始日期',
field: 'startData',
field: 'startDate',
sort: 'custom',
form: {
component: 'DatePicker',
@ -898,7 +898,7 @@ export const DeliverRecordImport = useCrudSchemas(reactive<CrudSchema[]>([
},
{
label: '结束日期',
field: 'finishData',
field: 'endDate',
sort: 'custom',
form: {
component: 'DatePicker',
@ -924,7 +924,7 @@ export const DeliverRecordImport = useCrudSchemas(reactive<CrudSchema[]>([
},
{
label: '结束序号',
field: 'finishNo',
field: 'endNo',
sort: 'custom',
form: {
component: 'InputNumber',
@ -935,41 +935,51 @@ export const DeliverRecordImport = useCrudSchemas(reactive<CrudSchema[]>([
},
},
]))
//导入表单校验
// 导入表单校验
export const DeliverRecordImportRules = reactive({
customerOrderNumber: [
{ required: true, message: '请输入单号', trigger: 'blur' }
incorporationNumber: [
{ required: true, message: '请输入纳入受领书单号', trigger: 'blur' }
],
startData: [
{ required: true, message: '请选择开始日期', trigger: 'change' }
orderNumber: [
{ required: true, message: '请输入订单号', trigger: 'blur' }
],
finishData: [
{ required: true, message: '请选择结束日期', trigger: 'change' }
type: [
{ required: true, message: '请选择类型', trigger: 'change' }
],
startNo: [
{ required: true, message: '请输入开始序号', trigger: 'change' }
materialCode: [
{ required: true, message: '请输入物料代码', trigger: 'blur' }
],
finishNo: [
{ required: true, message: '请输入结束序号', trigger: 'change' }
backNumber: [
{ 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: '纳入受领书单号',
field: 'customerOrderNumber',
field: 'incorporationNumber',
sort: 'custom',
},
{
label: '类型',
field: 'type',
sort: 'custom',
},
{
label: '订单号',
field: 'customerOrderNumber',
field: 'orderNumber',
sort: 'custom',
},
{
label: '物料代码',
field: 'itemCode',
field: 'materialCode',
sort: 'custom',
},
{
@ -979,7 +989,38 @@ export const DeliverRecordImportData = useCrudSchemas(reactive<CrudSchema[]>([
},
{
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',
},
{
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
ref="importFormRef"
url="/wms/deliver-record-main/import-parse-file"
:importTemplateData="importTemplateData"
:formSchema="DeliverRecordImport.allSchemas.formSchema"
:rules="DeliverRecordImportRules"
:tableColumns="DeliverRecordImportData.allSchemas.tableColumns"
@success="importSuccess" />
ref="importFormRef"
url="/wms/deliver-record-main/import-parse-file"
:importTemplateData="importTemplateData"
:formSchema="DeliverRecordImport.allSchemas.formSchema"
:rules="DeliverRecordImportRules"
:successTableColumns="ImportLeadershipDocTempData"
:errorTableColumns="ImportLeadershipDocErrorData"
@success="importSuccess"
accept=".txt"
:isShowDownloadBtn="false"
/>
</template>
<script setup lang="ts">
import download from '@/utils/download'
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 DeliverRecordDetailApi from '@/api/wms/deliverRecordDetail'
import * as defaultButtons from '@/utils/disposition/defaultButtons'
@ -254,7 +258,7 @@ onMounted(async () => {
tableObject.params.businessType = 'inducedProduct'
getList()
if(routeName.value == 'InducedProduct'){
importTemplateData.templateUrl = await DeliverRecordMainApi.importInducedProductTemplate()
// importTemplateData.templateUrl = await DeliverRecordMainApi.importInducedProductTemplate()
}
})
</script>

Loading…
Cancel
Save