From 031a187db2013472dbcb9fbe3a31004af805b023 Mon Sep 17 00:00:00 2001
From: "huojin\\hj" <982011>
Date: Tue, 29 Jul 2025 16:30:49 +0800
Subject: [PATCH] =?UTF-8?q?=E5=85=A5=E5=BA=93=E5=AF=BC=E5=85=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api/importData.js | 12 +
src/components/Crud/CRUD.operation.vue | 61 +++-
src/layout/index.vue | 24 +-
src/views/business-asn/asn/index.vue | 464 ++++++++++++++++++++-----
4 files changed, 434 insertions(+), 127 deletions(-)
create mode 100644 src/api/importData.js
diff --git a/src/api/importData.js b/src/api/importData.js
new file mode 100644
index 0000000..0870ffc
--- /dev/null
+++ b/src/api/importData.js
@@ -0,0 +1,12 @@
+import request from '@/utils/request'
+
+// 导入相关API
+export function importAsnData(data) {
+ return request({
+ url: 'api/importData/importAsn',
+ method: 'post',
+ data
+ })
+}
+
+export default { importAsnData }
diff --git a/src/components/Crud/CRUD.operation.vue b/src/components/Crud/CRUD.operation.vue
index 60b5a20..6463c85 100644
--- a/src/components/Crud/CRUD.operation.vue
+++ b/src/components/Crud/CRUD.operation.vue
@@ -180,35 +180,64 @@ export default {
},
methods: {
-
initcolumn() {
this.updateTableColumns()
- const strHidden=sessionStorage.getItem(this.tableKey)
- this.hiddenColumns= JSON.parse(strHidden);
- if(this.hiddenColumns.length>0){
- console.log("------移除---------------")
+ const strHidden = sessionStorage.getItem(this.tableKey)
+
+ // 检查 sessionStorage 值是否存在
+ if (!strHidden) {
+ this.hiddenColumns = []
+ return
+ }
+
+ // 安全解析 JSON 数据
+ try {
+ this.hiddenColumns = JSON.parse(strHidden) || []
+ } catch (error) {
+ this.hiddenColumns = []
+ return
+ }
+
+ if (this.hiddenColumns.length > 0) {
const table = this.crud.props.table
- this.table_configs_xs.forEach((column,index) => {
- const vm = table.$children.find(e => e.label === column.label)
+
+ // 预先构建 label 到 column 的映射,提高查找效率
+ const labelToColumnMap = {}
+ if (table && table.$children) {
+ table.$children.forEach(child => {
+ if (child.label) {
+ labelToColumnMap[child.label] = child
+ }
+ })
+ }
+
+ this.table_configs_xs.forEach((column, index) => {
+ const vm = labelToColumnMap[column.label]
+
+ // 检查元素是否存在
+ if (!vm) {
+ return
+ }
const columnConfig = vm.columnConfig
+ // 检查 columnConfig 是否有效
+ if (!columnConfig) {
+ return
+ }
- console.log(columnConfig)
- vm.owner.store.commit('removeColumn', columnConfig, null)
-
+ if (vm.owner && vm.owner.store) {
+ vm.owner.store.commit('removeColumn', columnConfig, null)
+ }
})
+
this.ignoreNextTableColumnsChange = false
- console.log("--------移除完成-------------")
+
setTimeout(() => {
// 方法区
- this.showcolumn();
+ this.showcolumn()
}, 200)
}
-
- //vm.owner.store.commit('insertColumn', columnConfig, newIndex+myindex + 1 , null)
-
-
},
showcolumn() {
console.log("------显示列------")
diff --git a/src/layout/index.vue b/src/layout/index.vue
index 58afe12..f443245 100644
--- a/src/layout/index.vue
+++ b/src/layout/index.vue
@@ -69,26 +69,14 @@ export default {
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
},
getTableConfig() {
- // eslint-disable-next-line no-unused-vars
- // console.log("-----------------")
crudTableConfig.gettables().then(res => {
-
- this.table_configs = res.map(function (obj) {
-
- return obj
- })
- console.log("-------------加载Table配置数量:"+this.table_configs.length+"---------")
+ this.table_configs = res.map(obj => obj);
+ console.log("-------------加载Table配置数量:" + this.table_configs.length + "---------");
this.table_configs.forEach(config => {
- sessionStorage.removeItem(config.tableType)
- sessionStorage.setItem(config.tableType,config.value)
- })
-
- //sessionStorage.setItem(tableKey, res.value)
-
- //var tableKey
- // eslint-disable-next-line no-unused-vars
- const hiddenColumns = JSON.parse(sessionStorage.getItem(tableKey))
- })
+ sessionStorage.removeItem(config.tableType);
+ sessionStorage.setItem(config.tableType, config.value);
+ });
+ });
}
}
}
diff --git a/src/views/business-asn/asn/index.vue b/src/views/business-asn/asn/index.vue
index b697fcc..2aca631 100644
--- a/src/views/business-asn/asn/index.vue
+++ b/src/views/business-asn/asn/index.vue
@@ -4,11 +4,13 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+ 导入
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
模板说明:
+
适用于标准导入,包含INVOICE NO.、BOI、PO&LN NO.、PART
+ NO.、DESCRIPTION、Q'TY 、C/NO.
+
下载模板
+
+
+
+ 将文件拖到此处,或点击上传
+ 注意:更新文件后请重新上传(支持.xlsx, .xls,
+ .csv 格式文件)
+
+
+
+
+
+
+
+
+
模板说明:
+
适用于大物导入,包含INVOICE NO.、BOI、PO&LN NO.、PART
+ NO.、DESCRIPTION、Q'TY 、C/NO.
+
+
+
+ 将文件拖到此处,或点击上传
+ 注意:更新文件后请重新上传(支持.xlsx, .xls,
+ .csv 格式文件)
+
+
+
+
+
+
+
+
+
模板说明:
+
适用于空运发票箱单导入,包含INVOICE NO.、BOI、PO&LN NO.、PART
+ NO.、DESCRIPTION、Q'TY 、C/NO.
+
+
+
+ 将文件拖到此处,或点击上传
+ 注意:更新文件后请重新上传(支持.xlsx, .xls,
+ .csv 格式文件)
+
+
+
+
+
+
+
+
-
+
@@ -197,7 +305,7 @@
- {{scope.row.billType.name}}
+ {{ scope.row.billType.name }}
@@ -207,12 +315,12 @@
- {{formatDate1(scope.row.orderDate)}}
+ {{ formatDate1(scope.row.orderDate) }}
- {{ formatDate1(scope.row.receivedDate)}}
+ {{ formatDate1(scope.row.receivedDate) }}
@@ -220,10 +328,11 @@
- {{ formatDate1(scope.row.createTime)}}
+ {{ formatDate1(scope.row.createTime) }}
-
+
import DateRangePicker from "@/components/DateRangePicker/index.vue";
-import crudAsn, { getCodeNo, queryAsnAll, save } from '@/api/asn'
-import CRUD, { presenter, header, form, crud } from '@crud/crud'
+import crudAsn, {getCodeNo, queryAsnAll, save} from '@/api/asn'
+import importData from '@/api/importData'
+import CRUD, {presenter, header, form, crud} from '@crud/crud'
import rrOperation from '@crud/RR.operation.vue'
import crudOperation from '@crud/CRUD.operation.vue'
import udOperation from '@crud/UD.operation.vue'
import pagination from '@crud/Pagination.vue'
-import { getAreas } from '@/api/area'
-import { getBillType } from '@/api/billType'
-import { add, invVerify, queryAsnDetailAll } from '@/api/asnDetail'
-import { queryPointList } from '@/api/point'
-import { queryItemAll } from '@/api/item'
-import { formatDate } from '@/utils/commonUtils'
+import {getAreas} from '@/api/area'
+import {getBillType} from '@/api/billType'
+import {add, invVerify, queryAsnDetailAll} from '@/api/asnDetail'
+import {queryPointList} from '@/api/point'
+import {queryItemAll} from '@/api/item'
+import {formatDate} from '@/utils/commonUtils'
+import UploadExcelComponent from '@/components/UploadExcel/index.vue'
const defaultForm = {
id: null,
@@ -295,12 +406,12 @@ const defaultForm = {
}
export default {
name: 'Asn',
- components: { pagination, crudOperation, rrOperation, udOperation,DateRangePicker },
+ components: {pagination, crudOperation, rrOperation, udOperation, DateRangePicker, UploadExcelComponent},
mixins: [presenter(), header(), form(defaultForm), crud()],
dicts: ['asn_status'],
cruds() {
return CRUD({
- title: 'asn', url: 'api/asn', idField: 'id', sort: 'id,desc', crudMethod: { ...crudAsn }, optShow: {
+ title: 'asn', url: 'api/asn', idField: 'id', sort: 'id,desc', crudMethod: {...crudAsn}, optShow: {
add: false,
edit: false,
del: true,
@@ -319,22 +430,23 @@ export default {
del: ['admin', 'asn:del'],
invVerify: ['admin', 'asn:invVerify'],
inserAsn: ['admin', 'asn:inserAsn'],
+ import: ['admin', 'asn:import'],
},
rules: {
code: [
- { required: true, message: '单号不能为空', trigger: 'blur' }
+ {required: true, message: '单号不能为空', trigger: 'blur'}
],
area: [
- { required: true, message: '库区不能为空', trigger: 'blur' }
+ {required: true, message: '库区不能为空', trigger: 'blur'}
],
orderDate: [
- { required: true, message: '订单日期不能为空', trigger: 'blur' }
+ {required: true, message: '订单日期不能为空', trigger: 'blur'}
]
},
queryTypeOptions: [
- { key: 'code', display_name: '单号' },
- { key: 'areaCode', display_name: '库区' },
- { key: 'status', display_name: '状态查询' },
+ {key: 'code', display_name: '单号'},
+ {key: 'areaCode', display_name: '库区'},
+ {key: 'status', display_name: '状态查询'},
],
areaOptions: [],
billTypeOptions: [],
@@ -405,7 +517,14 @@ export default {
itemListData: [],
pointList: [],
asnOptions: [],
- invVerifySTF:true
+ invVerifySTF: true,
+ // 导入相关数据
+ importDialogVisible: false,
+ activeImportTab: 'template1',
+ importLoading: false,
+ fileList1: [], // 用于存储当前文件
+ fileList2: [],
+ fileList3: []
}
},
mounted() {
@@ -422,7 +541,7 @@ export default {
[CRUD.HOOK.beforeRefresh]() {
return true
},
- formatDate1(value){
+ formatDate1(value) {
return formatDate(value);
// const date = new Date(value)
// const year = date.getUTCFullYear()
@@ -448,7 +567,7 @@ export default {
},
//新增加的开关
inserAsnOnOffM(data) {
- this.$router.push({path:'/business-asn/viewAsnDetail'})
+ this.$router.push({path: '/business-asn/viewAsnDetail'})
// this.inserAsnOnOff = true
// let no = null
// for (const billTypDateElement of this.billTypeOptions) {
@@ -479,7 +598,7 @@ export default {
crudAsn.add(data).then(res => {
this.$message.success('新增成功')
this.inserAsnOnOff = false
- this.asnFrom=defaultForm;
+ this.asnFrom = defaultForm;
this.crud.toQuery()
})
},
@@ -509,77 +628,236 @@ export default {
this.asnOptions = res
})
},
- asnDetailRouter(datas){
- this.$router.push({path:'/business-asn/viewAsnDetail',query: {ids:datas.id}})
+ asnDetailRouter(datas) {
+ this.$router.push({path: '/business-asn/viewAsnDetail', query: {ids: datas.id}})
},
//入库批量确认
- invVerifyS(data){
+ invVerifyS(data) {
console.log(data)
let ids = [];
for (const idsKey of data) {
ids.push(idsKey.id);
}
- invVerify(ids).then(res=>{
+ invVerify(ids).then(res => {
// if (res != null){
// this.$message.error(res)
// }else {
- this.$message.success(res)
- this.crud.toQuery()
+ this.$message.success(res)
+ this.crud.toQuery()
// }
- }).catch(e=>{
+ }).catch(e => {
this.$message.error(e)
})
},
- invVerifySTFM(selection, row){
- if (selection.length>0){
+ invVerifySTFM(selection, row) {
+ if (selection.length > 0) {
this.invVerifySTF = false;
- }else {
+ } else {
return
}
//判断
for (const selectionElement of selection) {
//打开/收货中
- if (!(selectionElement.status === 'OPEN' || selectionElement.status === 'RECEIVING')){
+ if (!(selectionElement.status === 'OPEN' || selectionElement.status === 'RECEIVING')) {
this.invVerifySTF = true;
}
}
},
- invVerifySTFAll(selection){
- if (selection.length>0){
+ invVerifySTFAll(selection) {
+ if (selection.length > 0) {
this.invVerifySTF = false;
- }else {
+ } else {
return
}
//判断
for (const selectionElement of selection) {
//打开/收货中
- if (!(selectionElement.status === 'OPEN' || selectionElement.status === 'RECEIVING')){
+ if (!(selectionElement.status === 'OPEN' || selectionElement.status === 'RECEIVING')) {
this.invVerifySTF = true;
}
}
- }
- /**
- * 根据条件禁用行复选框
- * 函数返回值为false则禁用选择(反之亦然)
- * @param {Object} row - 行数据
- * @param {String} index - 索引值
- * @return Boolean
- */
- // selectable: function(row, index) {
- // // 地址不是 "秦皇岛市海港区居民" 才能被选中
- // // if(row.receivedDate != null){
- // // return false;
- // // }
- // return !(row.status != null);
- // // 函数必须有返回值且是布尔值
- // // 页面刷新后该函数会执行 N 次进行判断(N 为表格行数)
- // // 如果没有返回值则默认返回false(全部无法选中)
- // },
+ },
+ // 导入相关方法
+ showImportDialog() {
+ this.importDialogVisible = true
+ },
+
+ downloadTemplate(templateType) {
+ const templateConfig = {
+ template1: {
+ filename: '标准导入模板.xlsx',
+ headers: ['INVOICE NO.', 'BOI', 'PO&LN NO.', 'PART NO.', 'DESCRIPTION', 'Q\'TY ', 'C/NO.'],
+ sampleData: [
+ ['KCWT04108SM', 'EXP -', '7291-5366', 'RD829-6640-7', 'ASSY BRACKET,SWING', '3', '7074786'],
+ ['KCWT04108SM', 'EXP -', '7291-5366', 'RD829-6640-7', 'ASSY BRACKET,SWING', '3', '7074785']
+ ]
+ }
+ }
+ const config = templateConfig[templateType]
+ if (!config) {
+ this.$message.error('模板类型不存在')
+ return
+ }
+
+ // 创建Excel文件并下载
+ this.createAndDownloadExcel(config)
+ },
+
+ createAndDownloadExcel(config) {
+ // 这里需要引入XLSX库来创建Excel文件
+ // 由于项目可能没有XLSX,我们使用简单的CSV格式
+ let csvContent = '\uFEFF' // BOM for UTF-8
+ csvContent += config.headers.join(',') + '\n'
+
+ config.sampleData.forEach(row => {
+ csvContent += row.join(',') + '\n'
+ })
+
+ const blob = new Blob([csvContent], {type: 'text/csv;charset=utf-8;'})
+ const link = document.createElement('a')
+ const url = URL.createObjectURL(blob)
+ link.setAttribute('href', url)
+ link.setAttribute('download', config.filename.replace('.xlsx', '.csv'))
+ link.style.visibility = 'hidden'
+ document.body.appendChild(link)
+ link.click()
+ document.body.removeChild(link)
+ },
+
+ async confirmImport() {
+ // 校验当前tab是否有文件
+ let hasFile = false;
+ let fileName = '';
+ let currentFile = null; // 新增变量存储文件对象
+
+ if (this.activeImportTab === 'template1') {
+ hasFile = this.fileList1.length > 0;
+ if (hasFile) {
+ currentFile = this.fileList1[0]; // 获取文件对象
+ fileName = currentFile.name;
+ }
+ } else if (this.activeImportTab === 'template2') {
+ hasFile = this.fileList2.length > 0;
+ if (hasFile) {
+ currentFile = this.fileList2[0];
+ fileName = currentFile.name;
+ }
+ } else if (this.activeImportTab === 'template3') {
+ hasFile = this.fileList3.length > 0;
+ if (hasFile) {
+ currentFile = this.fileList3[0];
+ fileName = currentFile.name;
+ }
+ }
+
+ if (!hasFile || !currentFile) {
+ this.$message.warning('请先上传文件');
+ return;
+ }
+
+ this.importLoading = true;
+ console.log('开始导入...' + this.activeImportTab + '文件:' + fileName);
+
+ const formData = new FormData();
+ // 修复:使用 currentFile.raw 获取原始文件对象
+ formData.append('file', currentFile.raw);
+ formData.append('templateType', this.activeImportTab);
+
+ const response = await importData.importAsnData(formData);
+ if (response.status === 200) {
+ this.crud.notify(response.message, CRUD.NOTIFICATION_TYPE.SUCCESS)
+ this.importDialogVisible = false;
+ this.importLoading = false;
+ this.crud.toQuery(); // 刷新列表
+ // 清空所有fileList
+ this.fileList1 = [];
+ this.fileList2 = [];
+ this.fileList3 = [];
+ } else {
+ this.crud.notify(response.message, CRUD.NOTIFICATION_TYPE.ERROR)
+ }
+
+ },
+ cancelImport() {
+ this.fileList1 = [];
+ this.fileList2 = [];
+ this.fileList3 = [];
+ this.importDialogVisible = false
+ },
+ // el-upload专用:校验文件大小和类型
+ beforeExcelUpload(file) {
+ const isExcel = /\.(xlsx|xls|csv)$/.test(file.name)
+ const isLt2M = file.size / 1024 / 1024 < 2
+ if (!isExcel) {
+ this.$message.error('只支持.xlsx, .xls, .csv 格式文件')
+ return false
+ }
+ if (!isLt2M) {
+ this.$message.error('文件大小不能超过2MB')
+ return false
+ }
+ return false
+ },
+ // el-upload专用:文件列表改变时;显示最新的文件
+ handleExcelChange(file, fileList) {
+ // 只保留当前tab的文件,其它tab清空
+ if (this.activeImportTab === 'template1') {
+ this.fileList1 = [file];
+ this.fileList2 = [];
+ this.fileList3 = [];
+ } else if (this.activeImportTab === 'template2') {
+ this.fileList1 = [];
+ this.fileList2 = [file];
+ this.fileList3 = [];
+ } else if (this.activeImportTab === 'template3') {
+ this.fileList1 = [];
+ this.fileList2 = [];
+ this.fileList3 = [file];
+ }
+ },
+ // el-upload专用:文件移除
+ handleExcelRemove() {
+ if (this.activeImportTab === 'template1') {
+ this.fileList1 = [];
+ } else if (this.activeImportTab === 'template2') {
+ this.fileList2 = [];
+ } else if (this.activeImportTab === 'template3') {
+ this.fileList3 = [];
+ }
+ },
}
}