Browse Source

add:大屏看板,fix:出库单维护

master
zhangzq 3 weeks ago
parent
commit
5abccd5880
  1. 6
      nladmin-system/nlsso-server/src/main/java/org/nl/wms/basedata_manage/service/dao/mapper/BsrealStorattrMapper.java
  2. 18
      nladmin-system/nlsso-server/src/main/java/org/nl/wms/basedata_manage/service/dao/mapper/BsrealStorattrMapper.xml
  3. 50
      nladmin-system/nlsso-server/src/main/java/org/nl/wms/bigscreen_manage/controller/BigScreenController.java
  4. 24
      nladmin-system/nlsso-server/src/main/java/org/nl/wms/bigscreen_manage/service/BigScreenService.java
  5. 11
      nladmin-system/nlsso-server/src/main/java/org/nl/wms/bigscreen_manage/service/dto/IvtAnalyse.java
  6. 355
      nladmin-system/nlsso-server/src/main/java/org/nl/wms/bigscreen_manage/service/impl/BigScreenServiceImpl.java
  7. 1
      nladmin-system/nlsso-server/src/main/java/org/nl/wms/pm_manage/form_data/service/dao/mapper/xml/PmFormDataMapper.xml
  8. 2
      nladmin-system/nlsso-server/src/main/java/org/nl/wms/pm_manage/form_data/service/dto/PmFormDataDto.java
  9. 9
      nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch_manage/enums/TaskStatus.java
  10. 3
      nladmin-system/nlsso-server/src/main/java/org/nl/wms/warehouse_management/service/impl/OutBillServiceImpl.java
  11. 10
      nladmin-ui/src/views/wms/st/outbill/AddDialog.vue

6
nladmin-system/nlsso-server/src/main/java/org/nl/wms/basedata_manage/service/dao/mapper/BsrealStorattrMapper.java

@ -7,6 +7,9 @@ import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.nl.wms.basedata_manage.service.dao.BsrealStorattr;
import org.nl.wms.basedata_manage.service.dao.BsrealStorattrDto;
import org.nl.wms.bigscreen_manage.service.dto.IvtAnalyse;
import java.util.List;
/**
* @author dsh
@ -15,5 +18,8 @@ import org.nl.wms.basedata_manage.service.dao.BsrealStorattrDto;
@Mapper
public interface BsrealStorattrMapper extends BaseMapper<BsrealStorattr> {
List<IvtAnalyse> sumMaterQty(String storCode);
IPage<BsrealStorattrDto> queryAllByPage(Page<BsrealStorattrDto> page, @Param("search") String search);
}

18
nladmin-system/nlsso-server/src/main/java/org/nl/wms/basedata_manage/service/dao/mapper/BsrealStorattrMapper.xml

@ -14,4 +14,22 @@
</where>
ORDER BY stor.update_time Desc
</select>
<select id="sumMaterQty" resultType="org.nl.wms.bigscreen_manage.service.dto.IvtAnalyse">
SELECT
st_ivt_structattr.stor_code,
md_me_materialbase.material_id,
md_me_materialbase.material_name,
SUM( qty ) as sum_qty
FROM
st_ivt_structattr
LEFT JOIN md_pb_groupplate ON st_ivt_structattr.storagevehicle_code = md_pb_groupplate.storagevehicle_code
LEFT JOIN md_me_materialbase ON md_me_materialbase.material_id = md_pb_groupplate.material_id
WHERE
st_ivt_structattr.storagevehicle_code IS NOT NULL
and md_pb_groupplate.material_id is not null
and stor_code = #{storCode}
GROUP BY
stor_code,material_id
ORDER BY sum_qty
</select>
</mapper>

50
nladmin-system/nlsso-server/src/main/java/org/nl/wms/bigscreen_manage/controller/BigScreenController.java

@ -0,0 +1,50 @@
package org.nl.wms.bigscreen_manage.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.base.TableDataInfo;
import org.nl.common.logging.annotation.Log;
import org.nl.wms.bigscreen_manage.service.BigScreenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 大屏显示 控制层
* </p>
*
* @author Liuxy
* @since 2025-06-24
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/bigScreen")
@Slf4j
public class BigScreenController {
@Autowired
private BigScreenService bigScreenService;
@PostMapping("/getData")
@Log("大屏数据")
@SaIgnore
public ResponseEntity<Object> getData(@RequestBody JSONObject stors) {
List<String> list = new ArrayList<>();
list.add("GW");
list.add("GW");
List<JSONObject> data = bigScreenService.getData(list);
return new ResponseEntity<>(TableDataInfo.build(data), HttpStatus.OK);
}
}

24
nladmin-system/nlsso-server/src/main/java/org/nl/wms/bigscreen_manage/service/BigScreenService.java

@ -0,0 +1,24 @@
package org.nl.wms.bigscreen_manage.service;
import com.alibaba.fastjson.JSONObject;
import java.util.List;
/**
* <p>
* 大屏显示 服务类
* </p>
*
* @author Liuxy
* @since 2025-06-24
*/
public interface BigScreenService {
/**
* 获取大屏数据
*根据配置的仓库
* @return PdaResponse
*/
List<JSONObject> getData(List<String> stors);
}

