zy-asrs-admin/src/views/loc/stockTransfer/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/LocController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/WorkController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/LocTransferParam.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/WorkService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/WorkServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskTimer.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
zy-asrs-admin/src/views/loc/stockTransfer/index.vue
New file @@ -0,0 +1,326 @@ <script setup> import { ref, reactive } from 'vue'; import { useRouter } from "vue-router"; import { get, post, postForm } from '@/utils/request.js' import { message, Modal } from 'ant-design-vue'; import { logout } from '@/config.js'; import { formatMessage } from '@/utils/localeUtils.js'; import useTableSearch from '@/utils/tableUtils.jsx'; import MatQueryView from '@/components/mat/matQuery/index.vue' const router = useRouter(); const TABLE_KEY = 'table-locDetl'; const matQueryChild = ref(null) const sourceLocNo = ref(null) const targetLocNo = ref(null) let tableData = ref([]); getColumns(); const { getColumnSearchProps, handleResizeColumn, } = useTableSearch(); const state = reactive({ selectedRowKeys: [], loading: false, columns: [], }); const onSelectChange = selectedRowKeys => { // console.log('selectedRowKeys changed: ', selectedRowKeys); state.selectedRowKeys = selectedRowKeys; }; state.columns = [ { title: formatMessage('db.man_loc_detl.loc_no', '库位号'), dataIndex: 'locNo', width: 140, ellipsis: true, ...getColumnSearchProps('locNo'), }, { title: formatMessage('db.man_loc_detl.matnr', '商品编号'), dataIndex: 'matnr', width: 140, ellipsis: true, ...getColumnSearchProps('matnr'), }, { title: formatMessage('db.man_loc_detl.batch', '批号'), dataIndex: 'batch', width: 140, ellipsis: true, ...getColumnSearchProps('batch'), }, { title: formatMessage('db.man_loc_detl.anfme', '库存数量'), dataIndex: 'anfme', width: 140, ellipsis: true, }, ]; let columnsOther = [ // { // title: formatMessage('db.man_loc_detl.loc_id', '库位'), // dataIndex: 'locId$', // width: 140, // ellipsis: true, // ...getColumnSearchProps('locId$'), // }, // { // title: formatMessage('db.man_loc_detl.mat_id', '商品'), // dataIndex: 'matId$', // width: 140, // ellipsis: true, // ...getColumnSearchProps('matId$'), // }, { title: formatMessage('db.man_loc_detl.order_no', '订单号'), dataIndex: 'orderNo', width: 140, ellipsis: true, ...getColumnSearchProps('orderNo'), }, { title: formatMessage('db.man_loc_detl.anfme', '数量'), dataIndex: 'anfme', width: 140, ellipsis: true, ...getColumnSearchProps('anfme'), }, { title: formatMessage('db.man_loc_detl.freeze', '是否冻结'), dataIndex: 'freeze$', width: 140, ellipsis: true, ...getColumnSearchProps('freeze$'), }, // { // title: formatMessage('db.man_loc_detl.status', '状态'), // dataIndex: 'status$', // width: 140, // ellipsis: true, // ...getColumnSearchProps('status$'), // }, // { // title: formatMessage('db.man_loc_detl.create_time', '添加时间'), // dataIndex: 'createTime$', // width: 140, // ellipsis: true, // ...getColumnSearchProps('createTime$'), // }, // { // title: formatMessage('db.man_loc_detl.create_by', '添加人员'), // dataIndex: 'createBy$', // width: 140, // ellipsis: true, // ...getColumnSearchProps('createBy$'), // }, // { // title: formatMessage('db.man_loc_detl.update_time', '修改时间'), // dataIndex: 'updateTime$', // width: 140, // ellipsis: true, // ...getColumnSearchProps('updateTime$'), // }, // { // title: formatMessage('db.man_loc_detl.update_by', '修改人员'), // dataIndex: 'updateBy$', // width: 140, // ellipsis: true, // ...getColumnSearchProps('updateBy$'), // }, { title: formatMessage('db.man_loc_detl.memo', '备注'), dataIndex: 'memo', width: 140, ellipsis: true, ...getColumnSearchProps('memo'), }, ] let fieldList = []; //加载扩展字段 async function getColumns() { let fieldResp = await post('/api/matField/list', { unique: 1 }) let fieldResult = fieldResp.data; let tmp = state.columns; if (fieldResult.code == 200) { let data = fieldResult.data; data.forEach((item) => { let filed = { title: formatMessage(item.language, item.describe), name: item.name, dataIndex: item.name, key: item.name, width: 140, editable: true, ...getColumnSearchProps(item.name), } tmp.push(filed) fieldList.push(filed) }) tmp = tmp.concat(columnsOther) state.columns = tmp; } else if (result.code === 401) { message.error(result.msg); logout() } else { message.error(result.msg); } } const handleMatQueryOk = (result) => { let tmp = []; if (tableData.value != undefined) { tmp = [...tableData.value] } for (let i = 0; i < result.length; i++) { let item = result[i] item.anfme = 0; item.qty = 0; item.matId = item.id; item.id = null; fieldList.forEach((filed) => { item[filed.key] = '' }) tmp.push(item) } tableData.value = tmp; } const onSourceLocNoChange = () => { state.loading = true; tableData.value = null; postForm('/api/loc/search/like/locNo', { locNo: sourceLocNo.value, }).then(resp => { let result = resp.data; if (result.code == 200) { let detls = []; result.data.forEach((item) => { item.qty = item.anfme; detls.push(item) }) tableData.value = detls; state.loading = false; } else { message.error(result.msg); tableData.value = null; } }) } const submitTransfer = () => { Modal.confirm({ title: formatMessage('page.stockTransfer.transfer', '库存移转'), content: formatMessage('page.stockTransfer.confirm', '确定库存移转吗?'), maskClosable: true, onOk: async () => { confirmTransfer() }, }); } const confirmTransfer = () => { if (sourceLocNo.value == null) { message.error(formatMessage('page.stockTransfer.sourceLocNoNull', '请输入源库位')); return; } if(targetLocNo.value == null) { message.error(formatMessage('page.stockTransfer.targetLocNoNull', '目标库位为空')); return; } post('/api/loc/transfer', { sourceLocNo: sourceLocNo.value, targetLocNo: targetLocNo.value }).then(resp => { let result = resp.data; if (result.code == 200) { message.success(formatMessage('page.stockTransfer.success', '库存移转成功')); sourceLocNo.value = null; targetLocNo.value = null; } else { message.error(result.msg); } }) } const locNoQueryList = ref(null); locNoQuery(""); function locNoQuery(locNo) { postForm('/api/loc/search/empty/locNo', { locNo: locNo }).then(resp => { let result = resp.data; let tmp = [] result.data.forEach((item) => { tmp.push({ value: item.locNo, label: item.locNo }) }) locNoQueryList.value = tmp; }) } const locNoSearch = (val) => { locNoQuery(val) } </script> <script> export default { name: '库存移转' } </script> <template> <div> <div style="margin-bottom: 20px;display: flex;align-items: center;"> <a-input v-model:value="sourceLocNo" :placeholder="formatMessage('page.stockTransfer.sourceLocNo', '源库位')" style="width: 200px;" @change="onSourceLocNoChange" /> <span style="margin-left: 10px;margin-right: 10px;">-</span> <a-select v-model:value="targetLocNo" :placeholder="formatMessage('page.stockTransfer.targetLocNo', '目标库位')" style="width: 200px" show-search :options="locNoQueryList" @search="locNoSearch" optionFilterProp="label" optionLabelProp="label"> </a-select> </div> <div class="table-header"> <div> <a-button type="primary" @click="submitTransfer">库位移转</a-button> </div> </div> <a-table :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }" :data-source="tableData" :defaultExpandAllRows="false" :key="TABLE_KEY" rowKey="id" :scroll="{ y: 768, scrollToFirstRowOnChange: true }" :columns="state.columns" :loading="state.loading" @resizeColumn="handleResizeColumn"> <template #bodyCell="{ column, text, record }"> </template> </a-table> <MatQueryView ref="matQueryChild" @handle-ok="handleMatQueryOk" /> </div> </template> <style></style> zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/LocController.java
@@ -5,6 +5,7 @@ import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.R; import com.zy.asrs.wms.asrs.entity.LocDetl; import com.zy.asrs.wms.asrs.entity.enums.LocStsType; import com.zy.asrs.wms.asrs.service.LocDetlService; import com.zy.asrs.wms.common.annotation.OperationLog; import com.zy.asrs.wms.common.domain.BaseParam; @@ -66,6 +67,27 @@ return R.ok().add(map); } @PreAuthorize("hasAuthority('asrs:loc:list')") @PostMapping("/loc/search/like/locNo") public R search(@RequestParam("locNo") String locNo) { if (Cools.isEmpty(locNo)) { return R.ok().add(new ArrayList<>()); } List<LocDetl> locDetls = locDetlService.list(new LambdaQueryWrapper<LocDetl>().like(LocDetl::getLocNo, locNo)); locDetls = locDetlService.parseLocDetl(locDetls); return R.ok().add(locDetls); } @PreAuthorize("hasAuthority('asrs:loc:list')") @PostMapping("/loc/search/empty/locNo") public R searchEmpty(@RequestParam("locNo") String locNo) { if (Cools.isEmpty(locNo)) { return R.ok().add(locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getLocStsId, LocStsType.O.val()))); } List<Loc> list = locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getLocStsId, LocStsType.O.val()).like(Loc::getLocNo, locNo)); return R.ok().add(list); } @PreAuthorize("hasAuthority('asrs:loc:save')") @OperationLog("添加库位") @PostMapping("/loc/save") zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/WorkController.java
@@ -5,12 +5,13 @@ import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.R; import com.zy.asrs.framework.exception.CoolException; import com.zy.asrs.wms.asrs.entity.Loc; import com.zy.asrs.wms.asrs.entity.LocDetl; import com.zy.asrs.wms.asrs.entity.LocDetlField; import com.zy.asrs.wms.asrs.entity.MatField; import com.zy.asrs.wms.asrs.entity.*; import com.zy.asrs.wms.asrs.entity.enums.LocStsType; import com.zy.asrs.wms.asrs.entity.enums.OrderSettleType; import com.zy.asrs.wms.asrs.entity.enums.TaskStsType; import com.zy.asrs.wms.asrs.entity.param.GeneratePakInParam; import com.zy.asrs.wms.asrs.entity.param.LocAdjustParam; import com.zy.asrs.wms.asrs.entity.param.LocTransferParam; import com.zy.asrs.wms.asrs.service.*; import com.zy.asrs.wms.common.annotation.OperationLog; import com.zy.asrs.wms.system.controller.BaseController; @@ -118,4 +119,16 @@ return R.ok(); } @OperationLog("库存移转") @PostMapping("/loc/transfer") @Transactional public R locTransfer(@RequestBody LocTransferParam param) { try { workService.locTransfer(param); return R.ok(); } catch (Exception e) { return R.error(e.getMessage()); } } } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/LocTransferParam.java
New file @@ -0,0 +1,15 @@ package com.zy.asrs.wms.asrs.entity.param; import lombok.Data; import java.util.List; import java.util.Map; @Data public class LocTransferParam { private String sourceLocNo; private String targetLocNo; } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/WorkService.java
@@ -3,6 +3,7 @@ import com.zy.asrs.wms.asrs.entity.Loc; import com.zy.asrs.wms.asrs.entity.param.FieldParam; import com.zy.asrs.wms.asrs.entity.param.GeneratePakInParam; import com.zy.asrs.wms.asrs.entity.param.LocTransferParam; import java.util.List; @@ -38,4 +39,7 @@ //拣料任务 boolean pickTask(Long taskId); //库位移转 boolean locTransfer(LocTransferParam param); } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/WorkServiceImpl.java
@@ -1,11 +1,14 @@ package com.zy.asrs.wms.asrs.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.R; import com.zy.asrs.framework.exception.CoolException; import com.zy.asrs.wms.asrs.entity.*; import com.zy.asrs.wms.asrs.entity.enums.*; import com.zy.asrs.wms.asrs.entity.param.FieldParam; import com.zy.asrs.wms.asrs.entity.param.GeneratePakInParam; import com.zy.asrs.wms.asrs.entity.param.LocTransferParam; import com.zy.asrs.wms.asrs.service.*; import com.zy.asrs.wms.utils.LocUtils; import com.zy.asrs.wms.utils.OrderUtils; @@ -37,6 +40,10 @@ private OrderDetlService orderDetlService; @Autowired private LocService locService; @Autowired private LocDetlService locDetlService; @Autowired private LocDetlFieldService locDetlFieldService; @Autowired private LocStsService locStsService; @Autowired @@ -499,8 +506,35 @@ throw new CoolException("波次明细更新失败"); } } break; case 11://库位移转 Loc originLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getOriginLoc())); if(originLoc == null){ throw new CoolException("源库位不存在"); } if (originLoc.getLocStsId() != LocStsType.R.val()) { throw new CoolException("源库位状态不处于R.出库预约"); } loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getTargetLoc())); if(loc == null){ throw new CoolException("目标库位不存在"); } if(loc.getLocStsId() != LocStsType.S.val()){ throw new CoolException("目标库位状态不处于S.入库预约"); } originLoc.setLocStsId(LocStsType.F.val()); originLoc.setUpdateTime(new Date()); if(!locService.updateById(originLoc)){ throw new CoolException("库位状态变更失败"); } loc.setLocStsId(LocStsType.O.val()); loc.setUpdateTime(new Date()); if(!locService.updateById(loc)){ throw new CoolException("库位状态变更失败"); } break; } @@ -650,4 +684,111 @@ return true; } @Override public boolean locTransfer(LocTransferParam param) { if (param == null) { throw new CoolException("参数不能为空"); } if (Cools.isEmpty(param.getSourceLocNo())) { throw new CoolException("源库位不能为空"); } if (Cools.isEmpty(param.getTargetLocNo())) { throw new CoolException("目标库位不能为空"); } Loc sourceLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, param.getSourceLocNo())); if (sourceLoc == null) { throw new CoolException("源库位不存在"); } if (sourceLoc.getLocStsId() != LocStsType.F.val()) { throw new CoolException("源库位非在库状态"); } Loc targetLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, param.getTargetLocNo())); if (targetLoc == null) { throw new CoolException("目标库位不存在"); } if(targetLoc.getLocStsId() != LocStsType.O.val()){ throw new CoolException("目标库位非空状态"); } TaskType taskType = taskTypeService.getById(11); if (taskType == null) { throw new CoolException("任务类型不存在"); } Task task = new Task(); task.setTaskNo(this.generateTaskNo(taskType.getId()));//任务号 task.setTaskSts(TaskStsType.GENERATE_IN.id);//1.生成入库任务 task.setTaskType(taskType.getId());//任务类型 task.setIoPri(this.generateIoPri(taskType.getId()));//优先级 task.setOriginLoc(param.getSourceLocNo()); task.setTargetLoc(param.getTargetLocNo()); task.setOriginSite(null); task.setTargetSite(null); task.setBarcode(sourceLoc.getBarcode());//托盘码 boolean taskSave = taskService.save(task); if (!taskSave) { throw new CoolException("任务生成失败"); } List<LocDetl> locDetls = locDetlService.list(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getLocId, sourceLoc.getId())); if(locDetls.isEmpty()){ throw new CoolException("源库位明细不存在"); } //生成任务明细 for (LocDetl locDetl : locDetls) { TaskDetl taskDetl = new TaskDetl(); taskDetl.setTaskId(task.getId()); taskDetl.setTaskNo(task.getTaskNo()); taskDetl.setAnfme(locDetl.getAnfme());//数量 taskDetl.setStock(0D);//库存 taskDetl.setBatch(locDetl.getBatch());//批号 taskDetl.setBarcode(sourceLoc.getBarcode()); taskDetl.setMatId(locDetl.getMatId()); taskDetl.setMatnr(locDetl.getMatnr()); boolean taskDetlSave = taskDetlService.save(taskDetl); if(!taskDetlSave){ throw new CoolException("任务明细生成失败"); } //生成明细扩展 List<LocDetlField> locDetlFieldList = locDetlFieldService.list(new LambdaQueryWrapper<LocDetlField>().eq(LocDetlField::getDetlId, locDetl.getId())); for (LocDetlField locDetlField : locDetlFieldList) { TaskDetlField taskDetlField = new TaskDetlField(); taskDetlField.setName(locDetlField.getName()); taskDetlField.setFieldId(locDetlField.getFieldId()); taskDetlField.setDetlId(taskDetl.getId()); taskDetlField.setValue(locDetlField.getValue()); boolean taskDetlFieldSave = taskDetlFieldService.save(taskDetlField); if(!taskDetlFieldSave){ throw new CoolException("明细扩展生成失败"); } } } //库位F => R sourceLoc.setLocStsId(LocStsType.R.val()); sourceLoc.setUpdateTime(new Date()); boolean sourceLocUpdate = locService.updateById(sourceLoc); if(!sourceLocUpdate){ throw new CoolException("库位状态更新失败"); } //库位O => S targetLoc.setLocStsId(LocStsType.S.val()); targetLoc.setUpdateTime(new Date()); boolean targetLocUpdate = locService.updateById(targetLoc); if(!targetLocUpdate){ throw new CoolException("库位状态更新失败"); } return true; } } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/timer/TaskTimer.java
@@ -74,6 +74,9 @@ case 1://入库 executeTask1(task); break; case 11://库位移转 executeTask11(task); break; case 53://拣料再入库 executeTask53(task); break; @@ -204,6 +207,88 @@ } } //库位移转 private void executeTask11(Task task) { Long hostId = task.getHostId(); Loc originLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getOriginLoc()).eq(Loc::getHostId, hostId)); if (originLoc == null) { throw new CoolException("源库位不存在"); } if (originLoc.getLocStsId() != LocStsType.R.val()) { throw new CoolException("库位状态不处于R.出库预约"); } Loc targetLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getTargetLoc()).eq(Loc::getHostId, hostId)); if (targetLoc == null) { throw new CoolException("目标库位不存在"); } if (targetLoc.getLocStsId() != LocStsType.S.val()) { throw new CoolException("库位状态不处于S.入库预约"); } originLoc.setLocStsId(LocStsType.O.val()); originLoc.setUpdateTime(new Date()); originLoc.setBarcode(""); if (!locService.updateById(originLoc)) { throw new CoolException("库位状态更新失败"); } targetLoc.setLocStsId(LocStsType.F.val()); targetLoc.setUpdateTime(new Date()); targetLoc.setBarcode(task.getBarcode()); if (!locService.updateById(targetLoc)) { throw new CoolException("库位状态更新失败"); } List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(task.getId()); if (taskDetls.isEmpty()) { throw new CoolException("任务明细不存在"); } //添加库存明细 for (TaskDetl taskDetl : taskDetls) { LocDetl locDetl = new LocDetl(); locDetl.setLocId(targetLoc.getId()); locDetl.setLocNo(targetLoc.getLocNo()); locDetl.setMatId(taskDetl.getMatId()); locDetl.setMatnr(taskDetl.getMat$().getMatnr()); locDetl.setOrderNo(taskDetl.getOrderNo()); locDetl.setBatch(taskDetl.getBatch()); locDetl.setAnfme(taskDetl.getAnfme()); locDetl.setHostId(hostId); if (!locDetlService.save(locDetl)) { throw new CoolException("插入库存明细失败"); } //添加库存明细扩展字段 List<TaskDetlField> detlFields = taskDetlFieldService.list(new LambdaQueryWrapper<TaskDetlField>().eq(TaskDetlField::getDetlId, taskDetl.getId()).eq(TaskDetlField::getHostId, hostId)); for (TaskDetlField detlField : detlFields) { LocDetlField locDetlField = new LocDetlField(); locDetlField.setDetlId(locDetl.getId()); locDetlField.setFieldId(detlField.getFieldId()); locDetlField.setName(detlField.getName()); locDetlField.setValue(detlField.getValue()); locDetlField.setHostId(hostId); if (!locDetlFieldService.save(locDetlField)) { throw new CoolException("插入明细扩展字段失败"); } } } List<LocDetl> locDetls = locDetlService.list(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getLocId, originLoc.getId())); for (LocDetl locDetl : locDetls) { boolean remove = locDetlFieldService.remove(new LambdaQueryWrapper<LocDetlField>().eq(LocDetlField::getDetlId, locDetl.getId())); boolean result = locDetlService.removeById(locDetl.getId()); if (!result) { throw new CoolException("清除明细失败"); } } } //拣料再入库 private void executeTask53(Task task) { Long hostId = task.getHostId();