Browse Source

add:物料编码转换导入功能新增

master1
gengby 3 weeks ago
parent
commit
49e535d119
  1. 148
      wms/nladmin-ui/src/views/wms/ivt/stock/UpdateUploadDialog.vue
  2. 120
      wms/nladmin-ui/src/views/wms/ivt/stock/index.vue
  3. 12
      wms/nladmin-ui/src/views/wms/ivt/stock/stock.js
  4. 7
      wms/nlsso-server/src/main/java/org/nl/wms/ivt/controller/StIvtStockDtlController.java
  5. 2
      wms/nlsso-server/src/main/java/org/nl/wms/ivt/service/IStIvtStockDtlService.java
  6. 82
      wms/nlsso-server/src/main/java/org/nl/wms/ivt/service/impl/StIvtStockDtlServiceImpl.java
  7. 2
      wms/nlsso-server/src/main/java/org/nl/wms/schedule/EasBillSchedule.java

148
wms/nladmin-ui/src/views/wms/ivt/stock/UpdateUploadDialog.vue

@ -0,0 +1,148 @@
<template>
<el-dialog
title="导入Excel文件"
append-to-body
:visible.sync="dialogVisible"
destroy-on-close
width="400px"
:show-close="true"
@close="close"
@open="open"
>
<el-upload
ref="upload"
class="upload-demo"
action=""
drag
:on-exceed="is_one"
:limit="1"
:auto-upload="false"
:multiple="false"
:show-file-list="true"
:on-change="uploadByJsqd"
:file-list="fileList"
accept=".xlsx,.xls"
>
<i class="el-icon-upload" />
<div class="el-upload__text">
将文件拖到此处
<em>点击上传</em>
</div>
<div slot="tip" class="el-upload__tip">只能上传Excel文件且不超过10MB</div>
</el-upload>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="submit"> </el-button>
</span>
</el-dialog>
</template>
<script>
import crudStock, { excelUpdateImport } from './stock'
import CRUD, { crud } from '@crud/crud'
import { MessageBox } from 'element-ui'
export default {
name: 'UpdateUploadDialog',
mixins: [crud()],
components: {},
props: {
dialogShow: {
type: Boolean,
default: false
},
openParam: {
type: String
}
},
data() {
return {
dialogVisible: false,
fileList: [],
file1: ''
}
},
watch: {
dialogShow: {
handler(newValue, oldValue) {
this.dialogVisible = newValue
}
},
openParam: {
handler(newValue, oldValue) {
this.opendtlParam = newValue
}
}
},
methods: {
open() {
},
close() {
this.$emit('update:dialogShow', false)
},
is_one() {
this.crud.notify('只能上传一个excel文件!', CRUD.NOTIFICATION_TYPE.WARNING)
},
//
beforeAvatarUpload(file) {
// 2Mb
if (file.size > 10 * 1024 * 1024) {
return false
}
return true
},
//
uploadByJsqd(file) {
this.file1 = file
},
submit() {
if (this.beforeAvatarUpload(this.file1)) {
//
MessageBox.confirm(
'您确定要上传该文件吗?',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
.then(() => {
//
this.fileList.name = this.file1.name
this.fileList.url = ''
var formdata = new FormData()
formdata.append('file', this.file1.raw)
// excelImport formdata
crudStock.excelUpdateImport(formdata).then((res) => {
this.crud.notify('导入成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.$emit('tableChanged4', '')
this.$emit('update:dialogShow', false)
})
})
.catch(() => {
//
this.crud.notify('已取消上传', CRUD.NOTIFICATION_TYPE.INFO)
})
} else {
this.crud.notify('文件过大,请上传小于10MB的文件〜', CRUD.NOTIFICATION_TYPE.WARNING)
}
// if (this.beforeAvatarUpload(this.file1)) {
// this.fileList.name = this.file1.name
// this.fileList.url = ''
// var formdata = new FormData()
// formdata.append('file', this.file1.raw)
// // excelImport formdata
// crudStock.excelImport(formdata).then((res) => {
// this.crud.notify('', CRUD.NOTIFICATION_TYPE.SUCCESS)
// this.$emit('tableChanged3', '')
// this.$emit('update:dialogShow', false)
// })
// } else {
// this.crud.notify('10MB', CRUD.NOTIFICATION_TYPE.WARNING)
// }
}
}
}
</script>

120
wms/nladmin-ui/src/views/wms/ivt/stock/index.vue

@ -46,7 +46,7 @@
@keyup.enter.native="crud.toQuery"
/>
</el-form-item>
<rrOperation/>
<rrOperation />
</el-form>
</div>
<!--如果想在工具栏加入更多按钮可以使用插槽方式 slot = 'left' or 'right'-->
@ -61,6 +61,16 @@
>
导入库存
</el-button>
<el-button
slot="right"
class="filter-item"
type="danger"
icon="el-icon-upload2"
size="mini"
@click="uploadUpdateShow = true"
>
库存编码更新
</el-button>
<el-button
slot="right"
class="filter-item"
@ -84,38 +94,52 @@
<el-form ref="form" :model="form" :rules="rules" size="mini" label-suffix=":" label-width="90px">
<el-row :gutter="20">
<el-col :span="12">
<!-- <el-form-item label="库位编码" prop="struct_code">-->
<!-- <el-input v-model="form.struct_code" style="width: 200px;"/>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="库位编码" prop="struct_code">-->
<!-- <el-input v-model="form.struct_code" style="width: 200px;"/>-->
<!-- </el-form-item>-->
<el-form-item label="库位编码" prop="struct_code">
<el-select filterable clearable style="width: 200px;" v-model="form.struct_code" placeholder="请选择库位编码">
<el-option v-for="item in structs" :key="item.struct_code" :label="item.struct_code" :value="item.struct_code"></el-option>
<el-select v-model="form.struct_code" filterable clearable style="width: 200px;" placeholder="请选择库位编码">
<el-option
v-for="item in structs"
:key="item.struct_code"
:label="item.struct_code"
:value="item.struct_code"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料编码" prop="material_code">
<el-input v-model="form.material_code" style="width: 200px;" @clear="clearMaterial"
@focus="getMaterial"/>
<el-input
v-model="form.material_code"
style="width: 200px;"
@clear="clearMaterial"
@focus="getMaterial"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物料名称" prop="material_name">
<el-input disabled v-model="form.material_name" style="width: 200px;"/>
<el-input v-model="form.material_name" disabled style="width: 200px;" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="数量" prop="qty">
<el-input @input="handleInput" :rules="[{ required: true, validator: validateQty, trigger: 'blur' }]" v-model="form.qty" style="width: 200px;"/>
<el-input
v-model="form.qty"
:rules="[{ required: true, validator: validateQty, trigger: 'blur' }]"
style="width: 200px;"
@input="handleInput"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="计量单位" prop="unit">
<el-input v-model="form.unit" style="width: 200px;"/>
<el-input v-model="form.unit" style="width: 200px;" />
</el-form-item>
</el-col>
<el-col :span="12">
@ -134,7 +158,7 @@
<el-col :span="12">
<el-form-item label="备注">
<label slot="label">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</label>
<el-input v-model="form.remark" style="width: 550px;" rows="2" type="textarea"/>
<el-input v-model="form.remark" style="width: 550px;" rows="2" type="textarea" />
</el-form-item>
</el-col>
</el-row>
@ -154,21 +178,21 @@
@selection-change="crud.selectionChangeHandler"
>
<!-- <el-table-column type="selection" width="55"/>-->
<el-table-column prop="id" label="库存ID" v-if="false" :min-width="flexWidth('id',crud.data,'库存ID')"/>
<el-table-column v-if="false" prop="id" label="库存ID" :min-width="flexWidth('id',crud.data,'库存ID')" />
<el-table-column prop="material_code" label="物料编码" :min-width="flexWidth('material_code',crud.data,'物料编码')">
<template slot-scope="scope">
<el-link type="warning" @click="toView(scope.row)">{{ scope.row.material_code }}</el-link>
</template>
</el-table-column>
<el-table-column prop="material_name" label="物料名称" :min-width="flexWidth('material_name',crud.data,'物料名称')"/>
<el-table-column prop="struct_code" label="仓位编码" :min-width="flexWidth('struct_code',crud.data,'仓位编码')"/>
<el-table-column prop="struct_name" label="仓位名称" :min-width="flexWidth('struct_name',crud.data,'仓位名称')"/>
<el-table-column prop="stor_code" label="仓库编码" :min-width="flexWidth('stor_code',crud.data,'仓库编码')"/>
<el-table-column prop="stor_name" label="仓库名称" :min-width="flexWidth('stor_name',crud.data,'仓库名称')"/>
<el-table-column prop="org_code" label="库存组织编码" :min-width="flexWidth('org_code',crud.data,'库存组织编码')"/>
<el-table-column prop="org_name" label="库存组织名称" :min-width="flexWidth('org_name',crud.data,'库存组织名称')"/>
<el-table-column prop="vehicle_code" label="载具编码" :min-width="flexWidth('vehicle_code',crud.data,'载具编码')"/>
<el-table-column prop="total_qty" label="数量" :min-width="flexWidth('total_qty',crud.data,'数量')"/>
<el-table-column prop="material_name" label="物料名称" :min-width="flexWidth('material_name',crud.data,'物料名称')" />
<el-table-column prop="struct_code" label="仓位编码" :min-width="flexWidth('struct_code',crud.data,'仓位编码')" />
<el-table-column prop="struct_name" label="仓位名称" :min-width="flexWidth('struct_name',crud.data,'仓位名称')" />
<el-table-column prop="stor_code" label="仓库编码" :min-width="flexWidth('stor_code',crud.data,'仓库编码')" />
<el-table-column prop="stor_name" label="仓库名称" :min-width="flexWidth('stor_name',crud.data,'仓库名称')" />
<el-table-column prop="org_code" label="库存组织编码" :min-width="flexWidth('org_code',crud.data,'库存组织编码')" />
<el-table-column prop="org_name" label="库存组织名称" :min-width="flexWidth('org_name',crud.data,'库存组织名称')" />
<el-table-column prop="vehicle_code" label="载具编码" :min-width="flexWidth('vehicle_code',crud.data,'载具编码')" />
<el-table-column prop="total_qty" label="数量" :min-width="flexWidth('total_qty',crud.data,'数量')" />
<!-- <el-table-column prop="remark" label="备注" :min-width="flexWidth('remark',crud.data,'备注')"-->
<!-- show-overflow-tooltip/>-->
<!-- <el-table-column prop="update_name" label="修改人" :min-width="flexWidth('update_name',crud.data,'修改人')"/>-->
@ -189,17 +213,18 @@
<!-- </el-table-column>-->
</el-table>
<!--分页组件-->
<pagination/>
<pagination />
</div>
<ViewDialog ref="itemView"/>
<MaterialDialog :dialog-show.sync="materialDialog" @tableChanged="tableChanged"/>
<UploadDialog :dialog-show.sync="uploadShow" @tableChanged3="tableChanged3"/>
<ViewDialog ref="itemView" />
<MaterialDialog :dialog-show.sync="materialDialog" @tableChanged="tableChanged" />
<UploadDialog :dialog-show.sync="uploadShow" @tableChanged3="tableChanged3" />
<UpdateUploadDialog :dialog-show.sync="uploadUpdateShow" @tableChanged4="tableChanged4" />
</div>
</template>
<script>
import crudStock from '@/views/wms/ivt/stock/stock'
import CRUD, {crud, form, header, presenter} from '@crud/crud'
import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
@ -209,7 +234,7 @@ import crudStruct from '@/views/wms/ivt/struct/structattr'
import MaterialDialog from '@/views/wms/ivt/stock/MaterialDialog.vue'
import ViewDialog from './ViewDialog'
import UploadDialog from './UploadDialog'
import UpdateUploadDialog from './UpdateUploadDialog'
const defaultForm = {
id: null,
@ -232,15 +257,24 @@ const defaultForm = {
export default {
name: 'Stock',
dicts: ['is_used', 'SCH_TASK_TYPE_DTL', 'placement_type'],
components: {pagination, crudOperation, rrOperation, udOperation, MaterialDialog, ViewDialog, UploadDialog},
components: {
pagination,
crudOperation,
rrOperation,
udOperation,
MaterialDialog,
ViewDialog,
UploadDialog,
UpdateUploadDialog
},
mixins: [presenter(), header(), form(defaultForm), crud()],
cruds() {
return CRUD({
title: '库存',
optShow: {add: true, reset: true, download: true},
optShow: { add: true, reset: true, download: true },
url: 'api/stIvtStockDtl',
idField: 'id',
crudMethod: {...crudStock},
crudMethod: { ...crudStock }
})
},
data() {
@ -262,29 +296,30 @@ export default {
stors: [],
structs: [],
uploadShow: false,
uploadUpdateShow: false,
materialDialog: false,
permission: {},
rules: {
struct_code: [
{required: true, message: '仓位编码不能为空', trigger: 'blur'}
{ required: true, message: '仓位编码不能为空', trigger: 'blur' }
],
material_code: [
{required: true, message: '物料编码不能为空', trigger: 'blur'}
{ required: true, message: '物料编码不能为空', trigger: 'blur' }
],
qty: [
{required: true, message: '数量不能为空', trigger: 'blur'}
{ required: true, message: '数量不能为空', trigger: 'blur' }
],
storage_time: [
{required: true, message: '入库时间不能为空', trigger: 'blur'}
{ required: true, message: '入库时间不能为空', trigger: 'blur' }
],
unit: [
{required: true, message: '计量单位不能为空', trigger: 'blur'}
],
{ required: true, message: '计量单位不能为空', trigger: 'blur' }
]
}
}
},
created() {
crudStruct.getStructs("3.03.001").then(res => {
crudStruct.getStructs('3.03.001').then(res => {
this.structs = res
})
},
@ -295,13 +330,13 @@ export default {
},
handleInput(value) {
//
this.form.qty = value.replace(/[^\d.]/g, '').replace(/^0+/, '');
this.form.qty = value.replace(/[^\d.]/g, '').replace(/^0+/, '')
},
validateQty(rule, value, callback) {
if (value <= 0 || isNaN(value)) {
callback(new Error('数量必须大于 0'));
callback(new Error('数量必须大于 0'))
} else {
callback();
callback()
}
},
[CRUD.HOOK.afterToEdit](crud, form) {
@ -371,6 +406,9 @@ export default {
tableChanged3() {
this.crud.toQuery()
},
tableChanged4() {
this.crud.toQuery()
},
initMaterialName() {
crudStock.initMaterialName().then(res => {
this.crud.toQuery()

12
wms/nladmin-ui/src/views/wms/ivt/stock/stock.js

@ -26,7 +26,7 @@ export function edit(data) {
export function getDtl(id, material_code) {
return request({
url: 'api/stIvtStockDtl/getDtl/' + id + "/" + material_code,
url: 'api/stIvtStockDtl/getDtl/' + id + '/' + material_code,
method: 'get'
})
}
@ -46,4 +46,12 @@ export function initMaterialName() {
})
}
export default {add, edit, del, getDtl, excelImport, initMaterialName}
export function excelUpdateImport(data) {
return request({
url: 'api/stIvtStockDtl/excelUpdateImport',
method: 'post',
data
})
}
export default { add, edit, del, getDtl, excelImport, initMaterialName, excelUpdateImport }

7
wms/nlsso-server/src/main/java/org/nl/wms/ivt/controller/StIvtStockDtlController.java

@ -4,7 +4,6 @@ package org.nl.wms.ivt.controller;
import org.nl.common.domain.query.PageQuery;
import org.nl.wms.ivt.service.IStIvtStockDtlService;
import org.nl.wms.ivt.service.dao.StIvtStockDtl;
import org.nl.wms.ivt.service.dto.OrgQuery;
import org.nl.wms.ivt.service.dto.StockDtlQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
@ -59,6 +58,12 @@ public class StIvtStockDtlController {
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/excelUpdateImport")
public ResponseEntity<Object> excelUpdateImport(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
stockDtlService.excelUpdateImport(file, request);
return new ResponseEntity<>(HttpStatus.OK);
}
@PutMapping("/initMaterialName")
public ResponseEntity<Object> initMaterialName() {
stockDtlService.initMaterialName();

2
wms/nlsso-server/src/main/java/org/nl/wms/ivt/service/IStIvtStockDtlService.java

@ -83,6 +83,8 @@ public interface IStIvtStockDtlService extends IService<StIvtStockDtl> {
void excelImport(MultipartFile file, HttpServletRequest request);
void excelUpdateImport(MultipartFile file, HttpServletRequest request);
void initMaterialName();

82
wms/nlsso-server/src/main/java/org/nl/wms/ivt/service/impl/StIvtStockDtlServiceImpl.java

@ -238,6 +238,88 @@ public class StIvtStockDtlServiceImpl extends ServiceImpl<StIvtStockDtlMapper, S
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void excelUpdateImport(MultipartFile file, HttpServletRequest request) {
if (file.isEmpty()) {
throw new BadRequestException("文件为空,请添加数据后重新导入");
}
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
ExcelReader excelReader = ExcelUtil.getReader(inputStream);
List<List<Object>> read = excelReader.read(1, excelReader.getRowCount());
Set<String> oldMaterialCodes = new HashSet<>();
List<MdBaseMaterial> materials = new ArrayList<>();
List<StIvtStockDtl> newStIvtStockDtls = new ArrayList<>();
// Collect all old material codes first
for (List<Object> row : read) {
String oldMaterialCode = row.get(0).toString().trim();
if (!StrUtil.isEmpty(oldMaterialCode)) {
oldMaterialCodes.add(oldMaterialCode);
}
}
// Batch query to get all materials at once
List<MdBaseMaterial> existingMaterials = materialService.list(new LambdaQueryWrapper<MdBaseMaterial>()
.in(MdBaseMaterial::getMaterial_code, oldMaterialCodes));
Map<String, MdBaseMaterial> materialMap = existingMaterials.stream()
.collect(Collectors.toMap(MdBaseMaterial::getMaterial_code, material -> material));
// Process data in batches
for (List<Object> row : read) {
String oldMaterialCode = row.get(0).toString().trim();
String newMaterialCode = row.get(1).toString().trim();
String materialName = row.get(2).toString().trim();
if (StrUtil.isEmpty(newMaterialCode) || StrUtil.isEmpty(oldMaterialCode)) {
continue;
}
MdBaseMaterial baseMaterial = materialMap.get(oldMaterialCode);
if (baseMaterial != null) {
baseMaterial.setMaterial_code(newMaterialCode);
baseMaterial.setMaterial_name(materialName);
materials.add(baseMaterial);
} else {
MdBaseMaterial newMaterial = new MdBaseMaterial();
newMaterial.setMaterial_id(IdUtil.getLongId().toString());
newMaterial.setMaterial_code(newMaterialCode);
newMaterial.setMaterial_name(materialName);
materials.add(newMaterial);
}
List<StIvtStockDtl> stockDtls = stockDtlMapper.selectList(
new LambdaQueryWrapper<StIvtStockDtl>().eq(StIvtStockDtl::getMaterial_code, oldMaterialCode)
);
if (CollectionUtils.isNotEmpty(stockDtls)) {
for (StIvtStockDtl stockDtl : stockDtls) {
stockDtl.setMaterial_code(newMaterialCode);
stockDtl.setMaterial_name(materialName);
newStIvtStockDtls.add(stockDtl);
}
}
}
// Batch insert/update
if (CollectionUtils.isNotEmpty(materials)) {
materialService.saveOrUpdateBatch(materials,5000);
}
if (CollectionUtils.isNotEmpty(newStIvtStockDtls)) {
this.updateBatchById(newStIvtStockDtls,5000);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void initMaterialName() {

2
wms/nlsso-server/src/main/java/org/nl/wms/schedule/EasBillSchedule.java

@ -62,7 +62,7 @@ public class EasBillSchedule {
easDataSyncService.syncAddUserInfo();
}
// @Scheduled(cron = "0/60 * * * * *")
// @Scheduled(cron = "0/60 * * * * *")
public void syncEasMaterial() {
easDataSyncService.syncAddMaterialInfo();
}

Loading…
Cancel
Save