完成简单入出库功能

pull/362/head
AlanScipio 2 years ago
parent 24f1f4c3e7
commit 1c38d91567

@ -1,5 +1,7 @@
package com.ruoyi.common.core.web.domain; package com.ruoyi.common.core.web.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serial; import java.io.Serial;
/** /**
@ -33,6 +35,16 @@ public class ExtBaseEntity extends BaseEntity {
*/ */
private Integer updateCount; private Integer updateCount;
/**
*
*
* @return truefalse
*/
@JsonIgnore
public boolean isLogicDeleted() {
return deleteFlag != null && deleteFlag == DELETED;
}
public Integer getDeleteFlag() { public Integer getDeleteFlag() {
return deleteFlag; return deleteFlag;
} }

@ -33,12 +33,12 @@ public class JobDataLogServiceImpl implements IJobDataLogService {
if (log.getLogId() == null) { if (log.getLogId() == null) {
log.setLogId(SnowFlakeIdGenerator.nextIdLong()); log.setLogId(SnowFlakeIdGenerator.nextIdLong());
} }
if (log.getJobClass() == null) { // if (log.getJobClass() == null) {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); // StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement caller = stackTraceElements[2]; // StackTraceElement caller = stackTraceElements[2];
log.setJobClass(caller.getClassName()); // log.setJobClass(caller.getClassName());
log.setJobMethod(caller.getMethodName()); // log.setJobMethod(caller.getMethodName());
} // }
jobDataLogMapper.insertSelective(log); jobDataLogMapper.insertSelective(log);
} }
} }

@ -134,16 +134,17 @@ public class VelocityUtils {
if ("mybatis-dynamic".equals(tplBackendType)) { if ("mybatis-dynamic".equals(tplBackendType)) {
//MyBatis Dynamic SQL //MyBatis Dynamic SQL
templates.add("vm/java/controller-dynamic.java.vm"); templates.add("vm/java/controller-dynamic.java.vm");
templates.add("vm/java/service-dynamic.java.vm");
templates.add("vm/java/serviceImpl-dynamic.java.vm"); templates.add("vm/java/serviceImpl-dynamic.java.vm");
} else { } else {
//常规 //常规
templates.add("vm/java/domain.java.vm"); templates.add("vm/java/domain.java.vm");
templates.add("vm/java/controller.java.vm"); templates.add("vm/java/controller.java.vm");
templates.add("vm/java/service.java.vm");
templates.add("vm/java/serviceImpl.java.vm"); templates.add("vm/java/serviceImpl.java.vm");
templates.add("vm/java/mapper.java.vm"); templates.add("vm/java/mapper.java.vm");
templates.add("vm/xml/mapper.xml.vm"); templates.add("vm/xml/mapper.xml.vm");
} }
templates.add("vm/java/service.java.vm");
templates.add("vm/sql/sql.vm"); templates.add("vm/sql/sql.vm");
//前端 //前端
templates.add("vm/js/api.js.vm"); templates.add("vm/js/api.js.vm");
@ -190,6 +191,8 @@ public class VelocityUtils {
fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className);
} else if (template.contains("service.java.vm")) { } else if (template.contains("service.java.vm")) {
fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className);
} else if (template.contains("service-dynamic.java.vm")) {
fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className);
} else if (template.contains("serviceImpl.java.vm")) { } else if (template.contains("serviceImpl.java.vm")) {
fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className);
} else if (template.contains("serviceImpl-dynamic.java.vm")) { } else if (template.contains("serviceImpl-dynamic.java.vm")) {

@ -0,0 +1,70 @@
package ${packageName}.service;
import java.util.List;
import ${packageName}.domain .${ClassName};
/**
* ${functionName}Service接口
*
* @author ${author}
* created on ${datetime}
*/
public interface I${ClassName}Service {
/**
* 查询${functionName}
*
* @param ${pkColumn.javaField} ${functionName}主键
* @return ${functionName}
*/
${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
/**
* 查询${functionName}列表
*
* @param ${className} ${functionName}
* @return ${functionName}集合
*/
List<${ClassName}> select${ClassName}List(${ClassName} ${className});
/**
* 新增${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
int insert${ClassName}(${ClassName} ${className});
/**
* 修改${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
int update${ClassName}(${ClassName} ${className});
/**
* 批量删除${functionName}
*
* @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合
* @return 结果
*/
int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s);
/**
* 删除${functionName}信息
*
* @param ${pkColumn.javaField} ${functionName}主键
* @return 结果
*/
int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
/**
* 检查${functionName}是否已存在
*
* @param ${pkColumn.javaField} 主键
* @param deleteIfLogicDeleted 如果是已经逻辑删除的数据则是否顺带物理删除掉如果为true则逻辑删除的也会返回null
* @return null:不存在; not null:存在
*/
${ClassName} check${pkColumn.capJavaField}Exists(${pkColumn.javaType} ${pkColumn.javaField}, boolean deleteIfLogicDeleted);
}

@ -220,4 +220,29 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
} }
} }
#end #end
/**
* 检查${functionName}是否已存在
*
* @param ${pkColumn.javaField} 主键
* @param deleteIfLogicDeleted 如果是已经逻辑删除的数据则是否顺带物理删除掉如果为true则逻辑删除的也会返回null
* @return null:不存在; not null:存在
*/
@Transactional
@Override
public ${ClassName} check${pkColumn.capJavaField}Exists(${pkColumn.javaType} ${pkColumn.javaField}, boolean deleteIfLogicDeleted) {
Optional<${ClassName}> existsRecordOpt = ${className}Mapper.selectOne(dsl -> dsl.where(${ClassName}DynamicSqlSupport.${pkColumn.javaField}, SqlBuilder.isEqualTo(${pkColumn.javaField})));
if (existsRecordOpt.isEmpty()) {
return null;
} else {
${ClassName} existsRecord = existsRecordOpt.get();
if (deleteIfLogicDeleted && existsRecord.isLogicDeleted()) {
//顺带物理删除掉
${className}Mapper.deleteByPrimaryKey(existsRecord.get${pkColumn.capJavaField}());
return null;
}
return existsRecord;
}
}
} }

@ -1,102 +1,101 @@
package com.ruoyi.job.service; package com.ruoyi.job.service;
import java.util.List;
import org.quartz.SchedulerException;
import com.ruoyi.common.core.exception.job.TaskException; import com.ruoyi.common.core.exception.job.TaskException;
import com.ruoyi.job.domain.SysJob; import com.ruoyi.job.domain.SysJob;
import org.quartz.SchedulerException;
import java.util.List;
/** /**
* *
* *
* @author ruoyi * @author ruoyi
*/ */
public interface ISysJobService public interface ISysJobService {
{
/** /**
* quartz * quartz
* *
* @param job * @param job
* @return * @return
*/ */
public List<SysJob> selectJobList(SysJob job); List<SysJob> selectJobList(SysJob job);
/** /**
* ID * ID
* *
* @param jobId ID * @param jobId ID
* @return * @return
*/ */
public SysJob selectJobById(Long jobId); SysJob selectJobById(Long jobId);
/** /**
* *
* *
* @param job * @param job
* @return * @return
*/ */
public int pauseJob(SysJob job) throws SchedulerException; int pauseJob(SysJob job) throws SchedulerException;
/** /**
* *
* *
* @param job * @param job
* @return * @return
*/ */
public int resumeJob(SysJob job) throws SchedulerException; int resumeJob(SysJob job) throws SchedulerException;
/** /**
* trigger * trigger
* *
* @param job * @param job
* @return * @return
*/ */
public int deleteJob(SysJob job) throws SchedulerException; int deleteJob(SysJob job) throws SchedulerException;
/** /**
* *
* *
* @param jobIds ID * @param jobIds ID
* @return
*/ */
public void deleteJobByIds(Long[] jobIds) throws SchedulerException; void deleteJobByIds(Long[] jobIds) throws SchedulerException;
/** /**
* *
* *
* @param job * @param job
* @return * @return
*/ */
public int changeStatus(SysJob job) throws SchedulerException; int changeStatus(SysJob job) throws SchedulerException;
/** /**
* *
* *
* @param job * @param job
* @return * @return
*/ */
public boolean run(SysJob job) throws SchedulerException; boolean run(SysJob job) throws SchedulerException;
/** /**
* *
* *
* @param job * @param job
* @return * @return
*/ */
public int insertJob(SysJob job) throws SchedulerException, TaskException; int insertJob(SysJob job) throws SchedulerException, TaskException;
/** /**
* *
* *
* @param job * @param job
* @return * @return
*/ */
public int updateJob(SysJob job) throws SchedulerException, TaskException; int updateJob(SysJob job) throws SchedulerException, TaskException;
/** /**
* cron * cron
* *
* @param cronExpression * @param cronExpression
* @return * @return
*/ */
public boolean checkCronExpressionIsValid(String cronExpression); boolean checkCronExpressionIsValid(String cronExpression);
} }

