puzhibing
2026-09-30 67d25f3d9eb0124c7aab544bf8f77031d6d8adc3
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TFleetController.java
@@ -1,5 +1,8 @@
package com.ruoyi.other.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.account.api.model.TVinManagement;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.PageInfo;
@@ -9,14 +12,17 @@
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.FleetExportDTO;
import com.ruoyi.other.api.dto.FleetImportDTO;
import com.ruoyi.other.api.dto.FleetQueryDTO;
import com.ruoyi.other.service.CompanyAccountAccessService;
import com.ruoyi.other.service.TFleetService;
import com.ruoyi.other.service.TGroupCompanyService;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -28,6 +34,7 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -51,10 +58,13 @@
    @Resource
    private TGroupCompanyService groupCompanyService;
    @Resource
    private CompanyAccountAccessService companyAccountAccessService;
    /**
     * 分页查询车队
     */
    @RequiresPermissions(value = {"/fleet/list"}, logical = Logical.OR)
    @RequiresPermissions(value = {"/fleet/list", "/vinManagement/list", "/chargingCard/list"}, logical = Logical.OR)
    @GetMapping("/page")
    @ApiOperation(value = "分页查询车队", tags = {"管理后台-车队管理"})
    public AjaxResult<PageInfo<TFleet>> page(@RequestParam(value = "current", defaultValue = "1") Integer current,
@@ -62,6 +72,8 @@
                                             @RequestParam(value = "fleetName", required = false) String fleetName,
                                             @RequestParam(value = "companyId", required = false) Integer companyId,
                                             @RequestParam(value = "status", required = false) Integer status) {
        // 公司账号强制按所属公司过滤,覆盖前端传入的公司筛选
        companyId = companyAccountAccessService.resolveCompanyFilter(companyId);
        PageInfo<TFleet> page = new PageInfo<>(current, size);
        fleetService.lambdaQuery()
                .like(StringUtils.hasText(fleetName), TFleet::getFleetName, fleetName)
@@ -70,6 +82,8 @@
                .orderByDesc(TFleet::getId)
                .page(page);
        fillCompanyName(page.getRecords());
        // 填充VIN车辆数/可充电站数/累计三列聚合
        fleetService.fillAggregates(page.getRecords());
        return AjaxResult.success(page);
    }
@@ -81,6 +95,8 @@
    @ApiOperation(value = "添加车队", tags = {"管理后台-车队管理"})
    @Log(title = "【车队管理】添加车队", businessType = BusinessType.INSERT)
    public AjaxResult add(@RequestBody TFleet fleet) {
        // 公司账号新增车队时强制归属本公司
        fleet.setCompanyId(companyAccountAccessService.resolveCompanyFilter(fleet.getCompanyId()));
        if (fleet.getCompanyId() == null) {
            return AjaxResult.error("所属公司不能为空");
        }
@@ -107,6 +123,13 @@
        if (fleet.getId() == null) {
            return AjaxResult.error("车队ID不能为空");
        }
        TFleet existing = fleetService.getById(fleet.getId());
        if (existing == null) {
            return AjaxResult.error("车队不存在或已删除");
        }
        // 公司账号越权校验:只能编辑本公司车队,且不允许改挂到其他公司
        companyAccountAccessService.assertCompanyVisible(existing.getCompanyId());
        fleet.setCompanyId(companyAccountAccessService.resolveCompanyFilter(fleet.getCompanyId()));
        fleetService.updateById(fleet);
        return AjaxResult.success();
    }
@@ -130,7 +153,15 @@
        if (idList.isEmpty()) {
            return AjaxResult.error("车队ID不能为空");
        }
        fleetService.removeByIds(idList);
        // 公司账号越权校验:只能删除本公司车队
        List<TFleet> records = fleetService.listByIds(idList);
        if (records == null || records.size() != idList.size()) {
            return AjaxResult.error("部分车队不存在或已删除");
        }
        for (TFleet record : records) {
            companyAccountAccessService.assertCompanyVisible(record.getCompanyId());
        }
        fleetService.deleteFleets(idList);
        return AjaxResult.success();
    }
