盘点功能完善

This commit is contained in:
lsymicc
2026-09-15 23:10:35 +08:00
parent 39632ef960
commit 42104d892b
25 changed files with 728 additions and 85 deletions

View File

@@ -1,6 +1,6 @@
{
"name" : "若依移动端",
"appid" : "__UNI__25A9D80",
"name" : "Fortucky",
"appid" : "__UNI__05FE81B",
"description" : "",
"versionName" : "1.2.0",
"versionCode" : "100",
@@ -14,7 +14,9 @@
"autoclose" : true,
"delay" : 0
},
"modules" : {},
"modules" : {
"Barcode" : {}
},
"distribute" : {
"android" : {
"permissions" : [
@@ -35,7 +37,9 @@
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios" : {},
"ios" : {
"dSYMs" : false
},
"sdkConfigs" : {}
}
},

View File

@@ -121,6 +121,26 @@
"navigationBarTitleText": "盘点管理"
}
}, {
"path": "pages/warehouse/inventory/inventoryConfirm",
"style": {
"navigationBarTitleText": "盘点任务列表"
}
},{
"path": "pages/warehouse/inventory/inventoryConfirm",
"style": {
"navigationBarTitleText": "扫码盘点确认"
}
}, {
"path": "pages/warehouse/inventory/inventoryConfirm",
"style": {
"navigationBarTitleText": "盘点差异记录"
}
},{
"path": "pages/warehouse/inventory/inventoryConfirm",
"style": {
"navigationBarTitleText": "盘点报告"
}
},{
"path": "pages/warehouse/stock/index",
"style": {
"navigationBarTitleText": "库存统计"
@@ -158,5 +178,15 @@
"navigationBarTextStyle": "black",
"navigationBarTitleText": "RuoYi",
"navigationBarBackgroundColor": "#FFFFFF"
}
},
"condition" : { //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [
{
"name": "", //模式名称
"path": "", //启动页面,必选
"query": "" //启动参数,在页面的onLoad函数里面得到
}
]
}
}

View File

@@ -14,7 +14,7 @@
<uni-icons type="right" size="16" color="#ccc"></uni-icons>
</view>
<view class="feature-card" @click="$modal.showToast('功能开发中')">
<view class="feature-card" @click="navigateTo('/pages/warehouse/inventory/inventoryConfirm')">
<view class="feature-left">
<uni-icons type="scan" size="20" color="#fa8c16"></uni-icons>
<text class="feature-name">扫码盘点</text>
@@ -39,17 +39,26 @@
</view>
</view>
<view class="empty-tip">
<!-- <view class="empty-tip">
<text class="tip-text">盘点管理模块正在开发中,敬请期待</text>
</view>
</view> -->
</view>
</template>
<script>
export default {
data() {
return {}
}
return {
}
},
methods:{
navigateTo(url) {
this.$tab.navigateTo(url)
},
}
}
</script>

View File

@@ -21,6 +21,14 @@ public interface BasCargoSpaceMapper
*/
public BasCargoSpace selectBasCargoSpaceByCargoSpaceId(String cargoSpaceId);
/**
* 查询货位信息
*
* @param trayCode 货位信息主键
* @return 货位信息
*/
public BasCargoSpace selectBasCargoSpaceByTrayCode(String trayCode);
/**
* 查询货位信息列表
*

View File

@@ -19,6 +19,14 @@ public interface IBasCargoSpaceService
*/
public BasCargoSpace selectBasCargoSpaceByCargoSpaceId(String cargoSpaceId);
/**
* 查询货位信息
*
* @param trayCode 托盘号
* @return 货位信息
*/
public BasCargoSpace selectBasCargoSpaceByTrayCode(String trayCode);
/**
* 查询货位信息列表

View File

@@ -34,6 +34,18 @@ public class BasCargoSpaceServiceImpl implements IBasCargoSpaceService
return basCargoSpaceMapper.selectBasCargoSpaceByCargoSpaceId(cargoSpaceId);
}
/**
* 查询货位信息
*
* @param trayCode 货位信息主键
* @return 货位信息
*/
@Override
public BasCargoSpace selectBasCargoSpaceByTrayCode(String trayCode)
{
return basCargoSpaceMapper.selectBasCargoSpaceByTrayCode(trayCode);
}
/**
* 查询货位信息列表
*

View File

@@ -12,7 +12,11 @@ public class BasStockCode {
public static final String STOCK_STATUS_EXCEPTION = "3";
/** 产品状态 - 正常 */
public static final String PRODUCT_STATUS_NORMAL = "1";
/** 产品状态 - 异常待检产品 */
public static final String PRODUCT_STATUS_EXCEPTION = "2";
}

View File

@@ -37,6 +37,11 @@ public class TaskIdType {
*/
public static final String TASK_STOCKOUT = "21";
/**
* 出库任务
*/
public static final String TASK_STOCKOUT_INVENTORY = "22";
}

View File

