| ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/dto/FleetExcelDTO.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/dto/FleetQueryDTO.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TFleetController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TFleetService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TFleetServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| sql/20260922_fleet.sql | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/dto/FleetExcelDTO.java
New file @@ -0,0 +1,22 @@ package com.ruoyi.other.api.dto; import com.ruoyi.common.core.annotation.Excel; import lombok.Data; import java.io.Serializable; /** * 车队导入导出 Excel DTO(模板下载、导入解析、导出共用) * * @author mxcd * @since 2026-09-23 */ @Data public class FleetExcelDTO implements Serializable { private static final long serialVersionUID = 1L; @Excel(name = "车队名称", width = 24, prompt = "必填,最多128个字符") private String fleetName; @Excel(name = "所属公司", width = 24, prompt = "必填,公司名称") private String companyName; @Excel(name = "联系人", width = 16) private String contactName; @Excel(name = "联系人电话", width = 16) private String contactPhone; @Excel(name = "启用状态", width = 14, readConverterExp = "1=启用,0=停用", combo = {"启用", "停用"}) private String status; @Excel(name = "备注", width = 30) private String remark; } ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/dto/FleetQueryDTO.java
New file @@ -0,0 +1,18 @@ package com.ruoyi.other.api.dto; import lombok.Data; import java.io.Serializable; /** * 车队导出查询条件 DTO * * @author mxcd * @since 2026-09-23 */ @Data public class FleetQueryDTO implements Serializable { private static final long serialVersionUID = 1L; private String fleetName; private Integer companyId; private Integer status; } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TFleetController.java
@@ -1,5 +1,6 @@ package com.ruoyi.other.controller; import com.ruoyi.common.core.utils.poi.ExcelUtil; import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.common.log.annotation.Log; @@ -8,6 +9,8 @@ import com.ruoyi.common.security.annotation.RequiresPermissions; import com.ruoyi.other.api.domain.TFleet; import com.ruoyi.other.api.domain.TGroupCompany; import com.ruoyi.other.api.dto.FleetExcelDTO; import com.ruoyi.other.api.dto.FleetQueryDTO; import com.ruoyi.other.service.TFleetService; import com.ruoyi.other.service.TGroupCompanyService; import io.swagger.annotations.ApiOperation; @@ -15,12 +18,16 @@ import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.Map; import java.util.Objects; @@ -146,6 +153,62 @@ } /** * 导入车队(Excel) */ @RequiresPermissions(value = {"/fleet/import"}, logical = Logical.OR) @PostMapping("/import") @ApiOperation(value = "导入车队", tags = {"管理后台-车队管理"}) @Log(title = "【车队管理】导入车队", businessType = BusinessType.IMPORT) public AjaxResult<String> importData(@RequestPart("file") MultipartFile file) throws Exception { List<FleetExcelDTO> items = new ExcelUtil<>(FleetExcelDTO.class).importExcel(file.getInputStream()); return AjaxResult.success(fleetService.importFleets(items)); } /** * 下载车队导入模板 */ @RequiresPermissions(value = {"/fleet/import"}, logical = Logical.OR) @GetMapping("/import-template") @ApiOperation(value = "下载车队导入模板", tags = {"管理后台-车队管理"}) public void template(HttpServletResponse response) { new ExcelUtil<>(FleetExcelDTO.class).importTemplateExcel(response, "车队导入模板"); } /** * 导出车队(Excel,按筛选条件) */ @RequiresPermissions(value = {"/fleet/export"}, logical = Logical.OR) @PutMapping("/export") @ApiOperation(value = "导出车队", tags = {"管理后台-车队管理"}) @Log(title = "【车队管理】导出车队", businessType = BusinessType.EXPORT) public void export(HttpServletResponse response, @RequestBody(required = false) FleetQueryDTO query) { new ExcelUtil<>(FleetExcelDTO.class).exportExcel(response, fleetService.selectExportList(query), "车队数据"); } /** * 查询车队详情(查看按钮使用) */ @RequiresPermissions(value = {"/fleet/list"}, logical = Logical.OR) @GetMapping("/detail") @ApiOperation(value = "查询车队详情", tags = {"管理后台-车队管理"}) public AjaxResult<TFleet> detail(@RequestParam("id") Integer id) { if (id == null) { return AjaxResult.error("车队ID不能为空"); } TFleet fleet = fleetService.getById(id); if (fleet == null) { return AjaxResult.error("车队不存在或已删除"); } if (fleet.getCompanyId() != null) { TGroupCompany company = groupCompanyService.getById(fleet.getCompanyId()); if (company != null) { fleet.setCompanyName(company.getName()); } } return AjaxResult.success(fleet); } /** * 按公司ID批量回填公司名称 */ private void fillCompanyName(List<TFleet> records) { ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TFleetService.java
@@ -2,6 +2,10 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.other.api.domain.TFleet; import com.ruoyi.other.api.dto.FleetExcelDTO; import com.ruoyi.other.api.dto.FleetQueryDTO; import java.util.List; /** * <p> @@ -13,4 +17,20 @@ */ public interface TFleetService extends IService<TFleet> { /** * 批量导入车队(Excel 解析结果),校验并入库 * * @param items Excel 解析出的车队数据 * @return 导入结果提示 */ String importFleets(List<FleetExcelDTO> items); /** * 按条件查询车队导出列表(含公司名称回填) * * @param query 导出查询条件 * @return 导出数据 */ List<FleetExcelDTO> selectExportList(FleetQueryDTO query); } ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TFleetServiceImpl.java
@@ -1,10 +1,28 @@ package com.ruoyi.other.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.other.api.domain.TFleet; import com.ruoyi.other.api.domain.TGroupCompany; import com.ruoyi.other.api.dto.FleetExcelDTO; import com.ruoyi.other.api.dto.FleetQueryDTO; import com.ruoyi.other.mapper.TFleetMapper; import com.ruoyi.other.service.TFleetService; import com.ruoyi.other.service.TGroupCompanyService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; /** * <p> @@ -17,4 +35,112 @@ @Service public class TFleetServiceImpl extends ServiceImpl<TFleetMapper, TFleet> implements TFleetService { private static final int ENABLED = 1; private static final int DISABLED = 0; @Resource private TGroupCompanyService groupCompanyService; @Override @Transactional(rollbackFor = Exception.class) public String importFleets(List<FleetExcelDTO> items) { if (items == null || items.isEmpty()) { throw new ServiceException("导入数据不能为空"); } Set<String> fleetNames = new HashSet<>(); Set<String> companyNames = new HashSet<>(); int row = 1; for (FleetExcelDTO item : items) { row++; if (item == null || !StringUtils.hasText(item.getFleetName())) { throw new ServiceException("第" + row + "行车队名称不能为空"); } String fleetName = item.getFleetName().trim(); if (fleetName.length() > 128) { throw new ServiceException("第" + row + "行车队名称不能超过128个字符"); } if (!StringUtils.hasText(item.getCompanyName())) { throw new ServiceException("第" + row + "行所属公司不能为空"); } parseStatus(item.getStatus(), row); if (!fleetNames.add(fleetName) || lambdaQuery().eq(TFleet::getFleetName, fleetName).count() > 0) { throw new ServiceException("第" + row + "行车队名称已存在或重复"); } companyNames.add(item.getCompanyName().trim()); } // 批量查询公司名称 -> ID Map<String, Integer> companyMap = groupCompanyService.lambdaQuery() .in(TGroupCompany::getName, companyNames) .list() .stream() .collect(Collectors.toMap(TGroupCompany::getName, TGroupCompany::getId, (a, b) -> a)); row = 1; for (FleetExcelDTO item : items) { row++; String companyName = item.getCompanyName().trim(); if (!companyMap.containsKey(companyName)) { throw new ServiceException("第" + row + "行所属公司不存在:" + companyName); } } LocalDateTime now = LocalDateTime.now(); for (FleetExcelDTO item : items) { TFleet fleet = new TFleet(); fleet.setCompanyId(companyMap.get(item.getCompanyName().trim())); fleet.setFleetName(item.getFleetName().trim()); fleet.setContactName(trim(item.getContactName())); fleet.setContactPhone(trim(item.getContactPhone())); fleet.setRemark(trim(item.getRemark())); fleet.setStatus(parseStatus(item.getStatus(), 0)); fleet.setDelFlag(false); fleet.setCreateTime(now); save(fleet); } return "成功导入" + items.size() + "条车队数据"; } @Override public List<FleetExcelDTO> selectExportList(FleetQueryDTO query) { FleetQueryDTO safe = query == null ? new FleetQueryDTO() : query; List<TFleet> fleets = lambdaQuery() .like(StringUtils.hasText(safe.getFleetName()), TFleet::getFleetName, safe.getFleetName()) .eq(safe.getCompanyId() != null, TFleet::getCompanyId, safe.getCompanyId()) .eq(safe.getStatus() != null, TFleet::getStatus, safe.getStatus()) .orderByDesc(TFleet::getId) .list(); if (fleets == null || fleets.isEmpty()) { return new ArrayList<>(); } Set<Integer> companyIds = fleets.stream() .map(TFleet::getCompanyId) .filter(Objects::nonNull) .collect(Collectors.toSet()); Map<Integer, String> nameMap = companyIds.isEmpty() ? Collections.emptyMap() : groupCompanyService.listByIds(companyIds).stream() .collect(Collectors.toMap(TGroupCompany::getId, TGroupCompany::getName, (a, b) -> a)); return fleets.stream().map(item -> { FleetExcelDTO dto = new FleetExcelDTO(); dto.setFleetName(item.getFleetName()); dto.setCompanyName(nameMap.get(item.getCompanyId())); dto.setContactName(item.getContactName()); dto.setContactPhone(item.getContactPhone()); dto.setStatus(item.getStatus() == null ? null : String.valueOf(item.getStatus())); dto.setRemark(item.getRemark()); return dto; }).collect(Collectors.toList()); } private String trim(String value) { return value == null ? null : value.trim(); } private Integer parseStatus(String value, int row) { if (!StringUtils.hasText(value) || "1".equals(value.trim()) || "启用".equals(value.trim())) { return ENABLED; } if ("0".equals(value.trim()) || "停用".equals(value.trim())) { return DISABLED; } throw new ServiceException((row > 0 ? "第" + row + "行" : "") + "启用状态错误"); } } sql/20260922_fleet.sql
@@ -2,6 +2,8 @@ -- 车队管理表 -- 创建日期: 2026-09-22 -- 库: charging_pile_other -- 执行途径: 必须经 DRDS 中间件 192.168.110.111:8066 执行 -- (直连 74 建表中间件无元数据,后端插入报 can not route) -- ---------------------------- CREATE TABLE `t_fleet` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',