11
nladmin-system/nlsso-server/src/main/java/org/nl/wms/bigscreen_manage/service/dto/IvtAnalyse.java

@ -0,0 +1,11 @@
package org.nl.wms.bigscreen_manage.service.dto;
import lombok.Data;
@Data
public class IvtAnalyse {
private String stor_code;
private String material_id;
private String material_name;
private Integer sum_qty;
}

355
nladmin-system/nlsso-server/src/main/java/org/nl/wms/bigscreen_manage/service/impl/BigScreenServiceImpl.java

@ -0,0 +1,355 @@
package org.nl.wms.bigscreen_manage.service.impl;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.nl.wms.basedata_manage.service.IStructattrService;
import org.nl.wms.basedata_manage.service.dao.Structattr;
import org.nl.wms.basedata_manage.service.dao.mapper.BsrealStorattrMapper;
import org.nl.wms.bigscreen_manage.service.BigScreenService;
import org.nl.wms.bigscreen_manage.service.dto.IvtAnalyse;
import org.nl.wms.sch_manage.enums.TaskStatus;
import org.nl.wms.sch_manage.service.ISchBaseTaskService;
import org.nl.wms.sch_manage.service.dao.SchBaseTask;
import org.nl.wms.warehouse_management.enums.IOSConstant;
import org.nl.wms.warehouse_management.enums.IOSEnum;
import org.nl.wms.warehouse_management.service.IOutBillService;
import org.nl.wms.warehouse_management.service.dao.IOStorInv;
import org.nl.wms.warehouse_management.service.dao.IOStorInvDis;
import org.nl.wms.warehouse_management.service.dao.mapper.IOStorInvDisMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 大屏显示 实现类
* </p>
*
* @author Liuxy
* @since 2025-06-24
*/
@Service
public class BigScreenServiceImpl implements BigScreenService {
@Autowired
private IStructattrService iStructattrService;
@Resource
private IOutBillService iOutBillService;
@Resource
private BsrealStorattrMapper screenMapper;
@Resource
private IOStorInvDisMapper ioStorInvDisMapper;
@Autowired
private ISchBaseTaskService iSchBaseTaskService;
@Override
public List<JSONObject> getData(List<String> stors) {
// String storCode = "GW";
List result = new ArrayList<>();
if (CollectionUtils.isEmpty(stors)){
return result;
}
for (String storCode : stors) {
JSONObject item = new JSONObject();
//1.【货位使用】数据
item.put("title","GW仓库");
item.put("pointUse", pointUse(storCode));
// //2.【实时库存分析】数据
item.put("ivtAnalyse", ivtAnalyse(storCode));
//3.【出入库趋势】数据
item.put("inAndOutTrend", inAndOutTrend(storCode));
// //4.【今日出入库】数据
item.put("toDayInAndOut", toDayInAndOut(storCode));
// //5.【今日出入库】数据
item.put("realTask", realTask(storCode));
//6.【未完成单据】数据
item.put("unIos", unIos(storCode));
result.add(item);
}
return result;
}
/**
//
// * 货位使用
// *
// * @return JSONObject {
// * total_qty: 总货位数
// * use_qty: 已用货位
// * emp_qty: 空余货位
// * use_percentage: 百分比(使用货位百分比)
// * }
// */
private JSONObject pointUse(String storCode) {
// 返回数据
JSONObject result = new JSONObject();
// 查询所有未删除且启用仓位
int emp_qty = iStructattrService.count(
new QueryWrapper<Structattr>().lambda()
.eq(Structattr::getIs_used, Boolean.TRUE)
.eq(Structattr::getStor_code, storCode)
.isNull(Structattr::getStoragevehicle_code));
int use_qty = iStructattrService.count(
new QueryWrapper<Structattr>().lambda()
.eq(Structattr::getIs_used, Boolean.TRUE)
.eq(Structattr::getStor_code, storCode)
.isNotNull(Structattr::getStoragevehicle_code));
int total_qty = iStructattrService.count(
new QueryWrapper<Structattr>().lambda()
.eq(Structattr::getIs_used, Boolean.TRUE)
.eq(Structattr::getStor_code, storCode));
// 总货位数
result.put("total_qty", total_qty);
// 已用货位数
result.put("use_qty", use_qty);
// 空余货位
result.put("emp_qty", emp_qty);
// 使用货位百分比
double use_percentage = NumberUtil.mul(NumberUtil.div(use_qty, total_qty), 100);
result.put("use_percentage", NumberUtil.round(use_percentage, 2));
return result;
}
/**
* 实时库存分析
*
* @return JSONObject {
* total_qty: 总数
* data: [
* material_name: 物料名称
* ivt_qty: 库存数量
* percentage: 百分比
* ]
* }
*/
private JSONObject ivtAnalyse(String storCode) {
JSONObject result = new JSONObject();
List<IvtAnalyse> list = screenMapper.sumMaterQty(storCode);
int sum = list.stream().mapToInt(IvtAnalyse::getSum_qty).sum();
result.put("total_qty", sum);
List<JSONObject> topFiveList = new ArrayList<>();
int i = 0;
int top5 = 0;
for (IvtAnalyse json : list) {
if (i==5){break;}
JSONObject item = new JSONObject();
item.put("ivt_qty", json.getSum_qty());
item.put("material_name", json.getMaterial_name());
double percentage = NumberUtil.mul(json.getSum_qty()/sum, 100);
item.put("percentage", NumberUtil.round(percentage, 2));
topFiveList.add(item);
i++;
top5 = top5+json.getSum_qty();
}
if (sum>top5){
JSONObject other = new JSONObject();
other.put("ivt_qty", sum-top5);
other.put("material_name", "其他物料");
other.put("percentage", NumberUtil.round(1-top5/sum, 2));
topFiveList.add(other);
}
result.put("data", topFiveList);
return result;
}
/**
* 出入库趋势
*
* @return JSONObject {
* in: [{date:日期qty:数量}]
* out: [{date:日期qty:数量}]
* }
*/
private JSONObject inAndOutTrend(String storCode) {
// 获取七天天数集合
DateTime dateTime = DateUtil.offsetDay(DateUtil.parseDate(DateUtil.today()), -6);
List<String> dateList = DateUtil.rangeToList(dateTime, DateUtil.parse(DateUtil.today()), DateField.DAY_OF_YEAR).stream()
.map(DateTime::toString)
.map(row -> row.substring(0, 10))
.collect(Collectors.toList());
// 查询七天内的出入库数据
List<IOStorInv> allIosList = iOutBillService.list(
new QueryWrapper<IOStorInv>().lambda()
.in(IOStorInv::getBiz_date, dateList)
.eq(IOStorInv::getIs_delete, IOSConstant.IS_DELETE_NO)
.eq(IOStorInv::getStor_code, storCode)
.eq(IOStorInv::getBill_status, IOSEnum.BILL_STATUS.code("完成"))
);
// 查询入库单据
List<IOStorInv> inIosList = allIosList.stream()
.filter(row -> row.getIo_type().equals(IOSEnum.IO_TYPE.code("入库")))
.collect(Collectors.toList());
// 查询出库单据
List<IOStorInv> outIosList = allIosList.stream()
.filter(row -> row.getIo_type().equals(IOSEnum.IO_TYPE.code("出库")))
.collect(Collectors.toList());
// 组织数据
List<JSONObject> inList = new ArrayList<>();
List<JSONObject> outList = new ArrayList<>();
for (String date : dateList) {
// 处理入库数量
JSONObject jsonIn = new JSONObject();
jsonIn.put("date", date);
double in_qty = inIosList.stream()
.filter(row -> row.getBiz_date().equals(date))
.map(row -> row.getTotal_qty().doubleValue())
.reduce(Double::sum).orElse(0.00);
jsonIn.put("qty", NumberUtil.round(in_qty, 2));
inList.add(jsonIn);
// 处理出库数据
JSONObject jsonOut = new JSONObject();
jsonOut.put("date", date);
double out_qty = outIosList.stream()
.filter(row -> row.getBiz_date().equals(date))
.map(row -> row.getTotal_qty().doubleValue())
.reduce(Double::sum).orElse(0.00);
jsonOut.put("qty", NumberUtil.round(out_qty, 2));
outList.add(jsonOut);
}
JSONObject result = new JSONObject();
result.put("in", inList);
result.put("out", outList);
return result;
}
/**
* 今日出入库
*
* @return JSONObject {
* in: {total_qty:总数量vehicle_qty:托盘数量}
* out: {total_qty:总数量vehicle_qty:托盘数量}
* }
*/
private JSONObject toDayInAndOut(String storCode) {
// 查询今天出入库单据
List<IOStorInv> inList = iOutBillService.list(
new QueryWrapper<IOStorInv>().lambda()
.eq(IOStorInv::getBiz_date, DateUtil.today())
.eq(IOStorInv::getIs_delete, IOSConstant.IS_DELETE_NO)
.eq(IOStorInv::getStor_code, storCode)
.eq(IOStorInv::getIo_type, IOSEnum.IO_TYPE.code("入库"))
.eq(IOStorInv::getBill_status, IOSEnum.BILL_STATUS.code("完成"))
);
// 查询今天出库单据
List<IOStorInv> outList = iOutBillService.list(
new QueryWrapper<IOStorInv>().lambda()
.eq(IOStorInv::getBiz_date, DateUtil.today())
.eq(IOStorInv::getIs_delete, IOSConstant.IS_DELETE_NO)
.eq(IOStorInv::getStor_code, storCode)
.eq(IOStorInv::getIo_type, IOSEnum.IO_TYPE.code("出库"))
.eq(IOStorInv::getBill_status, IOSEnum.BILL_STATUS.code("完成"))
);
// 入库
JSONObject jsonIn = new JSONObject();
// 总数量
double total_qty_in = inList.stream()
.map(row -> row.getTotal_qty().doubleValue())
.reduce(Double::sum).orElse(0.0);
jsonIn.put("total_qty", NumberUtil.round(total_qty_in, 2));
// 托盘数
List<IOStorInvDis> inDisList = new ArrayList<>();
if (ObjectUtil.isNotEmpty(inList)) {
inDisList = ioStorInvDisMapper.selectList(
new QueryWrapper<IOStorInvDis>().lambda()
.in(IOStorInvDis::getIostorinv_id, inList.stream()
.map(IOStorInv::getIostorinv_id)
.collect(Collectors.toList())
)
);
}
jsonIn.put("vehicle_qty", inDisList.size());
// 出库
JSONObject jsonOut = new JSONObject();
// 总数量
double total_qty_out = outList.stream()
.map(row -> row.getTotal_qty().doubleValue())
.reduce(Double::sum).orElse(0.0);
jsonOut.put("total_qty", NumberUtil.round(total_qty_out, 2));
// 托盘数
List<IOStorInvDis> outDisList = new ArrayList<>();
if (ObjectUtil.isNotEmpty(outList)) {
outDisList = ioStorInvDisMapper.selectList(
new QueryWrapper<IOStorInvDis>().lambda()
.in(IOStorInvDis::getIostorinv_id, outList.stream()
.map(IOStorInv::getIostorinv_id)
.collect(Collectors.toList())
)
);
}
jsonOut.put("vehicle_qty", outDisList.size());
JSONObject result = new JSONObject();
result.put("in", jsonIn);
result.put("out", jsonOut);
return result;
}
/**
* 实时任务
*
* @return List<SchBaseTask> {
* 任务实体列
* }
*/
private List<SchBaseTask> realTask(String storCode) {
List<SchBaseTask> list = iSchBaseTaskService.list(
new QueryWrapper<SchBaseTask>().lambda()
.le(SchBaseTask::getTask_status, TaskStatus.FINISHED.getCode())
.eq(SchBaseTask::getIs_delete, IOSConstant.IS_DELETE_NO)
.ge(SchBaseTask::getCreate_time,DateUtil.today())
);
list.stream().forEach(item -> {
item.setTask_status(TaskStatus.convertName(item.getTask_status()));
});
return list;
}
/**
* 未完成单据
*
* @return List<IOStorInv>{
* 出入库实体类
* }
*/
private List<IOStorInv> unIos(String storCode) {
List<IOStorInv> list = iOutBillService.list(
new QueryWrapper<IOStorInv>().lambda()
.eq(IOStorInv::getIs_delete, IOSConstant.IS_DELETE_NO)
.eq(IOStorInv::getStor_code, storCode)
.ne(IOStorInv::getBill_status, IOSEnum.BILL_STATUS.code("完成"))
);
list.stream().forEach(item -> {
item.setIo_type(item.getIo_type().equals(IOSEnum.IO_TYPE.code("入库"))?"入库":"出库");
if (item.getBill_status().equals(IOSEnum.BILL_STATUS.code("生成"))) {
item.setBill_status("生成");
}
if (item.getBill_status().equals(IOSEnum.BILL_STATUS.code("分配中"))) {
item.setBill_status("分配中");
}
if (item.getBill_status().equals(IOSEnum.BILL_STATUS.code("分配完"))) {
item.setBill_status("分配完");
}
item.setBill_type("dict.getLabel()");
});
return list;
}
}

