add:pda出库确认页面
This commit is contained in:
@@ -74,6 +74,6 @@ public interface ISectattrService extends IService<Sectattr> {
|
|||||||
* key:库区类型
|
* key:库区类型
|
||||||
* value:库区sectCode集合
|
* value:库区sectCode集合
|
||||||
*/
|
*/
|
||||||
Map<String,List<String>> getSectType();
|
Map<String,List<Sectattr>> getSectType();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -309,16 +309,14 @@ public class SectattrServiceImpl extends ServiceImpl<SectattrMapper, Sectattr> i
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = "baseConfig", key = "'allSectType'")
|
public Map<String, List<Sectattr>> getSectType() {
|
||||||
public Map<String, List<String>> getSectType() {
|
|
||||||
final List<Sectattr> list = this.list(new LambdaQueryWrapper<Sectattr>()
|
final List<Sectattr> list = this.list(new LambdaQueryWrapper<Sectattr>()
|
||||||
.eq(Sectattr::getIs_delete, BaseDataEnum.IS_YES_NOT.code("否"))
|
.eq(Sectattr::getIs_delete, BaseDataEnum.IS_YES_NOT.code("否"))
|
||||||
.eq(Sectattr::getIs_used, BaseDataEnum.IS_YES_NOT.code("是"))
|
.eq(Sectattr::getIs_used, BaseDataEnum.IS_YES_NOT.code("是"))
|
||||||
.select(Sectattr::getSect_type_attr, Sectattr::getSect_code));
|
.select(Sectattr::getSect_name,Sectattr::getSect_type_attr, Sectattr::getSect_code));
|
||||||
return list.stream()
|
return list.stream()
|
||||||
.collect(Collectors.groupingBy(
|
.collect(Collectors.groupingBy(
|
||||||
Sectattr::getSect_type_attr,
|
Sectattr::getSect_type_attr
|
||||||
Collectors.mapping(Sectattr::getSect_code, Collectors.toList())
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ package org.nl.wms.pda_manage.ios_manage.service;
|
|||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import org.nl.wms.pda_manage.outBound.dto.LineSideDto;
|
import org.nl.wms.pda_manage.outBound.dto.LineSideDto;
|
||||||
import org.nl.wms.pda_manage.util.PdaResponse;
|
import org.nl.wms.pda_manage.util.PdaResponse;
|
||||||
|
import org.nl.wms.warehouse_manage.inAndOut.service.dao.IOStorInvDis;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -15,14 +18,11 @@ import org.nl.wms.pda_manage.util.PdaResponse;
|
|||||||
public interface PdaIosOutService {
|
public interface PdaIosOutService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取库存明细
|
* 获取库区出库明细
|
||||||
*
|
*
|
||||||
* @param whereJson {
|
|
||||||
* storagevehicle_code: 载具码
|
|
||||||
* }
|
|
||||||
* @return PdaResponse
|
* @return PdaResponse
|
||||||
*/
|
*/
|
||||||
PdaResponse getDtl(JSONObject whereJson);
|
PdaResponse<List<IOStorInvDis>> selectSectOutDis(String sectCode);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package org.nl.wms.pda_manage.ios_manage.service.dto;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/5/20
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OutBoundDis implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出入单分配标识
|
||||||
|
*/
|
||||||
|
private String iostorinvdisId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 库区名称
|
||||||
|
*/
|
||||||
|
private String sectName;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物料标识
|
||||||
|
*/
|
||||||
|
private String materialCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数量计量单位名称
|
||||||
|
*/
|
||||||
|
private String unitName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行状态
|
||||||
|
*/
|
||||||
|
private String workStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计划数量
|
||||||
|
*/
|
||||||
|
private BigDecimal planQty;
|
||||||
|
/**
|
||||||
|
* 分配数量
|
||||||
|
*/
|
||||||
|
private BigDecimal assignQty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 仓位编码
|
||||||
|
*/
|
||||||
|
private String structCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储载具编码
|
||||||
|
*/
|
||||||
|
private String storagevehicleCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搬运方式0自动搬运1手工
|
||||||
|
*/
|
||||||
|
private Boolean handType;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.nl.common.annotation.Mock;
|
||||||
import org.nl.common.exception.BadRequestException;
|
import org.nl.common.exception.BadRequestException;
|
||||||
import org.nl.common.utils.CodeUtil;
|
import org.nl.common.utils.CodeUtil;
|
||||||
import org.nl.common.utils.IdUtil;
|
import org.nl.common.utils.IdUtil;
|
||||||
@@ -26,6 +27,7 @@ import org.nl.wms.basedata_manage.service.dto.StrategyMater;
|
|||||||
import org.nl.wms.basedata_manage.service.dto.StrategyStructMaterialVO;
|
import org.nl.wms.basedata_manage.service.dto.StrategyStructMaterialVO;
|
||||||
import org.nl.wms.basedata_manage.service.dto.StrategyStructParam;
|
import org.nl.wms.basedata_manage.service.dto.StrategyStructParam;
|
||||||
import org.nl.wms.pda_manage.ios_manage.service.PdaIosOutService;
|
import org.nl.wms.pda_manage.ios_manage.service.PdaIosOutService;
|
||||||
|
import org.nl.wms.pda_manage.ios_manage.service.dto.OutBoundDis;
|
||||||
import org.nl.wms.pda_manage.outBound.dto.LineSideDto;
|
import org.nl.wms.pda_manage.outBound.dto.LineSideDto;
|
||||||
import org.nl.wms.pda_manage.util.PdaResponse;
|
import org.nl.wms.pda_manage.util.PdaResponse;
|
||||||
import org.nl.wms.sch_manage.enums.StatusEnum;
|
import org.nl.wms.sch_manage.enums.StatusEnum;
|
||||||
@@ -140,11 +142,6 @@ public class PdaIosOutServiceImpl implements PdaIosOutService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IOStorInvDisMapper ioStorInvDisMapper;
|
private IOStorInvDisMapper ioStorInvDisMapper;
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新库存服务
|
|
||||||
*/
|
|
||||||
@Autowired
|
|
||||||
private UpdateIvtUtils updateIvtUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 出库任务类
|
* 出库任务类
|
||||||
@@ -160,8 +157,31 @@ public class PdaIosOutServiceImpl implements PdaIosOutService {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PdaResponse getDtl(JSONObject whereJson) {
|
@Mock
|
||||||
return null;
|
public PdaResponse selectSectOutDis(String sectCode) {
|
||||||
|
if (StringUtils.isEmpty(sectCode)){
|
||||||
|
throw new BadRequestException("查询手工出后配送失败,请求参数sect为空");
|
||||||
|
}
|
||||||
|
final List<IOStorInvDis> invDis = ioStorInvDisMapper.selectList(new LambdaQueryWrapper<IOStorInvDis>()
|
||||||
|
.eq(IOStorInvDis::getSect_code, sectCode)
|
||||||
|
.eq(IOStorInvDis::getWork_status, IOSEnum.INBILL_DIS_STATUS.code("生成"))
|
||||||
|
.eq(IOStorInvDis::getHand_type, Boolean.getBoolean(IOSEnum.HAND_TYPE.code("手动搬运"))));
|
||||||
|
final ArrayList<OutBoundDis> result = new ArrayList<>();
|
||||||
|
for (IOStorInvDis source : invDis) {
|
||||||
|
OutBoundDis target = new OutBoundDis();
|
||||||
|
// 字段映射(注意下划线命名转驼峰命名)
|
||||||
|
target.setIostorinvdisId(source.getIostorinvdis_id());
|
||||||
|
target.setSectName(source.getSect_name());
|
||||||
|
target.setStructCode(source.getStruct_code());
|
||||||
|
target.setStoragevehicleCode(source.getStoragevehicle_code());
|
||||||
|
target.setMaterialCode(source.getMaterial_code());
|
||||||
|
target.setUnitName(source.getQty_unit_name());
|
||||||
|
target.setWorkStatus(source.getWork_status());
|
||||||
|
target.setPlanQty(source.getPlan_qty());
|
||||||
|
target.setHandType(source.getHand_type());
|
||||||
|
result.add(target);
|
||||||
|
}
|
||||||
|
return PdaResponse.requestParamOk(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,15 +7,23 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.nl.common.base.TableDataInfo;
|
import org.nl.common.base.TableDataInfo;
|
||||||
import org.nl.common.logging.annotation.Log;
|
import org.nl.common.logging.annotation.Log;
|
||||||
|
import org.nl.common.utils.MapOf;
|
||||||
|
import org.nl.wms.basedata_manage.service.ISectattrService;
|
||||||
|
import org.nl.wms.basedata_manage.service.dao.Sectattr;
|
||||||
import org.nl.wms.pda_manage.ios_manage.service.PdaIosOutService;
|
import org.nl.wms.pda_manage.ios_manage.service.PdaIosOutService;
|
||||||
|
import org.nl.wms.pda_manage.ios_manage.service.dto.OutBoundDis;
|
||||||
import org.nl.wms.pda_manage.outBound.dto.LineSideDto;
|
import org.nl.wms.pda_manage.outBound.dto.LineSideDto;
|
||||||
|
import org.nl.wms.pda_manage.util.PdaResponse;
|
||||||
|
import org.nl.wms.warehouse_manage.enums.IOSEnum;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import java.util.Collections;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.nl.common.utils.ValidationUtil.assertNotBlankJson;
|
import static org.nl.common.utils.ValidationUtil.assertNotBlankJson;
|
||||||
|
|
||||||
@@ -28,17 +36,40 @@ import static org.nl.common.utils.ValidationUtil.assertNotBlankJson;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RequestMapping("/api/pda/iosOut")
|
@RequestMapping("/api/pda/iosOut")
|
||||||
@SaIgnore
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PdaIosOutController {
|
public class PdaIosOutController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PdaIosOutService pdaIosOutService;
|
private PdaIosOutService pdaIosOutService;
|
||||||
|
|
||||||
@PostMapping("/getDtl")
|
@Autowired
|
||||||
@Log("获取库存明细")
|
private ISectattrService iSectattrService;
|
||||||
public ResponseEntity<Object> getDtl(@RequestBody JSONObject whereJson) {
|
|
||||||
return new ResponseEntity<>(pdaIosOutService.getDtl(whereJson), HttpStatus.OK);
|
@GetMapping("/flatWarehouse")
|
||||||
|
@SaIgnore
|
||||||
|
public ResponseEntity<Object> flatWarehouse() {
|
||||||
|
final List<HashMap> flatWH = iSectattrService.getSectType()
|
||||||
|
.getOrDefault(IOSEnum.ST_SECT_TYPE.code("平库"), Collections.emptyList())
|
||||||
|
.stream()
|
||||||
|
.map(sectattr -> MapOf.of(
|
||||||
|
"label", sectattr.getSect_name(),
|
||||||
|
"value", sectattr.getSect_code()
|
||||||
|
))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return new ResponseEntity<>(PdaResponse.requestParamOk(flatWH), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/getOutBoundDtl")
|
||||||
|
@SaIgnore
|
||||||
|
public ResponseEntity<Object> getOutBoundDtl(String sectCode) {
|
||||||
|
return new ResponseEntity<>(pdaIosOutService.selectSectOutDis(sectCode), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/assignOutDis")
|
||||||
|
@SaIgnore
|
||||||
|
public ResponseEntity<Object> assignOutDis(OutBoundDis outBoundDis) {
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package org.nl.wms.pda_manage.util;
|
|||||||
|
|
||||||
import cn.hutool.http.HttpStatus;
|
import cn.hutool.http.HttpStatus;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import org.nl.common.base.TableDataInfo;
|
import org.nl.common.base.TableDataInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,6 +18,8 @@ import org.nl.common.base.TableDataInfo;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
public class PdaResponse<T> {
|
public class PdaResponse<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public enum IOSEnum {
|
|||||||
//入库分配明细状态
|
//入库分配明细状态
|
||||||
INBILL_DIS_STATUS(MapOf.of("未生成", "00", "生成", "01", "执行中", "02", "完成", "99")),
|
INBILL_DIS_STATUS(MapOf.of("未生成", "00", "生成", "01", "执行中", "02", "完成", "99")),
|
||||||
|
|
||||||
|
HAND_TYPE(MapOf.of("自动搬运", "false", "手动搬运", "true")),
|
||||||
|
|
||||||
//组盘记录状态
|
//组盘记录状态
|
||||||
GROUP_PLATE_STATUS(MapOf.of("生成", "00", "组盘", "01", "入库", "02", "出库", "03")),
|
GROUP_PLATE_STATUS(MapOf.of("生成", "00", "组盘", "01", "入库", "02", "出库", "03")),
|
||||||
|
|
||||||
|
|||||||
@@ -127,5 +127,9 @@ public class IOStorInvDis implements Serializable {
|
|||||||
* 出入点位标识
|
* 出入点位标识
|
||||||
*/
|
*/
|
||||||
private String point_code;
|
private String point_code;
|
||||||
|
/**
|
||||||
|
* 搬运方式0自动搬运1手工
|
||||||
|
*/
|
||||||
|
private Boolean hand_type;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.nl.wms.basedata_manage.service.IMdPbStoragevehicleinfoService;
|
|||||||
import org.nl.wms.basedata_manage.service.ISectattrService;
|
import org.nl.wms.basedata_manage.service.ISectattrService;
|
||||||
import org.nl.wms.basedata_manage.service.IStructattrService;
|
import org.nl.wms.basedata_manage.service.IStructattrService;
|
||||||
import org.nl.wms.basedata_manage.service.dao.BsrealStorattr;
|
import org.nl.wms.basedata_manage.service.dao.BsrealStorattr;
|
||||||
|
import org.nl.wms.basedata_manage.service.dao.Sectattr;
|
||||||
import org.nl.wms.basedata_manage.service.dao.Structattr;
|
import org.nl.wms.basedata_manage.service.dao.Structattr;
|
||||||
import org.nl.wms.basedata_manage.service.dao.mapper.MdPbStoragevehicleextMapper;
|
import org.nl.wms.basedata_manage.service.dao.mapper.MdPbStoragevehicleextMapper;
|
||||||
import org.nl.wms.basedata_manage.service.dto.*;
|
import org.nl.wms.basedata_manage.service.dto.*;
|
||||||
@@ -740,9 +741,9 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
|
|||||||
if (ObjectUtil.isEmpty(dtls)) {
|
if (ObjectUtil.isEmpty(dtls)) {
|
||||||
throw new BadRequestException("当前订单无可分配出库明细");
|
throw new BadRequestException("当前订单无可分配出库明细");
|
||||||
}
|
}
|
||||||
List<String> flatWarehouse = iSectattrService.getSectType()
|
List<Sectattr> collect = iSectattrService.getSectType()
|
||||||
.getOrDefault(IOSEnum.ST_SECT_TYPE.code("平库"),Collections.emptyList());
|
.getOrDefault(IOSEnum.ST_SECT_TYPE.code("平库"),Collections.emptyList());
|
||||||
|
final List<String> flatWarehouse = collect.stream().map(Sectattr::getSect_code).collect(Collectors.toList());
|
||||||
for (IOStorInvDtlDto dtl:dtls){
|
for (IOStorInvDtlDto dtl:dtls){
|
||||||
BigDecimal unassign_qty = dtl.getUnassign_qty();
|
BigDecimal unassign_qty = dtl.getUnassign_qty();
|
||||||
if (unassign_qty.intValue() <= 0){
|
if (unassign_qty.intValue() <= 0){
|
||||||
|
|||||||
@@ -49,3 +49,6 @@ CREATE TABLE `sys_mock_config` (
|
|||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `idx_class_method` (`class_name`, `method_name`)
|
KEY `idx_class_method` (`class_name`, `method_name`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Mock配置表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Mock配置表';
|
||||||
|
|
||||||
|
ALTER TABLE `st_ivt_iostorinvdis`
|
||||||
|
ADD COLUMN `hand_type` tinyint(1) NULL DEFAULT 0 COMMENT '出库类型:0自动搬运1手动搬运' AFTER `point_code`;
|
||||||
|
|||||||
2630
pda/pda/package-lock.json
generated
2630
pda/pda/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -25,12 +25,11 @@ const zh = {
|
|||||||
'平库上架',
|
'平库上架',
|
||||||
'平库库存查询',
|
'平库库存查询',
|
||||||
'库位绑定/解绑',
|
'库位绑定/解绑',
|
||||||
'拣选大厅',
|
'平库出库'
|
||||||
'无容器收货入库',
|
// '空托上架/下架/注册/呼叫',
|
||||||
'空托上架/下架/注册/呼叫',
|
// 'AGV配送',
|
||||||
'AGV配送',
|
// '人工盘点',
|
||||||
'人工盘点',
|
// '备货组盘查询',
|
||||||
'备货组盘查询',
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
receiveGroup: {
|
receiveGroup: {
|
||||||
@@ -131,6 +130,23 @@ const zh = {
|
|||||||
submit: '提交',
|
submit: '提交',
|
||||||
submitSuccess: '提交成功',
|
submitSuccess: '提交成功',
|
||||||
},
|
},
|
||||||
|
flatOutBound: {
|
||||||
|
title: '平库出库',
|
||||||
|
sectCode: '库区',
|
||||||
|
sectCodePlaceholder: '请选择库区',
|
||||||
|
sectCodeRequired: '请选择库区',
|
||||||
|
selectSect: '选择库区',
|
||||||
|
total: '共{0}条',
|
||||||
|
loading: '加载中...',
|
||||||
|
noData: '暂无待出库物料',
|
||||||
|
materialCode: '物料编码',
|
||||||
|
structCode: '库位号',
|
||||||
|
vehicleCode: '载具号',
|
||||||
|
planQty: '计划数量',
|
||||||
|
assignQty: '分配数量',
|
||||||
|
complete: '完成',
|
||||||
|
completeSuccess: '操作成功',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const en = {
|
const en = {
|
||||||
@@ -265,6 +281,23 @@ const en = {
|
|||||||
submit: 'Submit',
|
submit: 'Submit',
|
||||||
submitSuccess: 'Submitted successfully',
|
submitSuccess: 'Submitted successfully',
|
||||||
},
|
},
|
||||||
|
flatOutBound: {
|
||||||
|
title: 'Flat Outbound',
|
||||||
|
sectCode: 'Warehouse Area',
|
||||||
|
sectCodePlaceholder: 'Please select warehouse area',
|
||||||
|
sectCodeRequired: 'Please select warehouse area',
|
||||||
|
selectSect: 'Select Warehouse Area',
|
||||||
|
total: 'Total {0} items',
|
||||||
|
loading: 'Loading...',
|
||||||
|
noData: 'No pending outbound materials',
|
||||||
|
materialCode: 'Material Code',
|
||||||
|
structCode: 'Location',
|
||||||
|
vehicleCode: 'Vehicle Code',
|
||||||
|
planQty: 'Plan Qty',
|
||||||
|
assignQty: 'Assign Qty',
|
||||||
|
complete: 'Complete',
|
||||||
|
completeSuccess: 'Success',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const messages = {zh, en}
|
const messages = {zh, en}
|
||||||
|
|||||||
@@ -49,6 +49,12 @@ const routes = [
|
|||||||
component: () => import('@/views/ManualInbound.vue'),
|
component: () => import('@/views/ManualInbound.vue'),
|
||||||
meta: { requiresAuth: true },
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/flat-outbound',
|
||||||
|
name: 'FlatOutBound',
|
||||||
|
component: () => import('@/views/FlatOutBound.vue'),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/developing',
|
path: '/developing',
|
||||||
name: 'Developing',
|
name: 'Developing',
|
||||||
|
|||||||
315
pda/pda/src/views/FlatOutBound.vue
Normal file
315
pda/pda/src/views/FlatOutBound.vue
Normal file
@@ -0,0 +1,315 @@
|
|||||||
|
<template>
|
||||||
|
<div class="page-container">
|
||||||
|
<van-nav-bar
|
||||||
|
:title="t('flatOutBound.title')"
|
||||||
|
left-arrow
|
||||||
|
@click-left="router.push('/')"
|
||||||
|
/>
|
||||||
|
<div class="page-content">
|
||||||
|
<van-form ref="formRef">
|
||||||
|
<van-field
|
||||||
|
v-model="sectName"
|
||||||
|
:label="t('flatOutBound.sectCode')"
|
||||||
|
:placeholder="t('flatOutBound.sectCodePlaceholder')"
|
||||||
|
:rules="[{ required: true, message: t('flatOutBound.sectCodeRequired') }]"
|
||||||
|
name="sectCode"
|
||||||
|
readonly
|
||||||
|
is-link
|
||||||
|
@click="showSectPicker = true"
|
||||||
|
/>
|
||||||
|
</van-form>
|
||||||
|
|
||||||
|
<div class="detail-section">
|
||||||
|
<div class="detail-header">
|
||||||
|
<span class="detail-header-text">{{ t('flatOutBound.total', materialList.length) }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="loading" class="detail-loading">
|
||||||
|
<van-loading size="24px">{{ t('flatOutBound.loading') }}</van-loading>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="!materialList.length" class="detail-empty">
|
||||||
|
<van-empty :description="t('flatOutBound.noData')" image="search" />
|
||||||
|
</div>
|
||||||
|
<div v-else class="card-list">
|
||||||
|
<div
|
||||||
|
v-for="(item, idx) in materialList"
|
||||||
|
:key="idx"
|
||||||
|
class="detail-card"
|
||||||
|
>
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-index">#{{ idx + 1 }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="card-left">
|
||||||
|
<div class="card-row">
|
||||||
|
<div class="field-group">
|
||||||
|
<span class="field-label">库区</span>
|
||||||
|
<span class="field-value">{{ item.sectName }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-group">
|
||||||
|
<span class="field-label">库位号</span>
|
||||||
|
<span class="field-value">{{ item.structCode }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-row">
|
||||||
|
<div class="field-group">
|
||||||
|
<span class="field-label">载具号</span>
|
||||||
|
<span class="field-value">{{ item.storagevehicleCode }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-group">
|
||||||
|
<span class="field-label">物料编码</span>
|
||||||
|
<span class="field-value">{{ item.materialCode }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-row">
|
||||||
|
<div class="field-group">
|
||||||
|
<span class="field-label">计划数量</span>
|
||||||
|
<span class="field-value field-value--primary">{{ item.planQty }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-group field-group--stepper">
|
||||||
|
<span class="field-label">分配数量</span>
|
||||||
|
<van-stepper
|
||||||
|
v-model="item.assignQty"
|
||||||
|
:min="0"
|
||||||
|
:step="1"
|
||||||
|
:decimal-length="3"
|
||||||
|
input-width="60px"
|
||||||
|
button-size="28px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-right">
|
||||||
|
<van-button
|
||||||
|
type="primary"
|
||||||
|
size="normal"
|
||||||
|
:loading="item.submitting"
|
||||||
|
@click="onComplete(item, idx)"
|
||||||
|
>
|
||||||
|
完成
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<van-popup v-model:show="showSectPicker" position="bottom">
|
||||||
|
<van-picker
|
||||||
|
:columns="sectOptions"
|
||||||
|
:title="t('flatOutBound.selectSect')"
|
||||||
|
@confirm="onSectConfirm"
|
||||||
|
@cancel="showSectPicker = false"
|
||||||
|
/>
|
||||||
|
</van-popup>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { showToast } from 'vant'
|
||||||
|
import { useI18n } from '@/i18n'
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const sectName = ref('')
|
||||||
|
const sectCode = ref('')
|
||||||
|
const showSectPicker = ref(false)
|
||||||
|
const sectOptions = ref([])
|
||||||
|
const materialList = ref([])
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
async function fetchFlatWarehouse() {
|
||||||
|
try {
|
||||||
|
const res = await request.get('/api/pda/iosOut/flatWarehouse')
|
||||||
|
if (res.data && Array.isArray(res.data)) {
|
||||||
|
sectOptions.value = res.data.map(item => ({
|
||||||
|
text: item.label,
|
||||||
|
value: item.value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// error handled by interceptor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchOutBoundDtl(code) {
|
||||||
|
if (!code) return
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await request.get('/api/pda/iosOut/getOutBoundDtl', {
|
||||||
|
params: { sectCode: code },
|
||||||
|
})
|
||||||
|
if (res.data && Array.isArray(res.data)) {
|
||||||
|
materialList.value = res.data.map(item => ({
|
||||||
|
...item,
|
||||||
|
assignQty: item.assignQty ?? item.planQty,
|
||||||
|
submitting: false,
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
materialList.value = []
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
materialList.value = []
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSectConfirm({ selectedOptions }) {
|
||||||
|
const selected = selectedOptions[0]
|
||||||
|
sectName.value = selected.text
|
||||||
|
sectCode.value = selected.value
|
||||||
|
showSectPicker.value = false
|
||||||
|
fetchOutBoundDtl(selected.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onComplete(item, idx) {
|
||||||
|
if (item.submitting) return
|
||||||
|
item.submitting = true
|
||||||
|
try {
|
||||||
|
const res = await request.post('/api/pda/iosOut/assignOutDis', {
|
||||||
|
item
|
||||||
|
})
|
||||||
|
showToast({ message: res.message || t('flatOutBound.completeSuccess'), type: 'success' })
|
||||||
|
materialList.value.splice(idx, 1)
|
||||||
|
} catch {
|
||||||
|
// error handled by interceptor
|
||||||
|
} finally {
|
||||||
|
item.submitting = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
fetchFlatWarehouse()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.detail-section {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-header-text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-loading {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 40px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-empty {
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: var(--primary-gradient);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-index {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body {
|
||||||
|
padding: 12px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-left {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-group {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-group--stepper {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-label {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 56px;
|
||||||
|
text-align: right;
|
||||||
|
color: #999;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-value {
|
||||||
|
flex: 1;
|
||||||
|
color: #333;
|
||||||
|
font-size: 14px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-value--primary {
|
||||||
|
color: var(--primary-color);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-right {
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding-left: 16px;
|
||||||
|
margin-left: 16px;
|
||||||
|
border-left: 1px solid #f0f0f0;
|
||||||
|
align-self: stretch;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -53,6 +53,8 @@ const menuRoutes = {
|
|||||||
3: '/putaway',
|
3: '/putaway',
|
||||||
4: '/inventory',
|
4: '/inventory',
|
||||||
5: '/bind-unbind',
|
5: '/bind-unbind',
|
||||||
|
6: '/flat-outbound',
|
||||||
|
7: '/flat-outbound',
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMenuClick(index) {
|
function onMenuClick(index) {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="login-header">
|
<div class="login-header">
|
||||||
<div class="login-logo">
|
<div class="login-logo">
|
||||||
<div class="logo-box">ZD</div>
|
<div class="logo-box">诺力</div>
|
||||||
<div class="logo-text">{{ t('login.title') }}</div>
|
<div class="logo-text">WMS系统</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="login-form">
|
<div class="login-form">
|
||||||
|
|||||||
Reference in New Issue
Block a user