opt:西门子优化
This commit is contained in:
@@ -425,11 +425,10 @@ public class HandheldServiceImpl implements HandheldService {
|
||||
|
||||
//是否需要从日志表重新入库的标志
|
||||
Boolean reentry_flag = param.getBoolean("reentry_flag");
|
||||
reentry_flag = true;
|
||||
|
||||
//如果当前点位是SD01点位,且当前载具在组盘表中不存在
|
||||
List<Map> groups = iSchBaseVehiclematerialgroupService.selectGroupByVehicleCode(param.getString("vehicle_code"));
|
||||
if (reentry_flag!= null && reentry_flag && "SD01".equals(device_code) && CollectionUtil.isEmpty(groups) ) {
|
||||
if (reentry_flag!= null && reentry_flag && "SD01".equals(device_code)) {
|
||||
|
||||
List<Dict> dictList = dictService.getDictByName("sd01_interval_hour");
|
||||
if(CollectionUtil.isNotEmpty(dictList)){
|
||||
@@ -445,15 +444,13 @@ public class HandheldServiceImpl implements HandheldService {
|
||||
.apply("point_code = {0}", device_code)
|
||||
// 3. 核心新增:筛选 hour 小时内删除的数据
|
||||
.apply("delete_time >= DATE_SUB(NOW(), INTERVAL {0} HOUR)", hour)
|
||||
.orderByDesc(SchBaseVehiclematerialgroupDeleteLog::getDelete_time)
|
||||
.last("LIMIT 1"));
|
||||
.orderByDesc(SchBaseVehiclematerialgroupDeleteLog::getDelete_time));
|
||||
|
||||
//则自动将log表中的数据库插入到组盘表中
|
||||
if(CollectionUtil.isNotEmpty(logList)){
|
||||
SchBaseVehiclematerialgroupDeleteLog log = logList.get(0);
|
||||
SchBaseVehiclematerialgroup group = new SchBaseVehiclematerialgroup();
|
||||
BeanUtils.copyProperties(log,group);
|
||||
iSchBaseVehiclematerialgroupService.save(group);
|
||||
for(SchBaseVehiclematerialgroupDeleteLog log : logList) {
|
||||
iSchBaseVehiclematerialgroupDeleteLogService.removeById(log.getGroup_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -482,7 +479,7 @@ public class HandheldServiceImpl implements HandheldService {
|
||||
|
||||
@Override
|
||||
public SD01GroupLogRespondDto getSD01GroupLog(JSONObject param) {
|
||||
String device_code = param.getString("device_code");
|
||||
String device_code = param.getString("pointCode");
|
||||
String vehicle_code = param.getString("vehicle_code");
|
||||
|
||||
if(!"SD01".equals(device_code) || StringUtils.isBlank(vehicle_code)){
|
||||
@@ -501,7 +498,7 @@ public class HandheldServiceImpl implements HandheldService {
|
||||
|
||||
String hour = dict.getValue();
|
||||
|
||||
// 修复后的查询代码(兼容下划线字段的Lambda写法)
|
||||
// 修复后的查询代码(兼容下划线字段的Lambda写法)
|
||||
List<SchBaseVehiclematerialgroupDeleteLog> logList = iSchBaseVehiclematerialgroupDeleteLogService
|
||||
.list(Wrappers.lambdaQuery(SchBaseVehiclematerialgroupDeleteLog.class)
|
||||
// 1. 对数据库字段:用Lambda + 字段名(MyBatis-Plus会自动转下划线)
|
||||
@@ -510,23 +507,21 @@ public class HandheldServiceImpl implements HandheldService {
|
||||
.apply("point_code = {0}", device_code)
|
||||
// 3. 核心新增:筛选 hour 小时内删除的数据
|
||||
.apply("delete_time >= DATE_SUB(NOW(), INTERVAL {0} HOUR)", hour)
|
||||
.orderByDesc(SchBaseVehiclematerialgroupDeleteLog::getDelete_time)
|
||||
.last("LIMIT 1"));
|
||||
.orderByDesc(SchBaseVehiclematerialgroupDeleteLog::getDelete_time));
|
||||
|
||||
if(CollectionUtil.isEmpty(logList)){
|
||||
return null;
|
||||
}
|
||||
|
||||
SD01GroupLogRespondDto sd01GroupLogRespondDto = new SD01GroupLogRespondDto();
|
||||
LogMaterialDto logMaterialDto = new LogMaterialDto();
|
||||
|
||||
logMaterialDto.setMaterial_qty(logList.get(0).getMaterial_qty());
|
||||
logMaterialDto.setMaterial_code(logList.get(0).getMaterial_id());
|
||||
logMaterialDto.setDue_date(logList.get(0).getDue_date());
|
||||
logMaterialDto.setOrder_code(logList.get(0).getOrder_code());
|
||||
|
||||
List<LogMaterialDto> logMaterialDtos = new ArrayList<>();
|
||||
logMaterialDtos.add(logMaterialDto);
|
||||
SD01GroupLogRespondDto sd01GroupLogRespondDto = new SD01GroupLogRespondDto();
|
||||
for (SchBaseVehiclematerialgroupDeleteLog log : logList) {
|
||||
LogMaterialDto logMaterialDto = new LogMaterialDto();
|
||||
logMaterialDto.setMaterial_qty(log.getMaterial_qty());
|
||||
logMaterialDto.setMaterial_code(log.getMaterial_id());
|
||||
logMaterialDto.setDue_date(log.getDue_date());
|
||||
logMaterialDto.setOrder_code(log.getOrder_code());
|
||||
logMaterialDtos.add(logMaterialDto);
|
||||
}
|
||||
|
||||
sd01GroupLogRespondDto.setMaterial(logMaterialDtos);
|
||||
sd01GroupLogRespondDto.setDevice_code(device_code);
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package org.nl.wms.sch.agv_usage.controller;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.common.logging.annotation.Log;
|
||||
import org.nl.wms.sch.agv_usage.service.IAgvUsageService;
|
||||
import org.nl.wms.sch.agv_usage.service.dto.AgvUsageQuery;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@Api(tags = "AGV使用率统计")
|
||||
@RequestMapping("/api/agv_usage")
|
||||
public class AgvUsageController {
|
||||
|
||||
private final IAgvUsageService agvUsageService;
|
||||
|
||||
@GetMapping("/statistics")
|
||||
@Log("获取AGV使用率统计")
|
||||
@ApiOperation("获取AGV使用率统计")
|
||||
public ResponseEntity<Object> getStatistics(
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) {
|
||||
AgvUsageQuery query = new AgvUsageQuery();
|
||||
query.setStartDate(startDate);
|
||||
query.setEndDate(endDate);
|
||||
List<Map<String, Object>> result = agvUsageService.getAgvUsageStatistics(query);
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/statistics/detail")
|
||||
@Log("获取AGV详细统计")
|
||||
@ApiOperation("获取AGV详细统计")
|
||||
public ResponseEntity<Object> getStatisticsDetail(
|
||||
@RequestParam(required = false) String deviceCode,
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
|
||||
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) {
|
||||
AgvUsageQuery query = new AgvUsageQuery();
|
||||
query.setDeviceCode(deviceCode);
|
||||
query.setStartDate(startDate);
|
||||
query.setEndDate(endDate);
|
||||
List<Map<String, Object>> result = agvUsageService.getAgvUsageDetail(query);
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/today")
|
||||
@Log("获取今日AGV使用率")
|
||||
@ApiOperation("获取今日AGV使用率")
|
||||
public ResponseEntity<Object> getTodayUsageRate() {
|
||||
Map<String, Object> result = agvUsageService.getAgvUsageRateToday();
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.nl.wms.sch.agv_usage.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.nl.wms.sch.agv_usage.service.dto.AgvUsageQuery;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface IAgvUsageService {
|
||||
|
||||
List<Map<String, Object>> getAgvUsageStatistics(AgvUsageQuery query);
|
||||
|
||||
List<Map<String, Object>> getAgvUsageDetail(AgvUsageQuery query);
|
||||
|
||||
Map<String, Object> getAgvRealtimeStatus();
|
||||
|
||||
Map<String, Object> getAgvUsageRateToday();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.nl.wms.sch.agv_usage.service.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class AgvUsageQuery {
|
||||
|
||||
private String deviceCode;
|
||||
|
||||
private Date startDate;
|
||||
|
||||
private Date endDate;
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
package org.nl.wms.sch.agv_usage.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.config.SpringContextHolder;
|
||||
import org.nl.system.service.param.dao.Param;
|
||||
import org.nl.system.service.param.impl.SysParamServiceImpl;
|
||||
import org.nl.wms.sch.agv_usage.service.IAgvUsageService;
|
||||
import org.nl.wms.sch.agv_usage.service.dto.AgvUsageQuery;
|
||||
import org.nl.wms.sch.task_manage.GeneralDefinition;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class AgvUsageServiceImpl implements IAgvUsageService {
|
||||
|
||||
private String getAcsUrl() {
|
||||
SysParamServiceImpl sysParamService = SpringContextHolder.getBean(SysParamServiceImpl.class);
|
||||
Param acsUrlObj = sysParamService.findByCode(GeneralDefinition.ACS_URL);
|
||||
if (ObjectUtil.isEmpty(acsUrlObj)) {
|
||||
return null;
|
||||
}
|
||||
return acsUrlObj.getValue();
|
||||
}
|
||||
|
||||
private boolean isConnectAcs() {
|
||||
SysParamServiceImpl sysParamService = SpringContextHolder.getBean(SysParamServiceImpl.class);
|
||||
Param isConnectAcs = sysParamService.findByCode(GeneralDefinition.IS_CONNECT_ACS);
|
||||
if (ObjectUtil.isEmpty(isConnectAcs)) {
|
||||
return false;
|
||||
}
|
||||
return StrUtil.equals(GeneralDefinition.YES, isConnectAcs.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> getAgvUsageStatistics(AgvUsageQuery query) {
|
||||
if (!isConnectAcs()) {
|
||||
log.warn("未连接ACS系统");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
String acsUrl = getAcsUrl();
|
||||
if (StrUtil.isEmpty(acsUrl)) {
|
||||
log.warn("ACS地址未配置");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String startDate = sdf.format(query.getStartDate());
|
||||
String endDate = sdf.format(query.getEndDate());
|
||||
|
||||
String url = acsUrl + "api/agv_usage/statistics?startDate=" + startDate + "&endDate=" + endDate;
|
||||
|
||||
try {
|
||||
String result = HttpRequest.get(url)
|
||||
.setConnectionTimeout(5000)
|
||||
.execute()
|
||||
.body();
|
||||
// 修复点1:使用TypeReference指定泛型类型,解决List<Map>和List<Map<String, Object>>不兼容问题
|
||||
return JSON.parseObject(result, new TypeReference<List<Map<String, Object>>>() {});
|
||||
} catch (Exception e) {
|
||||
log.error("调用ACS获取AGV使用率统计失败: {}", e.getMessage());
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> getAgvUsageDetail(AgvUsageQuery query) {
|
||||
if (!isConnectAcs()) {
|
||||
log.warn("未连接ACS系统");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
String acsUrl = getAcsUrl();
|
||||
if (StrUtil.isEmpty(acsUrl)) {
|
||||
log.warn("ACS地址未配置");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String startDate = sdf.format(query.getStartDate());
|
||||
String endDate = sdf.format(query.getEndDate());
|
||||
|
||||
StringBuilder urlBuilder = new StringBuilder(acsUrl)
|
||||
.append("/api/agv_usage/statistics/detail?startDate=")
|
||||
.append(startDate)
|
||||
.append("&endDate=")
|
||||
.append(endDate);
|
||||
|
||||
if (StrUtil.isNotEmpty(query.getDeviceCode())) {
|
||||
urlBuilder.append("&deviceCode=").append(query.getDeviceCode());
|
||||
}
|
||||
|
||||
try {
|
||||
String result = HttpRequest.get(urlBuilder.toString())
|
||||
.setConnectionTimeout(5000)
|
||||
.execute()
|
||||
.body();
|
||||
// 修复点2:同上,统一使用TypeReference保证泛型类型匹配
|
||||
return JSON.parseObject(result, new TypeReference<List<Map<String, Object>>>() {});
|
||||
} catch (Exception e) {
|
||||
log.error("调用ACS获取AGV详细统计失败: {}", e.getMessage());
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAgvRealtimeStatus() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
if (!isConnectAcs()) {
|
||||
log.warn("未连接ACS系统");
|
||||
result.put("workingAgvList", new ArrayList<>());
|
||||
result.put("workingCount", 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
String acsUrl = getAcsUrl();
|
||||
if (StrUtil.isEmpty(acsUrl)) {
|
||||
log.warn("ACS地址未配置");
|
||||
result.put("workingAgvList", new ArrayList<>());
|
||||
result.put("workingCount", 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
String url = acsUrl + "api/agv_usage/realtime";
|
||||
|
||||
try {
|
||||
String response = HttpRequest.get(url)
|
||||
.setConnectionTimeout(5000)
|
||||
.execute()
|
||||
.body();
|
||||
// 修复点3:使用TypeReference指定Map<String, Object>,移除不必要的SuppressWarnings
|
||||
Map<String, Object> map = JSON.parseObject(response, new TypeReference<Map<String, Object>>() {});
|
||||
return map != null ? map : result;
|
||||
} catch (Exception e) {
|
||||
log.error("调用ACS获取AGV实时状态失败: {}", e.getMessage());
|
||||
result.put("workingAgvList", new ArrayList<>());
|
||||
result.put("workingCount", 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAgvUsageRateToday() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
if (!isConnectAcs()) {
|
||||
log.warn("未连接ACS系统");
|
||||
return result;
|
||||
}
|
||||
|
||||
String acsUrl = getAcsUrl();
|
||||
if (StrUtil.isEmpty(acsUrl)) {
|
||||
log.warn("ACS地址未配置");
|
||||
return result;
|
||||
}
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String today = sdf.format(new Date());
|
||||
String url = acsUrl + "api/agv_usage/statistics?startDate=" + today + "&endDate=" + today;
|
||||
|
||||
try {
|
||||
String response = HttpRequest.get(url)
|
||||
.setConnectionTimeout(5000)
|
||||
.execute()
|
||||
.body();
|
||||
// 修复点4:同上,使用TypeReference保证类型匹配
|
||||
return JSON.parseObject(response, new TypeReference<Map<String, Object>>() {});
|
||||
} catch (Exception e) {
|
||||
log.error("调用ACS获取今日AGV使用率失败: {}", e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,6 @@ public class SchBaseVehiclematerialgroupDeleteLog implements Serializable {
|
||||
@ApiModelProperty(value = "来源载具编码")
|
||||
private String source_vehicle_code;
|
||||
|
||||
@TableField(exist = false)
|
||||
@ApiModelProperty(value = "点位编码")
|
||||
private String point_code;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.nl.wms.sch.point.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
@@ -35,6 +36,10 @@ import org.nl.system.service.param.dao.Param;
|
||||
import org.nl.wms.database.vehicle.service.IMdBaseVehicleService;
|
||||
import org.nl.wms.database.vehicle.service.dao.MdBaseVehicle;
|
||||
import org.nl.wms.ext.fab.service.dto.OrderMater;
|
||||
import org.nl.wms.sch.group.service.ISchBaseVehiclematerialgroupService;
|
||||
import org.nl.wms.sch.group.service.dao.SchBaseVehiclematerialgroup;
|
||||
import org.nl.wms.sch.group_delete_log.service.ISchBaseVehiclematerialgroupDeleteLogService;
|
||||
import org.nl.wms.sch.group_delete_log.service.dao.SchBaseVehiclematerialgroupDeleteLog;
|
||||
import org.nl.wms.sch.point.service.ISchBasePointService;
|
||||
import org.nl.wms.sch.point.service.dao.SchBasePoint;
|
||||
import org.nl.wms.sch.point.service.dao.mapper.SchBasePointMapper;
|
||||
@@ -47,6 +52,7 @@ import org.nl.wms.sch.task_manage.enums.NoticeTypeEnum;
|
||||
import org.nl.wms.sch.task_manage.enums.PointStatusEnum;
|
||||
import org.nl.wms.sch.task_manage.task.core.TaskStatus;
|
||||
import org.nl.wms.util.PointUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
@@ -76,6 +82,11 @@ public class SchBasePointServiceImpl extends ServiceImpl<SchBasePointMapper, Sch
|
||||
private IMdBaseVehicleService iMdBaseVehicleService;
|
||||
@Autowired
|
||||
private ISysParamService iSysParamService;
|
||||
@Autowired
|
||||
private ISchBaseVehiclematerialgroupService schBaseVehiclematerialgroupService;
|
||||
|
||||
@Autowired
|
||||
private ISchBaseVehiclematerialgroupDeleteLogService schBaseVehiclematerialgroupDeleteLogService;
|
||||
|
||||
@Autowired
|
||||
private ISysDictService dictService;
|
||||
@@ -188,6 +199,38 @@ public class SchBasePointServiceImpl extends ServiceImpl<SchBasePointMapper, Sch
|
||||
String vehicle_code = entity.getVehicle_code();
|
||||
// 根据点位状态来判断更新内容
|
||||
if (ObjectUtil.isNotEmpty(pointStatus) && pointStatus.equals(GoodsEnum.OUT_OF_STOCK.getValue())) {
|
||||
|
||||
List<Dict> dictList = dictService.getDictByName("sd01_interval_hour");
|
||||
if(CollectionUtil.isNotEmpty(dictList)) {
|
||||
Dict dict = dictList.get(0);
|
||||
|
||||
if ("hour".equals(dict.getLabel())) {
|
||||
String hour = dict.getValue();
|
||||
//判断log中是否存在sd01 载具号=这个的单据
|
||||
List<SchBaseVehiclematerialgroupDeleteLog> loglist = schBaseVehiclematerialgroupDeleteLogService.list(Wrappers.lambdaQuery(SchBaseVehiclematerialgroupDeleteLog.class)
|
||||
// 1. 对数据库字段:用Lambda + 字段名(MyBatis-Plus会自动转下划线)
|
||||
.eq(SchBaseVehiclematerialgroupDeleteLog::getVehicle_code, vehicle_code)
|
||||
// 2. 对非数据库字段(@TableField(exist=false)):改用apply手动拼接
|
||||
.apply("point_code = {0}", "SD01")
|
||||
// 3. 核心新增:筛选 hour 小时内删除的数据
|
||||
.apply("delete_time >= DATE_SUB(NOW(), INTERVAL {0} HOUR)", hour));
|
||||
|
||||
if (CollectionUtils.isEmpty(loglist)) {
|
||||
//如果是设置为无货将组盘插入到日志表中,默认point_code=SD01
|
||||
List<SchBaseVehiclematerialgroup> schBaseVehiclematerialgroupList = schBaseVehiclematerialgroupService.list(Wrappers.lambdaQuery(SchBaseVehiclematerialgroup.class)
|
||||
.eq(SchBaseVehiclematerialgroup::getVehicle_code, vehicle_code));
|
||||
|
||||
for (SchBaseVehiclematerialgroup schBaseVehiclematerialgroup : schBaseVehiclematerialgroupList) {
|
||||
SchBaseVehiclematerialgroupDeleteLog deleteLog = new SchBaseVehiclematerialgroupDeleteLog();
|
||||
BeanUtils.copyProperties(schBaseVehiclematerialgroup, deleteLog);
|
||||
deleteLog.setDelete_time(DateUtil.now());
|
||||
deleteLog.setPoint_code("SD01");
|
||||
schBaseVehiclematerialgroupDeleteLogService.save(deleteLog);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vehicle_code = null;
|
||||
} else if (ObjectUtil.isNotEmpty(pointStatus) && (pointStatus.equals(GoodsEnum.EMPTY_PALLETS.getValue()) || pointStatus.equals(GoodsEnum.IN_STOCK.getValue()))) {
|
||||
if (StrUtil.isEmpty(entity.getVehicle_code())) throw new BadRequestException("载具编码不能为空");
|
||||
@@ -195,6 +238,7 @@ public class SchBasePointServiceImpl extends ServiceImpl<SchBasePointMapper, Sch
|
||||
pointMapper.update(entity, Wrappers.lambdaUpdate(SchBasePoint.class)
|
||||
.eq(SchBasePoint::getPoint_code, entity.getPoint_code())
|
||||
.set(SchBasePoint::getVehicle_code, vehicle_code));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
33
lms/nladmin-ui/src/views/wms/sch/agv_usage/agvUsage.js
Normal file
33
lms/nladmin-ui/src/views/wms/sch/agv_usage/agvUsage.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getAgvUsageStatistics(params) {
|
||||
return request({
|
||||
url: 'api/agv_usage/statistics',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function getAgvUsageDetail(params) {
|
||||
return request({
|
||||
url: 'api/agv_usage/statistics/detail',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function getAgvRealtimeStatus() {
|
||||
return request({
|
||||
url: 'api/agv_usage/realtime',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getTodayUsageRate() {
|
||||
return request({
|
||||
url: 'api/agv_usage/today',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export default { getAgvUsageStatistics, getAgvUsageDetail, getAgvRealtimeStatus, getTodayUsageRate }
|
||||
216
lms/nladmin-ui/src/views/wms/sch/agv_usage/index.vue
Normal file
216
lms/nladmin-ui/src/views/wms/sch/agv_usage/index.vue
Normal file
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<el-form ref="queryForm" :inline="true" :model="query" size="small">
|
||||
<el-form-item label="开始日期">
|
||||
<el-date-picker
|
||||
v-model="query.startDate"
|
||||
type="date"
|
||||
placeholder="选择开始日期"
|
||||
style="width: 150px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束日期">
|
||||
<el-date-picker
|
||||
v-model="query.endDate"
|
||||
type="date"
|
||||
placeholder="选择结束日期"
|
||||
style="width: 150px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="toQuery">搜索</el-button>
|
||||
<el-button type="info" icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>AGV使用率统计</span>
|
||||
</div>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
border
|
||||
style="width: 100%"
|
||||
size="small"
|
||||
>
|
||||
<el-table-column prop="deviceCode" label="AGV编码" width="120" />
|
||||
<el-table-column prop="deviceName" label="AGV名称" width="150" />
|
||||
<el-table-column prop="totalWorkDuration" label="总工作时长(秒)" width="120">
|
||||
<template slot-scope="scope">
|
||||
{{ formatDuration(scope.row.totalWorkDuration) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalTaskCount" label="任务数量" width="100" />
|
||||
<el-table-column prop="avgUsageRate" label="平均使用率(%)">
|
||||
<template slot-scope="scope">
|
||||
<el-progress
|
||||
:percentage="scope.row.avgUsageRate || 0"
|
||||
:color="getProgressColor(scope.row.avgUsageRate)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="操作" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="showDetail(scope.row)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>-->
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
<el-dialog
|
||||
title="AGV使用详情"
|
||||
:visible.sync="detailVisible"
|
||||
width="70%"
|
||||
>
|
||||
<el-table
|
||||
v-loading="detailLoading"
|
||||
:data="detailData"
|
||||
border
|
||||
style="width: 100%"
|
||||
size="small"
|
||||
>
|
||||
<el-table-column prop="deviceCode" label="AGV编码" width="120" />
|
||||
<el-table-column prop="deviceName" label="AGV名称" width="150" />
|
||||
<el-table-column prop="workDate" label="日期" width="120" />
|
||||
<el-table-column prop="totalWorkDuration" label="工作时长(秒)" width="120">
|
||||
<template slot-scope="scope">
|
||||
{{ formatDuration(scope.row.totalWorkDuration) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalIdleDuration" label="空闲时长(秒)" width="120">
|
||||
<template slot-scope="scope">
|
||||
{{ formatDuration(scope.row.totalIdleDuration) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="taskCount" label="任务数量" width="100" />
|
||||
<el-table-column prop="usageRate" label="使用率(%)">
|
||||
<template slot-scope="scope">
|
||||
<el-progress
|
||||
:percentage="scope.row.usageRate || 0"
|
||||
:color="getProgressColor(scope.row.usageRate)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudAgvUsage from './agvUsage'
|
||||
import { format } from 'date-fns'
|
||||
|
||||
export default {
|
||||
name: 'AgvUsage',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
detailLoading: false,
|
||||
detailVisible: false,
|
||||
query: {
|
||||
startDate: new Date(),
|
||||
endDate: new Date()
|
||||
},
|
||||
tableData: [],
|
||||
detailData: [],
|
||||
currentDeviceCode: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.toQuery()
|
||||
},
|
||||
methods: {
|
||||
toQuery() {
|
||||
this.loading = true
|
||||
const startDate = this.formatDate(this.query.startDate)
|
||||
const endDate = this.formatDate(this.query.endDate)
|
||||
const queryParams = {
|
||||
startDate: startDate,
|
||||
endDate: endDate
|
||||
}
|
||||
crudAgvUsage.getAgvUsageStatistics(queryParams).then(res => {
|
||||
this.tableData = res || []
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
resetQuery() {
|
||||
this.query = {
|
||||
startDate: new Date(),
|
||||
endDate: new Date()
|
||||
}
|
||||
this.toQuery()
|
||||
},
|
||||
showDetail(row) {
|
||||
this.currentDeviceCode = row.deviceCode
|
||||
this.detailVisible = true
|
||||
this.detailLoading = true
|
||||
const params = {
|
||||
deviceCode: row.deviceCode,
|
||||
startDate: this.formatDate(this.query.startDate),
|
||||
endDate: this.formatDate(this.query.endDate)
|
||||
}
|
||||
crudAgvUsage.getAgvUsageDetail(params).then(res => {
|
||||
this.detailData = res || []
|
||||
this.detailLoading = false
|
||||
}).catch(() => {
|
||||
this.detailLoading = false
|
||||
})
|
||||
},
|
||||
formatDuration(seconds) {
|
||||
if (!seconds) return '0秒'
|
||||
const hours = Math.floor(seconds / 3600)
|
||||
const minutes = Math.floor((seconds % 3600) / 60)
|
||||
const secs = seconds % 60
|
||||
let result = ''
|
||||
if (hours > 0) {
|
||||
result += hours + '小时'
|
||||
}
|
||||
if (minutes > 0) {
|
||||
result += minutes + '分钟'
|
||||
}
|
||||
if (secs > 0 || result === '') {
|
||||
result += secs + '秒'
|
||||
}
|
||||
return result
|
||||
},
|
||||
getProgressColor(percentage) {
|
||||
if (percentage >= 80) {
|
||||
return '#67c23a'
|
||||
} else if (percentage >= 50) {
|
||||
return '#e6a23c'
|
||||
} else {
|
||||
return '#f56c6c'
|
||||
}
|
||||
},
|
||||
formatDate(date) {
|
||||
if (!date) return ''
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.head-container {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.box-card {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user