1
nladmin-system/nlsso-server/src/main/java/org/nl/wms/pm_manage/form_data/service/dao/mapper/xml/PmFormDataMapper.xml

@ -111,6 +111,7 @@
SELECT
pm_form_data.*,
md_me_materialbase.material_code,
md_me_materialbase.material_id,
md_me_materialbase.material_name,
md_me_materialbase.material_spec,
md_me_materialbase.net_weight

2
nladmin-system/nlsso-server/src/main/java/org/nl/wms/pm_manage/form_data/service/dto/PmFormDataDto.java

@ -46,7 +46,7 @@ public class PmFormDataDto implements Serializable {
* 物料code
*/
private String material_code;
private String material_id;
/**
* 物料规格
*/

9
nladmin-system/nlsso-server/src/main/java/org/nl/wms/sch_manage/enums/TaskStatus.java

@ -73,4 +73,13 @@ public enum TaskStatus {
public void setDesc(String desc) {
this.desc = desc;
}
public static String convertName(String code){
for (TaskStatus value : TaskStatus.values()) {
if (value.getCode().equals(code)){
return value.getName();
}
}
return "";
}
}

3
nladmin-system/nlsso-server/src/main/java/org/nl/wms/warehouse_management/service/impl/OutBillServiceImpl.java

@ -312,6 +312,9 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper,IOStorInv> i
ioStorInvDtl.put("qty_unit_id", row.get("qty_unit_id"));
ioStorInvDtl.put("qty_unit_name", row.getString("qty_unit_name"));
ioStorInvDtl.put("plan_qty", row.get("qty"));
ioStorInvDtl.put("source_bill_code", row.get("source_bill_code"));
ioStorInvDtl.put("source_bill_type", row.get("source_bill_type"));
ioStorInvDtl.put("source_billdtl_id", row.get("source_billdtl_id"));
ioStorInvDtl.put("remark", row.getString("remark"));
ioStorInvDtl.put("assign_qty", "0");
ioStorInvDtl.put("unassign_qty", row.get("qty"));

10
nladmin-ui/src/views/wms/st/outbill/AddDialog.vue

@ -164,6 +164,12 @@
</template>
</el-table-column>
<el-table-column prop="qty_unit_name" label="单位" align="center" />
<el-table-column prop="source_bill_code" label="源单号" align="center" />
<el-table-column prop="source_bill_type" label="源单类型" align="center">
<template slot-scope="scope">
{{ dict.label.INANDOUT_BILL_TYPE[scope.row.source_bill_type] }}
</template>
</el-table-column>
<el-table-column show-overflow-tooltip prop="remark" label="明细备注" align="center">
<template scope="scope">
<el-input v-model="scope.row.remark" size="mini" />
@ -216,7 +222,7 @@ export default {
default: false
}
},
dicts: ['io_bill_status', 'ST_QUALITY_SCODE', 'ST_IVT_LEVEL', 'is_used', 'ST_INV_OUT_TYPE'],
dicts: ['io_bill_status', 'ST_QUALITY_SCODE', 'ST_IVT_LEVEL', 'is_used', 'ST_INV_OUT_TYPE', 'INANDOUT_BILL_TYPE'],
data() {
return {
dialogVisible: false,
@ -390,7 +396,7 @@ export default {
this.nowrow.plan_qty = data.qty
this.nowrow.qty = data.qty
this.nowrow.source_bill_code = data.code
this.nowrow.source_bill_id = data.id
this.nowrow.source_billdtl_id = data.id
this.nowrow.source_bill_type = data.form_type
this.nowrow.edit = false
this.form.tableData.splice(this.nowindex, 1, this.nowrow) // splice

Loading…
Cancel
Save