opt:西门子优化

This commit is contained in:
2026-03-10 13:37:58 +08:00
parent f76e7b1142
commit ff64d2d48c
19 changed files with 1136 additions and 23 deletions

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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

View 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 }

View 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>