mirror of
https://gitee.com/san-bing/JChargePointProtocol
synced 2026-05-05 02:19:56 +08:00
充电枪编辑功能
This commit is contained in:
@@ -16,6 +16,7 @@ import sanbing.jcpp.app.adapter.request.StationUpdateRequest;
|
|||||||
import sanbing.jcpp.app.adapter.response.ApiResponse;
|
import sanbing.jcpp.app.adapter.response.ApiResponse;
|
||||||
import sanbing.jcpp.app.adapter.response.PageResponse;
|
import sanbing.jcpp.app.adapter.response.PageResponse;
|
||||||
import sanbing.jcpp.app.adapter.response.StationOption;
|
import sanbing.jcpp.app.adapter.response.StationOption;
|
||||||
|
import sanbing.jcpp.app.adapter.response.StationPileCascaderOption;
|
||||||
import sanbing.jcpp.app.dal.entity.Station;
|
import sanbing.jcpp.app.dal.entity.Station;
|
||||||
import sanbing.jcpp.app.exception.JCPPException;
|
import sanbing.jcpp.app.exception.JCPPException;
|
||||||
import sanbing.jcpp.app.service.StationService;
|
import sanbing.jcpp.app.service.StationService;
|
||||||
@@ -104,4 +105,14 @@ public class StationController extends BaseController {
|
|||||||
List<StationOption> options = stationService.searchStationOptions(keyword, page, size);
|
List<StationOption> options = stationService.searchStationOptions(keyword, page, size);
|
||||||
return ResponseEntity.ok(ApiResponse.success("查询成功", options));
|
return ResponseEntity.ok(ApiResponse.success("查询成功", options));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取充电站-充电桩级联选择器数据(用于级联选择组件)
|
||||||
|
*/
|
||||||
|
@GetMapping("/pile-cascader")
|
||||||
|
public ResponseEntity<ApiResponse<List<StationPileCascaderOption>>> getStationPileCascaderOptions(
|
||||||
|
@RequestParam(required = false) String keyword) {
|
||||||
|
List<StationPileCascaderOption> options = stationService.getStationPileCascaderOptions(keyword);
|
||||||
|
return ResponseEntity.ok(ApiResponse.success("查询成功", options));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,5 +18,18 @@ public class GunUpdateRequest {
|
|||||||
@NoXss
|
@NoXss
|
||||||
private String gunName;
|
private String gunName;
|
||||||
|
|
||||||
|
@NotBlank(message = "枪号不能为空")
|
||||||
|
private String gunNo;
|
||||||
|
|
||||||
|
@NotBlank(message = "充电枪编码不能为空")
|
||||||
|
@NoXss
|
||||||
|
private String gunCode;
|
||||||
|
|
||||||
|
@NotBlank(message = "所属充电站不能为空")
|
||||||
|
private String stationId;
|
||||||
|
|
||||||
|
@NotBlank(message = "所属充电桩不能为空")
|
||||||
|
private String pileId;
|
||||||
|
|
||||||
private GunRunStatusEnum runStatus;
|
private GunRunStatusEnum runStatus;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||||
|
* 微信:mohan_88888
|
||||||
|
* 抖音:程序员三丙
|
||||||
|
* 付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||||
|
*/
|
||||||
|
package sanbing.jcpp.app.adapter.response;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 充电站-充电桩级联选择器选项响应
|
||||||
|
* 用于Ant Design Cascader组件
|
||||||
|
*
|
||||||
|
* @author 九筒
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class StationPileCascaderOption {
|
||||||
|
|
||||||
|
private String value; // 选项的值(充电站ID或充电桩ID)
|
||||||
|
private String label; // 显示的标签
|
||||||
|
private boolean isLeaf; // 是否为叶子节点
|
||||||
|
private List<StationPileCascaderOption> children; // 子选项(充电站下的充电桩)
|
||||||
|
|
||||||
|
// 额外信息
|
||||||
|
private String stationId; // 充电站ID(当是充电桩选项时)
|
||||||
|
private String stationName; // 充电站名称
|
||||||
|
private String stationCode; // 充电站编码
|
||||||
|
private String pileId; // 充电桩ID(当是充电桩选项时)
|
||||||
|
private String pileName; // 充电桩名称(当是充电桩选项时)
|
||||||
|
private String pileCode; // 充电桩编码(当是充电桩选项时)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建充电站选项
|
||||||
|
*/
|
||||||
|
public static StationPileCascaderOption createStationOption(UUID stationId, String stationName, String stationCode, List<StationPileCascaderOption> piles) {
|
||||||
|
StationPileCascaderOption option = new StationPileCascaderOption();
|
||||||
|
option.setValue(stationId.toString());
|
||||||
|
option.setLabel(stationName + " (" + stationCode + ")");
|
||||||
|
option.setLeaf(false);
|
||||||
|
option.setChildren(piles);
|
||||||
|
option.setStationId(stationId.toString());
|
||||||
|
option.setStationName(stationName);
|
||||||
|
option.setStationCode(stationCode);
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建充电桩选项
|
||||||
|
*/
|
||||||
|
public static StationPileCascaderOption createPileOption(UUID stationId, String stationName, String stationCode,
|
||||||
|
UUID pileId, String pileName, String pileCode) {
|
||||||
|
StationPileCascaderOption option = new StationPileCascaderOption();
|
||||||
|
option.setValue(pileId.toString());
|
||||||
|
option.setLabel(pileName + " (" + pileCode + ")");
|
||||||
|
option.setLeaf(true);
|
||||||
|
option.setChildren(null);
|
||||||
|
option.setStationId(stationId.toString());
|
||||||
|
option.setStationName(stationName);
|
||||||
|
option.setStationCode(stationCode);
|
||||||
|
option.setPileId(pileId.toString());
|
||||||
|
option.setPileName(pileName);
|
||||||
|
option.setPileCode(pileCode);
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import sanbing.jcpp.app.adapter.request.StationQueryRequest;
|
|||||||
import sanbing.jcpp.app.adapter.request.StationUpdateRequest;
|
import sanbing.jcpp.app.adapter.request.StationUpdateRequest;
|
||||||
import sanbing.jcpp.app.adapter.response.PageResponse;
|
import sanbing.jcpp.app.adapter.response.PageResponse;
|
||||||
import sanbing.jcpp.app.adapter.response.StationOption;
|
import sanbing.jcpp.app.adapter.response.StationOption;
|
||||||
|
import sanbing.jcpp.app.adapter.response.StationPileCascaderOption;
|
||||||
import sanbing.jcpp.app.dal.entity.Station;
|
import sanbing.jcpp.app.dal.entity.Station;
|
||||||
import sanbing.jcpp.app.exception.JCPPException;
|
import sanbing.jcpp.app.exception.JCPPException;
|
||||||
|
|
||||||
@@ -58,4 +59,9 @@ public interface StationService {
|
|||||||
* 搜索充电站选项列表(支持关键字搜索和分页)
|
* 搜索充电站选项列表(支持关键字搜索和分页)
|
||||||
*/
|
*/
|
||||||
List<StationOption> searchStationOptions(String keyword, int page, int size);
|
List<StationOption> searchStationOptions(String keyword, int page, int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取充电站-充电桩级联选择器数据(用于级联选择组件)
|
||||||
|
*/
|
||||||
|
List<StationPileCascaderOption> getStationPileCascaderOptions(String keyword);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,10 +86,10 @@ public class DefaultGunService implements GunService {
|
|||||||
.createdTime(existingGun.getCreatedTime())
|
.createdTime(existingGun.getCreatedTime())
|
||||||
.updatedTime(LocalDateTime.now()) // 更新时设置更新时间
|
.updatedTime(LocalDateTime.now()) // 更新时设置更新时间
|
||||||
.gunName(request.getGunName())
|
.gunName(request.getGunName())
|
||||||
.gunNo(existingGun.getGunNo()) // 编号不允许修改
|
.gunNo(request.getGunNo()) // 允许修改枪号
|
||||||
.gunCode(existingGun.getGunCode()) // 编码不允许修改
|
.gunCode(request.getGunCode()) // 允许修改编码
|
||||||
.stationId(existingGun.getStationId()) // 所属充电站不允许修改
|
.stationId(UUID.fromString(request.getStationId())) // 允许修改所属充电站
|
||||||
.pileId(existingGun.getPileId()) // 所属充电桩不允许修改
|
.pileId(UUID.fromString(request.getPileId())) // 允许修改所属充电桩
|
||||||
.additionalInfo(existingGun.getAdditionalInfo())
|
.additionalInfo(existingGun.getAdditionalInfo())
|
||||||
.version(existingGun.getVersion())
|
.version(existingGun.getVersion())
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import sanbing.jcpp.app.adapter.request.StationQueryRequest;
|
|||||||
import sanbing.jcpp.app.adapter.request.StationUpdateRequest;
|
import sanbing.jcpp.app.adapter.request.StationUpdateRequest;
|
||||||
import sanbing.jcpp.app.adapter.response.PageResponse;
|
import sanbing.jcpp.app.adapter.response.PageResponse;
|
||||||
import sanbing.jcpp.app.adapter.response.StationOption;
|
import sanbing.jcpp.app.adapter.response.StationOption;
|
||||||
|
import sanbing.jcpp.app.adapter.response.StationPileCascaderOption;
|
||||||
|
import sanbing.jcpp.app.dal.entity.Pile;
|
||||||
import sanbing.jcpp.app.dal.entity.Station;
|
import sanbing.jcpp.app.dal.entity.Station;
|
||||||
import sanbing.jcpp.app.dal.mapper.PileMapper;
|
import sanbing.jcpp.app.dal.mapper.PileMapper;
|
||||||
import sanbing.jcpp.app.dal.mapper.StationMapper;
|
import sanbing.jcpp.app.dal.mapper.StationMapper;
|
||||||
@@ -27,6 +29,7 @@ import sanbing.jcpp.infrastructure.util.jackson.JacksonUtil;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -190,4 +193,55 @@ public class DefaultStationService implements StationService {
|
|||||||
))
|
))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<StationPileCascaderOption> getStationPileCascaderOptions(String keyword) {
|
||||||
|
// 查询充电站
|
||||||
|
QueryWrapper<Station> stationWrapper = new QueryWrapper<>();
|
||||||
|
stationWrapper.select("id", "station_name", "station_code");
|
||||||
|
|
||||||
|
// 如果有关键字,按站名或编码模糊搜索
|
||||||
|
if (StringUtils.hasText(keyword)) {
|
||||||
|
stationWrapper.and(w -> w.like("station_name", keyword)
|
||||||
|
.or()
|
||||||
|
.like("station_code", keyword));
|
||||||
|
}
|
||||||
|
|
||||||
|
stationWrapper.orderByAsc("station_name");
|
||||||
|
List<Station> stations = stationMapper.selectList(stationWrapper);
|
||||||
|
|
||||||
|
if (stations.isEmpty()) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询所有充电桩
|
||||||
|
QueryWrapper<Pile> pileWrapper = new QueryWrapper<>();
|
||||||
|
pileWrapper.select("id", "pile_name", "pile_code", "station_id")
|
||||||
|
.in("station_id", stations.stream().map(Station::getId).collect(Collectors.toList()))
|
||||||
|
.orderByAsc("pile_name");
|
||||||
|
|
||||||
|
List<Pile> piles = pileMapper.selectList(pileWrapper);
|
||||||
|
|
||||||
|
// 按充电站ID分组充电桩
|
||||||
|
Map<UUID, List<Pile>> pilesByStation = piles.stream()
|
||||||
|
.collect(Collectors.groupingBy(Pile::getStationId));
|
||||||
|
|
||||||
|
// 构建级联选择器数据
|
||||||
|
return stations.stream()
|
||||||
|
.map(station -> {
|
||||||
|
List<Pile> stationPiles = pilesByStation.getOrDefault(station.getId(), List.of());
|
||||||
|
|
||||||
|
List<StationPileCascaderOption> pileOptions = stationPiles.stream()
|
||||||
|
.map(pile -> StationPileCascaderOption.createPileOption(
|
||||||
|
station.getId(), station.getStationName(), station.getStationCode(),
|
||||||
|
pile.getId(), pile.getPileName(), pile.getPileCode()
|
||||||
|
))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return StationPileCascaderOption.createStationOption(
|
||||||
|
station.getId(), station.getStationName(), station.getStationCode(), pileOptions
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import React, {useEffect, useMemo, useState} from 'react';
|
|||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
|
Cascader,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Col,
|
Col,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
@@ -29,7 +30,7 @@ import {getErrorMessage} from '../services/api';
|
|||||||
import * as gunService from '../services/gunService';
|
import * as gunService from '../services/gunService';
|
||||||
import * as stationService from '../services/stationService';
|
import * as stationService from '../services/stationService';
|
||||||
import {pileService} from '../services/pileService';
|
import {pileService} from '../services/pileService';
|
||||||
import type {Gun, GunCreateRequest, PileOption, StationOption} from '../types';
|
import type {Gun, GunCreateRequest, GunUpdateRequest, PileOption, StationOption} from '../types';
|
||||||
|
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ const GunManagement: React.FC = () => {
|
|||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [stationOptions, setStationOptions] = useState<StationOption[]>([]);
|
const [stationOptions, setStationOptions] = useState<StationOption[]>([]);
|
||||||
const [pileOptions, setPileOptions] = useState<PileOption[]>([]);
|
const [pileOptions, setPileOptions] = useState<PileOption[]>([]);
|
||||||
|
const [cascaderOptions, setCascaderOptions] = useState<any[]>([]);
|
||||||
const [modalVisible, setModalVisible] = useState(false);
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
const [modalLoading, setModalLoading] = useState(false);
|
const [modalLoading, setModalLoading] = useState(false);
|
||||||
const [isEdit, setIsEdit] = useState(false);
|
const [isEdit, setIsEdit] = useState(false);
|
||||||
@@ -236,9 +238,6 @@ const GunManagement: React.FC = () => {
|
|||||||
<Button type="link" size="small" onClick={() => handleEdit(record)}>
|
<Button type="link" size="small" onClick={() => handleEdit(record)}>
|
||||||
编辑
|
编辑
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="link" size="small" onClick={() => handleView(record)}>
|
|
||||||
查看
|
|
||||||
</Button>
|
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title="确认删除充电枪"
|
title="确认删除充电枪"
|
||||||
description={
|
description={
|
||||||
@@ -429,6 +428,16 @@ const GunManagement: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 加载级联选择器数据
|
||||||
|
const loadCascaderOptions = async () => {
|
||||||
|
try {
|
||||||
|
const response = await stationService.getStationPileCascaderOptions();
|
||||||
|
setCascaderOptions(Array.isArray(response) ? response : []);
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('加载级联选择器数据失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 监听搜索参数变化
|
// 监听搜索参数变化
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadData();
|
loadData();
|
||||||
@@ -439,6 +448,7 @@ const GunManagement: React.FC = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadStationOptions();
|
loadStationOptions();
|
||||||
loadPileOptions();
|
loadPileOptions();
|
||||||
|
loadCascaderOptions();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// 处理表格变化
|
// 处理表格变化
|
||||||
@@ -496,25 +506,23 @@ const GunManagement: React.FC = () => {
|
|||||||
setModalVisible(true);
|
setModalVisible(true);
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
...record,
|
...record,
|
||||||
gunNo: record.gunNo.toString()
|
gunNo: record.gunNo,
|
||||||
|
stationPile: [record.stationId, record.pileId] // 设置级联选择器的值
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理查看
|
|
||||||
const handleView = (record: Gun) => {
|
|
||||||
showMessage.info('查看功能待实现');
|
|
||||||
};
|
|
||||||
|
|
||||||
// 生成充电枪编码
|
// 生成充电枪编码
|
||||||
const handleGenerateGunCode = () => {
|
const handleGenerateGunCode = () => {
|
||||||
const pileId = form.getFieldValue('pileId');
|
const stationPile = form.getFieldValue('stationPile');
|
||||||
const gunNo = form.getFieldValue('gunNo');
|
const gunNo = form.getFieldValue('gunNo');
|
||||||
|
|
||||||
if (!pileId || !gunNo) {
|
if (!stationPile || stationPile.length !== 2 || !gunNo) {
|
||||||
showMessage.warning('请先选择充电桩和填写枪号');
|
showMessage.warning('请先选择充电站和充电桩,并填写枪号');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pileId = stationPile[1];
|
||||||
const selectedPile = pileOptions.find(p => p.id === pileId);
|
const selectedPile = pileOptions.find(p => p.id === pileId);
|
||||||
if (selectedPile) {
|
if (selectedPile) {
|
||||||
const code = generateGunCode(selectedPile.pileCode, gunNo);
|
const code = generateGunCode(selectedPile.pileCode, gunNo);
|
||||||
@@ -529,16 +537,38 @@ const GunManagement: React.FC = () => {
|
|||||||
setModalLoading(true);
|
setModalLoading(true);
|
||||||
|
|
||||||
if (isEdit && currentRecord) {
|
if (isEdit && currentRecord) {
|
||||||
// 编辑功能待实现
|
// 编辑充电枪
|
||||||
showMessage.info('编辑功能待实现');
|
// 从级联选择器值中获取充电站ID和充电桩ID
|
||||||
|
const cascaderValue = values.stationPile;
|
||||||
|
if (!cascaderValue || cascaderValue.length !== 2) {
|
||||||
|
showMessage.error('请选择充电站和充电桩');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateData: GunUpdateRequest = {
|
||||||
|
gunName: values.gunName,
|
||||||
|
gunNo: values.gunNo,
|
||||||
|
gunCode: values.gunCode,
|
||||||
|
stationId: cascaderValue[0], // 充电站ID
|
||||||
|
pileId: cascaderValue[1] // 充电桩ID
|
||||||
|
};
|
||||||
|
await gunService.updateGun(currentRecord.id, updateData);
|
||||||
|
showMessage.success('充电枪更新成功');
|
||||||
} else {
|
} else {
|
||||||
// 新建充电枪
|
// 新建充电枪
|
||||||
|
// 从级联选择器值中获取充电站ID和充电桩ID
|
||||||
|
const cascaderValue = values.stationPile;
|
||||||
|
if (!cascaderValue || cascaderValue.length !== 2) {
|
||||||
|
showMessage.error('请选择充电站和充电桩');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const createData: GunCreateRequest = {
|
const createData: GunCreateRequest = {
|
||||||
gunName: values.gunName,
|
gunName: values.gunName,
|
||||||
gunNo: values.gunNo,
|
gunNo: values.gunNo,
|
||||||
gunCode: values.gunCode,
|
gunCode: values.gunCode,
|
||||||
stationId: values.stationId,
|
stationId: cascaderValue[0], // 充电站ID
|
||||||
pileId: values.pileId
|
pileId: cascaderValue[1] // 充电桩ID
|
||||||
};
|
};
|
||||||
await gunService.createGun(createData);
|
await gunService.createGun(createData);
|
||||||
showMessage.success('充电枪创建成功');
|
showMessage.success('充电枪创建成功');
|
||||||
@@ -870,52 +900,25 @@ const GunManagement: React.FC = () => {
|
|||||||
<Input placeholder="请输入充电枪名称" />
|
<Input placeholder="请输入充电枪名称" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Row gutter={16}>
|
<Form.Item
|
||||||
<Col span={12}>
|
label="所属充电站/充电桩"
|
||||||
<Form.Item
|
name="stationPile"
|
||||||
label="所属充电站"
|
rules={[{ required: true, message: '请选择充电站和充电桩' }]}
|
||||||
name="stationId"
|
>
|
||||||
rules={[{ required: true, message: '请选择充电站' }]}
|
<Cascader
|
||||||
>
|
options={cascaderOptions}
|
||||||
<Select
|
placeholder="请选择充电站和充电桩"
|
||||||
placeholder="请选择充电站"
|
showSearch={{
|
||||||
showSearch
|
filter: (inputValue, path) =>
|
||||||
allowClear
|
path.some(option =>
|
||||||
filterOption={(input, option) =>
|
option.label.toLowerCase().includes(inputValue.toLowerCase())
|
||||||
(option?.children as unknown as string)?.toLowerCase().includes(input.toLowerCase())
|
)
|
||||||
}
|
}}
|
||||||
>
|
disabled={false}
|
||||||
{stationOptions.map(station => (
|
changeOnSelect={false}
|
||||||
<Select.Option key={station.id} value={station.id}>
|
expandTrigger="hover"
|
||||||
{station.label}
|
/>
|
||||||
</Select.Option>
|
</Form.Item>
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
<Col span={12}>
|
|
||||||
<Form.Item
|
|
||||||
label="所属充电桩"
|
|
||||||
name="pileId"
|
|
||||||
rules={[{ required: true, message: '请选择充电桩' }]}
|
|
||||||
>
|
|
||||||
<Select
|
|
||||||
placeholder="请选择充电桩"
|
|
||||||
showSearch
|
|
||||||
allowClear
|
|
||||||
filterOption={(input, option) =>
|
|
||||||
(option?.children as unknown as string)?.toLowerCase().includes(input.toLowerCase())
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{pileOptions.map(pile => (
|
|
||||||
<Select.Option key={pile.id} value={pile.id}>
|
|
||||||
{pile.label}
|
|
||||||
</Select.Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
@@ -935,13 +938,13 @@ const GunManagement: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
placeholder="请输入充电枪编码"
|
placeholder="请输入充电枪编码"
|
||||||
disabled={isEdit}
|
disabled={false}
|
||||||
suffix={
|
suffix={
|
||||||
<Button
|
<Button
|
||||||
type="link"
|
type="link"
|
||||||
size="small"
|
size="small"
|
||||||
onClick={handleGenerateGunCode}
|
onClick={handleGenerateGunCode}
|
||||||
disabled={isEdit}
|
disabled={false}
|
||||||
style={{
|
style={{
|
||||||
height: '24px',
|
height: '24px',
|
||||||
lineHeight: '24px',
|
lineHeight: '24px',
|
||||||
|
|||||||
@@ -299,9 +299,6 @@ const PileManagement: React.FC = () => {
|
|||||||
<Button type="link" size="small" onClick={() => handleEdit(record)} style={{ padding: '0 4px' }}>
|
<Button type="link" size="small" onClick={() => handleEdit(record)} style={{ padding: '0 4px' }}>
|
||||||
编辑
|
编辑
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="link" size="small" onClick={() => handleView(record)} style={{ padding: '0 4px' }}>
|
|
||||||
查看
|
|
||||||
</Button>
|
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title="确认删除充电桩"
|
title="确认删除充电桩"
|
||||||
description={
|
description={
|
||||||
@@ -597,11 +594,6 @@ const PileManagement: React.FC = () => {
|
|||||||
setModalVisible(true);
|
setModalVisible(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 查看充电桩详情
|
|
||||||
const handleView = (record: Pile) => {
|
|
||||||
console.log('查看充电桩详情:', record);
|
|
||||||
showMessage.info('查看功能暂未实现,请查看控制台日志');
|
|
||||||
};
|
|
||||||
|
|
||||||
// 生成充电桩编码
|
// 生成充电桩编码
|
||||||
const handleGeneratePileCode = () => {
|
const handleGeneratePileCode = () => {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* 付费课程知识星球:https://t.zsxq.com/aKtXo
|
* 付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||||
*/
|
*/
|
||||||
import {api} from './api';
|
import {api} from './api';
|
||||||
import type {Gun, GunCreateRequest, PageResponse, QueryParams} from '../types';
|
import type {Gun, GunCreateRequest, GunUpdateRequest, PageResponse, QueryParams} from '../types';
|
||||||
|
|
||||||
export const getGuns = async (params: QueryParams): Promise<PageResponse<Gun>> => {
|
export const getGuns = async (params: QueryParams): Promise<PageResponse<Gun>> => {
|
||||||
const response = await api.get('/api/guns', { params });
|
const response = await api.get('/api/guns', { params });
|
||||||
@@ -17,7 +17,7 @@ export const createGun = async (data: GunCreateRequest): Promise<Gun> => {
|
|||||||
return response.data.data;
|
return response.data.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateGun = async (id: string, data: Partial<Gun>): Promise<Gun> => {
|
export const updateGun = async (id: string, data: GunUpdateRequest): Promise<Gun> => {
|
||||||
const response = await api.put(`/api/guns/${id}`, data);
|
const response = await api.put(`/api/guns/${id}`, data);
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,3 +40,10 @@ export const getStationOptions = async (): Promise<StationOption[]> => {
|
|||||||
const response = await api.get('/api/stations/options');
|
const response = await api.get('/api/stations/options');
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取充电站-充电桩级联选择器数据
|
||||||
|
export const getStationPileCascaderOptions = async (keyword?: string): Promise<any[]> => {
|
||||||
|
const params = keyword ? { keyword } : {};
|
||||||
|
const response = await api.get('/api/stations/pile-cascader', { params });
|
||||||
|
return response.data.data;
|
||||||
|
};
|
||||||
@@ -120,7 +120,7 @@ export interface Gun {
|
|||||||
id: string;
|
id: string;
|
||||||
gunName: string;
|
gunName: string;
|
||||||
gunCode: string;
|
gunCode: string;
|
||||||
gunNo: number;
|
gunNo: string;
|
||||||
stationId: string;
|
stationId: string;
|
||||||
stationName?: string; // 所属充电站名称
|
stationName?: string; // 所属充电站名称
|
||||||
pileId: string;
|
pileId: string;
|
||||||
@@ -144,6 +144,7 @@ export interface GunCreateRequest {
|
|||||||
export interface GunUpdateRequest {
|
export interface GunUpdateRequest {
|
||||||
gunName: string;
|
gunName: string;
|
||||||
gunNo: string;
|
gunNo: string;
|
||||||
|
gunCode: string;
|
||||||
stationId: string;
|
stationId: string;
|
||||||
pileId: string;
|
pileId: string;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user