puzhibing
2026-09-23 9f6d07b4eb72dfce7fb52ad35dffdf18096ca135
增加新功能
2个文件已添加
4个文件已修改
251 ■■■■■ 已修改文件
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/dto/FleetExcelDTO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/dto/FleetQueryDTO.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TFleetController.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TFleetService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TFleetServiceImpl.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/20260922_fleet.sql 2 ●●●●● 补丁 | 查看 | 原始文档 | 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 '主键',