mirror of
https://gitee.com/san-bing/JChargePointProtocol
synced 2026-05-04 01:49:58 +08:00
新增刷新按钮
This commit is contained in:
@@ -82,7 +82,7 @@ public class GunController extends BaseController {
|
|||||||
// 通过AttributeService获取充电枪运行状态
|
// 通过AttributeService获取充电枪运行状态
|
||||||
ListenableFuture<Optional<AttributeKvEntry>> attributeFuture =
|
ListenableFuture<Optional<AttributeKvEntry>> attributeFuture =
|
||||||
attributeService.find(gun.getId(), AttrKeyEnum.GUN_RUN_STATUS.getCode());
|
attributeService.find(gun.getId(), AttrKeyEnum.GUN_RUN_STATUS.getCode());
|
||||||
|
|
||||||
Optional<AttributeKvEntry> attributeResult = attributeFuture.get();
|
Optional<AttributeKvEntry> attributeResult = attributeFuture.get();
|
||||||
String status = null;
|
String status = null;
|
||||||
if (attributeResult.isPresent()) {
|
if (attributeResult.isPresent()) {
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class PileController extends BaseController {
|
|||||||
// 通过AttributeService获取充电桩状态
|
// 通过AttributeService获取充电桩状态
|
||||||
ListenableFuture<Optional<AttributeKvEntry>> attributeFuture =
|
ListenableFuture<Optional<AttributeKvEntry>> attributeFuture =
|
||||||
attributeService.find(pile.getId(), AttrKeyEnum.STATUS.getCode());
|
attributeService.find(pile.getId(), AttrKeyEnum.STATUS.getCode());
|
||||||
|
|
||||||
Optional<AttributeKvEntry> attributeResult = attributeFuture.get();
|
Optional<AttributeKvEntry> attributeResult = attributeFuture.get();
|
||||||
String status = null;
|
String status = null;
|
||||||
if (attributeResult.isPresent()) {
|
if (attributeResult.isPresent()) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import sanbing.jcpp.proto.gen.DownlinkProto.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* RPC控制器 - 通用化的充电桩下行指令接口
|
* RPC控制器 - 通用化的充电桩下行指令接口
|
||||||
*
|
*
|
||||||
* @author 九筒
|
* @author 九筒
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@@ -156,7 +156,7 @@ public class RpcController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 处理离线卡余额更新指令
|
* 处理离线卡余额更新指令
|
||||||
*/
|
*/
|
||||||
private void handleOfflineCardBalanceUpdate(JsonNode parameter) {
|
private void handleOfflineCardBalanceUpdate(JsonNode parameter) throws Exception {
|
||||||
OfflineCardBalanceUpdateRequest request = JacksonUtil.fromJson(parameter, OfflineCardBalanceUpdateRequest.class);
|
OfflineCardBalanceUpdateRequest request = JacksonUtil.fromJson(parameter, OfflineCardBalanceUpdateRequest.class);
|
||||||
pileProtocolService.offlineCardBalanceUpdateRequest(request);
|
pileProtocolService.offlineCardBalanceUpdateRequest(request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import lombok.Data;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 重启充电桩DTO
|
* 重启充电桩DTO
|
||||||
*
|
*
|
||||||
* @author 九筒
|
* @author 九筒
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import sanbing.jcpp.proto.gen.DownlinkProto.SetPricingRequest;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置计费策略DTO
|
* 设置计费策略DTO
|
||||||
*
|
*
|
||||||
* @author 九筒
|
* @author 九筒
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.math.BigDecimal;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动充电DTO
|
* 启动充电DTO
|
||||||
*
|
*
|
||||||
* @author 九筒
|
* @author 九筒
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import lombok.Data;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 停止充电DTO
|
* 停止充电DTO
|
||||||
*
|
*
|
||||||
* @author 九筒
|
* @author 九筒
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.time.LocalDateTime;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 时间同步DTO
|
* 时间同步DTO
|
||||||
*
|
*
|
||||||
* @author 九筒
|
* @author 九筒
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import lombok.Data;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* RPC请求参数
|
* RPC请求参数
|
||||||
*
|
*
|
||||||
* @author 九筒
|
* @author 九筒
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ public class DefaultGunService implements GunService {
|
|||||||
// 保存充电枪状态到属性表
|
// 保存充电枪状态到属性表
|
||||||
saveGunStatusChange(gun.getId(), dbStatus.name(), ts);
|
saveGunStatusChange(gun.getId(), dbStatus.name(), ts);
|
||||||
|
|
||||||
log.info("充电枪状态更新成功: 桩编码={}, 枪编号={}, 原状态={}, 新状态={}",
|
log.info("充电枪状态更新成功: 桩编码={}, 枪编号={}, 原状态={}, 新状态={}",
|
||||||
pileCode, gunNo, currentStatus, dbStatus);
|
pileCode, gunNo, currentStatus, dbStatus);
|
||||||
|
|
||||||
// 根据充电枪状态判断是否需要更新充电桩状态
|
// 根据充电枪状态判断是否需要更新充电桩状态
|
||||||
|
|||||||
@@ -630,7 +630,7 @@ public class DefaultPileProtocolService implements PileProtocolService {
|
|||||||
String additionalInfo = bmsHandshakeProto.getAdditionalInfo();
|
String additionalInfo = bmsHandshakeProto.getAdditionalInfo();
|
||||||
|
|
||||||
log.info("BMS充电握手信息: 交易流水号: {}, 桩编码: {}, 枪号: {}, 车辆VIN: {}, BMS协议版本: {}, " +
|
log.info("BMS充电握手信息: 交易流水号: {}, 桩编码: {}, 枪号: {}, 车辆VIN: {}, BMS协议版本: {}, " +
|
||||||
"电池类型: {}, 电池容量: {}Ah, 附加信息: {}",
|
"电池类型: {}, 电池容量: {}Ah, 附加信息: {}",
|
||||||
tradeNo, pileCode, gunNo, carVinCode, bmsProtocolVersion,
|
tradeNo, pileCode, gunNo, carVinCode, bmsProtocolVersion,
|
||||||
bmsBatteryType, bmsPowerCapacity, additionalInfo);
|
bmsBatteryType, bmsPowerCapacity, additionalInfo);
|
||||||
|
|
||||||
|
|||||||
@@ -101,8 +101,8 @@
|
|||||||
|
|
||||||
<!-- 根据充电桩编码和充电枪编号查询充电枪 -->
|
<!-- 根据充电桩编码和充电枪编号查询充电枪 -->
|
||||||
<select id="selectByPileCodeAndGunNo" resultType="sanbing.jcpp.app.dal.entity.Gun">
|
<select id="selectByPileCodeAndGunNo" resultType="sanbing.jcpp.app.dal.entity.Gun">
|
||||||
SELECT g.* FROM t_gun g
|
SELECT g.* FROM t_gun g
|
||||||
INNER JOIN t_pile p ON g.pile_id = p.id
|
INNER JOIN t_pile p ON g.pile_id = p.id
|
||||||
WHERE p.pile_code = #{pileCode}
|
WHERE p.pile_code = #{pileCode}
|
||||||
AND g.gun_no = #{gunNo}
|
AND g.gun_no = #{gunNo}
|
||||||
</select>
|
</select>
|
||||||
@@ -139,8 +139,8 @@
|
|||||||
<!-- 状态相关属性 -->
|
<!-- 状态相关属性 -->
|
||||||
a_run_status.str_v as run_status
|
a_run_status.str_v as run_status
|
||||||
|
|
||||||
FROM t_gun g
|
FROM t_gun g
|
||||||
|
|
||||||
<!-- LEFT JOIN 获取充电站信息 -->
|
<!-- LEFT JOIN 获取充电站信息 -->
|
||||||
LEFT JOIN t_station s ON g.station_id = s.id
|
LEFT JOIN t_station s ON g.station_id = s.id
|
||||||
|
|
||||||
|
|||||||
@@ -36,9 +36,9 @@
|
|||||||
|
|
||||||
<!-- 充电枪数量 - 使用LEFT JOIN优化子查询 -->
|
<!-- 充电枪数量 - 使用LEFT JOIN优化子查询 -->
|
||||||
COALESCE(g.gun_count, 0) as gun_count
|
COALESCE(g.gun_count, 0) as gun_count
|
||||||
|
|
||||||
FROM t_pile p
|
|
||||||
|
|
||||||
|
FROM t_pile p
|
||||||
|
|
||||||
<!-- 单次JOIN获取所有属性,避免多次JOIN -->
|
<!-- 单次JOIN获取所有属性,避免多次JOIN -->
|
||||||
LEFT JOIN t_attr a ON (
|
LEFT JOIN t_attr a ON (
|
||||||
a.entity_id = p.id AND
|
a.entity_id = p.id AND
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class LvnengV340HeartbeatULCmd extends LvnengUplinkCmdExe {
|
|||||||
//5预留
|
//5预留
|
||||||
byteBuf.skipBytes(16);
|
byteBuf.skipBytes(16);
|
||||||
|
|
||||||
|
// 会话添加充电桩编码
|
||||||
tcpSession.addPileCode(pileCode);
|
tcpSession.addPileCode(pileCode);
|
||||||
|
|
||||||
// 注册前置会话
|
// 注册前置会话
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ public class LvnengV340RealTimeDataULCmd extends LvnengUplinkCmdExe {
|
|||||||
//46 预留 1
|
//46 预留 1
|
||||||
byteBuf.skipBytes(1);
|
byteBuf.skipBytes(1);
|
||||||
|
|
||||||
|
// 会话添加充电桩编码
|
||||||
tcpSession.addPileCode(pileCode);
|
tcpSession.addPileCode(pileCode);
|
||||||
|
|
||||||
// 注册前置会话
|
// 注册前置会话
|
||||||
|
|||||||
@@ -140,6 +140,12 @@ public class YunKuaiChongV150RealTimeDataULCmd extends YunKuaiChongUplinkCmdExe
|
|||||||
.addAllFaultMessages(faults)
|
.addAllFaultMessages(faults)
|
||||||
.setAdditionalInfo(additionalInfo.toString());
|
.setAdditionalInfo(additionalInfo.toString());
|
||||||
|
|
||||||
|
// 会话添加充电桩编码
|
||||||
|
tcpSession.addPileCode(pileCode);
|
||||||
|
|
||||||
|
// 注册前置会话
|
||||||
|
ctx.getProtocolSessionRegistryProvider().register(tcpSession);
|
||||||
|
|
||||||
// 转发到后端
|
// 转发到后端
|
||||||
UplinkQueueMessage gunRunStatusMessage = uplinkMessageBuilder(pileCode, tcpSession, yunKuaiChongUplinkMessage)
|
UplinkQueueMessage gunRunStatusMessage = uplinkMessageBuilder(pileCode, tcpSession, yunKuaiChongUplinkMessage)
|
||||||
.setGunRunStatusProto(gunRunStatusProtoBuilder)
|
.setGunRunStatusProto(gunRunStatusProtoBuilder)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
import React, {useEffect, useState} from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import {useNavigate, useParams, useSearchParams} from 'react-router-dom';
|
import {useNavigate, useParams, useSearchParams} from 'react-router-dom';
|
||||||
import {Alert, Breadcrumb, Button, Card, Descriptions, Divider, message, Space, Spin, Typography} from 'antd';
|
import {Alert, Breadcrumb, Button, Card, Descriptions, Divider, message, Space, Spin, Typography} from 'antd';
|
||||||
import {ArrowLeftOutlined, BugOutlined, HomeOutlined, PlayCircleOutlined} from '@ant-design/icons';
|
import {ArrowLeftOutlined, BugOutlined, CopyOutlined, HomeOutlined, PlayCircleOutlined} from '@ant-design/icons';
|
||||||
import {Gun} from '../types';
|
import {Gun} from '../types';
|
||||||
import * as gunService from '../services/gunService';
|
import * as gunService from '../services/gunService';
|
||||||
import {api, getErrorMessage} from '../services/api';
|
import {api, getErrorMessage} from '../services/api';
|
||||||
@@ -91,6 +91,47 @@ const GunDebug: React.FC = () => {
|
|||||||
navigate(returnUrl);
|
navigate(returnUrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取完整的请求头信息(类似Swagger)
|
||||||
|
const getCompleteHeaders = () => {
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
const headers: Record<string, string> = {
|
||||||
|
'Accept': 'application/json;charset=UTF-8',
|
||||||
|
'Content-Type': 'application/json;charset=UTF-8',
|
||||||
|
};
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
headers['Authorization'] = `Bearer ${token}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 生成curl命令(类似Swagger UI)
|
||||||
|
const generateCurlCommand = (url: string, method: string, headers: Record<string, string>, requestBody: any) => {
|
||||||
|
let curlCommand = `curl -X ${method} "${url}"`;
|
||||||
|
|
||||||
|
// 添加请求头
|
||||||
|
Object.entries(headers).forEach(([key, value]) => {
|
||||||
|
curlCommand += ` \\\n -H "${key}: ${value}"`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加请求体(如果有)
|
||||||
|
if (requestBody && method !== 'GET') {
|
||||||
|
curlCommand += ` \\\n -d '${JSON.stringify(requestBody)}'`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return curlCommand;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 复制curl命令到剪贴板
|
||||||
|
const copyCurlCommand = (curlCommand: string) => {
|
||||||
|
navigator.clipboard.writeText(curlCommand).then(() => {
|
||||||
|
message.success('cURL命令已复制到剪贴板');
|
||||||
|
}).catch(() => {
|
||||||
|
message.error('复制失败,请手动复制');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 执行充电枪状态查询调试
|
// 执行充电枪状态查询调试
|
||||||
const handleDebugGunStatus = async () => {
|
const handleDebugGunStatus = async () => {
|
||||||
if (!gun) return;
|
if (!gun) return;
|
||||||
@@ -98,16 +139,16 @@ const GunDebug: React.FC = () => {
|
|||||||
// 清除充电桩调试结果,只显示充电枪调试结果
|
// 清除充电桩调试结果,只显示充电枪调试结果
|
||||||
setPileDebugResult(null);
|
setPileDebugResult(null);
|
||||||
setDebugLoading(true);
|
setDebugLoading(true);
|
||||||
try {
|
|
||||||
const headers = {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
};
|
|
||||||
|
|
||||||
|
const fullUrl = `${api.defaults.baseURL}/api/guns/status/${gun.gunCode}`;
|
||||||
|
const headers = getCompleteHeaders();
|
||||||
|
|
||||||
|
try {
|
||||||
// 直接调用现有的正确API接口
|
// 直接调用现有的正确API接口
|
||||||
const response = await api.get(`/api/guns/status/${gun.gunCode}`);
|
const response = await api.get(`/api/guns/status/${gun.gunCode}`);
|
||||||
|
|
||||||
setDebugResult({
|
setDebugResult({
|
||||||
url: `/api/guns/status/${gun.gunCode}`,
|
url: fullUrl,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers,
|
headers,
|
||||||
requestBody: null,
|
requestBody: null,
|
||||||
@@ -123,9 +164,9 @@ const GunDebug: React.FC = () => {
|
|||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const errorResult = {
|
const errorResult = {
|
||||||
url: `/api/guns/status/${gun.gunCode}`,
|
url: fullUrl,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers,
|
||||||
requestBody: null,
|
requestBody: null,
|
||||||
response: {success: false, message: getErrorMessage(error)},
|
response: {success: false, message: getErrorMessage(error)},
|
||||||
timestamp: new Date().toLocaleString(),
|
timestamp: new Date().toLocaleString(),
|
||||||
@@ -149,16 +190,16 @@ const GunDebug: React.FC = () => {
|
|||||||
// 清除充电枪调试结果,只显示充电桩调试结果
|
// 清除充电枪调试结果,只显示充电桩调试结果
|
||||||
setDebugResult(null);
|
setDebugResult(null);
|
||||||
setPileDebugLoading(true);
|
setPileDebugLoading(true);
|
||||||
try {
|
|
||||||
const headers = {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
};
|
|
||||||
|
|
||||||
|
const fullUrl = `${api.defaults.baseURL}/api/piles/status/${gun.pileCode}`;
|
||||||
|
const headers = getCompleteHeaders();
|
||||||
|
|
||||||
|
try {
|
||||||
// 直接调用现有的正确API接口
|
// 直接调用现有的正确API接口
|
||||||
const response = await api.get(`/api/piles/status/${gun.pileCode}`);
|
const response = await api.get(`/api/piles/status/${gun.pileCode}`);
|
||||||
|
|
||||||
setPileDebugResult({
|
setPileDebugResult({
|
||||||
url: `/api/piles/status/${gun.pileCode}`,
|
url: fullUrl,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers,
|
headers,
|
||||||
requestBody: null,
|
requestBody: null,
|
||||||
@@ -174,9 +215,9 @@ const GunDebug: React.FC = () => {
|
|||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const errorResult = {
|
const errorResult = {
|
||||||
url: `/api/piles/status/${gun.pileCode}`,
|
url: fullUrl,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers,
|
||||||
requestBody: null,
|
requestBody: null,
|
||||||
response: {success: false, message: getErrorMessage(error)},
|
response: {success: false, message: getErrorMessage(error)},
|
||||||
timestamp: new Date().toLocaleString(),
|
timestamp: new Date().toLocaleString(),
|
||||||
@@ -302,6 +343,30 @@ const GunDebug: React.FC = () => {
|
|||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
</Descriptions>
|
</Descriptions>
|
||||||
|
|
||||||
|
<Divider orientation="left">
|
||||||
|
cURL 命令
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
icon={<CopyOutlined/>}
|
||||||
|
onClick={() => copyCurlCommand(generateCurlCommand(debugResult.url, debugResult.method, debugResult.headers, debugResult.requestBody))}
|
||||||
|
style={{marginLeft: 8}}
|
||||||
|
>
|
||||||
|
复制
|
||||||
|
</Button>
|
||||||
|
</Divider>
|
||||||
|
<pre style={{
|
||||||
|
background: '#1f1f1f',
|
||||||
|
color: '#f8f8f2',
|
||||||
|
padding: 12,
|
||||||
|
borderRadius: 4,
|
||||||
|
fontSize: 12,
|
||||||
|
overflow: 'auto',
|
||||||
|
fontFamily: 'Monaco, Menlo, "Ubuntu Mono", monospace'
|
||||||
|
}}>
|
||||||
|
{generateCurlCommand(debugResult.url, debugResult.method, debugResult.headers, debugResult.requestBody)}
|
||||||
|
</pre>
|
||||||
|
|
||||||
<Divider orientation="left">请求头 (Headers)</Divider>
|
<Divider orientation="left">请求头 (Headers)</Divider>
|
||||||
<pre style={{
|
<pre style={{
|
||||||
background: '#f5f5f5',
|
background: '#f5f5f5',
|
||||||
@@ -321,7 +386,7 @@ const GunDebug: React.FC = () => {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
overflow: 'auto'
|
overflow: 'auto'
|
||||||
}}>
|
}}>
|
||||||
{JSON.stringify(debugResult.requestBody, null, 2)}
|
{debugResult.requestBody ? JSON.stringify(debugResult.requestBody, null, 2) : 'null'}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<Divider orientation="left">响应结果 (Response)</Divider>
|
<Divider orientation="left">响应结果 (Response)</Divider>
|
||||||
@@ -361,6 +426,30 @@ const GunDebug: React.FC = () => {
|
|||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
</Descriptions>
|
</Descriptions>
|
||||||
|
|
||||||
|
<Divider orientation="left">
|
||||||
|
cURL 命令
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
icon={<CopyOutlined/>}
|
||||||
|
onClick={() => copyCurlCommand(generateCurlCommand(pileDebugResult.url, pileDebugResult.method, pileDebugResult.headers, pileDebugResult.requestBody))}
|
||||||
|
style={{marginLeft: 8}}
|
||||||
|
>
|
||||||
|
复制
|
||||||
|
</Button>
|
||||||
|
</Divider>
|
||||||
|
<pre style={{
|
||||||
|
background: '#1f1f1f',
|
||||||
|
color: '#f8f8f2',
|
||||||
|
padding: 12,
|
||||||
|
borderRadius: 4,
|
||||||
|
fontSize: 12,
|
||||||
|
overflow: 'auto',
|
||||||
|
fontFamily: 'Monaco, Menlo, "Ubuntu Mono", monospace'
|
||||||
|
}}>
|
||||||
|
{generateCurlCommand(pileDebugResult.url, pileDebugResult.method, pileDebugResult.headers, pileDebugResult.requestBody)}
|
||||||
|
</pre>
|
||||||
|
|
||||||
<Divider orientation="left">请求头 (Headers)</Divider>
|
<Divider orientation="left">请求头 (Headers)</Divider>
|
||||||
<pre style={{
|
<pre style={{
|
||||||
background: '#f5f5f5',
|
background: '#f5f5f5',
|
||||||
@@ -380,7 +469,7 @@ const GunDebug: React.FC = () => {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
overflow: 'auto'
|
overflow: 'auto'
|
||||||
}}>
|
}}>
|
||||||
{JSON.stringify(pileDebugResult.requestBody, null, 2)}
|
{pileDebugResult.requestBody ? JSON.stringify(pileDebugResult.requestBody, null, 2) : 'null'}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<Divider orientation="left">响应结果 (Response)</Divider>
|
<Divider orientation="left">响应结果 (Response)</Divider>
|
||||||
|
|||||||
@@ -597,6 +597,13 @@ const GunManagement: React.FC = () => {
|
|||||||
updateSearchParams(newParams);
|
updateSearchParams(newParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 刷新数据
|
||||||
|
const handleRefresh = () => {
|
||||||
|
// 使用当前的搜索参数重新加载数据
|
||||||
|
updateSearchParams({...searchParams});
|
||||||
|
setSelectedRowKeys([]);
|
||||||
|
};
|
||||||
|
|
||||||
// 显示新建模态框
|
// 显示新建模态框
|
||||||
const showCreateModal = () => {
|
const showCreateModal = () => {
|
||||||
setIsEdit(false);
|
setIsEdit(false);
|
||||||
@@ -942,20 +949,30 @@ const GunManagement: React.FC = () => {
|
|||||||
<Card
|
<Card
|
||||||
title="充电枪列表"
|
title="充电枪列表"
|
||||||
extra={
|
extra={
|
||||||
<Dropdown
|
<Space size="small">
|
||||||
menu={columnSelectorMenu}
|
<Button
|
||||||
placement="bottomRight"
|
icon={<ReloadOutlined/>}
|
||||||
trigger={['click']}
|
type="text"
|
||||||
overlayStyle={{ minWidth: 180 }}
|
size="small"
|
||||||
>
|
style={{padding: '4px 8px'}}
|
||||||
<Button
|
title="刷新数据"
|
||||||
icon={<TableOutlined />}
|
onClick={handleRefresh}
|
||||||
type="text"
|
/>
|
||||||
size="small"
|
<Dropdown
|
||||||
style={{ padding: '4px 8px' }}
|
menu={columnSelectorMenu}
|
||||||
title="自定义列"
|
placement="bottomRight"
|
||||||
/>
|
trigger={['click']}
|
||||||
</Dropdown>
|
overlayStyle={{minWidth: 180}}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
icon={<TableOutlined/>}
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
style={{padding: '4px 8px'}}
|
||||||
|
title="自定义列"
|
||||||
|
/>
|
||||||
|
</Dropdown>
|
||||||
|
</Space>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
Tag,
|
Tag,
|
||||||
Typography
|
Typography
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import {DeleteOutlined, PlusOutlined, TableOutlined} from '@ant-design/icons';
|
import {DeleteOutlined, PlusOutlined, ReloadOutlined, TableOutlined} from '@ant-design/icons';
|
||||||
import type {ColumnsType, TableProps} from 'antd/es/table';
|
import type {ColumnsType, TableProps} from 'antd/es/table';
|
||||||
import {pileService} from '../services/pileService';
|
import {pileService} from '../services/pileService';
|
||||||
import * as stationService from '../services/stationService';
|
import * as stationService from '../services/stationService';
|
||||||
@@ -585,6 +585,13 @@ const PileManagement: React.FC = () => {
|
|||||||
setSearchParams(newParams);
|
setSearchParams(newParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 刷新数据
|
||||||
|
const handleRefresh = () => {
|
||||||
|
// 使用当前的搜索参数重新加载数据
|
||||||
|
setSearchParams({...searchParams});
|
||||||
|
setSelectedRowKeys([]);
|
||||||
|
};
|
||||||
|
|
||||||
// 显示新建Modal
|
// 显示新建Modal
|
||||||
const showCreateModal = async () => {
|
const showCreateModal = async () => {
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
@@ -969,20 +976,30 @@ const PileManagement: React.FC = () => {
|
|||||||
<Card
|
<Card
|
||||||
title="充电桩列表"
|
title="充电桩列表"
|
||||||
extra={
|
extra={
|
||||||
<Dropdown
|
<Space size="small">
|
||||||
menu={columnSelectorMenu}
|
<Button
|
||||||
placement="bottomRight"
|
icon={<ReloadOutlined/>}
|
||||||
trigger={['click']}
|
type="text"
|
||||||
overlayStyle={{ minWidth: 180 }}
|
size="small"
|
||||||
>
|
style={{padding: '4px 8px'}}
|
||||||
<Button
|
title="刷新数据"
|
||||||
icon={<TableOutlined />}
|
onClick={handleRefresh}
|
||||||
type="text"
|
/>
|
||||||
size="small"
|
<Dropdown
|
||||||
style={{ padding: '4px 8px' }}
|
menu={columnSelectorMenu}
|
||||||
title="自定义列"
|
placement="bottomRight"
|
||||||
/>
|
trigger={['click']}
|
||||||
</Dropdown>
|
overlayStyle={{minWidth: 180}}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
icon={<TableOutlined/>}
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
style={{padding: '4px 8px'}}
|
||||||
|
title="自定义列"
|
||||||
|
/>
|
||||||
|
</Dropdown>
|
||||||
|
</Space>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
|
|||||||
@@ -505,6 +505,13 @@ const StationManagement: React.FC = () => {
|
|||||||
setSearchParams(newParams);
|
setSearchParams(newParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 刷新数据
|
||||||
|
const handleRefresh = () => {
|
||||||
|
// 使用当前的搜索参数重新加载数据
|
||||||
|
setSearchParams({...searchParams});
|
||||||
|
setSelectedRowKeys([]);
|
||||||
|
};
|
||||||
|
|
||||||
// 显示创建模态框
|
// 显示创建模态框
|
||||||
const showCreateModal = () => {
|
const showCreateModal = () => {
|
||||||
setIsEdit(false);
|
setIsEdit(false);
|
||||||
@@ -929,20 +936,30 @@ const StationManagement: React.FC = () => {
|
|||||||
<Card
|
<Card
|
||||||
title="充电站列表"
|
title="充电站列表"
|
||||||
extra={
|
extra={
|
||||||
<Dropdown
|
<Space size="small">
|
||||||
menu={columnSelectorMenu}
|
<Button
|
||||||
placement="bottomRight"
|
icon={<ReloadOutlined/>}
|
||||||
trigger={['click']}
|
type="text"
|
||||||
overlayStyle={{ minWidth: 180 }}
|
size="small"
|
||||||
>
|
style={{padding: '4px 8px'}}
|
||||||
<Button
|
title="刷新数据"
|
||||||
icon={<TableOutlined />}
|
onClick={handleRefresh}
|
||||||
type="text"
|
/>
|
||||||
size="small"
|
<Dropdown
|
||||||
style={{ padding: '4px 8px' }}
|
menu={columnSelectorMenu}
|
||||||
title="自定义列"
|
placement="bottomRight"
|
||||||
/>
|
trigger={['click']}
|
||||||
</Dropdown>
|
overlayStyle={{minWidth: 180}}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
icon={<TableOutlined/>}
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
style={{padding: '4px 8px'}}
|
||||||
|
title="自定义列"
|
||||||
|
/>
|
||||||
|
</Dropdown>
|
||||||
|
</Space>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
|
|||||||
Reference in New Issue
Block a user