add:增加看板及报表
@@ -0,0 +1,15 @@
|
||||
package org.nl.wms.biBoard;
|
||||
|
||||
import org.nl.wms.biBoard.screen.service.dto.AgvStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class StaticData {
|
||||
public static Map<String,AgvStatus> agv_status= new HashMap<>();
|
||||
|
||||
public void sync(String carId,AgvStatus agvStatus){
|
||||
agv_status.put(carId,agvStatus);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.nl.wms.biBoard.consumptionReport;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.common.base.TableDataInfo;
|
||||
import org.nl.common.domain.query.PageQuery;
|
||||
import org.nl.common.logging.annotation.Log;
|
||||
import org.nl.wms.biBoard.consumptionReport.service.IConsumeReportService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/report")
|
||||
@Slf4j
|
||||
public class ReportController {
|
||||
|
||||
@Autowired
|
||||
private IConsumeReportService iConsumeReportService;
|
||||
|
||||
@GetMapping("/consumeReport")
|
||||
@Log("班组焊材消耗报表查询")
|
||||
public ResponseEntity<Object> queryConsumeReport(@RequestParam Map whereJson, PageQuery page) {
|
||||
return new ResponseEntity<>(TableDataInfo.build(iConsumeReportService.queryConsumeReport(whereJson, page)), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/consumeReport/download")
|
||||
@Log("导出班组焊材消耗报表")
|
||||
public void downloadConsumeReport(@RequestParam Map whereJson, HttpServletResponse response) {
|
||||
iConsumeReportService.downloadConsumeReport(whereJson, response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.nl.wms.biBoard.consumptionReport.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 班组焊材消耗报表 DTO
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@Data
|
||||
public class ConsumeReportDto implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 序号
|
||||
*/
|
||||
private Integer rowNum;
|
||||
|
||||
/**
|
||||
* 班组编码
|
||||
*/
|
||||
private String groupCode;
|
||||
|
||||
/**
|
||||
* 班组名称
|
||||
*/
|
||||
private String groupName;
|
||||
|
||||
/**
|
||||
* 物料编码
|
||||
*/
|
||||
private String materialCode;
|
||||
|
||||
/**
|
||||
* 物料名称
|
||||
*/
|
||||
private String materialName;
|
||||
|
||||
/**
|
||||
* 规格型号
|
||||
*/
|
||||
private String materialSpec;
|
||||
|
||||
/**
|
||||
* 批次
|
||||
*/
|
||||
private String batchNo;
|
||||
|
||||
/**
|
||||
* 领料重量
|
||||
*/
|
||||
private BigDecimal receiveQty;
|
||||
|
||||
/**
|
||||
* 退料重量
|
||||
*/
|
||||
private BigDecimal returnQty;
|
||||
|
||||
/**
|
||||
* 消耗重量
|
||||
*/
|
||||
private BigDecimal consumeQty;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
private String qtyUnitName;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.nl.wms.biBoard.consumptionReport.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.nl.common.domain.query.PageQuery;
|
||||
import org.nl.wms.biBoard.consumptionReport.dto.ConsumeReportDto;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 班组焊材消耗报表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
public interface IConsumeReportService {
|
||||
|
||||
/**
|
||||
* 分页查询班组焊材消耗报表
|
||||
*
|
||||
* @param whereJson : {查询参数}
|
||||
* @param page : 分页对象
|
||||
* @return 返回结果
|
||||
*/
|
||||
IPage<ConsumeReportDto> queryConsumeReport(Map whereJson, PageQuery page);
|
||||
|
||||
/**
|
||||
* 导出班组焊材消耗报表
|
||||
*
|
||||
* @param whereJson : {查询参数}
|
||||
* @param response : 响应对象
|
||||
*/
|
||||
void downloadConsumeReport(Map whereJson, HttpServletResponse response);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package org.nl.wms.biBoard.consumptionReport.service;
|
||||
|
||||
public class ReportService {
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.nl.wms.biBoard.consumptionReport.service.dao.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.nl.wms.biBoard.consumptionReport.dto.ConsumeReportDto;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 班组焊材消耗报表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@Mapper
|
||||
public interface ConsumeReportMapper {
|
||||
|
||||
/**
|
||||
* 班组焊材消耗报表分页查询
|
||||
* @param page 分页条件
|
||||
* @param whereJson 查询条件
|
||||
* @return IPage<ConsumeReportDto>
|
||||
*/
|
||||
IPage<ConsumeReportDto> queryConsumeReport(Page<ConsumeReportDto> page, @Param("param") Map whereJson);
|
||||
|
||||
/**
|
||||
* 班组焊材消耗报表合计
|
||||
* @param whereJson 查询条件
|
||||
* @return ConsumeReportDto
|
||||
*/
|
||||
ConsumeReportDto queryConsumeReportSum(@Param("param") Map whereJson);
|
||||
|
||||
/**
|
||||
* 班组焊材消耗报表全部数据(用于导出)
|
||||
* @param whereJson 查询条件
|
||||
* @return List<ConsumeReportDto>
|
||||
*/
|
||||
List<ConsumeReportDto> queryConsumeReportAll(@Param("param") Map whereJson);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.nl.wms.biBoard.report.service.dao.mapper.ConsumeReportMapper">
|
||||
|
||||
<!-- 班组焊材消耗报表分页查询 -->
|
||||
<select id="queryConsumeReport" resultType="org.nl.wms.biBoard.consumptionReport.dto.ConsumeReportDto">
|
||||
SELECT
|
||||
@rownum := @rownum + 1 AS rowNum,
|
||||
bom.create_id AS groupCode,
|
||||
bom.create_name AS groupName,
|
||||
mater.material_code AS materialCode,
|
||||
mater.material_name AS materialName,
|
||||
mater.material_spec AS materialSpec,
|
||||
bom.bom_code AS batchNo,
|
||||
bom.real_qty AS receiveQty,
|
||||
(IFNULL(bom.return_one_qty, 0) + IFNULL(bom.return_two_qty, 0)) AS returnQty,
|
||||
(bom.real_qty - IFNULL(bom.return_one_qty, 0) - IFNULL(bom.return_two_qty, 0)) AS consumeQty,
|
||||
bom.qty_unit_name AS qtyUnitName
|
||||
FROM
|
||||
pdm_bom_callmaterial bom
|
||||
INNER JOIN md_me_materialbase mater ON mater.material_id = bom.material_id,
|
||||
(SELECT @rownum := 0) r
|
||||
<where>
|
||||
1 = 1
|
||||
<if test="param.groupCode != null and param.groupCode != ''">
|
||||
AND bom.create_id = #{param.groupCode}
|
||||
</if>
|
||||
<if test="param.materialCode != null and param.materialCode != ''">
|
||||
AND (mater.material_code LIKE CONCAT('%', #{param.materialCode}, '%')
|
||||
OR mater.material_name LIKE CONCAT('%', #{param.materialCode}, '%'))
|
||||
</if>
|
||||
<if test="param.batchNo != null and param.batchNo != ''">
|
||||
AND bom.bom_code LIKE CONCAT('%', #{param.batchNo}, '%')
|
||||
</if>
|
||||
<if test="param.startDate != null and param.startDate != ''">
|
||||
AND DATE(bom.create_time) >= #{param.startDate}
|
||||
</if>
|
||||
<if test="param.endDate != null and param.endDate != ''">
|
||||
AND DATE(bom.create_time) <= #{param.endDate}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY bom.create_time DESC
|
||||
</select>
|
||||
|
||||
<!-- 班组焊材消耗报表合计 -->
|
||||
<select id="queryConsumeReportSum" resultType="org.nl.wms.biBoard.consumptionReport.dto.ConsumeReportDto">
|
||||
SELECT
|
||||
SUM(bom.real_qty) AS receiveQty,
|
||||
SUM(IFNULL(bom.return_one_qty, 0) + IFNULL(bom.return_two_qty, 0)) AS returnQty,
|
||||
SUM(bom.real_qty - IFNULL(bom.return_one_qty, 0) - IFNULL(bom.return_two_qty, 0)) AS consumeQty,
|
||||
'KG' AS qtyUnitName
|
||||
FROM
|
||||
pdm_bom_callmaterial bom
|
||||
INNER JOIN md_me_materialbase mater ON mater.material_id = bom.material_id
|
||||
<where>
|
||||
1 = 1
|
||||
<if test="param.groupCode != null and param.groupCode != ''">
|
||||
AND bom.create_id = #{param.groupCode}
|
||||
</if>
|
||||
<if test="param.materialCode != null and param.materialCode != ''">
|
||||
AND (mater.material_code LIKE CONCAT('%', #{param.materialCode}, '%')
|
||||
OR mater.material_name LIKE CONCAT('%', #{param.materialCode}, '%'))
|
||||
</if>
|
||||
<if test="param.batchNo != null and param.batchNo != ''">
|
||||
AND bom.bom_code LIKE CONCAT('%', #{param.batchNo}, '%')
|
||||
</if>
|
||||
<if test="param.startDate != null and param.startDate != ''">
|
||||
AND DATE(bom.create_time) >= #{param.startDate}
|
||||
</if>
|
||||
<if test="param.endDate != null and param.endDate != ''">
|
||||
AND DATE(bom.create_time) <= #{param.endDate}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 班组焊材消耗报表全部数据(用于导出) -->
|
||||
<select id="queryConsumeReportAll" resultType="org.nl.wms.biBoard.consumptionReport.dto.ConsumeReportDto">
|
||||
SELECT
|
||||
bom.create_id AS groupCode,
|
||||
bom.create_name AS groupName,
|
||||
mater.material_code AS materialCode,
|
||||
mater.material_name AS materialName,
|
||||
mater.material_spec AS materialSpec,
|
||||
bom.bom_code AS batchNo,
|
||||
bom.real_qty AS receiveQty,
|
||||
(IFNULL(bom.return_one_qty, 0) + IFNULL(bom.return_two_qty, 0)) AS returnQty,
|
||||
(bom.real_qty - IFNULL(bom.return_one_qty, 0) - IFNULL(bom.return_two_qty, 0)) AS consumeQty,
|
||||
bom.qty_unit_name AS qtyUnitName
|
||||
FROM
|
||||
pdm_bom_callmaterial bom
|
||||
INNER JOIN md_me_materialbase mater ON mater.material_id = bom.material_id
|
||||
<where>
|
||||
1 = 1
|
||||
<if test="param.groupCode != null and param.groupCode != ''">
|
||||
AND bom.create_id = #{param.groupCode}
|
||||
</if>
|
||||
<if test="param.materialCode != null and param.materialCode != ''">
|
||||
AND (mater.material_code LIKE CONCAT('%', #{param.materialCode}, '%')
|
||||
OR mater.material_name LIKE CONCAT('%', #{param.materialCode}, '%'))
|
||||
</if>
|
||||
<if test="param.batchNo != null and param.batchNo != ''">
|
||||
AND bom.bom_code LIKE CONCAT('%', #{param.batchNo}, '%')
|
||||
</if>
|
||||
<if test="param.startDate != null and param.startDate != ''">
|
||||
AND DATE(bom.create_time) >= #{param.startDate}
|
||||
</if>
|
||||
<if test="param.endDate != null and param.endDate != ''">
|
||||
AND DATE(bom.create_time) <= #{param.endDate}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY bom.create_time DESC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,172 @@
|
||||
package org.nl.wms.biBoard.consumptionReport.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.nl.common.domain.query.PageQuery;
|
||||
import org.nl.common.exception.BadRequestException;
|
||||
import org.nl.wms.biBoard.consumptionReport.dto.ConsumeReportDto;
|
||||
import org.nl.wms.biBoard.consumptionReport.service.IConsumeReportService;
|
||||
import org.nl.wms.biBoard.consumptionReport.service.dao.mapper.ConsumeReportMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 班组焊材消耗报表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@Service
|
||||
public class ConsumeReportServiceImpl implements IConsumeReportService {
|
||||
|
||||
@Autowired
|
||||
private ConsumeReportMapper consumeReportMapper;
|
||||
|
||||
@Override
|
||||
public IPage<ConsumeReportDto> queryConsumeReport(Map whereJson, PageQuery page) {
|
||||
IPage<ConsumeReportDto> resultPage = consumeReportMapper.queryConsumeReport(
|
||||
new Page<>(page.getPage() + 1, page.getSize()), whereJson);
|
||||
|
||||
// 添加合计行
|
||||
List<ConsumeReportDto> records = resultPage.getRecords();
|
||||
ConsumeReportDto sumDto = consumeReportMapper.queryConsumeReportSum(whereJson);
|
||||
|
||||
if (!CollectionUtils.isEmpty(records) && sumDto != null) {
|
||||
sumDto.setGroupCode("合计");
|
||||
records.add(sumDto);
|
||||
}
|
||||
|
||||
resultPage.setRecords(records);
|
||||
return resultPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadConsumeReport(Map whereJson, HttpServletResponse response) {
|
||||
// 查询所有数据
|
||||
List<ConsumeReportDto> dataList = consumeReportMapper.queryConsumeReportAll(whereJson);
|
||||
if (CollectionUtils.isEmpty(dataList)){
|
||||
throw new RuntimeException("数据为空");
|
||||
}
|
||||
try {
|
||||
// 创建工作簿
|
||||
Workbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("班组焊材消耗报表");
|
||||
|
||||
// 创建标题样式
|
||||
CellStyle titleStyle = workbook.createCellStyle();
|
||||
Font titleFont = workbook.createFont();
|
||||
titleFont.setBold(true);
|
||||
titleFont.setFontHeightInPoints((short) 12);
|
||||
titleStyle.setFont(titleFont);
|
||||
titleStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
titleStyle.setBorderBottom(BorderStyle.THIN);
|
||||
titleStyle.setBorderTop(BorderStyle.THIN);
|
||||
titleStyle.setBorderLeft(BorderStyle.THIN);
|
||||
titleStyle.setBorderRight(BorderStyle.THIN);
|
||||
|
||||
// 创建数据样式
|
||||
CellStyle dataStyle = workbook.createCellStyle();
|
||||
dataStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||
dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
dataStyle.setBorderBottom(BorderStyle.THIN);
|
||||
dataStyle.setBorderTop(BorderStyle.THIN);
|
||||
dataStyle.setBorderLeft(BorderStyle.THIN);
|
||||
dataStyle.setBorderRight(BorderStyle.THIN);
|
||||
|
||||
// 创建标题行
|
||||
Row headerRow = sheet.createRow(0);
|
||||
String[] headers = {"序号", "班组编码", "班组名称", "物料编码", "物料名称", "规格型号", "批次", "领料重量", "退料重量", "消耗重量", "单位"};
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
Cell cell = headerRow.createCell(i);
|
||||
cell.setCellValue(headers[i]);
|
||||
cell.setCellStyle(titleStyle);
|
||||
sheet.setColumnWidth(i, 4000);
|
||||
}
|
||||
|
||||
// 填充数据
|
||||
int rowNum = 1;
|
||||
BigDecimal totalReceive = BigDecimal.ZERO;
|
||||
BigDecimal totalReturn = BigDecimal.ZERO;
|
||||
BigDecimal totalConsume = BigDecimal.ZERO;
|
||||
|
||||
for (ConsumeReportDto dto : dataList) {
|
||||
Row row = sheet.createRow(rowNum);
|
||||
|
||||
createCell(row, 0, rowNum, dataStyle);
|
||||
createCell(row, 1, dto.getGroupCode(), dataStyle);
|
||||
createCell(row, 2, dto.getGroupName(), dataStyle);
|
||||
createCell(row, 3, dto.getMaterialCode(), dataStyle);
|
||||
createCell(row, 4, dto.getMaterialName(), dataStyle);
|
||||
createCell(row, 5, dto.getMaterialSpec(), dataStyle);
|
||||
createCell(row, 6, dto.getBatchNo(), dataStyle);
|
||||
createCell(row, 7, dto.getReceiveQty(), dataStyle);
|
||||
createCell(row, 8, dto.getReturnQty(), dataStyle);
|
||||
createCell(row, 9, dto.getConsumeQty(), dataStyle);
|
||||
createCell(row, 10, dto.getQtyUnitName(), dataStyle);
|
||||
|
||||
if (dto.getReceiveQty() != null) totalReceive = totalReceive.add(dto.getReceiveQty());
|
||||
if (dto.getReturnQty() != null) totalReturn = totalReturn.add(dto.getReturnQty());
|
||||
if (dto.getConsumeQty() != null) totalConsume = totalConsume.add(dto.getConsumeQty());
|
||||
|
||||
rowNum++;
|
||||
}
|
||||
|
||||
// 添加合计行
|
||||
Row sumRow = sheet.createRow(rowNum);
|
||||
createCell(sumRow, 0, "", dataStyle);
|
||||
createCell(sumRow, 1, "合计", dataStyle);
|
||||
createCell(sumRow, 2, "", dataStyle);
|
||||
createCell(sumRow, 3, "", dataStyle);
|
||||
createCell(sumRow, 4, "", dataStyle);
|
||||
createCell(sumRow, 5, "", dataStyle);
|
||||
createCell(sumRow, 6, "", dataStyle);
|
||||
createCell(sumRow, 7, totalReceive, dataStyle);
|
||||
createCell(sumRow, 8, totalReturn, dataStyle);
|
||||
createCell(sumRow, 9, totalConsume, dataStyle);
|
||||
createCell(sumRow, 10, "KG", dataStyle);
|
||||
|
||||
// 设置响应头
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = URLEncoder.encode("班组焊材消耗报表_" + DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss"), "UTF-8");
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||
|
||||
// 输出
|
||||
OutputStream outputStream = response.getOutputStream();
|
||||
workbook.write(outputStream);
|
||||
workbook.close();
|
||||
outputStream.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new BadRequestException("导出Excel失败"+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void createCell(Row row, int column, Object value, CellStyle style) {
|
||||
Cell cell = row.createCell(column);
|
||||
if (value == null) {
|
||||
cell.setCellValue("");
|
||||
} else if (value instanceof BigDecimal) {
|
||||
cell.setCellValue(((BigDecimal) value).doubleValue());
|
||||
} else if (value instanceof Integer) {
|
||||
cell.setCellValue((Integer) value);
|
||||
} else {
|
||||
cell.setCellValue(value.toString());
|
||||
}
|
||||
cell.setCellStyle(style);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.nl.wms.biBoard.materialRequisition;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.common.base.TableDataInfo;
|
||||
import org.nl.common.domain.query.PageQuery;
|
||||
import org.nl.common.logging.annotation.Log;
|
||||
import org.nl.wms.biBoard.materialRequisition.service.IIosReportService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 领料出库及退料入库数据报表 控制层
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/iosReport")
|
||||
@Slf4j
|
||||
public class IosReportController {
|
||||
|
||||
@Autowired
|
||||
private IIosReportService iIosReportService;
|
||||
|
||||
@GetMapping
|
||||
@Log("领料出库及退料入库数据报表查询")
|
||||
public ResponseEntity<Object> queryIosReport(@RequestParam Map whereJson, PageQuery page) {
|
||||
return new ResponseEntity<>(TableDataInfo.build(iIosReportService.queryIosReport(whereJson, page)), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/download")
|
||||
@Log("导出领料出库及退料入库数据报表")
|
||||
public void downloadIosReport(@RequestParam Map whereJson, HttpServletResponse response) {
|
||||
iIosReportService.downloadIosReport(whereJson, response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.nl.wms.biBoard.materialRequisition.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 领料出库及退料入库数据报表 DTO
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@Data
|
||||
public class IosReportDto implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 序号
|
||||
*/
|
||||
private Integer rowNum;
|
||||
|
||||
/**
|
||||
* 领退时间
|
||||
*/
|
||||
private String confirmTime;
|
||||
|
||||
/**
|
||||
* 班组编码
|
||||
*/
|
||||
private String groupCode;
|
||||
|
||||
/**
|
||||
* 班组名称
|
||||
*/
|
||||
private String groupName;
|
||||
|
||||
/**
|
||||
* 领退类型
|
||||
*/
|
||||
private String iosType;
|
||||
|
||||
/**
|
||||
* 物料编码
|
||||
*/
|
||||
private String materialCode;
|
||||
|
||||
/**
|
||||
* 物料名称
|
||||
*/
|
||||
private String materialName;
|
||||
|
||||
/**
|
||||
* 规格型号
|
||||
*/
|
||||
private String materialSpec;
|
||||
|
||||
/**
|
||||
* 批次
|
||||
*/
|
||||
private String batchNo;
|
||||
|
||||
/**
|
||||
* 重量
|
||||
*/
|
||||
private BigDecimal weight;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
private String qtyUnitName;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.nl.wms.biBoard.materialRequisition.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.nl.common.domain.query.PageQuery;
|
||||
import org.nl.wms.biBoard.materialRequisition.dto.IosReportDto;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 领料出库及退料入库数据报表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
public interface IIosReportService {
|
||||
|
||||
/**
|
||||
* 分页查询领料出库及退料入库数据报表
|
||||
*
|
||||
* @param whereJson : {查询参数}
|
||||
* @param page : 分页对象
|
||||
* @return 返回结果
|
||||
*/
|
||||
IPage<IosReportDto> queryIosReport(Map whereJson, PageQuery page);
|
||||
|
||||
/**
|
||||
* 导出领料出库及退料入库数据报表
|
||||
*
|
||||
* @param whereJson : {查询参数}
|
||||
* @param response : 响应对象
|
||||
*/
|
||||
void downloadIosReport(Map whereJson, HttpServletResponse response);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.nl.wms.biBoard.materialRequisition.service.dao.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.nl.wms.biBoard.materialRequisition.dto.IosReportDto;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 领料出库及退料入库数据报表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@Mapper
|
||||
public interface IosReportMapper {
|
||||
|
||||
/**
|
||||
* 领料出库及退料入库数据报表分页查询
|
||||
* @param page 分页条件
|
||||
* @param whereJson 查询条件
|
||||
* @return IPage<IosReportDto>
|
||||
*/
|
||||
IPage<IosReportDto> queryIosReport(Page<IosReportDto> page, @Param("param") Map whereJson);
|
||||
|
||||
/**
|
||||
* 领料出库及退料入库数据报表合计
|
||||
* @param whereJson 查询条件
|
||||
* @return IosReportDto
|
||||
*/
|
||||
IosReportDto queryIosReportSum(@Param("param") Map whereJson);
|
||||
|
||||
/**
|
||||
* 领料出库及退料入库数据报表全部数据(用于导出)
|
||||
* @param whereJson 查询条件
|
||||
* @return List<IosReportDto>
|
||||
*/
|
||||
List<IosReportDto> queryIosReportAll(@Param("param") Map whereJson);
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.nl.wms.biBoard.iosReport.service.dao.mapper.IosReportMapper">
|
||||
|
||||
<!-- 领料出库及退料入库数据报表分页查询 -->
|
||||
<select id="queryIosReport" resultType="org.nl.wms.biBoard.materialRequisition.dto.IosReportDto">
|
||||
SELECT
|
||||
@rownum := @rownum + 1 AS rowNum,
|
||||
DATE_FORMAT(inv.confirm_time, '%Y-%m-%d %H:%i:%s') AS confirmTime,
|
||||
inv.confirm_optid AS groupCode,
|
||||
inv.confirm_optname AS groupName,
|
||||
CASE inv.bill_type
|
||||
WHEN '1001' THEN '领料'
|
||||
WHEN '0002' THEN '退料'
|
||||
ELSE ''
|
||||
END AS iosType,
|
||||
mater.material_code AS materialCode,
|
||||
mater.material_name AS materialName,
|
||||
mater.material_spec AS materialSpec,
|
||||
dtl.pcsn AS batchNo,
|
||||
dtl.real_qty AS weight,
|
||||
dtl.qty_unit_name AS qtyUnitName
|
||||
FROM
|
||||
st_ivt_iostorinv inv
|
||||
INNER JOIN st_ivt_iostorinvdtl dtl ON inv.iostorinv_id = dtl.iostorinv_id
|
||||
INNER JOIN md_me_materialbase mater ON mater.material_id = dtl.material_id,
|
||||
(SELECT @rownum := 0) r
|
||||
<where>
|
||||
inv.bill_status = '99'
|
||||
AND inv.bill_type IN ('1001', '0002')
|
||||
<if test="param.groupCode != null and param.groupCode != ''">
|
||||
AND inv.confirm_optid = #{param.groupCode}
|
||||
</if>
|
||||
<if test="param.materialCode != null and param.materialCode != ''">
|
||||
AND (mater.material_code LIKE CONCAT('%', #{param.materialCode}, '%')
|
||||
OR mater.material_name LIKE CONCAT('%', #{param.materialCode}, '%'))
|
||||
</if>
|
||||
<if test="param.batchNo != null and param.batchNo != ''">
|
||||
AND dtl.pcsn LIKE CONCAT('%', #{param.batchNo}, '%')
|
||||
</if>
|
||||
<if test="param.startDate != null and param.startDate != ''">
|
||||
AND DATE(inv.confirm_time) >= #{param.startDate}
|
||||
</if>
|
||||
<if test="param.endDate != null and param.endDate != ''">
|
||||
AND DATE(inv.confirm_time) <= #{param.endDate}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY inv.confirm_time DESC
|
||||
</select>
|
||||
|
||||
<!-- 领料出库及退料入库数据报表合计 -->
|
||||
<select id="queryIosReportSum" resultType="org.nl.wms.biBoard.materialRequisition.dto.IosReportDto">
|
||||
SELECT
|
||||
SUM(dtl.real_qty) AS weight,
|
||||
'KG' AS qtyUnitName
|
||||
FROM
|
||||
st_ivt_iostorinv inv
|
||||
INNER JOIN st_ivt_iostorinvdtl dtl ON inv.iostorinv_id = dtl.iostorinv_id
|
||||
INNER JOIN md_me_materialbase mater ON mater.material_id = dtl.material_id
|
||||
<where>
|
||||
inv.bill_status = '99'
|
||||
AND inv.bill_type IN ('1001', '0002')
|
||||
<if test="param.groupCode != null and param.groupCode != ''">
|
||||
AND inv.confirm_optid = #{param.groupCode}
|
||||
</if>
|
||||
<if test="param.materialCode != null and param.materialCode != ''">
|
||||
AND (mater.material_code LIKE CONCAT('%', #{param.materialCode}, '%')
|
||||
OR mater.material_name LIKE CONCAT('%', #{param.materialCode}, '%'))
|
||||
</if>
|
||||
<if test="param.batchNo != null and param.batchNo != ''">
|
||||
AND dtl.pcsn LIKE CONCAT('%', #{param.batchNo}, '%')
|
||||
</if>
|
||||
<if test="param.startDate != null and param.startDate != ''">
|
||||
AND DATE(inv.confirm_time) >= #{param.startDate}
|
||||
</if>
|
||||
<if test="param.endDate != null and param.endDate != ''">
|
||||
AND DATE(inv.confirm_time) <= #{param.endDate}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 领料出库及退料入库数据报表全部数据(用于导出) -->
|
||||
<select id="queryIosReportAll" resultType="org.nl.wms.biBoard.materialRequisition.dto.IosReportDto">
|
||||
SELECT
|
||||
DATE_FORMAT(inv.confirm_time, '%Y-%m-%d %H:%i:%s') AS confirmTime,
|
||||
inv.confirm_optid AS groupCode,
|
||||
inv.confirm_optname AS groupName,
|
||||
CASE inv.bill_type
|
||||
WHEN '1001' THEN '领料'
|
||||
WHEN '0002' THEN '退料'
|
||||
ELSE ''
|
||||
END AS iosType,
|
||||
mater.material_code AS materialCode,
|
||||
mater.material_name AS materialName,
|
||||
mater.material_spec AS materialSpec,
|
||||
dtl.pcsn AS batchNo,
|
||||
dtl.real_qty AS weight,
|
||||
dtl.qty_unit_name AS qtyUnitName
|
||||
FROM
|
||||
st_ivt_iostorinv inv
|
||||
INNER JOIN st_ivt_iostorinvdtl dtl ON inv.iostorinv_id = dtl.iostorinv_id
|
||||
INNER JOIN md_me_materialbase mater ON mater.material_id = dtl.material_id
|
||||
<where>
|
||||
inv.bill_status = '99'
|
||||
AND inv.bill_type IN ('1001', '0002')
|
||||
<if test="param.groupCode != null and param.groupCode != ''">
|
||||
AND inv.confirm_optid = #{param.groupCode}
|
||||
</if>
|
||||
<if test="param.materialCode != null and param.materialCode != ''">
|
||||
AND (mater.material_code LIKE CONCAT('%', #{param.materialCode}, '%')
|
||||
OR mater.material_name LIKE CONCAT('%', #{param.materialCode}, '%'))
|
||||
</if>
|
||||
<if test="param.batchNo != null and param.batchNo != ''">
|
||||
AND dtl.pcsn LIKE CONCAT('%', #{param.batchNo}, '%')
|
||||
</if>
|
||||
<if test="param.startDate != null and param.startDate != ''">
|
||||
AND DATE(inv.confirm_time) >= #{param.startDate}
|
||||
</if>
|
||||
<if test="param.endDate != null and param.endDate != ''">
|
||||
AND DATE(inv.confirm_time) <= #{param.endDate}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY inv.confirm_time DESC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,168 @@
|
||||
package org.nl.wms.biBoard.materialRequisition.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.nl.common.domain.query.PageQuery;
|
||||
import org.nl.common.exception.BadRequestException;
|
||||
import org.nl.wms.biBoard.materialRequisition.dto.IosReportDto;
|
||||
import org.nl.wms.biBoard.materialRequisition.service.IIosReportService;
|
||||
import org.nl.wms.biBoard.materialRequisition.service.dao.mapper.IosReportMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 领料出库及退料入库数据报表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@Service
|
||||
public class IosReportServiceImpl implements IIosReportService {
|
||||
|
||||
@Autowired
|
||||
private IosReportMapper iosReportMapper;
|
||||
|
||||
@Override
|
||||
public IPage<IosReportDto> queryIosReport(Map whereJson, PageQuery page) {
|
||||
IPage<IosReportDto> resultPage = iosReportMapper.queryIosReport(
|
||||
new Page<>(page.getPage() + 1, page.getSize()), whereJson);
|
||||
|
||||
// 添加合计行
|
||||
List<IosReportDto> records = resultPage.getRecords();
|
||||
IosReportDto sumDto = iosReportMapper.queryIosReportSum(whereJson);
|
||||
|
||||
if (!CollectionUtils.isEmpty(records) && sumDto != null) {
|
||||
sumDto.setGroupCode("合计");
|
||||
records.add(sumDto);
|
||||
}
|
||||
|
||||
resultPage.setRecords(records);
|
||||
return resultPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadIosReport(Map whereJson, HttpServletResponse response) {
|
||||
// 查询所有数据
|
||||
List<IosReportDto> dataList = iosReportMapper.queryIosReportAll(whereJson);
|
||||
if (CollectionUtils.isEmpty(dataList)){
|
||||
throw new RuntimeException("数据为空");
|
||||
}
|
||||
try {
|
||||
// 创建工作簿
|
||||
Workbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("焊材领退明细报表");
|
||||
|
||||
// 创建标题样式
|
||||
CellStyle titleStyle = workbook.createCellStyle();
|
||||
Font titleFont = workbook.createFont();
|
||||
titleFont.setBold(true);
|
||||
titleFont.setFontHeightInPoints((short) 12);
|
||||
titleStyle.setFont(titleFont);
|
||||
titleStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
titleStyle.setBorderBottom(BorderStyle.THIN);
|
||||
titleStyle.setBorderTop(BorderStyle.THIN);
|
||||
titleStyle.setBorderLeft(BorderStyle.THIN);
|
||||
titleStyle.setBorderRight(BorderStyle.THIN);
|
||||
|
||||
// 创建数据样式
|
||||
CellStyle dataStyle = workbook.createCellStyle();
|
||||
dataStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||
dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
dataStyle.setBorderBottom(BorderStyle.THIN);
|
||||
dataStyle.setBorderTop(BorderStyle.THIN);
|
||||
dataStyle.setBorderLeft(BorderStyle.THIN);
|
||||
dataStyle.setBorderRight(BorderStyle.THIN);
|
||||
|
||||
// 创建标题行
|
||||
Row headerRow = sheet.createRow(0);
|
||||
String[] headers = {"序号", "领退时间", "班组编码", "班组名称", "领退类型", "物料编码", "物料名称", "规格型号", "批次", "重量", "单位"};
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
Cell cell = headerRow.createCell(i);
|
||||
cell.setCellValue(headers[i]);
|
||||
cell.setCellStyle(titleStyle);
|
||||
sheet.setColumnWidth(i, 4000);
|
||||
}
|
||||
|
||||
// 填充数据
|
||||
int rowNum = 1;
|
||||
BigDecimal totalWeight = BigDecimal.ZERO;
|
||||
|
||||
for (IosReportDto dto : dataList) {
|
||||
Row row = sheet.createRow(rowNum);
|
||||
|
||||
createCell(row, 0, rowNum, dataStyle);
|
||||
createCell(row, 1, dto.getConfirmTime(), dataStyle);
|
||||
createCell(row, 2, dto.getGroupCode(), dataStyle);
|
||||
createCell(row, 3, dto.getGroupName(), dataStyle);
|
||||
createCell(row, 4, dto.getIosType(), dataStyle);
|
||||
createCell(row, 5, dto.getMaterialCode(), dataStyle);
|
||||
createCell(row, 6, dto.getMaterialName(), dataStyle);
|
||||
createCell(row, 7, dto.getMaterialSpec(), dataStyle);
|
||||
createCell(row, 8, dto.getBatchNo(), dataStyle);
|
||||
createCell(row, 9, dto.getWeight(), dataStyle);
|
||||
createCell(row, 10, dto.getQtyUnitName(), dataStyle);
|
||||
|
||||
if (dto.getWeight() != null) totalWeight = totalWeight.add(dto.getWeight());
|
||||
|
||||
rowNum++;
|
||||
}
|
||||
|
||||
// 添加合计行
|
||||
Row sumRow = sheet.createRow(rowNum);
|
||||
createCell(sumRow, 0, "", dataStyle);
|
||||
createCell(sumRow, 1, "", dataStyle);
|
||||
createCell(sumRow, 2, "合计", dataStyle);
|
||||
createCell(sumRow, 3, "", dataStyle);
|
||||
createCell(sumRow, 4, "", dataStyle);
|
||||
createCell(sumRow, 5, "", dataStyle);
|
||||
createCell(sumRow, 6, "", dataStyle);
|
||||
createCell(sumRow, 7, "", dataStyle);
|
||||
createCell(sumRow, 8, "", dataStyle);
|
||||
createCell(sumRow, 9, totalWeight, dataStyle);
|
||||
createCell(sumRow, 10, "KG", dataStyle);
|
||||
|
||||
// 设置响应头
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = URLEncoder.encode("焊材领退明细报表_" + DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss"), "UTF-8");
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||
|
||||
// 输出
|
||||
OutputStream outputStream = response.getOutputStream();
|
||||
workbook.write(outputStream);
|
||||
workbook.close();
|
||||
outputStream.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new BadRequestException("导出Excel失败"+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void createCell(Row row, int column, Object value, CellStyle style) {
|
||||
Cell cell = row.createCell(column);
|
||||
if (value == null) {
|
||||
cell.setCellValue("");
|
||||
} else if (value instanceof BigDecimal) {
|
||||
cell.setCellValue(((BigDecimal) value).doubleValue());
|
||||
} else if (value instanceof Integer) {
|
||||
cell.setCellValue((Integer) value);
|
||||
} else {
|
||||
cell.setCellValue(value.toString());
|
||||
}
|
||||
cell.setCellStyle(style);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.nl.wms.biBoard.screen;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.common.logging.annotation.Log;
|
||||
import org.nl.wms.biBoard.screen.service.IScreenService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 智慧大屏 控制层
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/screen")
|
||||
@Slf4j
|
||||
public class ScreenController {
|
||||
|
||||
@Autowired
|
||||
private IScreenService iScreenService;
|
||||
|
||||
@GetMapping("/inventory")
|
||||
@SaIgnore
|
||||
// @Log("获取库存统计数据")
|
||||
public ResponseEntity<Object> getInventoryData() {
|
||||
return new ResponseEntity<>(iScreenService.getInventoryData(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/agvStatus")
|
||||
@SaIgnore
|
||||
// @Log("获取AGV状态")
|
||||
public ResponseEntity<Object> getAgvStatus() {
|
||||
return new ResponseEntity<>(iScreenService.getAgvStatus(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/tempTrend")
|
||||
@SaIgnore
|
||||
// @Log("获取当天温度走势")
|
||||
public ResponseEntity<Object> getTempTrend() {
|
||||
return new ResponseEntity<>(iScreenService.getTempTrend(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/todayReport")
|
||||
@SaIgnore
|
||||
// @Log("获取当天报表数据")
|
||||
public ResponseEntity<Object> getTodayReport() {
|
||||
return new ResponseEntity<>(iScreenService.getTodayReport(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/weekReport")
|
||||
@SaIgnore
|
||||
// @Log("获取本周报表数据")
|
||||
public ResponseEntity<Object> getWeekReport() {
|
||||
return new ResponseEntity<>(iScreenService.getWeekReport(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/materialTop5")
|
||||
@SaIgnore
|
||||
// @Log("获取焊材使用Top5")
|
||||
public ResponseEntity<Object> getMaterialTop5() {
|
||||
return new ResponseEntity<>(iScreenService.getMaterialTop5(), HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.nl.wms.biBoard.screen.service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 智慧大屏 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
public interface IScreenService {
|
||||
|
||||
/**
|
||||
* 获取库存统计数据
|
||||
* @return Map
|
||||
*/
|
||||
Map<String, Object> getInventoryData();
|
||||
|
||||
/**
|
||||
* 获取AGV状态
|
||||
* @return Map
|
||||
*/
|
||||
Map<String, Object> getAgvStatus();
|
||||
|
||||
/**
|
||||
* 获取当天温度走势
|
||||
* @return Map
|
||||
*/
|
||||
Map<String, Object> getTempTrend();
|
||||
|
||||
/**
|
||||
* 获取当天报表数据
|
||||
* @return Map
|
||||
*/
|
||||
Map<String, Object> getTodayReport();
|
||||
|
||||
/**
|
||||
* 获取本周报表数据
|
||||
* @return Map
|
||||
*/
|
||||
Map<String, Object> getWeekReport();
|
||||
|
||||
/**
|
||||
* 获取焊材使用Top5
|
||||
* @return Map
|
||||
*/
|
||||
Map<String, Object> getMaterialTop5();
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.nl.wms.biBoard.screen.service.dao.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 智慧大屏 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@Mapper
|
||||
public interface ScreenMapper {
|
||||
|
||||
/**
|
||||
* 获取库存分类统计
|
||||
* @return Map
|
||||
*/
|
||||
Map<String, Object> getInventoryCategory();
|
||||
|
||||
/**
|
||||
* 获取库存前5数量及物料占比
|
||||
* @return List
|
||||
*/
|
||||
List<Map<String, Object>> getInventoryTop5();
|
||||
|
||||
/**
|
||||
* 获取库位统计
|
||||
* @return Map
|
||||
*/
|
||||
Map<String, Object> getStructStatistics();
|
||||
|
||||
/**
|
||||
* 获取温度走势
|
||||
* @param params 参数
|
||||
* @return List
|
||||
*/
|
||||
List<Map<String, Object>> getTempTrend(@Param("param") Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 获取班组焊材消耗报表
|
||||
* @param params 参数
|
||||
* @return List
|
||||
*/
|
||||
List<Map<String, Object>> getConsumeReport(@Param("param") Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 获取班组领退料明细报表
|
||||
* @param params 参数
|
||||
* @return List
|
||||
*/
|
||||
List<Map<String, Object>> getIosReport(@Param("param") Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 获取焊材使用Top5
|
||||
* @param params 参数
|
||||
* @return List
|
||||
*/
|
||||
List<Map<String, Object>> getMaterialTop5(@Param("param") Map<String, Object> params);
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.nl.wms.biBoard.screen.service.dao.mapper.ScreenMapper">
|
||||
|
||||
<!-- 获取库存分类统计 -->
|
||||
<select id="getInventoryCategory" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
COUNT(DISTINCT s.struct_id) as totalCount,
|
||||
SUM(CASE WHEN s.storagevehicle_code IS NOT NULL AND s.is_emptyvehicle = '0' THEN 1 ELSE 0 END) as hasGoodsCount,
|
||||
SUM(CASE WHEN s.is_emptyvehicle = '1' THEN 1 ELSE 0 END) as emptyBoxCount,
|
||||
SUM(CASE WHEN s.storagevehicle_code IS NULL THEN 1 ELSE 0 END) as noGoodsCount
|
||||
FROM st_ivt_structattr s
|
||||
WHERE s.is_delete = '0' AND s.is_used = '1'
|
||||
</select>
|
||||
|
||||
<!-- 获取库存前5数量及物料占比 -->
|
||||
<select id="getInventoryTop5" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
st_ivt_structattr.struct_code,
|
||||
st_ivt_structattr.storagevehicle_code,
|
||||
md_pb_groupplate.qty,
|
||||
md_pb_groupplate.material_id,
|
||||
md_me_materialbase.material_name
|
||||
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_pb_groupplate.material_id = md_me_materialbase.material_id
|
||||
where st_ivt_structattr.storagevehicle_code is not null and st_ivt_structattr.storagevehicle_code != ''
|
||||
ORDER BY md_pb_groupplate.qty desc limit 5
|
||||
</select>
|
||||
|
||||
<!-- 获取库位统计 -->
|
||||
<select id="getStructStatistics" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
SUM(CASE WHEN s.storagevehicle_code IS NOT NULL AND s.is_emptyvehicle = '0' THEN 1 ELSE 0 END) as hasGoods,
|
||||
SUM(CASE WHEN s.is_emptyvehicle = '1' THEN 1 ELSE 0 END) as emptyBox,
|
||||
SUM(CASE WHEN s.storagevehicle_code IS NULL THEN 1 ELSE 0 END) as noGoods
|
||||
FROM st_ivt_structattr s
|
||||
WHERE s.is_delete = '0' AND s.is_used = '1'
|
||||
</select>
|
||||
|
||||
<!-- 获取温度走势 -->
|
||||
<select id="getTempTrend" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
DATE_FORMAT(record_timee, '%H:%i') as time,
|
||||
temp as temperature
|
||||
FROM bi_temp_record
|
||||
<where>
|
||||
<if test="param.startDate != null and param.startDate != ''">
|
||||
AND record_datee >= #{param.startDate}
|
||||
</if>
|
||||
<if test="param.endDate != null and param.endDate != ''">
|
||||
AND record_datee <= #{param.endDate}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY record_timee ASC
|
||||
</select>
|
||||
|
||||
<!-- 获取班组焊材消耗报表 -->
|
||||
<select id="getConsumeReport" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
bom.create_id AS groupCode,
|
||||
bom.create_name AS groupName,
|
||||
mater.material_code AS materialCode,
|
||||
mater.material_name AS materialName,
|
||||
bom.real_qty AS receiveQty,
|
||||
(IFNULL(bom.return_one_qty, 0) + IFNULL(bom.return_two_qty, 0)) AS returnQty,
|
||||
(bom.real_qty - IFNULL(bom.return_one_qty, 0) - IFNULL(bom.return_two_qty, 0)) AS consumeQty
|
||||
FROM
|
||||
pdm_bom_callmaterial bom
|
||||
INNER JOIN md_me_materialbase mater ON mater.material_id = bom.material_id
|
||||
<where>
|
||||
1 = 1
|
||||
<if test="param.startDate != null and param.startDate != ''">
|
||||
AND DATE(bom.create_time) >= #{param.startDate}
|
||||
</if>
|
||||
<if test="param.endDate != null and param.endDate != ''">
|
||||
AND DATE(bom.create_time) <= #{param.endDate}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY bom.create_time DESC
|
||||
LIMIT 10
|
||||
</select>
|
||||
|
||||
<!-- 获取班组领退料明细报表 -->
|
||||
<select id="getIosReport" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
DATE_FORMAT(inv.confirm_time, '%Y-%m-%d %H:%i:%s') AS confirmTime,
|
||||
inv.confirm_optid AS groupCode,
|
||||
inv.confirm_optname AS groupName,
|
||||
CASE inv.bill_type
|
||||
WHEN '1001' THEN '领料'
|
||||
WHEN '0002' THEN '退料'
|
||||
ELSE ''
|
||||
END AS iosType,
|
||||
mater.material_code AS materialCode,
|
||||
mater.material_name AS materialName,
|
||||
dtl.real_qty AS weight
|
||||
FROM
|
||||
st_ivt_iostorinv inv
|
||||
INNER JOIN st_ivt_iostorinvdtl dtl ON inv.iostorinv_id = dtl.iostorinv_id
|
||||
INNER JOIN md_me_materialbase mater ON mater.material_id = dtl.material_id
|
||||
<where>
|
||||
inv.bill_status = '99'
|
||||
AND inv.bill_type IN ('1001', '0002')
|
||||
<if test="param.startDate != null and param.startDate != ''">
|
||||
AND DATE(inv.confirm_time) >= #{param.startDate}
|
||||
</if>
|
||||
<if test="param.endDate != null and param.endDate != ''">
|
||||
AND DATE(inv.confirm_time) <= #{param.endDate}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY inv.confirm_time DESC
|
||||
LIMIT 10
|
||||
</select>
|
||||
|
||||
<!-- 获取焊材使用Top5 -->
|
||||
<select id="getMaterialTop5" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
mater.material_code AS materialCode,
|
||||
mater.material_name AS materialName,
|
||||
SUM(dtl.real_qty) AS totalQty
|
||||
FROM
|
||||
st_ivt_iostorinv inv
|
||||
INNER JOIN st_ivt_iostorinvdtl dtl ON inv.iostorinv_id = dtl.iostorinv_id
|
||||
INNER JOIN md_me_materialbase mater ON mater.material_id = dtl.material_id
|
||||
WHERE
|
||||
inv.bill_status = '99'
|
||||
AND inv.bill_type = '1001'
|
||||
<if test="param.startDate != null and param.startDate != ''">
|
||||
AND DATE(inv.confirm_time) >= #{param.startDate}
|
||||
</if>
|
||||
<if test="param.endDate != null and param.endDate != ''">
|
||||
AND DATE(inv.confirm_time) <= #{param.endDate}
|
||||
</if>
|
||||
GROUP BY
|
||||
mater.material_code,
|
||||
mater.material_name
|
||||
LIMIT 5
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.nl.wms.biBoard.screen.service.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class AgvStatus {
|
||||
private String carId;
|
||||
/**
|
||||
* 车辆类型:潜伏式AGV,料箱式AGV
|
||||
*/
|
||||
private String carType;
|
||||
/**
|
||||
* 车辆图标:对应在resources/static
|
||||
*/
|
||||
private String icon = "resources/static/icon/料箱式AGV.png";
|
||||
/**
|
||||
* 当前执行任务号
|
||||
*/
|
||||
private String taskCode;
|
||||
/**
|
||||
* 电量单位%
|
||||
*/
|
||||
private String power;
|
||||
/**
|
||||
* 0待机 1正常 2故障
|
||||
*/
|
||||
private String status;
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package org.nl.wms.biBoard.screen.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import org.nl.wms.biBoard.StaticData;
|
||||
import org.nl.wms.biBoard.screen.service.dto.AgvStatus;
|
||||
import org.nl.wms.biBoard.screen.service.IScreenService;
|
||||
import org.nl.wms.biBoard.screen.service.dao.mapper.ScreenMapper;
|
||||
import org.nl.wms.biBoard.temp.service.dao.mapper.BiTempRecordMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 智慧大屏 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@Service
|
||||
public class ScreenServiceImpl implements IScreenService {
|
||||
|
||||
@Autowired
|
||||
private ScreenMapper screenMapper;
|
||||
|
||||
@Autowired
|
||||
private BiTempRecordMapper biTempRecordMapper;
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getInventoryData() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// 库存分类统计
|
||||
Map<String, Object> categoryData = screenMapper.getInventoryCategory();
|
||||
result.put("category", categoryData);
|
||||
|
||||
// 库存前5数量及物料占比
|
||||
List<Map<String, Object>> top5List = screenMapper.getInventoryTop5();
|
||||
result.put("top5", top5List);
|
||||
|
||||
// 库位统计:有货、空料箱、无货
|
||||
Map<String, Object> structData = screenMapper.getStructStatistics();
|
||||
result.put("structStat", structData);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAgvStatus() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// 从StaticData获取AGV状态
|
||||
Map<String, AgvStatus> agvStatusMap = StaticData.agv_status;
|
||||
agvStatusMap.put("1",AgvStatus.builder()
|
||||
.status("1")
|
||||
.carId("2")
|
||||
.icon("潜伏式AGV.png")
|
||||
.carType("潜伏式AGV").power("66").taskCode("123123").build());
|
||||
agvStatusMap.put("1",AgvStatus.builder()
|
||||
.status("1")
|
||||
.carId("1")
|
||||
.carType("CTU料箱AGV")
|
||||
.icon("料箱式AGV.png")
|
||||
.power("77")
|
||||
.taskCode("33322")
|
||||
.build());
|
||||
agvStatusMap.put("2",AgvStatus.builder()
|
||||
.status("1")
|
||||
.carId("2")
|
||||
.carType("CTU料箱AGV")
|
||||
.icon("料箱式AGV.png")
|
||||
.power("77")
|
||||
.taskCode("33322")
|
||||
.build());
|
||||
agvStatusMap.put("3",AgvStatus.builder()
|
||||
.status("1")
|
||||
.carId("3")
|
||||
.carType("CTU料箱AGV")
|
||||
.icon("料箱式AGV.png")
|
||||
.power("77")
|
||||
.taskCode("33322")
|
||||
.build());
|
||||
agvStatusMap.put("5",AgvStatus.builder()
|
||||
.status("1")
|
||||
.carId("5")
|
||||
.carType("CTU料箱AGV")
|
||||
.icon("料箱式AGV.png")
|
||||
.power("77")
|
||||
.taskCode("33322")
|
||||
.build());
|
||||
agvStatusMap.put("4",AgvStatus.builder()
|
||||
.status("1")
|
||||
.carId("4")
|
||||
.carType("CTU料箱AGV")
|
||||
.icon("料箱式AGV.png")
|
||||
.power("77")
|
||||
.taskCode("33322")
|
||||
.build());
|
||||
agvStatusMap.put("6",AgvStatus.builder()
|
||||
.status("1")
|
||||
.carId("6")
|
||||
.carType("CTU料箱AGV")
|
||||
.icon("料箱式AGV.png")
|
||||
.power("77")
|
||||
.taskCode("33322")
|
||||
.build());
|
||||
agvStatusMap.put("7",AgvStatus.builder()
|
||||
.status("1")
|
||||
.carId("7")
|
||||
.carType("CTU料箱AGV")
|
||||
.icon("料箱式AGV.png")
|
||||
.power("77")
|
||||
.taskCode("33322")
|
||||
.build());
|
||||
Object[] objects = agvStatusMap.values().toArray();
|
||||
result.put("agvList", objects);
|
||||
result.put("total", objects.length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getTempTrend() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// 查询当天温度记录
|
||||
String today = DateUtil.today();
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("startDate", today);
|
||||
params.put("endDate", today);
|
||||
|
||||
List<Map<String, Object>> tempList = screenMapper.getTempTrend(params);
|
||||
|
||||
result.put("tempData", tempList);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getTodayReport() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
String today = DateUtil.today();
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
// params.put("startDate", today);
|
||||
// params.put("endDate", today);
|
||||
|
||||
// 班组焊材消耗报表
|
||||
List<Map<String, Object>> consumeList = screenMapper.getConsumeReport(params);
|
||||
result.put("consumeReport", consumeList);
|
||||
|
||||
// 班组领退料明细报表
|
||||
List<Map<String, Object>> iosList = screenMapper.getIosReport(params);
|
||||
result.put("iosReport", iosList);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getWeekReport() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// 获取本周开始和结束日期
|
||||
LocalDate now = LocalDate.now();
|
||||
LocalDate weekStart = now.minusDays(now.getDayOfWeek().getValue() - 1);
|
||||
LocalDate weekEnd = now;
|
||||
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("startDate", weekStart.format(formatter));
|
||||
params.put("endDate", weekEnd.format(formatter));
|
||||
|
||||
// 班组焊材消耗报表
|
||||
List<Map<String, Object>> consumeList = screenMapper.getConsumeReport(params);
|
||||
result.put("consumeReport", consumeList);
|
||||
|
||||
// 班组领退料明细报表
|
||||
List<Map<String, Object>> iosList = screenMapper.getIosReport(params);
|
||||
result.put("iosReport", iosList);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getMaterialTop5() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
String today = DateUtil.today();
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
// params.put("startDate", today);
|
||||
// params.put("endDate", today);
|
||||
|
||||
// 焊材使用前Top5(通过领料出库单查询汇总)
|
||||
List<Map<String, Object>> top5List = screenMapper.getMaterialTop5(params);
|
||||
result.put("top5", top5List);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.nl.wms.biBoard.temp.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.common.base.TableDataInfo;
|
||||
import org.nl.common.domain.query.PageQuery;
|
||||
import org.nl.common.logging.annotation.Log;
|
||||
import org.nl.wms.biBoard.temp.service.IBiTempRecordService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 温度记录表 控制层
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/tempRecord")
|
||||
@Slf4j
|
||||
public class TempRecordController {
|
||||
|
||||
@Autowired
|
||||
private IBiTempRecordService iBiTempRecordService;
|
||||
|
||||
@GetMapping
|
||||
@Log("分页查询温度记录")
|
||||
public ResponseEntity<Object> query(@RequestParam Map whereJson, PageQuery page) {
|
||||
return new ResponseEntity<>(TableDataInfo.build(iBiTempRecordService.queryAll(whereJson, page)), HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.nl.wms.biBoard.temp.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.nl.common.domain.query.PageQuery;
|
||||
import org.nl.wms.biBoard.temp.service.dao.BiTempRecord;
|
||||
import org.nl.wms.biBoard.temp.service.dto.BiTempRecordDto;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 温度记录表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
public interface IBiTempRecordService extends IService<BiTempRecord> {
|
||||
|
||||
/**
|
||||
* 分页查询温度记录
|
||||
*
|
||||
* @param whereJson : {查询参数}
|
||||
* @param page : 分页对象
|
||||
* @return 返回结果
|
||||
*/
|
||||
IPage<BiTempRecordDto> queryAll(Map whereJson, PageQuery page);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.nl.wms.biBoard.temp.service.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 温度记录表
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableName("bi_temp_record")
|
||||
public class BiTempRecord implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键自增
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 温度:acs定时获取
|
||||
*/
|
||||
private BigDecimal temp;
|
||||
|
||||
/**
|
||||
* 记录时间
|
||||
*/
|
||||
private LocalDateTime recordTimee;
|
||||
|
||||
/**
|
||||
* 记录日期
|
||||
*/
|
||||
private LocalDate recordDatee;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.nl.wms.biBoard.temp.service.dao.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.nl.wms.biBoard.temp.service.dao.BiTempRecord;
|
||||
import org.nl.wms.biBoard.temp.service.dto.BiTempRecordDto;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 温度记录表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
public interface BiTempRecordMapper extends BaseMapper<BiTempRecord> {
|
||||
|
||||
/**
|
||||
* 温度记录分页查询
|
||||
* @param page 分页条件
|
||||
* @param whereJson 查询条件
|
||||
* @return IPage<BiTempRecordDto>
|
||||
*/
|
||||
IPage<BiTempRecordDto> queryAllByPage(Page<BiTempRecordDto> page, @Param("param") Map whereJson);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.nl.wms.biBoard.temp.service.dao.mapper.BiTempRecordMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="org.nl.wms.biBoard.temp.service.dao.BiTempRecord">
|
||||
<id column="id" property="id" />
|
||||
<result column="temp" property="temp" />
|
||||
<result column="record_timee" property="recordTimee" />
|
||||
<result column="record_datee" property="recordDatee" />
|
||||
</resultMap>
|
||||
|
||||
<!-- 温度记录分页查询 -->
|
||||
<select id="queryAllByPage" resultType="org.nl.wms.biBoard.temp.service.dto.BiTempRecordDto">
|
||||
SELECT
|
||||
id,
|
||||
temp,
|
||||
DATE_FORMAT(record_timee, '%Y-%m-%d %H:%i:%s') as recordTimee,
|
||||
DATE_FORMAT(record_datee, '%Y-%m-%d') as recordDatee,
|
||||
'自动记录' as recorder
|
||||
FROM bi_temp_record
|
||||
<where>
|
||||
<if test="param.startDate != null and param.startDate != ''">
|
||||
AND record_datee >= #{param.startDate}
|
||||
</if>
|
||||
<if test="param.endDate != null and param.endDate != ''">
|
||||
AND record_datee <= #{param.endDate}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY record_timee DESC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.nl.wms.biBoard.temp.service.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 温度记录表 DTO
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@Data
|
||||
public class BiTempRecordDto implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键自增
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 温度
|
||||
*/
|
||||
private BigDecimal temp;
|
||||
|
||||
/**
|
||||
* 记录时间
|
||||
*/
|
||||
private String recordTimee;
|
||||
|
||||
/**
|
||||
* 记录日期
|
||||
*/
|
||||
private String recordDatee;
|
||||
|
||||
/**
|
||||
* 记录人
|
||||
*/
|
||||
private String recorder;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.nl.wms.biBoard.temp.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.nl.common.domain.query.PageQuery;
|
||||
import org.nl.wms.biBoard.temp.service.IBiTempRecordService;
|
||||
import org.nl.wms.biBoard.temp.service.dao.BiTempRecord;
|
||||
import org.nl.wms.biBoard.temp.service.dao.mapper.BiTempRecordMapper;
|
||||
import org.nl.wms.biBoard.temp.service.dto.BiTempRecordDto;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 温度记录表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author System
|
||||
* @since 2026-03-07
|
||||
*/
|
||||
@Service
|
||||
public class BiTempRecordServiceImpl extends ServiceImpl<BiTempRecordMapper, BiTempRecord> implements IBiTempRecordService {
|
||||
|
||||
@Override
|
||||
public IPage<BiTempRecordDto> queryAll(Map whereJson, PageQuery page) {
|
||||
return this.baseMapper.queryAllByPage(new Page<>(page.getPage() + 1, page.getSize()), whereJson);
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,11 @@ server:
|
||||
nl:
|
||||
config:
|
||||
mysql:
|
||||
ip: 192.168.81.251
|
||||
ip: 127.0.0.1
|
||||
port: 3306
|
||||
username: root
|
||||
password: P@ssw0rd.
|
||||
database: xujiang_hanyun_wms
|
||||
password: 123456
|
||||
database: xghy_wmsa
|
||||
# ip: 127.0.0.1
|
||||
# port: 3306
|
||||
# username: root
|
||||
|
||||
|
After Width: | Height: | Size: 4.3 MiB |
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 173 KiB |
BIN
wms/nladmin-ui/src/assets/images/agv.png
Normal file
|
After Width: | Height: | Size: 173 KiB |
BIN
wms/nladmin-ui/src/assets/images/boardImg.png
Normal file
|
After Width: | Height: | Size: 4.3 MiB |
BIN
wms/nladmin-ui/src/assets/images/料箱式AGV.png
Normal file
|
After Width: | Height: | Size: 173 KiB |
BIN
wms/nladmin-ui/src/assets/images/潜伏式AGV.png
Normal file
|
After Width: | Height: | Size: 173 KiB |
@@ -170,7 +170,7 @@
|
||||
@selection-change="crud.selectionChangeHandler"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column :label="$t('menu.table.menu_title')" :prop="$langPre.computedProp('title')" :min-width="flexWidth($langPre.computedProp('title'),crud.data,$t('menu.table.menu_title'))" />
|
||||
<el-table-column :label="$t('menu.table.menu_title')" prop="title" :min-width="150" />
|
||||
<el-table-column :label="$t('menu.table.system')" prop="system_type" :min-width="flexWidth('system_type',crud.data,$t('menu.table.system'))">
|
||||
<template slot-scope="scope">
|
||||
{{ dict.label.system_type[scope.row.system_type] }} : {{ scope.row.system_type }}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function query(params) {
|
||||
return request({
|
||||
url: 'api/report/consumeReport',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function downloadExcel(params) {
|
||||
return request({
|
||||
url: 'api/report/consumeReport/download',
|
||||
method: 'get',
|
||||
params,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
export default { query, downloadExcel }
|
||||
263
wms/nladmin-ui/src/views/wms/biBoard/consumeReport/index.vue
Normal file
@@ -0,0 +1,263 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!--工具栏-->
|
||||
<div class="head-container">
|
||||
<div v-if="crud.props.searchToggle">
|
||||
<el-form
|
||||
size="mini"
|
||||
:inline="true"
|
||||
class="demo-form-inline"
|
||||
label-position="right"
|
||||
label-width="80px"
|
||||
label-suffix=":"
|
||||
>
|
||||
<el-form-item label="班组">
|
||||
<el-input
|
||||
v-model="query.groupCode"
|
||||
clearable
|
||||
placeholder="请输入班组编码"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="物料">
|
||||
<el-input
|
||||
v-model="query.materialCode"
|
||||
clearable
|
||||
placeholder="编码、名称"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="批次号">
|
||||
<el-input
|
||||
v-model="query.batchNo"
|
||||
clearable
|
||||
placeholder="请输入批次号"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间">
|
||||
<el-date-picker
|
||||
v-model="query.startDate"
|
||||
type="date"
|
||||
placeholder="选择开始时间"
|
||||
value-format="yyyy-MM-dd"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间">
|
||||
<el-date-picker
|
||||
v-model="query.endDate"
|
||||
type="date"
|
||||
placeholder="选择结束时间"
|
||||
value-format="yyyy-MM-dd"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<rrOperation />
|
||||
</el-form>
|
||||
</div>
|
||||
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||
<crudOperation :permission="permission">
|
||||
<el-button
|
||||
slot="left"
|
||||
class="filter-item"
|
||||
size="mini"
|
||||
type="success"
|
||||
icon="el-icon-download"
|
||||
:loading="downloadLoading"
|
||||
@click="handleDownload"
|
||||
>
|
||||
导出EXCEL
|
||||
</el-button>
|
||||
</crudOperation>
|
||||
<!--表格渲染-->
|
||||
<el-table ref="table" border v-loading="crud.loading" :data="crud.data" size="mini" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="rowNum" label="序号" width="80" align="center" />
|
||||
<el-table-column prop="groupCode" label="班组编码" width="120" />
|
||||
<el-table-column prop="groupName" label="班组名称" width="120" />
|
||||
<el-table-column prop="materialCode" label="物料编码" width="150" />
|
||||
<el-table-column prop="materialName" label="物料名称" />
|
||||
<el-table-column prop="materialSpec" label="规格型号" />
|
||||
<el-table-column prop="batchNo" label="批次" width="150" />
|
||||
<el-table-column prop="receiveQty" label="领料重量" width="100" align="right" />
|
||||
<el-table-column prop="returnQty" label="退料重量" width="100" align="right" />
|
||||
<el-table-column prop="consumeQty" label="消耗重量" width="100" align="right" />
|
||||
<el-table-column prop="qtyUnitName" label="单位" width="80" align="center" />
|
||||
</el-table>
|
||||
<!--分页组件-->
|
||||
<pagination />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudConsumeReport from '@/views/wms/biBoard/consumeReport/consumeReport'
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud'
|
||||
import rrOperation from '@crud/RR.operation'
|
||||
import crudOperation from '@crud/CRUD.operation'
|
||||
import pagination from '@crud/Pagination'
|
||||
|
||||
const defaultForm = { }
|
||||
export default {
|
||||
name: 'ConsumeReport',
|
||||
components: { pagination, crudOperation, rrOperation },
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||
cruds() {
|
||||
return CRUD({
|
||||
title: '班组焊材消耗报表',
|
||||
url: 'api/report/consumeReport',
|
||||
idField: 'rowNum',
|
||||
sort: '',
|
||||
query: { groupCode: '', materialCode: '', batchNo: '', startDate: '', endDate: '' },
|
||||
crudMethod: { ...crudConsumeReport },
|
||||
optShow: {
|
||||
add: false,
|
||||
edit: false,
|
||||
del: false,
|
||||
download: false,
|
||||
reset: true
|
||||
}
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
permission: {},
|
||||
downloadLoading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
const params = {
|
||||
groupCode: this.query.groupCode || '',
|
||||
materialCode: this.query.materialCode || '',
|
||||
batchNo: this.query.batchNo || '',
|
||||
startDate: this.query.startDate || '',
|
||||
endDate: this.query.endDate || ''
|
||||
}
|
||||
|
||||
crudConsumeReport.downloadExcel(params).then(res => {
|
||||
const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = '班组焊材消耗报表_' + new Date().getTime() + '.xlsx'
|
||||
link.click()
|
||||
window.URL.revokeObjectURL(url)
|
||||
this.$message.success('导出成功')
|
||||
this.downloadLoading = false
|
||||
}).catch(() => {
|
||||
this.$message.error('导出失败')
|
||||
this.downloadLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
::v-deep {
|
||||
|
||||
.vue-treeselect__menu {
|
||||
|
||||
overflow-x: auto !important;
|
||||
|
||||
width: 300px;
|
||||
|
||||
max-height: 300px !important;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__label {
|
||||
|
||||
overflow: unset;
|
||||
|
||||
text-overflow: unset;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__control {
|
||||
|
||||
height: 20px !important;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__multi-value-item-container,
|
||||
|
||||
.vue-treeselect--has-value .vue-treeselect__multi-value {
|
||||
|
||||
height: 30px;
|
||||
|
||||
line-height: 24px;
|
||||
|
||||
padding: 0;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__limit-tip,
|
||||
|
||||
.vue-treeselect--searchable.vue-treeselect--multi.vue-treeselect--has-value
|
||||
|
||||
.vue-treeselect__input-container {
|
||||
|
||||
padding-top: 0;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__placeholder,
|
||||
|
||||
.vue-treeselect__single-value {
|
||||
|
||||
height: 28px;
|
||||
|
||||
line-height: 32px;
|
||||
|
||||
font-size: small;
|
||||
|
||||
color: "#CCCFD6";
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect--has-value .vue-treeselect__input {
|
||||
|
||||
height: 18px !important;
|
||||
|
||||
line-height: 18px !important;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect div,
|
||||
|
||||
.vue-treeselect span {
|
||||
|
||||
box-sizing: content-box;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__multi-value-label {
|
||||
|
||||
display: block;
|
||||
|
||||
width: 140px;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__value-container {
|
||||
|
||||
display: block;
|
||||
|
||||
height: 32px;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
263
wms/nladmin-ui/src/views/wms/biBoard/iosReport/index.vue
Normal file
@@ -0,0 +1,263 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!--工具栏-->
|
||||
<div class="head-container">
|
||||
<div v-if="crud.props.searchToggle">
|
||||
<el-form
|
||||
size="mini"
|
||||
:inline="true"
|
||||
class="demo-form-inline"
|
||||
label-position="right"
|
||||
label-width="80px"
|
||||
label-suffix=":"
|
||||
>
|
||||
<el-form-item label="班组">
|
||||
<el-input
|
||||
v-model="query.groupCode"
|
||||
clearable
|
||||
placeholder="请输入班组编码"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="物料">
|
||||
<el-input
|
||||
v-model="query.materialCode"
|
||||
clearable
|
||||
placeholder="编码、名称"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="批次号">
|
||||
<el-input
|
||||
v-model="query.batchNo"
|
||||
clearable
|
||||
placeholder="请输入批次号"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间">
|
||||
<el-date-picker
|
||||
v-model="query.startDate"
|
||||
type="date"
|
||||
placeholder="选择开始时间"
|
||||
value-format="yyyy-MM-dd"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间">
|
||||
<el-date-picker
|
||||
v-model="query.endDate"
|
||||
type="date"
|
||||
placeholder="选择结束时间"
|
||||
value-format="yyyy-MM-dd"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<rrOperation />
|
||||
</el-form>
|
||||
</div>
|
||||
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||
<crudOperation :permission="permission">
|
||||
<el-button
|
||||
slot="left"
|
||||
class="filter-item"
|
||||
size="mini"
|
||||
type="success"
|
||||
icon="el-icon-download"
|
||||
:loading="downloadLoading"
|
||||
@click="handleDownload"
|
||||
>
|
||||
导出EXCEL
|
||||
</el-button>
|
||||
</crudOperation>
|
||||
<!--表格渲染-->
|
||||
<el-table ref="table" border v-loading="crud.loading" :data="crud.data" size="mini" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="rowNum" label="序号" width="80" align="center" />
|
||||
<el-table-column prop="confirmTime" label="领退时间" width="180" />
|
||||
<el-table-column prop="groupCode" label="班组编码" width="120" />
|
||||
<el-table-column prop="groupName" label="班组名称" width="120" />
|
||||
<el-table-column prop="iosType" label="领退类型" width="100" align="center" />
|
||||
<el-table-column prop="materialCode" label="物料编码" width="150" />
|
||||
<el-table-column prop="materialName" label="物料名称" />
|
||||
<el-table-column prop="materialSpec" label="规格型号" />
|
||||
<el-table-column prop="batchNo" label="批次" width="150" />
|
||||
<el-table-column prop="weight" label="重量" width="100" align="right" />
|
||||
<el-table-column prop="qtyUnitName" label="单位" width="80" align="center" />
|
||||
</el-table>
|
||||
<!--分页组件-->
|
||||
<pagination />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudIosReport from '@/views/wms/biBoard/iosReport/iosReport'
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud'
|
||||
import rrOperation from '@crud/RR.operation'
|
||||
import crudOperation from '@crud/CRUD.operation'
|
||||
import pagination from '@crud/Pagination'
|
||||
|
||||
const defaultForm = { }
|
||||
export default {
|
||||
name: 'IosReport',
|
||||
components: { pagination, crudOperation, rrOperation },
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||
cruds() {
|
||||
return CRUD({
|
||||
title: '焊材领退明细报表',
|
||||
url: 'api/iosReport',
|
||||
idField: 'rowNum',
|
||||
sort: '',
|
||||
query: { groupCode: '', materialCode: '', batchNo: '', startDate: '', endDate: '' },
|
||||
crudMethod: { ...crudIosReport },
|
||||
optShow: {
|
||||
add: false,
|
||||
edit: false,
|
||||
del: false,
|
||||
download: false,
|
||||
reset: true
|
||||
}
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
permission: {},
|
||||
downloadLoading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
const params = {
|
||||
groupCode: this.query.groupCode || '',
|
||||
materialCode: this.query.materialCode || '',
|
||||
batchNo: this.query.batchNo || '',
|
||||
startDate: this.query.startDate || '',
|
||||
endDate: this.query.endDate || ''
|
||||
}
|
||||
|
||||
crudIosReport.downloadExcel(params).then(res => {
|
||||
const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = '焊材领退明细报表_' + new Date().getTime() + '.xlsx'
|
||||
link.click()
|
||||
window.URL.revokeObjectURL(url)
|
||||
this.$message.success('导出成功')
|
||||
this.downloadLoading = false
|
||||
}).catch(() => {
|
||||
this.$message.error('导出失败')
|
||||
this.downloadLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
::v-deep {
|
||||
|
||||
.vue-treeselect__menu {
|
||||
|
||||
overflow-x: auto !important;
|
||||
|
||||
width: 300px;
|
||||
|
||||
max-height: 300px !important;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__label {
|
||||
|
||||
overflow: unset;
|
||||
|
||||
text-overflow: unset;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__control {
|
||||
|
||||
height: 20px !important;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__multi-value-item-container,
|
||||
|
||||
.vue-treeselect--has-value .vue-treeselect__multi-value {
|
||||
|
||||
height: 30px;
|
||||
|
||||
line-height: 24px;
|
||||
|
||||
padding: 0;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__limit-tip,
|
||||
|
||||
.vue-treeselect--searchable.vue-treeselect--multi.vue-treeselect--has-value
|
||||
|
||||
.vue-treeselect__input-container {
|
||||
|
||||
padding-top: 0;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__placeholder,
|
||||
|
||||
.vue-treeselect__single-value {
|
||||
|
||||
height: 28px;
|
||||
|
||||
line-height: 32px;
|
||||
|
||||
font-size: small;
|
||||
|
||||
color: "#CCCFD6";
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect--has-value .vue-treeselect__input {
|
||||
|
||||
height: 18px !important;
|
||||
|
||||
line-height: 18px !important;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect div,
|
||||
|
||||
.vue-treeselect span {
|
||||
|
||||
box-sizing: content-box;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__multi-value-label {
|
||||
|
||||
display: block;
|
||||
|
||||
width: 140px;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__value-container {
|
||||
|
||||
display: block;
|
||||
|
||||
height: 32px;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
20
wms/nladmin-ui/src/views/wms/biBoard/iosReport/iosReport.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function query(params) {
|
||||
return request({
|
||||
url: 'api/iosReport',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function downloadExcel(params) {
|
||||
return request({
|
||||
url: 'api/iosReport/download',
|
||||
method: 'get',
|
||||
params,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
export default { query, downloadExcel }
|
||||
886
wms/nladmin-ui/src/views/wms/biBoard/screen/index.vue
Normal file
@@ -0,0 +1,886 @@
|
||||
<template>
|
||||
<div class="screen-container">
|
||||
<!-- 头部标题 -->
|
||||
<div class="screen-header">
|
||||
<div class="header-logo">
|
||||
<img src="@/assets/images/logo.png" alt="logo" class="logo-img">
|
||||
</div>
|
||||
<div class="header-title">
|
||||
哈电汽轮机(镇江)有限责任公司数字化焊材库智慧大屏
|
||||
</div>
|
||||
<div class="header-time">
|
||||
<div class="time">{{ currentTime }}</div>
|
||||
<div class="date">{{ currentDate }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主体内容 -->
|
||||
<div class="screen-content">
|
||||
<!-- 左侧区域 - 库存信息 -->
|
||||
<div class="left-panel">
|
||||
<div class="panel-title">库存分类总览</div>
|
||||
<div class="inventory-category">
|
||||
<div class="category-item">
|
||||
<div class="item-label">合格</div>
|
||||
<div class="item-value">{{ inventoryData.category.hasGoodsCount || 0 }}</div>
|
||||
</div>
|
||||
<div class="category-item">
|
||||
<div class="item-label">不合格</div>
|
||||
<div class="item-value">0</div>
|
||||
</div>
|
||||
<div class="category-item">
|
||||
<div class="item-label">待检</div>
|
||||
<div class="item-value">0</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-title">焊材库存占比</div>
|
||||
<div class="chart-container">
|
||||
<div id="structChart" style="width: 100%; height: 280px;"></div>
|
||||
</div>
|
||||
|
||||
<div class="panel-title">焊材领料Top5</div>
|
||||
<div class="chart-container">
|
||||
<div id="materialTop5Chart" style="width: 100%; height: 300px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中间区域 -->
|
||||
<div class="center-panel">
|
||||
<div class="center-left">
|
||||
<!-- 3D仓库图 -->
|
||||
<div class="warehouse-3d">
|
||||
<img :src="warehouseImg" alt="仓库3D图" class="warehouse-img">
|
||||
</div>
|
||||
|
||||
<!-- 底部监控区域 -->
|
||||
<div class="bottom-monitor">
|
||||
<!-- AGV监控 -->
|
||||
<div class="agv-monitor">
|
||||
<div class="monitor-title">AGV监控</div>
|
||||
<div class="agv-list">
|
||||
<div v-for="(agv, index) in displayAgvList" :key="index" class="agv-item">
|
||||
<div class="agv-icon">
|
||||
<img :src="getAgvIcon(agv.icon)" alt="AGV" class="agv-img">
|
||||
</div>
|
||||
<div class="agv-id">{{ agv.carId }}</div>
|
||||
<div class="agv-status" :class="getAgvStatusClass(agv.status)">
|
||||
{{ getAgvStatusText(agv.status) }}
|
||||
</div>
|
||||
<div class="agv-task">当前任务:{{ agv.taskCode || '无' }}</div>
|
||||
<div class="agv-battery">电量:{{ agv.battery || 0 }}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 温湿度监控 -->
|
||||
<div class="temp-monitor">
|
||||
<div class="monitor-title">温湿度监控</div>
|
||||
<div id="tempChart" style="width: 100%; height: 200px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="center-right">
|
||||
<!-- 预留右侧区域 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧区域 - 报表数据 -->
|
||||
<div class="right-panel">
|
||||
<div class="panel-title">
|
||||
班组焊材领退明细
|
||||
<el-radio-group v-model="reportType" size="mini" @change="handleReportTypeChange">
|
||||
<el-radio-button label="today">当日</el-radio-button>
|
||||
<el-radio-button label="week">本周</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="detail-list scroll-list">
|
||||
<div v-for="(item, index) in displayIosReportData" :key="index" class="detail-item">
|
||||
<div class="detail-time">{{ item.confirmTime }}</div>
|
||||
<div class="detail-type" :class="item.iosType === '领料' ? 'type-out' : 'type-in'">
|
||||
{{ item.iosType }}
|
||||
</div>
|
||||
<div class="detail-material">{{ item.materialCode }}</div>
|
||||
<div class="detail-weight">{{ item.weight }}</div>
|
||||
<div class="detail-person">{{ item.groupName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-title">班组焊材消耗</div>
|
||||
<div class="chart-container">
|
||||
<div id="consumeChart" style="width: 100%; height: 250px;"></div>
|
||||
</div>
|
||||
|
||||
<div class="panel-title">当日领退明细</div>
|
||||
<div class="detail-list scroll-list">
|
||||
<div v-for="(item, index) in displayTodayDetailList" :key="index" class="detail-item">
|
||||
<div class="detail-time">{{ item.confirmTime }}</div>
|
||||
<div class="detail-type" :class="item.iosType === '领料' ? 'type-out' : 'type-in'">
|
||||
{{ item.iosType }}
|
||||
</div>
|
||||
<div class="detail-material">{{ item.materialCode }}</div>
|
||||
<div class="detail-weight">{{ item.weight }}</div>
|
||||
<div class="detail-person">{{ item.groupName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import request from '@/utils/request'
|
||||
|
||||
export default {
|
||||
name: 'BiScreen',
|
||||
data() {
|
||||
return {
|
||||
currentTime: '',
|
||||
currentDate: '',
|
||||
reportType: 'today',
|
||||
warehouseImg: require('@/assets/images/boardImg.png'),
|
||||
inventoryData: {
|
||||
category: {},
|
||||
top5: [],
|
||||
structStat: {}
|
||||
},
|
||||
agvList: [],
|
||||
tempData: [],
|
||||
consumeReportData: [],
|
||||
iosReportData: [],
|
||||
todayDetailList: [],
|
||||
materialTop5Data: [],
|
||||
timer: null,
|
||||
dataTimer: null,
|
||||
scrollTimer1: null,
|
||||
scrollTimer2: null,
|
||||
scrollTimer3: null,
|
||||
scrollIndex1: 0,
|
||||
scrollIndex2: 0,
|
||||
scrollIndex3: 0
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.updateTime()
|
||||
this.timer = setInterval(this.updateTime, 1000)
|
||||
|
||||
this.loadAllData()
|
||||
this.dataTimer = setInterval(this.loadAllData, 30000) // 30秒刷新一次
|
||||
|
||||
this.startScrolling()
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
if (this.dataTimer) {
|
||||
clearInterval(this.dataTimer)
|
||||
}
|
||||
if (this.scrollTimer1) {
|
||||
clearInterval(this.scrollTimer1)
|
||||
}
|
||||
if (this.scrollTimer2) {
|
||||
clearInterval(this.scrollTimer2)
|
||||
}
|
||||
if (this.scrollTimer3) {
|
||||
clearInterval(this.scrollTimer3)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
displayIosReportData() {
|
||||
if (this.iosReportData.length <= 5) {
|
||||
return this.iosReportData
|
||||
}
|
||||
const result = []
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const index = (this.scrollIndex1 + i) % this.iosReportData.length
|
||||
result.push(this.iosReportData[index])
|
||||
}
|
||||
return result
|
||||
},
|
||||
displayTodayDetailList() {
|
||||
if (this.todayDetailList.length <= 5) {
|
||||
return this.todayDetailList
|
||||
}
|
||||
const result = []
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const index = (this.scrollIndex2 + i) % this.todayDetailList.length
|
||||
result.push(this.todayDetailList[index])
|
||||
}
|
||||
return result
|
||||
},
|
||||
displayAgvList() {
|
||||
if (this.agvList.length <= 4) {
|
||||
return this.agvList
|
||||
}
|
||||
const result = []
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const index = (this.scrollIndex3 + i) % this.agvList.length
|
||||
result.push(this.agvList[index])
|
||||
}
|
||||
return result
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateTime() {
|
||||
const now = new Date()
|
||||
this.currentTime = now.toTimeString().slice(0, 8)
|
||||
this.currentDate = now.toLocaleDateString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
weekday: 'long'
|
||||
})
|
||||
},
|
||||
|
||||
async loadAllData() {
|
||||
await Promise.all([
|
||||
this.loadInventoryData(),
|
||||
this.loadAgvStatus(),
|
||||
this.loadTempTrend(),
|
||||
this.loadReportData(),
|
||||
this.loadMaterialTop5()
|
||||
])
|
||||
},
|
||||
|
||||
async loadInventoryData() {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/api/screen/inventory',
|
||||
method: 'get'
|
||||
})
|
||||
this.inventoryData = res
|
||||
this.$nextTick(() => {
|
||||
this.initStructChart()
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('加载库存数据失败', error)
|
||||
}
|
||||
},
|
||||
|
||||
async loadAgvStatus() {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/api/screen/agvStatus',
|
||||
method: 'get'
|
||||
})
|
||||
this.agvList = res.agvList || []
|
||||
} catch (error) {
|
||||
console.error('加载AGV状态失败', error)
|
||||
}
|
||||
},
|
||||
|
||||
async loadTempTrend() {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/api/screen/tempTrend',
|
||||
method: 'get'
|
||||
})
|
||||
this.tempData = res.tempData || []
|
||||
this.$nextTick(() => {
|
||||
this.initTempChart()
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('加载温度数据失败', error)
|
||||
}
|
||||
},
|
||||
|
||||
async loadReportData() {
|
||||
try {
|
||||
const url = this.reportType === 'today' ? '/api/screen/todayReport' : '/api/screen/weekReport'
|
||||
const res = await request({
|
||||
url: url,
|
||||
method: 'get'
|
||||
})
|
||||
this.consumeReportData = res.consumeReport || []
|
||||
this.iosReportData = res.iosReport || []
|
||||
this.todayDetailList = res.iosReport || []
|
||||
this.scrollIndex1 = 0
|
||||
this.scrollIndex2 = 0
|
||||
this.$nextTick(() => {
|
||||
this.initConsumeChart()
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('加载报表数据失败', error)
|
||||
}
|
||||
},
|
||||
|
||||
async loadMaterialTop5() {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/api/screen/materialTop5',
|
||||
method: 'get'
|
||||
})
|
||||
this.materialTop5Data = res.top5 || []
|
||||
this.$nextTick(() => {
|
||||
this.initMaterialTop5Chart()
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('加载焊材Top5数据失败', error)
|
||||
}
|
||||
},
|
||||
|
||||
handleReportTypeChange() {
|
||||
this.loadReportData()
|
||||
},
|
||||
|
||||
startScrolling() {
|
||||
// 班组焊材领退明细滚动
|
||||
this.scrollTimer1 = setInterval(() => {
|
||||
if (this.iosReportData.length > 5) {
|
||||
this.scrollIndex1 = (this.scrollIndex1 + 1) % this.iosReportData.length
|
||||
}
|
||||
}, 3000)
|
||||
|
||||
// 当日领退明细滚动
|
||||
this.scrollTimer2 = setInterval(() => {
|
||||
if (this.todayDetailList.length > 5) {
|
||||
this.scrollIndex2 = (this.scrollIndex2 + 1) % this.todayDetailList.length
|
||||
}
|
||||
}, 3000)
|
||||
|
||||
// AGV监控滚动
|
||||
this.scrollTimer3 = setInterval(() => {
|
||||
if (this.agvList.length > 4) {
|
||||
this.scrollIndex3 = (this.scrollIndex3 + 1) % this.agvList.length
|
||||
}
|
||||
}, 3000)
|
||||
},
|
||||
|
||||
getAgvIcon(icon) {
|
||||
if (!icon) {
|
||||
return require('@/assets/images/agv.png')
|
||||
}
|
||||
try {
|
||||
return require(`@/assets/images/${icon}`)
|
||||
} catch (e) {
|
||||
return require('@/assets/images/agv.png')
|
||||
}
|
||||
},
|
||||
|
||||
getAgvStatusClass(status) {
|
||||
if (!status) return 'status-idle'
|
||||
if (status.status === '正常') return 'status-normal'
|
||||
if (status.status === '故障') return 'status-error'
|
||||
return 'status-idle'
|
||||
},
|
||||
|
||||
getAgvStatusText(status) {
|
||||
return status ? status.status || '空闲' : '空闲'
|
||||
},
|
||||
|
||||
initStructChart() {
|
||||
const chart = echarts.init(document.getElementById('structChart'))
|
||||
const data = this.inventoryData.structStat || {}
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{b}: {c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
right: 10,
|
||||
top: 'center',
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
center: ['40%', '50%'],
|
||||
data: [
|
||||
{ value: data.hasGoods || 0, name: '有货', itemStyle: { color: '#5470c6' } },
|
||||
{ value: data.emptyBox || 0, name: '空料箱', itemStyle: { color: '#91cc75' } },
|
||||
{ value: data.noGoods || 0, name: '无货', itemStyle: { color: '#fac858' } }
|
||||
],
|
||||
label: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
chart.setOption(option)
|
||||
},
|
||||
|
||||
initTempChart() {
|
||||
const chart = echarts.init(document.getElementById('tempChart'))
|
||||
|
||||
const times = this.tempData.map(item => item.time)
|
||||
const temps = this.tempData.map(item => item.temperature)
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
top: '10%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: times,
|
||||
axisLine: { lineStyle: { color: '#fff' } },
|
||||
axisLabel: { color: '#fff' }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#fff' } },
|
||||
axisLabel: { color: '#fff' },
|
||||
splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } }
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: temps,
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
itemStyle: { color: '#ee6666' },
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: 'rgba(238, 102, 102, 0.5)' },
|
||||
{ offset: 1, color: 'rgba(238, 102, 102, 0.1)' }
|
||||
])
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
chart.setOption(option)
|
||||
},
|
||||
|
||||
initConsumeChart() {
|
||||
const chart = echarts.init(document.getElementById('consumeChart'))
|
||||
|
||||
const groups = this.consumeReportData.map(item => item.groupName)
|
||||
const consumeQty = this.consumeReportData.map(item => item.consumeQty)
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { type: 'shadow' }
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
top: '10%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: groups,
|
||||
axisLine: { lineStyle: { color: '#fff' } },
|
||||
axisLabel: { color: '#fff', rotate: 30 }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#fff' } },
|
||||
axisLabel: { color: '#fff' },
|
||||
splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } }
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: consumeQty,
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: '#83bff6' },
|
||||
{ offset: 1, color: '#188df0' }
|
||||
])
|
||||
},
|
||||
barWidth: '60%'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
chart.setOption(option)
|
||||
},
|
||||
|
||||
initMaterialTop5Chart() {
|
||||
const chart = echarts.init(document.getElementById('materialTop5Chart'))
|
||||
|
||||
const materials = this.materialTop5Data.map(item => item.materialName)
|
||||
const qtys = this.materialTop5Data.map(item => item.totalQty)
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { type: 'shadow' }
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
top: '10%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#fff' } },
|
||||
axisLabel: { color: '#fff' },
|
||||
splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: materials,
|
||||
axisLine: { lineStyle: { color: '#fff' } },
|
||||
axisLabel: { color: '#fff' }
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: qtys,
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||||
{ offset: 0, color: '#fac858' },
|
||||
{ offset: 1, color: '#ee6666' }
|
||||
])
|
||||
},
|
||||
barWidth: '60%'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
chart.setOption(option)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.screen-container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: linear-gradient(to bottom, #0a1e3e, #0f2847);
|
||||
color: #fff;
|
||||
overflow: hidden;
|
||||
font-family: 'Microsoft YaHei', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.screen-header {
|
||||
height: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 30px;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-bottom: 2px solid #1e90ff;
|
||||
|
||||
.header-logo {
|
||||
width: 200px;
|
||||
|
||||
.logo-img {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
color: #00d4ff;
|
||||
text-shadow: 0 0 10px rgba(0, 212, 255, 0.8);
|
||||
}
|
||||
|
||||
.header-time {
|
||||
width: 200px;
|
||||
text-align: right;
|
||||
|
||||
.time {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: #00d4ff;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 14px;
|
||||
color: #8ab4f8;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.screen-content {
|
||||
display: flex;
|
||||
height: calc(100vh - 80px);
|
||||
padding: 20px;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.left-panel,
|
||||
.right-panel {
|
||||
flex: 0 0 25%;
|
||||
background: rgba(0, 30, 60, 0.6);
|
||||
border: 1px solid rgba(30, 144, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(30, 144, 255, 0.5);
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.center-panel {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.center-left {
|
||||
flex: 0 0 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.center-right {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #00d4ff;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid rgba(30, 144, 255, 0.3);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.inventory-category {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.category-item {
|
||||
text-align: center;
|
||||
|
||||
.item-label {
|
||||
font-size: 14px;
|
||||
color: #8ab4f8;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.item-value {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
color: #00d4ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.warehouse-3d {
|
||||
flex: 2;
|
||||
background: rgba(0, 30, 60, 0.6);
|
||||
border: 1px solid rgba(30, 144, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
|
||||
.warehouse-img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-monitor {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.agv-monitor,
|
||||
.temp-monitor {
|
||||
flex: 1;
|
||||
background: rgba(0, 30, 60, 0.6);
|
||||
border: 1px solid rgba(30, 144, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monitor-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #00d4ff;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.agv-list {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.agv-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
background: rgba(0, 50, 100, 0.4);
|
||||
border: 1px solid rgba(30, 144, 255, 0.2);
|
||||
border-radius: 4px;
|
||||
padding: 6px 10px;
|
||||
margin-bottom: 6px;
|
||||
transition: all 0.5s ease;
|
||||
|
||||
.agv-icon {
|
||||
flex: 0 0 40px;
|
||||
|
||||
.agv-img {
|
||||
width: 40px;
|
||||
height: 25px;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.agv-id {
|
||||
flex: 0 0 60px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.agv-status {
|
||||
flex: 0 0 60px;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
|
||||
&.status-normal {
|
||||
color: #52c41a;
|
||||
background: rgba(82, 196, 26, 0.2);
|
||||
}
|
||||
|
||||
&.status-error {
|
||||
color: #ff4d4f;
|
||||
background: rgba(255, 77, 79, 0.2);
|
||||
}
|
||||
|
||||
&.status-idle {
|
||||
color: #faad14;
|
||||
background: rgba(250, 173, 20, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.agv-task {
|
||||
flex: 1;
|
||||
font-size: 11px;
|
||||
color: #8ab4f8;
|
||||
}
|
||||
|
||||
.agv-battery {
|
||||
flex: 0 0 80px;
|
||||
font-size: 11px;
|
||||
color: #00d4ff;
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.report-table {
|
||||
margin-bottom: 30px;
|
||||
|
||||
::v-deep .el-table {
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
|
||||
th, td {
|
||||
background: transparent;
|
||||
border-color: rgba(30, 144, 255, 0.2);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
th {
|
||||
background: rgba(0, 50, 100, 0.4);
|
||||
}
|
||||
|
||||
tr:hover > td {
|
||||
background: rgba(0, 100, 200, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-list {
|
||||
&.scroll-list {
|
||||
height: 300px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
background: rgba(0, 50, 100, 0.4);
|
||||
border: 1px solid rgba(30, 144, 255, 0.2);
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
transition: all 0.5s ease;
|
||||
|
||||
.detail-time {
|
||||
flex: 0 0 90px;
|
||||
color: #8ab4f8;
|
||||
}
|
||||
|
||||
.detail-type {
|
||||
flex: 0 0 50px;
|
||||
text-align: center;
|
||||
padding: 2px 8px;
|
||||
border-radius: 3px;
|
||||
|
||||
&.type-out {
|
||||
background: rgba(255, 77, 79, 0.2);
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
&.type-in {
|
||||
background: rgba(82, 196, 26, 0.2);
|
||||
color: #52c41a;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-material {
|
||||
flex: 1;
|
||||
margin: 0 10px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.detail-weight {
|
||||
flex: 0 0 60px;
|
||||
text-align: right;
|
||||
color: #00d4ff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.detail-person {
|
||||
flex: 0 0 80px;
|
||||
text-align: right;
|
||||
color: #8ab4f8;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
193
wms/nladmin-ui/src/views/wms/biBoard/temp/index.vue
Normal file
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!--工具栏-->
|
||||
<div class="head-container">
|
||||
<div v-if="crud.props.searchToggle">
|
||||
<el-form
|
||||
size="mini"
|
||||
:inline="true"
|
||||
class="demo-form-inline"
|
||||
label-position="right"
|
||||
label-width="80px"
|
||||
label-suffix=":"
|
||||
>
|
||||
<el-form-item label="开始日期">
|
||||
<el-date-picker
|
||||
v-model="query.startDate"
|
||||
type="date"
|
||||
placeholder="选择开始日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束日期">
|
||||
<el-date-picker
|
||||
v-model="query.endDate"
|
||||
type="date"
|
||||
placeholder="选择结束日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<rrOperation />
|
||||
</el-form>
|
||||
</div>
|
||||
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||
<crudOperation :permission="permission" />
|
||||
<!--表格渲染-->
|
||||
<el-table ref="table" border v-loading="crud.loading" :data="crud.data" size="mini" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="recordDatee" label="日期" />
|
||||
<el-table-column prop="recordTimee" label="记录时间" />
|
||||
<el-table-column prop="temp" label="温度℃" />
|
||||
<el-table-column prop="recorder" label="记录人" />
|
||||
</el-table>
|
||||
<!--分页组件-->
|
||||
<pagination />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudTempRecord from '@/views/wms/biBoard/temp/tempRecord'
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud'
|
||||
import rrOperation from '@crud/RR.operation'
|
||||
import crudOperation from '@crud/CRUD.operation'
|
||||
import pagination from '@crud/Pagination'
|
||||
|
||||
const defaultForm = { }
|
||||
export default {
|
||||
name: 'TempRecord',
|
||||
components: { pagination, crudOperation, rrOperation },
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||
cruds() {
|
||||
return CRUD({
|
||||
title: '温度记录表',
|
||||
url: 'api/tempRecord',
|
||||
idField: 'id',
|
||||
sort: '',
|
||||
query: { startDate: '', endDate: '' },
|
||||
crudMethod: { ...crudTempRecord },
|
||||
optShow: {
|
||||
add: false,
|
||||
edit: false,
|
||||
del: false,
|
||||
download: false,
|
||||
reset: true
|
||||
}
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
permission: {
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
::v-deep {
|
||||
|
||||
.vue-treeselect__menu {
|
||||
|
||||
overflow-x: auto !important;
|
||||
|
||||
width: 300px;
|
||||
|
||||
max-height: 300px !important;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__label {
|
||||
|
||||
overflow: unset;
|
||||
|
||||
text-overflow: unset;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__control {
|
||||
|
||||
height: 20px !important;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__multi-value-item-container,
|
||||
|
||||
.vue-treeselect--has-value .vue-treeselect__multi-value {
|
||||
|
||||
height: 30px;
|
||||
|
||||
line-height: 24px;
|
||||
|
||||
padding: 0;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__limit-tip,
|
||||
|
||||
.vue-treeselect--searchable.vue-treeselect--multi.vue-treeselect--has-value
|
||||
|
||||
.vue-treeselect__input-container {
|
||||
|
||||
padding-top: 0;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__placeholder,
|
||||
|
||||
.vue-treeselect__single-value {
|
||||
|
||||
height: 28px;
|
||||
|
||||
line-height: 32px;
|
||||
|
||||
font-size: small;
|
||||
|
||||
color: "#CCCFD6";
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect--has-value .vue-treeselect__input {
|
||||
|
||||
height: 18px !important;
|
||||
|
||||
line-height: 18px !important;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect div,
|
||||
|
||||
.vue-treeselect span {
|
||||
|
||||
box-sizing: content-box;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__multi-value-label {
|
||||
|
||||
display: block;
|
||||
|
||||
width: 140px;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
|
||||
}
|
||||
|
||||
.vue-treeselect__value-container {
|
||||
|
||||
display: block;
|
||||
|
||||
height: 32px;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
11
wms/nladmin-ui/src/views/wms/biBoard/temp/tempRecord.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function query(params) {
|
||||
return request({
|
||||
url: 'api/tempRecord',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export default { query }
|
||||