@@ -243,21 +243,17 @@ public class MydoJobServiceImpl implements IMydoJobService
public AjaxResult cancelJob(String jobId)
{
//任务主表
List<MydoJob> jobs = mydoJobMapper.selectMydoJobList(
new MydoJob().builder().jobId(jobId).build()
);
MydoJob mydoJob = selectMydoJobByJobId(jobId);
if (jobs.isEmpty()){
if (ObjUtil.isEmpty(mydoJob)){
log.warn("【操作异常】找不到该作业信息,作业号:{}", jobId);
return AjaxResult.error("找不到该作业信息");
}
for (MydoJob mydoJob : jobs){
//任务状态标记为【作废】
mydoJob.setStatus(TaskStatusEnum.CANCEL.getCode());
updateMydoJob(mydoJob);
log.warn("【手动作废】执行成功,当前作业已标记为<手动作废>,作业号:{}", jobId);
}
//任务状态标记为【作废】
mydoJob.setStatus(TaskStatusEnum.CANCEL.getCode());
updateMydoJob(mydoJob);
log.warn("【手动作废】执行成功,当前作业已标记为<手动作废>,作业号:{}", jobId);
return AjaxResult.success("操作成功,当前作业已标记为<手动作废>,作业号:" + jobId);
}
@@ -311,20 +307,16 @@ public class MydoJobServiceImpl implements IMydoJobService
public AjaxResult manualCompleteJob(String jobId)
{
//任务主表
List<MydoJob> jobs = mydoJobMapper.selectMydoJobList(
new MydoJob().builder().jobId(jobId).build()
);
MydoJob mydoJob = selectMydoJobByJobId(jobId);
if (jobs.isEmpty()){
if (ObjUtil.isEmpty(mydoJob)){
log.warn("【操作异常】找不到该作业信息,作业号:{}", jobId);
return AjaxResult.error("找不到该作业信息");
}
for (MydoJob mydoJob : jobs){
//任务状态标记为【手动完成】
mydoJob.setStatus(TaskStatusEnum.MANUAL_FINISHED.getCode());
updateMydoJob(mydoJob);
}
//任务状态标记为【手动完成】
mydoJob.setStatus(TaskStatusEnum.MANUAL_FINISHED.getCode());
updateMydoJob(mydoJob);
log.warn("【手动操作】执行成功,当前作业已标记为<手动完成>,作业号:{}", jobId);

View File

@@ -1,6 +1,8 @@
package com.ruoyi.pd.stockpd.controller;
import java.util.List;
import com.ruoyi.in.job.service.IMydoJobService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
@@ -151,7 +153,8 @@ public class PdStockpdController extends BaseController
@PutMapping("/autoAssign/{stockpdId}")
public AjaxResult autoAssign(@PathVariable("stockpdId") String stockpdId)
{
return pdStockpdService.autoAssignPdStockpd(stockpdId);
// return pdStockpdService.autoAssignPdStockpd(stockpdId);
return pdStockpdService.autoAssignPdStock(stockpdId);
}
/**

View File

@@ -1,6 +1,10 @@
package com.ruoyi.pd.stockpd.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
@@ -15,6 +19,10 @@ import java.util.Date;
* @author ruoyi
* @date 2026-05-27
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class PdStockpd extends BaseEntity
{
private static final long serialVersionUID = 1L;

View File

@@ -21,6 +21,7 @@ public interface IPdStockpdService
*/
public PdStockpd selectPdStockpdByStockpdId(String stockpdId);
/**
* 查询盘点单据主信息列表
*
@@ -29,6 +30,7 @@ public interface IPdStockpdService
*/
public List<PdStockpd> selectPdStockpdList(PdStockpd pdStockpd);
/**
* 新增盘点单据主信息
*
@@ -37,6 +39,7 @@ public interface IPdStockpdService
*/
public int insertPdStockpd(PdStockpd pdStockpd);
/**
* 修改盘点单据主信息
*
@@ -45,6 +48,7 @@ public interface IPdStockpdService
*/
public int updatePdStockpd(PdStockpd pdStockpd);
/**
* 批量删除盘点单据主信息
*
@@ -53,6 +57,7 @@ public interface IPdStockpdService
*/
public int deletePdStockpdByStockpdIds(String[] stockpdIds);
/**
* 删除盘点单据主信息信息
*
@@ -61,6 +66,7 @@ public interface IPdStockpdService
*/
public int deletePdStockpdByStockpdId(String stockpdId);
/**
* 手动作废盘点单据
*
@@ -69,6 +75,7 @@ public interface IPdStockpdService
*/
public AjaxResult cancelPdStockpd(String stockpdId);
/**
* 审核盘点单据
*
@@ -77,6 +84,7 @@ public interface IPdStockpdService
*/
public AjaxResult auditPdStockpd(String stockpdId);
/**
* 完成盘点单据
*
@@ -85,14 +93,25 @@ public interface IPdStockpdService
*/
public AjaxResult finishPdStockpd(String stockpdId);
/**
* 自动分配盘点单据
* 自动分配盘点单据(存储过程)
*
* @param stockpdId 盘点订单ID
* @return 结果
*/
public AjaxResult autoAssignPdStockpd(String stockpdId);
/**
* 自动分配盘点单据(非过程)
*
* @param stockpdId 盘点订单ID
* @return 结果
*/
public AjaxResult autoAssignPdStock(String stockpdId);
/**
* 查询盘点单据完成列表
*
@@ -101,6 +120,7 @@ public interface IPdStockpdService
*/
List<PdStockpd> selectPdStockpdFinishList(PdStockpd pdStockpd);
/**
* 保存盘点单据(主单+明细)
*

View File

@@ -1,14 +1,27 @@
package com.ruoyi.pd.stockpd.service.impl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Date;
import cn.hutool.core.util.ObjUtil;
import com.ruoyi.bas.cargospace.domain.BasCargoSpace;
import com.ruoyi.bas.cargospace.service.IBasCargoSpaceService;
import com.ruoyi.bas.id.taskno.service.IBasTaskNoService;
import com.ruoyi.bas.stock.domain.BasStock;
import com.ruoyi.bas.stock.service.IBasStockService;
import com.ruoyi.common.*;
import com.ruoyi.in.job.domain.MydoJob;
import com.ruoyi.in.job.service.IMydoJobService;
import com.ruoyi.in.jobdetail.service.IMydoJobDetailService;
import com.ruoyi.pd.stockpddetail.service.IPdStockpdDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.bas.id.job.service.IBasJobIdService;
import com.ruoyi.common.PdStockpdStatusEnum;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.SecurityUtils;
@@ -27,19 +40,31 @@ import com.ruoyi.pd.stockpddetail.domain.PdStockpdDetail;
* @date 2026-05-27
*/
@Service
@Slf4j
public class PdStockpdServiceImpl implements IPdStockpdService
{
@Autowired
private PdStockpdMapper pdStockpdMapper;
@Autowired
private PdStockpdDetailMapper pdStockpdDetailMapper;
@Autowired
private SysDeptMapper sysDeptMapper;
@Autowired
private IBasJobIdService IBasJobIdService;
private IBasJobIdService basJobIdService;
@Autowired
IBasTaskNoService basTaskNoService;
@Autowired
IPdStockpdDetailService pdStockpdDetailService;
@Autowired
IMydoJobService mydoJobService;
@Autowired
IMydoJobDetailService mydojobDetailService;
@Autowired
IBasCargoSpaceService bascargoSpaceService;
@Autowired
IBasStockService basStockService;
/**
* 查询盘点单据主信息
@@ -199,6 +224,90 @@ public class PdStockpdServiceImpl implements IPdStockpdService
return AjaxResult.success(str);
}
/**
* 自动分配盘点单据
*/
@Override
public AjaxResult autoAssignPdStock(String stockpdId)
{
PdStockpd pdStockpd = selectPdStockpdByStockpdId(stockpdId);
if (ObjUtil.isNull(pdStockpd)) {
log.error("【盘点出库分配】操作失败,找不到该盘点单据,请检查单据状态,单据号:{}", stockpdId);
return AjaxResult.error("操作失败,找不到该盘点单据,请检查单据状态");
}
if (!pdStockpd.getStatus().equals(StockStatusEnum.RUNNING.getCode())) {
log.error("【盘点出库分配】操作失败,只有状态为<执行中>的单据才能执行分配,单据号:{}", stockpdId);
return AjaxResult.error("操作失败,只有状态为<执行中>的单据才能执行分配,单据号:{}" + stockpdId);
}
//获取盘点出库单明细
List<PdStockpdDetail> details = pdStockpdDetailService.selectPdStockpdDetailList(
new PdStockpdDetail().builder().stockpdId(stockpdId).build()
);
if (details.isEmpty()){
log.error("【盘点出库分配】操作失败,找不到该盘点单对应的单据明细,单据号:{}", stockpdId);
return AjaxResult.error("操作失败,找不到该盘点单对应的单据明细");
}
for (PdStockpdDetail detail : details) {
//更新明细分配数量
detail.setAllotNum(BigDecimal.ONE);
pdStockpdDetailService.updatePdStockpdDetail(detail);
//生成托盘盘点出库作业
MydoJob mydoJob = mydoJobService.selectMydoJobByTrayCode(detail.getTrayCode());
if (ObjUtil.isNull(mydoJob)){
String jobId = basJobIdService.getId(JobIdType.MYDOJOB_INVENTORY_STOCKOUT);
String taskNo = basTaskNoService.getTaskNo(TaskIdType.TASK_STOCKOUT_INVENTORY);
int taskType = TaskType.TASKTYPE_STOCKOUT_INVENTORY;
BasCargoSpace cargoSpace = bascargoSpaceService.selectBasCargoSpaceByTrayCode(detail.getTrayCode());
if (ObjUtil.isNull(cargoSpace)){
log.error("【盘点出库分配】操作失败,找不到当前盘点单明细托盘号的货位信息,请检查托盘库存状态和货位信息是否正确,单据号:{},托盘号:{}", stockpdId, detail.getTrayCode());
return AjaxResult.error("找不到当前盘点单明细托盘号的货位信息,请检查托盘库存状态和货位信息是否正确,托盘号:{}" + detail.getTrayCode());
}
mydoJob = new MydoJob().builder()
.jobId(jobId)
.taskNo(taskNo)
.status(TaskStatusEnum.READY.getCode())
.warehouseId("01")
.warehouseName("立体库")
.executionPhase("0")
.inOrOut(taskType)
.trayCode(detail.getTrayCode())
.roadwayId(cargoSpace.getRoadwayId())
.cargoSpaceId(cargoSpace.getCargoSpaceId())
.cargoSpaceName(cargoSpace.getCargoSpaceName())
.trayType(cargoSpace.getTheType())
.priority(10)
.build();
mydoJobService.insertMydoJob(mydoJob);
log.info("【wms生成盘点出库】<盘点出库>作业,作业号:{},任务号:{},托盘号:{},盘点货位:{}",mydoJob.getJobId() ,mydoJob.getTaskNo() ,mydoJob.getTrayCode(), cargoSpace.getCargoSpaceId());
bascargoSpaceService.updateBasCargoSpaceStatus(cargoSpace.getCargoSpaceId(), mydoJob.getTrayCode(), CargoSpaceCode.CARGOSPACE_STATUS_PRE_STOCKOUT);
List<BasStock> stocks = basStockService.selectBasStockListByTrayCode(detail.getTrayCode());
if (!stocks.isEmpty()){
for (BasStock stock : stocks) {
stock.setStockStatus(BasStockCode.STOCK_STATUS_OCCUPIED);
basStockService.updateBasStock(stock);
}
}
log.info("【wms生成盘点出库】更新出库货位和库存状态,作业号:{},任务号:{},托盘号:{},盘点货位:{}");
}
}
return AjaxResult.success();
}
/**
* 查询盘点单据完成列表
*/
@@ -217,7 +326,7 @@ public class PdStockpdServiceImpl implements IPdStockpdService
{
// 1. 生成主单ID
if (saveDTO.getStockpdId() == null || saveDTO.getStockpdId().isEmpty()) {
saveDTO.setStockpdId(IBasJobIdService.getId("PDD"));
saveDTO.setStockpdId(basJobIdService.getId("PDD"));
}
// 2. 保存主单
saveDTO.setCreateDate(new Date());

View File

@@ -47,7 +47,7 @@ public class PdStockpdDetailController extends BaseController
startPage();
List<PdStockpdDetail> list;
if (StringUtils.isEmpty(pdStockpdDetail.getStatus()) || Convert.toInt(pdStockpdDetail.getStatus())< 4){
if (Convert.toInt(pdStockpdDetail.getStatus())< 4){
list = pdStockpdDetailService.selectPdStockpdDetailList(pdStockpdDetail);
}else {
list = pdStockpdDetailService.selectPdStockpdDetailFinishList(pdStockpdDetail);

View File

@@ -56,7 +56,7 @@ public class PdStockpdDetail extends BaseEntity
@Excel(name = "实际数量")
private BigDecimal assignNum;
private int status;
private Integer status;
}

View File

@@ -2,6 +2,9 @@ package com.ruoyi.pda.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.ruoyi.bas.stock.domain.BasStock;
import com.ruoyi.bas.stock.service.IBasStockInfoService;
import com.ruoyi.bas.stock.service.IBasStockService;
import com.ruoyi.common.TaskType;
import com.ruoyi.common.Utils.DecimalUtil;
import com.ruoyi.common.core.controller.BaseController;
@@ -47,6 +50,8 @@ public class PdaController extends BaseController {
IInStockinService inStockinService;
@Autowired
IInStockinDetailService inStockinDetailService;
@Autowired
IBasStockService basStockService;
/**
@@ -211,7 +216,6 @@ public class PdaController extends BaseController {
}
/**
* 入库绑盘-查询物料信息(子单号查询)
* @param detailId 子单号
@@ -439,4 +443,71 @@ public class PdaController extends BaseController {
}
//==================================== 盘点 ========================================
//==================================== 盘点 ========================================
//==================================== 盘点 ========================================
/**
* 盘点出库待处理任务列表
*/
@GetMapping("/inventoryOutTaskList")
@PreAuthorize("@ss.hasPermi('inventory:task:list')")
public TableDataInfo listInventoryTask(MydoJob mydoJob) {
mydoJob.setInOrOut(TaskType.TASKTYPE_STOCKOUT_INVENTORY);
startPage();
List<MydoJob> list = mydoJobService.selectMydoJobList(mydoJob);
return getDataTable(list);
}
/**
* 盘点-查询物料库存(托盘号查询)
* @param trayCode 托盘号
* @return
*/
@GetMapping("/getInventoryOutInfoByTrayCode")
@PreAuthorize("@ss.hasPermi('out:inventory:task:info')")
public AjaxResult getInventoryOutInfoByTrayCode(String trayCode) {
try {
MydoJob job = mydoJobService.selectMydoJobByTrayCode(trayCode);
// List<MydoJobDetail> info = pdaService.getStockoutInfoByTrayCode(trayCode);
List<BasStock> stocks = basStockService.selectBasStockListByTrayCode(trayCode);
if(ObjUtil.isNull(job) || stocks.isEmpty()){
return AjaxResult.error("找不到当前托盘出库明细,请检查作业状态");
}else{
return AjaxResult.success(stocks);
}
} catch (RuntimeException e) {
return AjaxResult.error(e.getMessage());
}
}
/**
* 物料(版辊)库存【产品状态】异常标记
* @param params
* @return
*/
@PostMapping("/inventoryStockExcetion")
@PreAuthorize("@ss.hasPermi('out:inventory:task:info')")
public AjaxResult inventoryStockExcetion(@RequestBody Map<String, Object> params) {
return pdaService.inventoryStockExcetion(params);
}
/**
* 手动指定出库确认 - 版辊单独确认
* @param params
* @return
*/
@PostMapping("/inventoryTrayCodeComplete")
@PreAuthorize("@ss.hasPermi('out:bound:task:info')")
public AjaxResult inventoryTrayCodeComplete(Map<String, Object> params) {
return pdaService.inventoryTrayCodeComplete(params);
}
}

View File

@@ -178,4 +178,24 @@ public interface IPdaService {
AjaxResult stockoutTrayCodeCompleteAll(String trayCode);
//=============================================== 盘点 ===================================================
//=============================================== 盘点 ===================================================
//=============================================== 盘点 ===================================================
/**
* 盘点出库 - 标记库存产品状态异常
* @param params
* @return
*/
AjaxResult inventoryStockExcetion(Map<String, Object> params);
/**
* 托盘扫码 - 盘点出库确认
* @param params
* @return
*/
public AjaxResult inventoryTrayCodeComplete(Map<String, Object> params);
}

View File

@@ -35,6 +35,9 @@ import com.ruoyi.out.stockout.service.IOutStockoutService;
import com.ruoyi.out.stockoutdetail.domain.OutStockoutDetail;
import com.ruoyi.out.stockoutdetail.mapper.OutStockoutDetailMapper;
import com.ruoyi.out.stockoutdetail.service.IOutStockoutDetailService;
import com.ruoyi.pd.stockpd.service.IPdStockpdService;
import com.ruoyi.pd.stockpddetail.domain.PdStockpdDetail;
import com.ruoyi.pd.stockpddetail.service.IPdStockpdDetailService;
import com.ruoyi.pda.domain.AddInJobRequest;
import com.ruoyi.pda.domain.TrayMsgBinding;
import com.ruoyi.pda.domain.BindTrayRequest;
@@ -94,6 +97,10 @@ public class PdaServiceImpl implements IPdaService {
IBasTaskNoService basTaskNoService;
@Autowired
IBasCargoSpaceService basCargoSpaceService;
@Autowired
IPdStockpdService pdStockpdService;
@Autowired
IPdStockpdDetailService pdStockpdDetailService;
// ─────────────────────────────────────────────
@@ -496,7 +503,7 @@ public class PdaServiceImpl implements IPdaService {
/**
* 托盘扫码 - 版辊单据出库确认
* 单版辊强行出库确认
* @param params
* @return
*/
@@ -556,7 +563,7 @@ public class PdaServiceImpl implements IPdaService {
/**
* 托盘扫码 - 版辊单据出库确认
* 托盘扫码 - 版辊单据出库标记
* @param params
* @return
*/
@@ -594,7 +601,7 @@ public class PdaServiceImpl implements IPdaService {
/**
* 托盘扫码 - 托盘单据出库确认
* 托盘扫码 - 托盘出库确认(需求单据)
* @param trayCode
* @return
*/
@@ -723,7 +730,7 @@ public class PdaServiceImpl implements IPdaService {
/**
* 托盘扫码 - 手动指定出库确认
* 托盘扫码 - 手动指定出库确认(不依赖单据)
* @param trayCode
* @return
*/
@@ -832,7 +839,7 @@ public class PdaServiceImpl implements IPdaService {
/**
* 托盘出库确认 - 托盘一键确认
* 托盘出库确认 - 托盘一键确认(需求单据)
* @param trayCode
* @return
*/
@@ -944,4 +951,89 @@ public class PdaServiceImpl implements IPdaService {
}
//============================================== 盘点 ================================================
//============================================== 盘点 ================================================
//============================================== 盘点 ================================================
/**
* 盘点出库 - 标记库存产品状态异常
* @param params
* @return
*/
@Override
public AjaxResult inventoryStockExcetion(Map<String, Object> params){
String rollerNumber = (String) params.get("barcode");
String productStatus = (String)params.get("productStatus");
BasStock stock = basStockService.selectBasStockByRollerNumber(rollerNumber);
if (ObjUtil.isNull(stock)){
log.warn("【操作失败】找不到当前版辊的库存信息,可能是库存错误或入库有误,辊号:{}", rollerNumber);
return AjaxResult.error("找不到当前版辊的库存信息,可能是库存或入库有误");
}
if (stock.getProductStatus().equals(BasStockCode.PRODUCT_STATUS_NORMAL)){
stock.setProductStatus(BasStockCode.PRODUCT_STATUS_EXCEPTION);
basStockService.updateBasStock(stock);
log.info("【盘点异常标记】版辊库存的<产品状态>已更新:异常待检【{}】,辊号:{}", BasStockCode.PRODUCT_STATUS_EXCEPTION, rollerNumber);
}else{
log.info("【盘点异常标记】版辊库存的<产品状态>已经是异常待检【{}】状态,请勿重复操作,辊号:{}", BasStockCode.PRODUCT_STATUS_EXCEPTION, rollerNumber);
return AjaxResult.error("该版辊已经执行过出库确认操作,请勿重复操作");
}
return AjaxResult.success();
}
/**
* 托盘扫码 - 盘点出库确认
* @param params
* @return
*/
@Override
public AjaxResult inventoryTrayCodeComplete(Map<String, Object> params){
String trayCode = (String) params.get("barcode");
MydoJob mydoJob = mydoJobService.selectMydoJobByTrayCode(trayCode);
if (ObjUtil.isNull(mydoJob)){
log.warn("【操作失败】找不到当前出库盘点作业,可能是已经完成或者任务异常,请检查任务状态,托盘号:{}", trayCode);
return AjaxResult.error("找不到当前出库盘点作业,可能是已经完成或者任务异常,请检查任务状态");
}
if (!mydoJob.getStatus().equals(TaskStatusEnum.AUTO_FINISHED.getCode())){
log.warn("【操作失败】请等待当前盘点作业出库完成再执行确认操作,托盘号:{}", trayCode);
return AjaxResult.error("请等待当前盘点作业出库完成再执行确认操作");
}
List<PdStockpdDetail> details = pdStockpdDetailService.selectPdStockpdDetailList(
new PdStockpdDetail().builder().trayCode(trayCode).build()
);
for (PdStockpdDetail detail : details){
detail.setAssignNum(BigDecimal.ONE);
pdStockpdDetailService.updatePdStockpdDetail(detail);
}
String jobId = basJobIdService.getId(JobIdType.JOB_MANUAL_LIST_INVENTORY_STOCKIN);
String taskNo = basTaskNoService.getTaskNo(TaskIdType.TASK_STOCKIN_INVENTORY);
mydoJob.setJobId(jobId);
mydoJob.setTaskNo(taskNo);
mydoJob.setStatus(TaskStatusEnum.READY.getCode());
mydoJob.setExecutionPhase("0");
mydoJob.setInOrOut(TaskType.TASKTYPE_INVENTORY_BACK);
mydoJobService.updateMydoJob(mydoJob);
log.warn("【盘点出库确认】确认完成,生成盘点回库任务,等待执行中,作业号:{},托盘号:{}", jobId, trayCode);
basCargoSpaceService.updateBasCargoSpaceStatus(mydoJob.getCargoSpaceId(), mydoJob.getTrayCode(),CargoSpaceCode.CARGOSPACE_STATUS_PRE_STOCKIN);
return AjaxResult.success();
}
}

View File

@@ -382,16 +382,8 @@ public class MydoJobHandler {
if (mydoJobs.isEmpty()) return;
for (MydoJob mydoJob : mydoJobs) {
//任务子表
if (mydoJob.getInOrOut() != TaskType.TASKTYPE_STOCKOUT_INVENTORY || mydoJob.getInOrOut() != TaskType.TASKTYPE_INVENTORY_BACK) continue;
if (mydoJob.getInOrOut() != TaskType.TASKTYPE_STOCKOUT_INVENTORY && mydoJob.getInOrOut() != TaskType.TASKTYPE_INVENTORY_BACK) continue;
List<MydoJobDetail> details = mydoJobDetailService.selectMydoJobDetailByJobId(mydoJob.getJobId());
if (!details.isEmpty()){
//移除任务子表
mydoJobDetailService.insertMydoJobDetailsForJobFinish(mydoJob.getJobId());
mydoJobDetailService.deleteMydoJobDetailsByJobId(mydoJob.getJobId());
log.info("【手动作废任务】移除<盘点出库>任务明细,作业号:{}", mydoJob.getJobId());
}
//库存子表
List<BasStock> stocks = basStockService.selectBasStockListByTrayCode(mydoJob.getTrayCode());
if (!stocks.isEmpty()){
@@ -409,19 +401,32 @@ public class MydoJobHandler {
stockInfo.setCargoSpaceId(mydoJob.getCargoSpaceId());
basStockInfoService.updateBasStockInfo(stockInfo);
}
// for (MydoJobDetail mydoJobDetail : details){
// //还原子单数量
// PdStockpdDetail pdStockpdDetail = pdStockpdDetailService.selectPdStockpdDetailList(mydoJobDetail.getRollerNumber());
// if(ObjUtil.isNotNull(pdStockpdDetail)){
// pdStockpdDetail.setAllotNum(BigDecimal.ZERO);
// pdStockpdDetail.setAssignNum(BigDecimal.ZERO);
// pdStockpdDetail.setStatus(0);
// pdStockpdDetailService.updatePdStockpdDetail(pdStockpdDetail);
// }
// }
//还原盘点子单分配数量
List<PdStockpdDetail> pdStockpdDetails = pdStockpdDetailService.selectPdStockpdDetailList(
new PdStockpdDetail().builder().trayCode(mydoJob.getTrayCode()).build()
);
if(!pdStockpdDetails.isEmpty()){
for (PdStockpdDetail pdStockpdDetail : pdStockpdDetails){
pdStockpdDetail.setAllotNum(BigDecimal.ZERO);
pdStockpdDetail.setAssignNum(BigDecimal.ZERO);
pdStockpdDetail.setStatus(0);
pdStockpdDetailService.updatePdStockpdDetail(pdStockpdDetail);
}
}
//任务子表
List<MydoJobDetail> details = mydoJobDetailService.selectMydoJobDetailByJobId(mydoJob.getJobId());
if (!details.isEmpty()){
//移除任务子表
mydoJobDetailService.insertMydoJobDetailsForJobFinish(mydoJob.getJobId());
mydoJobDetailService.deleteMydoJobDetailsByJobId(mydoJob.getJobId());
log.info("【手动作废任务】移除<盘点出库>任务明细,作业号:{}", mydoJob.getJobId());
}
mydoJobService.insertMydoJobFinish(mydoJob.getJobId());
mydoJobService.deleteMydoJobByJobId(mydoJob.getJobId());
log.info("【账务处理-出库】任务作废,更新货位和库存信息,作业号:{}", mydoJob.getJobId());
log.info("【账务处理-盘点出库】任务作废,更新货位和库存信息,作业号:{}", mydoJob.getJobId());
}
@@ -826,18 +831,9 @@ public class MydoJobHandler {
if (mydoJobs.isEmpty()) return;
for (MydoJob mydoJob : mydoJobs) {
//任务子表
if (mydoJob.getInOrOut() != TaskType.TASKTYPE_STOCKOUT_INVENTORY || mydoJob.getInOrOut() != TaskType.TASKTYPE_INVENTORY_BACK) continue;
if (mydoJob.getInOrOut() != TaskType.TASKTYPE_STOCKOUT_INVENTORY && mydoJob.getInOrOut() != TaskType.TASKTYPE_INVENTORY_BACK) continue;
List<MydoJobDetail> details = mydoJobDetailService.selectMydoJobDetailByJobId(mydoJob.getJobId());
if (!details.isEmpty()){
//移除任务子表
mydoJobDetailService.insertMydoJobDetailsForJobFinish(mydoJob.getJobId());
mydoJobDetailService.deleteMydoJobDetailsByJobId(mydoJob.getJobId());
log.info("【手动完成任务】移除<盘点>任务明细,作业号:{}", mydoJob.getJobId());
}
//库存子表
List<BasStock> stocks = basStockService.selectBasStockListByTrayCode(mydoJob.getTrayCode());
if (!stocks.isEmpty()){
@@ -848,9 +844,30 @@ public class MydoJobHandler {
}
}
//还原盘点子单分配数量
List<PdStockpdDetail> pdStockpdDetails = pdStockpdDetailService.selectPdStockpdDetailList(
new PdStockpdDetail().builder().trayCode(mydoJob.getTrayCode()).build()
);
if(!pdStockpdDetails.isEmpty()){
for (PdStockpdDetail pdStockpdDetail : pdStockpdDetails){
pdStockpdDetail.setAssignNum(BigDecimal.ONE);
pdStockpdDetail.setStatus(1);
pdStockpdDetailService.updatePdStockpdDetail(pdStockpdDetail);
}
}
basCargoSpaceService.updateBasCargoSpaceStatus(mydoJob.getCargoSpaceId(), mydoJob.getTrayCode(), CargoSpaceCode.CARGOSPACE_STATUS_OCCUPIED);
log.info("【账务处理-盘点】任务完成,更新货位和库存信息,作业号:{},托盘号:{}", mydoJob.getJobId(), mydoJob.getTrayCode());
//任务子表
List<MydoJobDetail> details = mydoJobDetailService.selectMydoJobDetailByJobId(mydoJob.getJobId());
if (!details.isEmpty()){
//移除任务子表
mydoJobDetailService.insertMydoJobDetailsForJobFinish(mydoJob.getJobId());
mydoJobDetailService.deleteMydoJobDetailsByJobId(mydoJob.getJobId());
log.info("【手动完成任务】移除<盘点>任务明细,作业号:{}", mydoJob.getJobId());
}
mydoJobService.insertMydoJobFinish(mydoJob.getJobId());
mydoJobService.deleteMydoJobByJobId(mydoJob.getJobId());
log.info( "【账务处理-盘点】任务完成,移除作业信息,作业号:{},托盘号:{}", mydoJob.getJobId(), mydoJob.getTrayCode());

View File

@@ -243,7 +243,7 @@ public class RequestWcsHandler {
/**
* 盘点确认完成 - 推送wcs回流任务
* 盘点确认完成 - 推送wcs盘点回流任务
*/
@Scheduled(fixedRate = TIMEINTERVAL_2000)
public void sendWcsInventoryBackTask(){

View File

@@ -102,6 +102,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectBasCargoSpaceVo"/>
where cargo_space_id = #{cargoSpaceId}
</select>
<select id="selectBasCargoSpaceByTrayCode" parameterType="String" resultMap="BasCargoSpaceResult">
<include refid="selectBasCargoSpaceVo"/>
where tray_code = #{trayCode}
</select>
<select id="selectBasCargoSpaceListByGroupByStatus" resultType="com.ruoyi.kpi.domain.BasCargoSpaceStatus">
select status, count(*) as count
from bas_cargo_space

View File

@@ -14,10 +14,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="allotNum" column="allot_num" />
<result property="assignNum" column="assign_num" />
<result property="remark" column="remark" />
<result property="status" column="status" />
</resultMap>
<sql id="selectPdStockpdDetailVo">
select stockpd_detail_id, stockpd_id, tray_code, product_id, product_name, quantity, allot_num, assign_num, remark from pd_stockpd_detail
select stockpd_detail_id, stockpd_id, tray_code, product_id, product_name, quantity, allot_num, assign_num, remark, status from pd_stockpd_detail
</sql>
<sql id="selectPdStockpdDetailFinishVo">
select stockpd_detail_id,
@@ -28,7 +29,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
quantity,
allot_num,
assign_num,
remark
remark,
status
from pd_stockpd_detail_finish
</sql>
@@ -42,6 +44,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="quantity != null "> and quantity = #{quantity}</if>
<if test="allotNum != null "> and allot_num = #{allotNum}</if>
<if test="assignNum != null "> and assign_num = #{assignNum}</if>
<if test="status != null "> and status = #{status}</if>
</where>
</select>
@@ -59,6 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="quantity != null "> and quantity = #{quantity}</if>
<if test="allotNum != null "> and allot_num = #{allotNum}</if>
<if test="assignNum != null "> and assign_num = #{assignNum}</if>
<if test="status != null "> and status = #{status}</if>
</where>
</select>
@@ -74,6 +78,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="allotNum != null">allot_num,</if>
<if test="assignNum != null">assign_num,</if>
<if test="remark != null">remark,</if>
<if test="status != null">status,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="stockpdDetailId != null">#{stockpdDetailId},</if>
@@ -85,6 +90,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="allotNum != null">#{allotNum},</if>
<if test="assignNum != null">#{assignNum},</if>
<if test="remark != null">#{remark},</if>
<if test="status != null">#{status},</if>
</trim>
</insert>
@@ -99,6 +105,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="allotNum != null">allot_num = #{allotNum},</if>
<if test="assignNum != null">assign_num = #{assignNum},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="status != null">status = #{status},</if>
</trim>
where stockpd_detail_id = #{stockpdDetailId}
</update>

View File

@@ -46,7 +46,8 @@ export function delJob(jobId) {
// 手动作废作业
export function cancelJob(jobId) {
return request({
url: '/pd/inJob/cancel/' + jobId,
// url: '/pd/inJob/cancel/' + jobId,
url: '/in/job/cancel/' + jobId,
method: 'put'
})
}
@@ -54,7 +55,8 @@ export function cancelJob(jobId) {
// 手动完成作业
export function completeJob(jobId) {
return request({
url: '/pd/inJob/complete/' + jobId,
// url: '/pd/inJob/complete/' + jobId,
url: '/in/job/complete/' + jobId,
method: 'put'
})
}

View File

@@ -46,7 +46,8 @@ export function delJob(jobId) {
// 手动作废作业
export function cancelJob(jobId) {
return request({
url: '/pd/outJob/cancel/' + jobId,
// url: '/pd/outJob/cancel/' + jobId,
url: '/in/job/cancel/' + jobId,
method: 'put'
})
}
@@ -54,7 +55,7 @@ export function cancelJob(jobId) {
// 手动完成作业
export function completeJob(jobId) {
return request({
url: '/pd/outJob/complete/' + jobId,
url: '/in/job/complete/' + jobId,
method: 'put'
})
}

View File

@@ -82,12 +82,22 @@
<el-card shadow="never" class="section-card" style="margin-top:16px;">
<div slot="header" class="card-header">
<span><i class="el-icon-goods"></i> 物料明细</span>
<el-button
type="primary"
size="mini"
icon="el-icon-plus"
:disabled="!mainForm.warehouseId"
@click="openCargoDialog"
v-show="mainForm.pdType==1"
v-hasPermi="['bas:cargospace:list']"
>选择货位</el-button>
<el-button
type="primary"
size="mini"
icon="el-icon-plus"
:disabled="!mainForm.warehouseId"
@click="openStockDialog"
v-show="mainForm.pdType==2 || !mainForm.pdType"
v-hasPermi="['bas:stock:list']"
>选择库存</el-button>
</div>
@@ -244,6 +254,129 @@
</div>
</el-dialog>
<!-- ===== 货位选择弹框 ===== -->
<el-dialog
title="选择盘点货位"
:visible.sync="cargoDialogVisible"
width="900px"
append-to-body
top="6vh"
@open="onCargoDialogOpen"
>
<!-- 搜索栏 -->
<div class="stock-search">
<el-input
v-model="cargoQuery.warehouseId"
placeholder="仓库ID"
size="small"
clearable
style="width:140px;margin-right:8px;"
@keyup.enter.native="searchCargo"
/>
<el-input
v-model="cargoQuery.cargoSpaceId"
placeholder="货位编号"
size="small"
clearable
style="width:160px;margin-right:8px;"
@keyup.enter.native="searchCargo"
/>
<el-input
v-model="cargoQuery.cargoAreaId"
placeholder="货区编号"
size="small"
clearable
style="width:140px;margin-right:8px;"
@keyup.enter.native="searchCargo"
/>
<el-input
v-model="cargoQuery.trayCode"
placeholder="托盘号"
size="small"
clearable
style="width:130px;margin-right:8px;"
@keyup.enter.native="searchCargo"
/>
<el-input
v-model="cargoQuery.status"
placeholder="状态"
size="small"
clearable
style="width:130px;margin-right:8px;"
@keyup.enter.native="searchCargo"
/>
<el-input
v-model="cargoQuery.thePlatoon"
placeholder="排"
size="small"
clearable
style="width:130px;margin-right:8px;"
@keyup.enter.native="searchCargo"
/>
<el-input
v-model="cargoQuery.theColumn"
placeholder="列"
size="small"
clearable
style="width:130px;margin-right:8px;"
@keyup.enter.native="searchCargo"
/>
<el-input
v-model="cargoQuery.theFloor"
placeholder="层"
size="small"
clearable
style="width:130px;margin-right:8px;"
@keyup.enter.native="searchCargo"
/>
<el-button type="primary" size="small" icon="el-icon-search" @click="searchCargo">搜索</el-button>
<el-button size="small" icon="el-icon-refresh" @click="resetCargoSearch">重置</el-button>
</div>
<!-- 库存表格(多选) -->
<el-table
ref="cargoTable"
v-loading="cargoLoading"
:data="cargoList"
size="small"
border
stripe
style="width:100%;margin-top:10px;"
:header-cell-style="{ background:'#f5f7fa', color:'#606266' }"
@selection-change="onCargoSelectionChange"
>
<el-table-column type="selection" width="45" align="center" :selectable="isCargoSelectable" />
<el-table-column label="仓库" prop="warehouseName" align="center" width="120"/>
<el-table-column label="货位" prop="cargoSpaceId" align="center" width="100" />
<el-table-column label="货区" prop="cargoAreaId" align="center" width="120" />
<el-table-column label="托盘号" prop="trayCode" align="center" min-width="130" show-overflow-tooltip />
<el-table-column label="状态" prop="status" align="center" min-width="130" />
<el-table-column label="排" prop="thePlatoon" align="center" width="120" />
<el-table-column label="列" prop="theColumn" align="center" width="120"/>
<el-table-column label="层" prop="theFloor" align="center" width="90" />
</el-table>
<!-- 弹框分页 -->
<pagination
v-show="cargoTotal > 0"
:total="cargoTotal"
:page.sync="cargoQuery.pageNum"
:limit.sync="cargoQuery.pageSize"
@pagination="fetchCargoList"
style="margin-top:4px;"
/>
<div slot="footer" class="dialog-footer">
<span style="float:left;color:#606266;font-size:13px;line-height:32px;">
已选 <strong style="color:#409eff;">{{ selectedCargos.length }}</strong> 条库存记录
</span>
<el-button @click="cargoDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmCargos" :disabled="selectedCargos.length === 0">
确认添加
</el-button>
</div>
</el-dialog>
</div>
</template>
@@ -251,6 +384,7 @@
import { saveWithDetails } from '@/api/pd/stockpd'
import { listWarehouse } from '@/api/bas/warehouse'
import { listStock } from '@/api/bas/stock'
import { listCargospace } from '@/api/bas/cargospace'
export default {
name: 'CreateStockpd',
@@ -293,7 +427,26 @@ export default {
productName: null,
lotNo: null
},
selectedStocks: []
selectedStocks: [],
// ---------- 货位弹框 ----------
cargoDialogVisible: false,
cargoLoading: false,
cargoList: [],
cargoTotal: 0,
cargoQuery: {
pageNum: 1,
pageSize: 8,
warehouseId: null,
cargoSpaceId: null,
cargoAreaId: null,
trayCode: null,
thePlatoon: null,
theColumn: null,
theFloor: null,
},
selectedCargos: []
}
},
@@ -391,6 +544,68 @@ export default {
this.stockDialogVisible = false
},
// ===== 货位弹框 =====
openCargoDialog() {
this.cargoDialogVisible = true
},
onCargoDialogOpen() {
this.resetCargoSearch()
this.cargoQuery.warehouseId = this.mainForm.warehouseId
this.fetchCargoList()
},
searchCargo() {
this.cargoQuery.pageNum = 1
this.fetchCargoList()
},
resetCargoSearch() {
this.cargoQuery.cargoSpaceId = null
this.cargoQuery.trayCode = null
this.cargoQuery.status = null
this.cargoQuery.pageNum = 1
},
fetchCargoList() {
this.cargoLoading = true
listCargospace(this.cargoQuery).then(res => {
this.cargoList = res.rows || []
this.cargoTotal = res.total || 0
this.cargoLoading = false
// 回显已选中行
this.$nextTick(() => {
if (this.$refs.cargoTable) {
this.cargoList.forEach(row => {
const already = this.detailLines.some(l => l.cargoSpaceId === row.cargoSpaceId)
if (already) {
this.$refs.cargoTable.toggleRowSelection(row, true)
}
})
}
})
}).catch(() => { this.cargoLoading = false })
},
onCargoSelectionChange(selection) {
this.selectedCargos = selection
},
// 已在明细行中的库存记录置为不可重复勾选
isCargoSelectable(row) {
return !this.detailLines.some(l => l.cargoSpaceId === row.cargoSpaceId)
},
confirmCargos() {
this.selectedCargos.forEach(s => {
if (!this.detailLines.some(l => l.cargoSpaceId === s.cargoSpaceId)) {
this.detailLines.push({
cargoSpaceId: s.cargoSpaceId || '',
trayCode: s.trayCode || '',
thePlatoon: s.thePlatoon,
theColumn: s.theColumn,
theFloor: s.theFloor,
status: s.status,
theType: s.theType,
})
}
})
this.cargoDialogVisible = false
},
// ===== 明细行操作 =====
removeLine(index) {
this.detailLines.splice(index, 1)
@@ -408,7 +623,7 @@ export default {
}
// 3. 数量校验
const invalidLine = this.detailLines.find(l => !l.pdQuantity || l.pdQuantity <= 0)
if (invalidLine) {
if (invalidLine && mainForm.pdType==2) {
this.$modal.msgWarning(`物料【${invalidLine.productName}】的盘点数量必须大于 0`)
return
}