@ -8,6 +8,7 @@ import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType; import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions; import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.wms.domain.BaseStock; import com.ruoyi.wms.domain.BaseStock;
import com.ruoyi.wms.domain.vo.StockVo;
import com.ruoyi.wms.service.stock.IBaseStockService; import com.ruoyi.wms.service.stock.IBaseStockService;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -64,4 +65,22 @@ public class BaseStockController extends BaseController {
return success(baseStockService.selectBaseStockByPK(form.getWhsCd(), form.getStgBinCd(), form.getItemCd(), form.getLotNo(), form.getSubLotNo())); return success(baseStockService.selectBaseStockByPK(form.getWhsCd(), form.getStgBinCd(), form.getItemCd(), form.getLotNo(), form.getSubLotNo()));
} }
/**
*
*/
@RequiresPermissions("wms:BaseStock:instock")
@PostMapping(value = "/instock")
public AjaxResult instock(@RequestBody StockVo stockVo) throws Exception {
return baseStockService.instock(stockVo);
}
/**
*
*/
@RequiresPermissions("wms:BaseStock:outstock")
@PostMapping(value = "/outstock")
public AjaxResult outstock(@RequestBody StockVo stockVo) throws Exception {
return baseStockService.outstock(stockVo);
}
} }

@ -59,113 +59,113 @@ public class InvTransHis extends ExtBaseEntity implements Serializable {
//==================== ↓↓↓↓↓↓ 表字段 ↓↓↓↓↓↓ ==================== //==================== ↓↓↓↓↓↓ 表字段 ↓↓↓↓↓↓ ====================
/** /**
* *
*/ */
@Excel(name = "入出库履历号", sort = 1) @Excel(name = "入出库履历号", sort = 1)
private String invTransNo; private String invTransNo;
/** /**
* ID * ID
*/ */
private Integer deptId; private Integer deptId;
/** /**
* (1:,2:) * (1:,2:)
*/ */
private Integer invTransType; private Integer invTransType;
/** /**
* *
*/ */
private String whsCd; private String whsCd;
/** /**
* *
*/ */
private String stgBinCd; private String stgBinCd;
/** /**
* ID * ID
*/ */
private String palletId; private String palletId;
/** /**
* *
*/ */
private BigDecimal stdUnitQty; private BigDecimal stdUnitQty;
/** /**
* *
*/ */
private BigDecimal pkgUnitQty; private BigDecimal pkgUnitQty;
/** /**
* *
*/ */
private String transOrderNo; private String transOrderNo;
/** /**
* *
*/ */
private String transOrderDetlNo; private String transOrderDetlNo;
/** /**
* *
*/ */
private String operator; private String operator;
/** /**
* *
*/ */
private String businessCls; private String businessCls;
/** /**
* *
*/ */
private String itemCd; private String itemCd;
/** /**
* *
*/ */
private String lotNo; private String lotNo;
/** /**
* *
*/ */
private String subLotNo; private String subLotNo;
/** /**
* *
*/ */
private String serialNo; private String serialNo;
/** /**
* *
*/ */
private String reason; private String reason;
/** /**
* 1 * 1
*/ */
private String remark1; private String remark1;
/** /**
* 2 * 2
*/ */
private String remark2; private String remark2;
/** /**
* 3 * 3
*/ */
private String remark3; private String remark3;
/** /**
* 4 * 4
*/ */
private String remark4; private String remark4;
/** /**
* 5 * 5
*/ */
private String remark5; private String remark5;

@ -0,0 +1,147 @@
package com.ruoyi.wms.domain.vo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author Alan Scipio
* created on 2024/3/6
*/
@Data
public class StockVo {
/**
* : 1.
*/
public static final int INSTOCK = 1;
/**
* : 2.
*/
public static final int OUTSTOCK = 2;
/**
*
*/
private Integer stockType;
/**
*
*/
private String whsCd;
/**
*
*/
private String stgBinCd;
/**
*
*/
private String lotNo;
/**
*
*/
private String subLotNo;
/**
*
*/
private String itemCd;
/**
* ID
*/
private Integer deptId;
/**
*
*/
private BigDecimal stdUnitQty;
/**
*
*/
private BigDecimal pkgUnitQty;
/**
* ID
*/
private String palletId;
/**
*
*/
private String operator;
/**
*
*/
private String businessCls;
/**
*
*/
private String serialNo;
/**
*
*/
private String reason;
/**
*
*/
private String transOrderNo;
/**
*
*/
private String transOrderDetlNo;
@JsonIgnore
public boolean isOutstock() {
return stockType != null && stockType == OUTSTOCK;
}
@JsonIgnore
public boolean isInstock() {
return stockType != null && stockType == INSTOCK;
}
@JsonIgnore
public boolean equalsKey(StockVo stockVo) {
if (stockVo == null) {
return false;
}
if (stockType == null || !stockType.equals(stockVo.stockType)) {
return false;
}
if (whsCd == null || !whsCd.equals(stockVo.whsCd)) {
return false;
}
if (stgBinCd == null || !stgBinCd.equals(stockVo.stgBinCd)) {
return false;
}
if (itemCd == null || !itemCd.equals(stockVo.itemCd)) {
return false;
}
if (lotNo != null && !lotNo.equals(stockVo.lotNo)) {
return false;
}
if (subLotNo != null && !subLotNo.equals(stockVo.subLotNo)) {
return false;
}
if (stdUnitQty != null && stdUnitQty.compareTo(stockVo.stdUnitQty) != 0) {
return false;
}
if (pkgUnitQty != null && pkgUnitQty.compareTo(stockVo.pkgUnitQty) != 0) {
return false;
}
return true;
}
}

@ -0,0 +1,23 @@
package com.ruoyi.wms.exception;
import com.ruoyi.common.core.exception.base.BaseException;
/**
*
*
* @author Alan Scipio
* created on 2024/3/6
*/
public class StockException extends BaseException {
public StockException(String code, Object[] args, String defaultMessage) {
super("wms.stock", code, args, defaultMessage);
}
public StockException(String code, Object[] args) {
super("wms.stock", code, args);
}
public StockException(String defaultMessage) {
super("wms.stock", defaultMessage);
}
}

@ -59,4 +59,13 @@ public interface IItemInfoService {
* @return * @return
*/ */
int deleteItemInfoByItemCd(String itemCd); int deleteItemInfoByItemCd(String itemCd);
/**
*
*
* @param itemCd
* @param deleteIfLogicDeleted truenull
* @return null:; not null:
*/
ItemInfo checkItemCdExists(String itemCd, boolean deleteIfLogicDeleted);
} }

@ -58,4 +58,17 @@ public interface IUnitInfoService {
* @return * @return
*/ */
int deleteUnitInfoByUnitCode(String unitCode); int deleteUnitInfoByUnitCode(String unitCode);
/**
*
*
* @param unitName
* @param remark
*/
void addIfNotExist(String unitName, String remark);
default void addIfNotExist(String unitName) {
addIfNotExist(unitName, null);
}
} }

@ -1,8 +1,8 @@
package com.ruoyi.wms.service.master; package com.ruoyi.wms.service.master;
import java.util.List; import com.ruoyi.wms.domain.WarehouseInfo;
import com.ruoyi.wms.domain .WarehouseInfo; import java.util.List;
/** /**
* Service * Service
@ -58,4 +58,13 @@ public interface IWarehouseInfoService {
* @return * @return
*/ */
int deleteWarehouseInfoByWhsCd(String whsCd); int deleteWarehouseInfoByWhsCd(String whsCd);
/**
*
*
* @param whsCd
* @param deleteIfLogicDeleted truenull
* @return null:; not null:
*/
WarehouseInfo checkWhsCdExists(String whsCd, boolean deleteIfLogicDeleted);
} }