@@ -145,6 +176,12 @@
        if (id == null) {
            return AjaxResult.error("车队ID不能为空");
        }
        TFleet record = fleetService.getById(id);
        if (record == null) {
            return AjaxResult.error("车队不存在或已删除");
        }
        // 公司账号越权校验:只能操作本公司车队
        companyAccountAccessService.assertCompanyVisible(record.getCompanyId());
        TFleet update = new TFleet();
        update.setId(id);
        update.setStatus(status);
@@ -160,7 +197,7 @@
    @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());
        List<FleetImportDTO> items = new ExcelUtil<>(FleetImportDTO.class).importExcel(file.getInputStream());
        return AjaxResult.success(fleetService.importFleets(items));
    }
@@ -171,7 +208,7 @@
    @GetMapping("/import-template")
    @ApiOperation(value = "下载车队导入模板", tags = {"管理后台-车队管理"})
    public void template(HttpServletResponse response) {
        new ExcelUtil<>(FleetExcelDTO.class).importTemplateExcel(response, "车队导入模板");
        new ExcelUtil<>(FleetImportDTO.class).importTemplateExcel(response, "车队导入模板");
    }
    /**
@@ -182,7 +219,12 @@
    @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), "车队数据");
        if (query == null) {
            query = new FleetQueryDTO();
        }
        // 公司账号强制按所属公司过滤,覆盖前端传入的公司筛选
        query.setCompanyId(companyAccountAccessService.resolveCompanyFilter(query.getCompanyId()));
        new ExcelUtil<>(FleetExportDTO.class).exportExcel(response, fleetService.selectExportList(query), "车队数据");
    }
    /**
@@ -199,13 +241,35 @@
        if (fleet == null) {
            return AjaxResult.error("车队不存在或已删除");
        }
        // 公司账号越权校验:只能查看本公司车队
        companyAccountAccessService.assertCompanyVisible(fleet.getCompanyId());
        if (fleet.getCompanyId() != null) {
            TGroupCompany company = groupCompanyService.getById(fleet.getCompanyId());
            if (company != null) {
                fleet.setCompanyName(company.getName());
            }
        }
        // 详情亦填充5列聚合(保持与列表一致)
        fleetService.fillAggregates(java.util.Collections.singletonList(fleet));
        return AjaxResult.success(fleet);
    }
    /**
     * 分页查询车队下的VIN码车辆(查看车队抽屉使用)
     */
    @RequiresPermissions(value = {"/fleet/list"}, logical = Logical.OR)
    @GetMapping("/vin-page")
    @ApiOperation(value = "分页查询车队下VIN码车辆", tags = {"管理后台-车队管理"})
    public AjaxResult<Page<TVinManagement>> vinPage(@RequestParam("id") Integer id,
                                                    @RequestParam(value = "current", defaultValue = "1") Integer current,
                                                    @RequestParam(value = "size", defaultValue = "10") Integer size) {
        TFleet fleet = fleetService.getById(id);
        if (fleet == null) {
            return AjaxResult.error("车队不存在或已删除");
        }
        // 公司账号越权校验:只能查看本公司车队下的VIN
        companyAccountAccessService.assertCompanyVisible(fleet.getCompanyId());
        return AjaxResult.success(fleetService.selectVinPage(id, current, size));
    }
    /**
@@ -228,4 +292,32 @@
        records.forEach(item -> item.setCompanyName(nameMap.get(item.getCompanyId())));
    }
    /**
     * 远程接口:车队详情(VIN码车辆所属车队校验使用,内部调用)
     */
    @PostMapping("/remote/get/{id}")
    @ApiOperation(value = "远程-车队详情", tags = {"内部调用"})
    public R<TFleet> remoteGet(@PathVariable("id") Integer id) {
        if (id == null) {
            return R.fail("车队ID不能为空");
        }
        return R.ok(fleetService.getById(id));
    }
    /**
     * 远程接口:按ID批量查询车队(VIN列表回填车队名称使用,内部调用)
     */
    @PostMapping("/remote/list-by-ids")
    @ApiOperation(value = "远程-按ID批量查询车队", tags = {"内部调用"})
    public R<List<TFleet>> remoteListByIds(@RequestBody List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            return R.ok(new ArrayList<>());
        }
        List<Integer> distinct = ids.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
        if (distinct.isEmpty()) {
            return R.ok(new ArrayList<>());
        }
        return R.ok(fleetService.listByIds(distinct));
    }
}