@ -46,8 +46,10 @@ public class ItemInfoServiceImpl implements IItemInfoService {
*/ */
@Override @Override
public ItemInfo selectItemInfoByItemCd(String itemCd) { public ItemInfo selectItemInfoByItemCd(String itemCd) {
Optional<ItemInfo> result = itemInfoMapper.selectOne(dsl -> dsl.where(ItemInfoDynamicSqlSupport.itemCd, SqlBuilder.isEqualTo(itemCd))); ItemInfo queryForm = new ItemInfo();
return result.orElse(null); queryForm.setItemCd(itemCd);
List<ItemInfo> result = itemInfoExtMapper.selectPageList(queryForm);
return result.isEmpty() ? null : result.getFirst();
} }
/** /**
@ -70,6 +72,12 @@ public class ItemInfoServiceImpl implements IItemInfoService {
@Transactional @Transactional
@Override @Override
public AjaxResult insertItemInfo(ItemInfo item) { public AjaxResult insertItemInfo(ItemInfo item) {
//检查物品代码是否已存在
ItemInfo oldRecord = checkItemCdExists(item.getItemCd(), true);
if (oldRecord != null) {
//存在未删除的记录
return AjaxResult.error("物品代码[" + item.getItemCd() + "]已存在");
}
//上传图片文件 //上传图片文件
String uploadErrMsg = uploadItemImage(item); String uploadErrMsg = uploadItemImage(item);
if (StringUtils.isNotBlank(uploadErrMsg)) { if (StringUtils.isNotBlank(uploadErrMsg)) {
@ -135,6 +143,30 @@ public class ItemInfoServiceImpl implements IItemInfoService {
return itemInfoMapper.updateByPrimaryKey(record); return itemInfoMapper.updateByPrimaryKey(record);
} }
/**
*
*
* @param itemCd
* @param deleteIfLogicDeleted truenull
* @return null:; not null:
*/
@Transactional
@Override
public ItemInfo checkItemCdExists(String itemCd, boolean deleteIfLogicDeleted) {
Optional<ItemInfo> itemInfo = itemInfoMapper.selectOne(dsl -> dsl.where(ItemInfoDynamicSqlSupport.itemCd, SqlBuilder.isEqualTo(itemCd)));
if (itemInfo.isEmpty()) {
return null;
} else {
ItemInfo result = itemInfo.get();
if (deleteIfLogicDeleted && result.isLogicDeleted()) {
//顺带物理删除掉
itemInfoMapper.deleteByPrimaryKey(result.getItemCd());
return null;
}
return result;
}
}
/** /**
* *
* *

@ -15,6 +15,7 @@ import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -70,8 +71,20 @@ public class UnitInfoServiceImpl implements IUnitInfoService {
* @param unitInfo * @param unitInfo
* @return * @return
*/ */
@Transactional
@Override @Override
public int insertUnitInfo(UnitInfo unitInfo) { public int insertUnitInfo(UnitInfo unitInfo) {
//检查是否已存在单位名称
UnitInfo existsRecord = selectByUnitName(unitInfo.getUnitName());
if (existsRecord != null) {
if (existsRecord.isLogicDeleted()) {
//物理删除掉旧数据
unitInfoMapper.deleteByPrimaryKey(existsRecord.getUnitCode());
} else {
throw new IllegalArgumentException("单位名称已存在");
}
}
//单位代码为空时生成
if (StringUtils.isBlank(unitInfo.getUnitCode())) { if (StringUtils.isBlank(unitInfo.getUnitCode())) {
String unitCode = sequenceService.getNextSequence(SeqType.UNIT_CD); String unitCode = sequenceService.getNextSequence(SeqType.UNIT_CD);
unitInfo.setUnitCode(unitCode); unitInfo.setUnitCode(unitCode);
@ -85,6 +98,7 @@ public class UnitInfoServiceImpl implements IUnitInfoService {
* @param unitInfo * @param unitInfo
* @return * @return
*/ */
@Transactional
@Override @Override
public int updateUnitInfo(UnitInfo unitInfo) { public int updateUnitInfo(UnitInfo unitInfo) {
return unitInfoMapper.updateByPrimaryKeySelective(unitInfo); return unitInfoMapper.updateByPrimaryKeySelective(unitInfo);
@ -96,6 +110,7 @@ public class UnitInfoServiceImpl implements IUnitInfoService {
* @param unitCodes * @param unitCodes
* @return * @return
*/ */
@Transactional
@Override @Override
public int deleteUnitInfoByUnitCodes(String[] unitCodes) { public int deleteUnitInfoByUnitCodes(String[] unitCodes) {
String userId = SecurityUtilsExt.getUserIdStr(); String userId = SecurityUtilsExt.getUserIdStr();
@ -115,6 +130,7 @@ public class UnitInfoServiceImpl implements IUnitInfoService {
* @param unitCode * @param unitCode
* @return * @return
*/ */
@Transactional
@Override @Override
public int deleteUnitInfoByUnitCode(String unitCode) { public int deleteUnitInfoByUnitCode(String unitCode) {
UnitInfo record = new UnitInfo(); UnitInfo record = new UnitInfo();
@ -122,4 +138,38 @@ public class UnitInfoServiceImpl implements IUnitInfoService {
record.setDeleteFlag(ExtBaseEntity.DELETED); record.setDeleteFlag(ExtBaseEntity.DELETED);
return unitInfoMapper.updateByPrimaryKey(record); return unitInfoMapper.updateByPrimaryKey(record);
} }
/**
*
*
* @param unitName
* @param remark
*/
@Transactional
@Override
public void addIfNotExist(String unitName, String remark) {
UnitInfo existsRecord = selectByUnitName(unitName);
if (existsRecord != null) {
if (!existsRecord.isLogicDeleted()) {
String unitCode = sequenceService.getNextSequence(SeqType.UNIT_CD);
existsRecord.setUnitCode(unitCode);
existsRecord.setDeleteFlag(ExtBaseEntity.NOT_DELETE);
existsRecord.setRemark1(remark == null ? "" : remark);
unitInfoMapper.updateByPrimaryKeySelective(existsRecord);
}
} else {
UnitInfo newRecord = new UnitInfo();
String unitCode = sequenceService.getNextSequence(SeqType.UNIT_CD);
newRecord.setUnitCode(unitCode);
newRecord.setUnitName(unitName);
newRecord.setRemark1(remark);
unitInfoMapper.insertSelective(newRecord);
}
}
private UnitInfo selectByUnitName(String unitName) {
Optional<UnitInfo> result = unitInfoMapper.selectOne(dsl -> dsl.where(UnitInfoDynamicSqlSupport.unitName, SqlBuilder.isEqualTo(unitName)));
return result.orElse(null);
}
} }

@ -15,6 +15,7 @@ import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -70,8 +71,16 @@ public class WarehouseInfoServiceImpl implements IWarehouseInfoService {
* @param warehouseInfo * @param warehouseInfo
* @return * @return
*/ */
@Transactional
@Override @Override
public int insertWarehouseInfo(WarehouseInfo warehouseInfo) { public int insertWarehouseInfo(WarehouseInfo warehouseInfo) {
// 检查是否存在未删除的记录
// WarehouseInfo existsRecord = checkWhsCdExists(warehouseInfo.getWhsCd(), true);
// if (existsRecord != null) {
// //存在未删除的记录
// throw new IllegalArgumentException("仓库代码[" + warehouseInfo.getWhsCd() + "]已存在");
// }
// 仓库代码为空时,自动生成
if (StringUtils.isBlank(warehouseInfo.getWhsCd())) { if (StringUtils.isBlank(warehouseInfo.getWhsCd())) {
String whsCd = sequenceService.getNextSequence(SeqType.WHS_CD); String whsCd = sequenceService.getNextSequence(SeqType.WHS_CD);
warehouseInfo.setWhsCd(whsCd); warehouseInfo.setWhsCd(whsCd);
@ -85,6 +94,7 @@ public class WarehouseInfoServiceImpl implements IWarehouseInfoService {
* @param warehouseInfo * @param warehouseInfo
* @return * @return
*/ */
@Transactional
@Override @Override
public int updateWarehouseInfo(WarehouseInfo warehouseInfo) { public int updateWarehouseInfo(WarehouseInfo warehouseInfo) {
return warehouseInfoMapper.updateByPrimaryKeySelective(warehouseInfo); return warehouseInfoMapper.updateByPrimaryKeySelective(warehouseInfo);
@ -96,6 +106,7 @@ public class WarehouseInfoServiceImpl implements IWarehouseInfoService {
* @param whsCds * @param whsCds
* @return * @return
*/ */
@Transactional
@Override @Override
public int deleteWarehouseInfoByWhsCds(String[] whsCds) { public int deleteWarehouseInfoByWhsCds(String[] whsCds) {
String userId = SecurityUtilsExt.getUserIdStr(); String userId = SecurityUtilsExt.getUserIdStr();
@ -115,6 +126,7 @@ public class WarehouseInfoServiceImpl implements IWarehouseInfoService {
* @param whsCd * @param whsCd
* @return * @return
*/ */
@Transactional
@Override @Override
public int deleteWarehouseInfoByWhsCd(String whsCd) { public int deleteWarehouseInfoByWhsCd(String whsCd) {
WarehouseInfo record = new WarehouseInfo(); WarehouseInfo record = new WarehouseInfo();
@ -123,4 +135,26 @@ public class WarehouseInfoServiceImpl implements IWarehouseInfoService {
record.setUpdateTime(DateUtils.getNowDate()); record.setUpdateTime(DateUtils.getNowDate());
return warehouseInfoMapper.updateByPrimaryKey(record); return warehouseInfoMapper.updateByPrimaryKey(record);
} }
/**
*
*
* @param whsCd
* @param deleteIfLogicDeleted truenull
* @return null:; not null:
*/
@Transactional
@Override
public WarehouseInfo checkWhsCdExists(String whsCd, boolean deleteIfLogicDeleted) {
Optional<WarehouseInfo> result = warehouseInfoMapper.selectOne(dsl -> dsl.where(WarehouseInfoDynamicSqlSupport.whsCd, SqlBuilder.isEqualTo(whsCd)));
if (result.isEmpty()) {
return null;
}
WarehouseInfo warehouseInfo = result.get();
if (deleteIfLogicDeleted && warehouseInfo.isLogicDeleted()) {
warehouseInfoMapper.deleteByPrimaryKey(whsCd);
return null;
}
return warehouseInfo;
}
} }

@ -1,11 +1,18 @@
package com.ruoyi.wms.service.stock; package com.ruoyi.wms.service.stock;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.domain.ExtBaseEntity; import com.ruoyi.common.core.web.domain.ExtBaseEntity;
import com.ruoyi.wms.domain.BaseStock; import com.ruoyi.wms.domain.BaseStock;
import com.ruoyi.wms.domain.ItemInfo;
import com.ruoyi.wms.domain.WarehouseInfo;
import com.ruoyi.wms.domain.vo.StockVo;
import com.ruoyi.wms.exception.StockException;
import com.ruoyi.wms.mapper.stock.BaseStockDynamicSqlSupport; import com.ruoyi.wms.mapper.stock.BaseStockDynamicSqlSupport;
import com.ruoyi.wms.mapper.stock.BaseStockExtMapper; import com.ruoyi.wms.mapper.stock.BaseStockExtMapper;
import com.ruoyi.wms.mapper.stock.BaseStockMapper; import com.ruoyi.wms.mapper.stock.BaseStockMapper;
import com.ruoyi.wms.service.master.IItemInfoService;
import com.ruoyi.wms.service.master.IWarehouseInfoService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.mybatis.dynamic.sql.SqlBuilder; import org.mybatis.dynamic.sql.SqlBuilder;
import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.render.RenderingStrategies;
@ -15,7 +22,6 @@ import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
@ -34,8 +40,12 @@ public class BaseStockServiceImpl implements IBaseStockService {
private BaseStockExtMapper baseStockExtMapper; private BaseStockExtMapper baseStockExtMapper;
@Resource @Resource
private IInvTransHisService invTransHisService; private IInvTransHisService invTransHisService;
@Resource
private IWarehouseInfoService warehouseInfoService;
@Resource
private IItemInfoService itemInfoService;
private final Queue<BaseStock> dataQueue = new ConcurrentLinkedQueue<>(); private final Queue<StockVo> dataQueue = new ConcurrentLinkedQueue<>();
/** /**
* *
@ -45,14 +55,14 @@ public class BaseStockServiceImpl implements IBaseStockService {
*/ */
@Override @Override
public BaseStock selectBaseStockByPK(String whsCd, String stgBinCd, String itemCd, String lotNo, String subLotNo) { public BaseStock selectBaseStockByPK(String whsCd, String stgBinCd, String itemCd, String lotNo, String subLotNo) {
Optional<BaseStock> result = baseStockMapper.selectOne(dsl -> BaseStock queryForm = new BaseStock();
dsl.where(BaseStockDynamicSqlSupport.whsCd, SqlBuilder.isEqualTo(whsCd)) queryForm.setWhsCd(whsCd);
.and(BaseStockDynamicSqlSupport.stgBinCd, SqlBuilder.isEqualTo(stgBinCd)) queryForm.setStgBinCd(stgBinCd);
.and(BaseStockDynamicSqlSupport.itemCd, SqlBuilder.isEqualTo(itemCd)) queryForm.setItemCd(itemCd);
.and(BaseStockDynamicSqlSupport.lotNo, SqlBuilder.isEqualTo(lotNo)) queryForm.setLotNo(lotNo);
.and(BaseStockDynamicSqlSupport.subLotNo, SqlBuilder.isEqualTo(subLotNo)) queryForm.setSubLotNo(subLotNo);
); List<BaseStock> result = baseStockExtMapper.selectPageList(queryForm);
return result.orElse(null); return result.isEmpty() ? null : result.getFirst();
} }
/** /**
@ -69,78 +79,142 @@ public class BaseStockServiceImpl implements IBaseStockService {
/** /**
* *
* *
* @param baseStock * @param stockVo
* @return * @return
*/ */
@Transactional @Transactional
@Override @Override
public AjaxResult instock(BaseStock baseStock) { public AjaxResult instock(StockVo stockVo) {
//TODO 参数检查 // 参数检查
AjaxResult checkResult = checkInoutStock(stockVo);
//队列维持数据一致性 if (!checkResult.isSuccess()) {
dataQueue.offer(baseStock); return checkResult;
BaseStock data = dataQueue.remove(); }
doInoutStock(data); // 队列维持数据一致性
stockVo.setStockType(StockVo.INSTOCK);
dataQueue.offer(stockVo);
StockVo data = null;
while (data == null || !data.equalsKey(stockVo)) {
data = dataQueue.remove();
doInoutStock(data);
}
return AjaxResult.success(); return AjaxResult.success();
} }
/** /**
* *
* *
* @param baseStock * @param stockVo
* @return * @return
*/ */
@Transactional @Transactional
@Override @Override
public AjaxResult outstock(BaseStock baseStock) { public AjaxResult outstock(StockVo stockVo) {
//TODO 参数检查 // 参数检查
AjaxResult checkResult = checkInoutStock(stockVo);
//队列维持数据一致性 if (!checkResult.isSuccess()) {
dataQueue.offer(baseStock); return checkResult;
BaseStock data = dataQueue.remove(); }
doInoutStock(data); // 队列维持数据一致性
stockVo.setStockType(StockVo.OUTSTOCK);
dataQueue.offer(stockVo);
StockVo data = null;
while (data == null || !data.equalsKey(stockVo)) {
data = dataQueue.remove();
doInoutStock(data);
}
return AjaxResult.success(); return AjaxResult.success();
} }
/** /**
* *
*/ */
private void doInoutStock(BaseStock form) { private void doInoutStock(StockVo stockVo) {
//查询库存 //查询库存
List<BaseStock> stockList = queryWhenInoutStock(form); List<BaseStock> stockList = queryWhenInoutStock(stockVo);
//更新库存 //更新库存
if (stockList.isEmpty()) { if (stockList.isEmpty()) {
if (stockVo.isOutstock()) {
throw new StockException("库存不足");
}
//insert //insert
baseStockMapper.insert(form); BaseStock newRecord = buildNewRecord(stockVo);
//TODO 写入出库履历 baseStockMapper.insertSelective(newRecord);
//写入出库履历
invTransHisService.addInvTransHis(stockVo);
} else { } else {
//update //update
BaseStock oldRecord = stockList.getFirst(); BaseStock oldRecord = stockList.getFirst();
BigDecimal newStdUnitQty = oldRecord.getStdUnitQty().add(form.getStdUnitQty()); if (stockVo.isOutstock()) {
BigDecimal newPkgUnitQty = oldRecord.getPkgUnitQty().add(form.getPkgUnitQty()); //出库时的检查
oldRecord.setStdUnitQty(newStdUnitQty); if (oldRecord.getStdUnitQty().compareTo(stockVo.getStdUnitQty()) < 0) {
oldRecord.setPkgUnitQty(newPkgUnitQty); throw new StockException("库存不足");
baseStockMapper.updateByPrimaryKey(oldRecord); }
//TODO 写入出库履历 }
BaseStock updateRecord = buildUpdateRecord(stockVo, oldRecord);
baseStockMapper.updateByPrimaryKeySelective(updateRecord);
//写入出库履历
invTransHisService.addInvTransHis(stockVo);
}
}
/**
*
*/
private AjaxResult checkInoutStock(StockVo stockVo) {
//非空检查
if (stockVo == null) {
return AjaxResult.error("stockVo is null");
}
if (stockVo.getStockType() == null || stockVo.getStockType() < 1 || stockVo.getStockType() > 2) {
return AjaxResult.error("入出库类型为空或不合法");
}
if (StringUtils.isBlank(stockVo.getWhsCd())) {
return AjaxResult.error("仓库代码为空");
} }
if (StringUtils.isBlank(stockVo.getStgBinCd())) {
return AjaxResult.error("货架号为空");
}
if (StringUtils.isBlank(stockVo.getItemCd())) {
return AjaxResult.error("物品代码为空");
}
if (stockVo.getStdUnitQty() == null) {
return AjaxResult.error("标准单位数量为空");
}
if (stockVo.getStdUnitQty().compareTo(BigDecimal.ZERO) < 0) {
return AjaxResult.error("标准单位数量不能小于0");
}
if (stockVo.getPkgUnitQty() != null && stockVo.getPkgUnitQty().compareTo(BigDecimal.ZERO) < 0) {
return AjaxResult.error("包装单位数量不能小于0");
}
//检查仓库代码是否存在
WarehouseInfo warehouseInfo = warehouseInfoService.checkWhsCdExists(stockVo.getWhsCd(), false);
if (warehouseInfo == null || warehouseInfo.isLogicDeleted()) {
return AjaxResult.error("仓库不存在");
}
//检查物品代码是否存在
ItemInfo itemInfo = itemInfoService.checkItemCdExists(stockVo.getItemCd(), false);
if (itemInfo == null || itemInfo.isLogicDeleted()) {
return AjaxResult.error("物品不存在");
}
return AjaxResult.success();
} }
/** /**
* *
* *
* @param form * @param stockVo
* @return * @return
*/ */
private List<BaseStock> queryWhenInoutStock(BaseStock form) { private List<BaseStock> queryWhenInoutStock(StockVo stockVo) {
SelectStatementProvider query = SqlBuilder.select(BaseStockMapper.selectList) SelectStatementProvider query = SqlBuilder.select(BaseStockMapper.selectList)
.from(BaseStockDynamicSqlSupport.baseStock) .from(BaseStockDynamicSqlSupport.baseStock)
.where(BaseStockDynamicSqlSupport.deleteFlag, SqlBuilder.isEqualTo(ExtBaseEntity.NOT_DELETE)) .where(BaseStockDynamicSqlSupport.deleteFlag, SqlBuilder.isEqualTo(ExtBaseEntity.NOT_DELETE))
.and(BaseStockDynamicSqlSupport.whsCd, SqlBuilder.isEqualTo(form.getWhsCd())) .and(BaseStockDynamicSqlSupport.whsCd, SqlBuilder.isEqualTo(stockVo.getWhsCd()))
.and(BaseStockDynamicSqlSupport.stgBinCd, SqlBuilder.isEqualTo(form.getStgBinCd())) .and(BaseStockDynamicSqlSupport.stgBinCd, SqlBuilder.isEqualTo(stockVo.getStgBinCd()))
.and(BaseStockDynamicSqlSupport.itemCd, SqlBuilder.isEqualTo(form.getItemCd())) .and(BaseStockDynamicSqlSupport.itemCd, SqlBuilder.isEqualTo(stockVo.getItemCd()))
.and(BaseStockDynamicSqlSupport.lotNo, SqlBuilder.isEqualTo(form.getLotNo())) .and(BaseStockDynamicSqlSupport.lotNo, SqlBuilder.isEqualTo(stockVo.getLotNo()))
.and(BaseStockDynamicSqlSupport.subLotNo, SqlBuilder.isEqualTo(form.getSubLotNo())) .and(BaseStockDynamicSqlSupport.subLotNo, SqlBuilder.isEqualTo(stockVo.getSubLotNo()))
.orderBy(BaseStockDynamicSqlSupport.createTime.descending()) .orderBy(BaseStockDynamicSqlSupport.createTime.descending())
.limit(1) .limit(1)
.build() .build()
@ -148,4 +222,38 @@ public class BaseStockServiceImpl implements IBaseStockService {
return baseStockMapper.selectMany(query); return baseStockMapper.selectMany(query);
} }
private BaseStock buildNewRecord(StockVo stockVo) {
BaseStock record = new BaseStock();
record.setWhsCd(stockVo.getWhsCd());
record.setStgBinCd(stockVo.getStgBinCd());
record.setItemCd(stockVo.getItemCd());
record.setLotNo(stockVo.getLotNo());
record.setSubLotNo(stockVo.getSubLotNo());
record.setStdUnitQty(stockVo.getStdUnitQty());
record.setPkgUnitQty(stockVo.getPkgUnitQty());
return record;
}
private BaseStock buildUpdateRecord(StockVo stockVo, BaseStock oldRecord) {
// 标准单位数量
if (stockVo.isOutstock()) {
//出库数量为负数
stockVo.setStdUnitQty(stockVo.getStdUnitQty().negate());
}
BigDecimal newStdUnitQty = oldRecord.getStdUnitQty().add(stockVo.getStdUnitQty());
oldRecord.setStdUnitQty(newStdUnitQty);
// 包装单位数量
if (stockVo.getPkgUnitQty() != null) {
if (stockVo.isOutstock()) {
//出库数量为负数
stockVo.setPkgUnitQty(stockVo.getPkgUnitQty().negate());
}
BigDecimal newPkgUnitQty = oldRecord.getPkgUnitQty().add(stockVo.getPkgUnitQty());
oldRecord.setPkgUnitQty(newPkgUnitQty);
}
return oldRecord;
}
} }

@ -2,6 +2,7 @@ package com.ruoyi.wms.service.stock;
import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.wms.domain.BaseStock; import com.ruoyi.wms.domain.BaseStock;
import com.ruoyi.wms.domain.vo.StockVo;
import java.util.List; import java.util.List;
@ -32,17 +33,17 @@ public interface IBaseStockService {
/** /**
* *
* *
* @param baseStock * @param form
* @return * @return
*/ */
AjaxResult instock(BaseStock baseStock) throws Exception; AjaxResult instock(StockVo form) throws Exception;
/** /**
* *
* *
* @param baseStock * @param form
* @return * @return
*/ */
AjaxResult outstock(BaseStock baseStock) throws Exception; AjaxResult outstock(StockVo form) throws Exception;
} }

@ -1,6 +1,7 @@
package com.ruoyi.wms.service.stock; package com.ruoyi.wms.service.stock;
import com.ruoyi.wms.domain.InvTransHis; import com.ruoyi.wms.domain.InvTransHis;
import com.ruoyi.wms.domain.vo.StockVo;
import java.util.List; import java.util.List;
@ -42,4 +43,11 @@ public interface IInvTransHisService {
* @return * @return
*/ */
int deleteInvTransHisByInvTransNo(String invTransNo); int deleteInvTransHisByInvTransNo(String invTransNo);
/**
*
*
* @param stockVo
*/
void addInvTransHis(StockVo stockVo);
} }

@ -1,9 +1,12 @@
package com.ruoyi.wms.service.stock; package com.ruoyi.wms.service.stock;
import com.ruoyi.common.core.utils.DateUtils; import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.uuid.snowflake.SnowFlakeIdGenerator;
import com.ruoyi.common.core.web.domain.ExtBaseEntity; import com.ruoyi.common.core.web.domain.ExtBaseEntity;
import com.ruoyi.common.security.utils.SecurityUtilsExt; import com.ruoyi.common.security.utils.SecurityUtilsExt;
import com.ruoyi.wms.domain.InvTransHis; import com.ruoyi.wms.domain.InvTransHis;
import com.ruoyi.wms.domain.vo.StockVo;
import com.ruoyi.wms.mapper.stock.InvTransHisDynamicSqlSupport; import com.ruoyi.wms.mapper.stock.InvTransHisDynamicSqlSupport;
import com.ruoyi.wms.mapper.stock.InvTransHisExtMapper; import com.ruoyi.wms.mapper.stock.InvTransHisExtMapper;
import com.ruoyi.wms.mapper.stock.InvTransHisMapper; import com.ruoyi.wms.mapper.stock.InvTransHisMapper;
@ -89,4 +92,51 @@ public class InvTransHisServiceImpl implements IInvTransHisService {
record.setUpdateTime(DateUtils.getNowDate()); record.setUpdateTime(DateUtils.getNowDate());
return invTransHisMapper.updateByPrimaryKey(record); return invTransHisMapper.updateByPrimaryKey(record);
} }
/**
*
*
* @param stockVo
*/
@Transactional
@Override
public void addInvTransHis(StockVo stockVo) {
if (stockVo == null) {
throw new IllegalArgumentException("stockVo is null");
}
if (stockVo.getStockType() == null || stockVo.getStockType() < 1 || stockVo.getStockType() > 2) {
throw new IllegalArgumentException("stockType is null or invalid");
}
if (StringUtils.isBlank(stockVo.getWhsCd())) {
throw new IllegalArgumentException("whsCd is blank");
}
if (StringUtils.isBlank(stockVo.getStgBinCd())) {
throw new IllegalArgumentException("stgBinCd is blank");
}
if (StringUtils.isBlank(stockVo.getItemCd())) {
throw new IllegalArgumentException("itemCd is blank");
}
if (stockVo.getStdUnitQty() == null) {
throw new IllegalArgumentException("stdUnitQty is null");
}
InvTransHis record = new InvTransHis();
record.setInvTransType(stockVo.getStockType()); // 入出库类型(1:入库,2:出库)
record.setWhsCd(stockVo.getWhsCd()); // 仓库代码
record.setStgBinCd(stockVo.getStgBinCd()); // 货架号
record.setLotNo(stockVo.getLotNo()); // 批号
record.setSubLotNo(stockVo.getSubLotNo()); // 子批号
record.setItemCd(stockVo.getItemCd()); // 物品代码
record.setStdUnitQty(stockVo.getStdUnitQty()); // 标准单位数量
record.setPkgUnitQty(stockVo.getPkgUnitQty()); // 包装单位数量
record.setPalletId(stockVo.getPalletId()); // 托盘ID
record.setSerialNo(stockVo.getSerialNo()); // 序列号
record.setBusinessCls(stockVo.getBusinessCls()); // 业务分类
record.setReason(stockVo.getReason()); // 入出库理由
record.setTransOrderNo(stockVo.getTransOrderNo()); // 交易单号
record.setTransOrderDetlNo(stockVo.getTransOrderDetlNo()); // 交易单明细号
record.setDeptId(stockVo.getDeptId()); // 从属部门ID
record.setOperator(SecurityUtilsExt.getUsernameFromRedis()); // 操作人
record.setInvTransNo(SnowFlakeIdGenerator.nextId()); // 入出库履历号
invTransHisMapper.insertSelective(record);
}
} }

@ -74,6 +74,9 @@
<if test="lotNo != null and lotNo != ''"> <if test="lotNo != null and lotNo != ''">
and t.LOT_NO like concat('%', #{lotNo}, '%') and t.LOT_NO like concat('%', #{lotNo}, '%')
</if> </if>
<if test="subLotNo != null and subLotNo != ''">
and t.SUB_LOT_NO like concat('%', #{subLotNo}, '%')
</if>
</where> </where>
</select> </select>

@ -1,5 +1,5 @@
# 页面标题 # 页面标题
VITE_APP_TITLE=RYAS管理系统 VITE_APP_TITLE=RYAS
# 环境指定 # 环境指定
VITE_APP_ENV='development' VITE_APP_ENV='development'

@ -7,7 +7,7 @@
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="/favicon.ico"> <link rel="icon" href="/favicon.ico">
<title>RYAS管理系统</title> <title>RYAS</title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]--> <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style> <style>
html, html,

@ -17,3 +17,23 @@ export function getBaseStock(data) {
data: data data: data
}) })
} }
// 入库
export function instock(data) {
data.stockType = 1;
return request({
url: '/wms/BaseStock/instock',
method: 'post',
data: data
})
}
// 出库
export function outstock(data) {
data.stockType = 2;
return request({
url: '/wms/BaseStock/outstock',
method: 'post',
data: data
})
}

@ -2,12 +2,6 @@
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="仓库" prop="whsCd"> <el-form-item label="仓库" prop="whsCd">
<!-- <el-input-->
<!-- v-model="queryParams.whsCd"-->
<!-- placeholder="请输入仓库代码"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- />-->
<data-select v-model="queryParams.whsCd" :fetch-data="fetchWarehouseData" /> <data-select v-model="queryParams.whsCd" :fetch-data="fetchWarehouseData" />
</el-form-item> </el-form-item>
<el-form-item label="货架号" prop="stgBinCd"> <el-form-item label="货架号" prop="stgBinCd">
@ -52,25 +46,25 @@
v-hasPermi="['wms:BaseStock:export']" v-hasPermi="['wms:BaseStock:export']"
>导出</el-button> >导出</el-button>
</el-col> </el-col>
<!-- <el-col :span="1.5">--> <el-col :span="1.5">
<!-- <el-button--> <el-button
<!-- type="primary"--> type="primary"
<!-- plain--> plain
<!-- icon="Plus"--> icon="Plus"
<!-- @click="handleInstock"--> @click="handleInstock"
<!-- v-hasPermi="['wms:BaseStock:instock']"--> v-hasPermi="['wms:BaseStock:instock']"
<!-- >入库</el-button>--> >入库</el-button>
<!-- </el-col>--> </el-col>
<!-- <el-col :span="1.5">--> <el-col :span="1.5">
<!-- <el-button--> <el-button
<!-- type="success"--> type="success"
<!-- plain--> plain
<!-- icon="Edit"--> icon="Edit"
<!-- :disabled="single"--> :disabled="single"
<!-- @click="handleOutstock"--> @click="handleOutstock"
<!-- v-hasPermi="['wms:BaseStock:outstock']"--> v-hasPermi="['wms:BaseStock:outstock']"
<!-- >出库</el-button>--> >出库</el-button>
<!-- </el-col>--> </el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
@ -92,8 +86,8 @@
<el-table-column label="包装单位" align="center" prop="pkgUnitName" /> <el-table-column label="包装单位" align="center" prop="pkgUnitName" />
</el-table-column> </el-table-column>
<el-table-column label="序列号" align="center" prop="serialNo" /> <el-table-column label="序列号" align="center" prop="serialNo" />
<el-table-column label="托盘ID" align="center" prop="palletId" /> <!-- <el-table-column label="托盘ID" align="center" prop="palletId" />-->
<el-table-column label="父托盘ID" align="center" prop="parentPalletId" /> <!-- <el-table-column label="父托盘ID" align="center" prop="parentPalletId" />-->
</el-table> </el-table>
<pagination <pagination
@ -105,8 +99,99 @@
/> />
<!-- 入出库对话框 --> <!-- 入出库对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body> <el-dialog :title="title" v-model="open" width="650px" append-to-body>
<el-form ref="BaseStockRef" :model="form" :rules="rules" label-width="80px"> <el-form ref="BaseStockRef" :model="form" :rules="rules" label-width="90px">
<el-row>
<el-col :span="12">
<el-form-item label="仓库代码" prop="whsCd">
<data-select v-model="form.whsCd" :fetch-data="fetchWarehouseData" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="货架号" prop="stgBinCd">
<el-input v-model="form.stgBinCd" placeholder="请输入货架号"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="物品代码" prop="itemCd">
<el-input v-model="form.itemCd" placeholder="请输入物品代码" @blur="handleItemInfoBlur"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物品名称" prop="itemName">
<el-input v-model="form.itemName" disabled/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="批号" prop="lotNo">
<el-input v-model="form.lotNo" placeholder="请输入批号"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="子批号" prop="itemName">
<el-input v-model="form.subLotNo" placeholder="请输入子批号"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="数量" prop="stdUnitQty">
<el-input-number v-model="form.stdUnitQty" placeholder="标准单位数量" style="width: 100%;" :precision="6" :min="0"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="标准单位" prop="stdUnitName">
<el-input v-model="form.stdUnitName" disabled/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="数量" prop="pkgUnitQty">
<el-input-number v-model="form.pkgUnitQty" placeholder="包装单位数量" style="width: 100%;" :precision="6" :min="0"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="包装单位" prop="pkgUnitName">
<el-input v-model="form.pkgUnitName" disabled/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item :label="reasonTitle" prop="reason">
<el-input v-model="form.reason" placeholder="请输入理由"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="业务区分" prop="businessCls">
<el-input v-model="form.businessCls" placeholder="请输入业务区分"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="序列号" prop="serialNo">
<el-input v-model="form.serialNo" placeholder="请输入序列号"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="交易单号" prop="transOrderNo">
<el-input v-model="form.transOrderNo" placeholder="请输入交易单号"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="交易明细号" prop="transOrderDetlNo">
<el-input v-model="form.transOrderDetlNo" placeholder="请输入交易明细号"/>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
@ -119,9 +204,11 @@
</template> </template>
<script setup name="BaseStock"> <script setup name="BaseStock">
import { listBaseStock, getBaseStock } from "@/api/wms/BaseStock" import { listBaseStock, getBaseStock, instock, outstock } from "@/api/wms/BaseStock"
import { listWarehouseInfo } from "@/api/wms/WarehouseInfo"; import { listWarehouseInfo } from "@/api/wms/WarehouseInfo";
import { getItemInfo } from "@/api/wms/ItemInfo";
import DataSelect from "@/components/DataSelect/index.vue"; import DataSelect from "@/components/DataSelect/index.vue";
import {ElLoading} from "element-plus";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
@ -134,6 +221,7 @@ const single = ref(true);
const multiple = ref(true); const multiple = ref(true);
const total = ref(0); const total = ref(0);
const title = ref(""); const title = ref("");
const reasonTitle = ref("");
const data = reactive({ const data = reactive({
form: {}, form: {},
@ -146,6 +234,18 @@ const data = reactive({
lotNo: null, lotNo: null,
}, },
rules: { rules: {
whsCd: [
{required: true, message: "仓库代码不能为空", trigger: "blur"}
],
stgBinCd: [
{required: true, message: "货架号不能为空", trigger: "blur"}
],
itemCd: [
{required: true, message: "物品代码不能为空", trigger: "blur"}
],
stdUnitQty: [
{required: true, message: "标准单位数量不能为空", trigger: "blur"},
],
} }
}); });
@ -170,29 +270,26 @@ function cancel() {
// //
function reset() { function reset() {
form.value = { form.value = {
deptId: null, stockType: null,
whsCd: null, whsCd: null,
stgBinCd: null, stgBinCd: null,
itemCd: null, itemCd: null,
lotNo: null, lotNo: '',
subLotNo: null, subLotNo: '',
stdUnitQty: null, stdUnitQty: null,
pkgUnitQty: null, pkgUnitQty: null,
serialNo: null, serialNo: null,
palletId: null, palletId: null,
parentPalletId: null, operator: null,
remark1: null, businessCls: null,
remark2: null, reason: null,
remark3: null, transOrderNo: null,
remark4: null, transOrderDetlNo: null,
remark5: null, itemName: null,
updateCount: null, stdUnitName: null,
deleteFlag: null, pkgUnitName: null,
createBy: null, itemNotExists: false,
createTime: null, lastItemCd: null, //
updateBy: null,
updateTime: null,
remark: null
}; };
proxy.resetForm("BaseStockRef"); proxy.resetForm("BaseStockRef");
} }
@ -227,38 +324,49 @@ function handleSelectionChange(selection) {
/** 入库按钮操作 */ /** 入库按钮操作 */
function handleInstock() { function handleInstock() {
reset(); reset();
open.value = true; form.value.stockType = 1;
title.value = "入库"; title.value = "入库";
reasonTitle.value = "入库理由";
open.value = true;
} }
/** 出库按钮操作 */ /** 出库按钮操作 */
function handleOutstock() { function handleOutstock() {
reset(); reset();
let primaryKey = ids.value[0] let primaryKey = ids.value[0];
getBaseStock(primaryKey).then(response => { getBaseStock(primaryKey).then(response => {
form.value = response.data; form.value = response.data;
open.value = true; form.value.stockType = 2;
form.value.stdUnitQty = 0;
form.value.pkgUnitQty = 0;
title.value = "出库"; title.value = "出库";
reasonTitle.value = "出库理由";
open.value = true;
}); });
} }
/** 提交按钮 */ /** 提交按钮 */
function submitForm() { function submitForm() {
//TODO
proxy.$refs["BaseStockRef"].validate(valid => { proxy.$refs["BaseStockRef"].validate(valid => {
if (valid) { if (valid) {
if (form.value.deptId != null) { if (form.value.itemNotExists) {
// instock(form.value).then(response => { proxy.$modal.msgError("此物品代码不存在");
// proxy.$modal.msgSuccess(""); return;
// open.value = false; }
// getList(); if (form.value.stockType === 1) {
// }); //
instock(form.value).then(response => {
proxy.$modal.msgSuccess("入库成功");
open.value = false;
getList();
});
} else { } else {
// outstock(form.value).then(response => { //
// proxy.$modal.msgSuccess(""); outstock(form.value).then(response => {
// open.value = false; proxy.$modal.msgSuccess("出库成功");
// getList(); open.value = false;
// }); getList();
});
} }
} }
}); });
@ -271,7 +379,7 @@ function handleExport() {
}, `BaseStock_${new Date().getTime()}.xlsx`) }, `BaseStock_${new Date().getTime()}.xlsx`)
} }
// /** 获取仓库数据 */
async function fetchWarehouseData() { async function fetchWarehouseData() {
const response = await listWarehouseInfo({}) const response = await listWarehouseInfo({})
const dataList = [] const dataList = []
@ -284,6 +392,29 @@ async function fetchWarehouseData() {
return dataList return dataList
} }
/** 查询物品信息 */
function handleItemInfoBlur() {
if (form.value.itemCd && form.value.itemCd !== ' ' && form.value.lastItemCd !== form.value.itemCd) {
const loadingObj = ElLoading.service({text: "正在查询物品信息 ... ...", background: "rgba(0, 0, 0, 0.7)",})
getItemInfo(form.value.itemCd).then(response => {
if (response.data) {
form.value.itemName = response.data.itemName
form.value.stdUnitName = response.data.stdUnitName
form.value.pkgUnitName = response.data.pkgUnitName
form.value.itemNotExists = false
} else {
form.value.itemName = '无此物品信息'
form.value.stdUnitName = ''
form.value.pkgUnitName = ''
form.value.itemNotExists = true
}
}).finally(() => {
loadingObj.close()
form.value.lastItemCd = form.value.itemCd
})
}
}
// //
//getList(); //getList();
</script> </script>

@ -11,7 +11,7 @@
Target Server Version : 80200 (8.2.0) Target Server Version : 80200 (8.2.0)
File Encoding : 65001 File Encoding : 65001
Date: 04/03/2024 16:13:20 Date: 06/03/2024 16:25:34
*/ */
SET NAMES utf8mb4; SET NAMES utf8mb4;
@ -51,8 +51,7 @@ CREATE TABLE `WMS_B_BASE_STOCK` (
-- ---------------------------- -- ----------------------------
-- Records of WMS_B_BASE_STOCK -- Records of WMS_B_BASE_STOCK
-- ---------------------------- -- ----------------------------
INSERT INTO `WMS_B_BASE_STOCK` VALUES (100, 'WHS001', 'A1-10-1', 'G00001', '', '', 20.000000, 0.000000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, '1', '2024-02-23 10:15:22', '1', '2024-02-23 10:15:25', NULL); INSERT INTO `WMS_B_BASE_STOCK` VALUES (100, 'WHS001', 'A-1-1', 'G00001', '', '', 15.000000, 0.000000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2, 0, '1', '2024-03-06 15:50:11', '1', '2024-03-06 16:15:43', NULL);
INSERT INTO `WMS_B_BASE_STOCK` VALUES (100, 'WHS001', 'A1-10-2', 'G00001', '', '', 50.000000, 0.000000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, '1', '2024-02-23 10:15:22', '1', '2024-02-23 10:15:25', NULL);
-- ---------------------------- -- ----------------------------
-- Table structure for WMS_B_INV_TRANS_HIS -- Table structure for WMS_B_INV_TRANS_HIS
@ -94,7 +93,8 @@ CREATE TABLE `WMS_B_INV_TRANS_HIS` (
-- ---------------------------- -- ----------------------------
-- Records of WMS_B_INV_TRANS_HIS -- Records of WMS_B_INV_TRANS_HIS
-- ---------------------------- -- ----------------------------
INSERT INTO `WMS_B_INV_TRANS_HIS` VALUES (100, 'ITN00001', 1, 'WHS0001', 'A1-10-1', NULL, 20.000000, 0.000000, NULL, NULL, NULL, '0', 'G00001', '', '', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, '1', '2024-02-23 13:50:43', '', NULL, NULL); INSERT INTO `WMS_B_INV_TRANS_HIS` VALUES (100, '6636342291713', 1, 'WHS001', 'A-1-1', NULL, 20.000000, 0.000000, NULL, NULL, 'admin', '0', 'G00001', '', '', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, '1', '2024-03-06 15:50:11', '1', '2024-03-06 15:50:11', NULL);
INSERT INTO `WMS_B_INV_TRANS_HIS` VALUES (100, '6636538433153', 2, 'WHS001', 'A-1-1', NULL, -5.000000, 0.000000, NULL, NULL, 'admin', '0', 'G00001', '', '', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, '1', '2024-03-06 16:15:43', '1', '2024-03-06 16:15:43', NULL);
-- ---------------------------- -- ----------------------------
-- Table structure for WMS_M_ITEM_INFO -- Table structure for WMS_M_ITEM_INFO
@ -582,10 +582,10 @@ INSERT INTO `sys_config` VALUES (2, '用户管理-账号初始密码', 'sys.user
INSERT INTO `sys_config` VALUES (3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', '2024-01-30 05:05:41', '', NULL, '深色主题theme-dark浅色主题theme-light'); INSERT INTO `sys_config` VALUES (3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', '2024-01-30 05:05:41', '', NULL, '深色主题theme-dark浅色主题theme-light');
INSERT INTO `sys_config` VALUES (4, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', '2024-01-30 05:05:41', '', NULL, '是否开启注册用户功能true开启false关闭'); INSERT INTO `sys_config` VALUES (4, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', '2024-01-30 05:05:41', '', NULL, '是否开启注册用户功能true开启false关闭');
INSERT INTO `sys_config` VALUES (5, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', '2024-01-30 05:05:41', '', NULL, '设置登录IP黑名单限制多个匹配项以;分隔,支持匹配(*通配、网段)'); INSERT INTO `sys_config` VALUES (5, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', '2024-01-30 05:05:41', '', NULL, '设置登录IP黑名单限制多个匹配项以;分隔,支持匹配(*通配、网段)');
INSERT INTO `sys_config` VALUES (100, '邮件-SMTP服务器', 'sys.mail.smtpHost', 'smtp.test.com', 'Y', 'admin', '2024-03-01 10:05:41', '', NULL, ''); INSERT INTO `sys_config` VALUES (100, '邮件-SMTP服务器', 'sys.mail.smtpHost', 'smtp.test.com', 'Y', 'admin', '2024-03-01 10:05:41', '1', '2024-03-04 08:39:18', '');
INSERT INTO `sys_config` VALUES (101, '邮件-SMTP服务器端口', 'sys.mail.smtpPort', '587', 'Y', 'admin', '2024-03-01 10:05:41', '', NULL, ''); INSERT INTO `sys_config` VALUES (101, '邮件-SMTP服务器端口', 'sys.mail.smtpPort', '587', 'Y', 'admin', '2024-03-01 10:05:41', '', NULL, '');
INSERT INTO `sys_config` VALUES (102, '邮件-认证用户名', 'sys.mail.username', 'sender@test.com', 'Y', 'admin', '2024-03-01 10:05:41', '', NULL, '也会作为默认发件人'); INSERT INTO `sys_config` VALUES (102, '邮件-认证用户名', 'sys.mail.username', 'sender@test.com', 'Y', 'admin', '2024-03-01 10:05:41', '1', '2024-03-04 08:39:33', '也会作为默认发件人');
INSERT INTO `sys_config` VALUES (103, '邮件-认证密码', 'sys.mail.password', 'abcdefg', 'Y', 'admin', '2024-03-01 10:05:41', '', NULL, ''); INSERT INTO `sys_config` VALUES (103, '邮件-认证密码', 'sys.mail.password', 'abcdefg', 'Y', 'admin', '2024-03-01 10:05:41', '1', '2024-03-04 08:39:56', '');
INSERT INTO `sys_config` VALUES (104, '邮件-附件保存地址', 'sys.mail.attachmentsSavedPath', 'D:\\temp\\RYAS\\mailAttachments', 'Y', 'admin', '2024-03-04 10:05:41', '', NULL, ''); INSERT INTO `sys_config` VALUES (104, '邮件-附件保存地址', 'sys.mail.attachmentsSavedPath', 'D:\\temp\\RYAS\\mailAttachments', 'Y', 'admin', '2024-03-04 10:05:41', '', NULL, '');
-- ---------------------------- -- ----------------------------
@ -834,7 +834,7 @@ CREATE TABLE `sys_logininfor` (
PRIMARY KEY (`info_id`) USING BTREE, PRIMARY KEY (`info_id`) USING BTREE,
INDEX `idx_sys_logininfor_s`(`status` ASC) USING BTREE, INDEX `idx_sys_logininfor_s`(`status` ASC) USING BTREE,
INDEX `idx_sys_logininfor_lt`(`access_time` ASC) USING BTREE INDEX `idx_sys_logininfor_lt`(`access_time` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 157 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '系统访问记录' ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 158 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '系统访问记录' ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of sys_logininfor -- Records of sys_logininfor
@ -1081,7 +1081,7 @@ CREATE TABLE `sys_oper_log` (
INDEX `idx_sys_oper_log_bt`(`business_type` ASC) USING BTREE, INDEX `idx_sys_oper_log_bt`(`business_type` ASC) USING BTREE,
INDEX `idx_sys_oper_log_s`(`status` ASC) USING BTREE, INDEX `idx_sys_oper_log_s`(`status` ASC) USING BTREE,
INDEX `idx_sys_oper_log_ot`(`oper_time` ASC) USING BTREE INDEX `idx_sys_oper_log_ot`(`oper_time` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 319 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '操作日志记录' ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 325 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '操作日志记录' ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of sys_oper_log -- Records of sys_oper_log

Loading…
Cancel
Save