puzhibing
2026-09-04 6b74cf2b7b5d1813d951e8638044e25c1cbb11f1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package com.ruoyi.account.service.impl;
 
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.api.dto.VinManagementExcelDTO;
import com.ruoyi.account.api.dto.VinManagementQueryDTO;
import com.ruoyi.account.api.dto.VinManagementSaveDTO;
import com.ruoyi.account.api.model.TVinManagement;
import com.ruoyi.account.mapper.TVinManagementMapper;
import com.ruoyi.account.service.TVinManagementService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.order.api.vo.VinChargingStatusVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
@Slf4j
@Service
public class TVinManagementServiceImpl extends ServiceImpl<TVinManagementMapper, TVinManagement> implements TVinManagementService {
    private static final int ENABLED = 1;
    private static final int DISABLED = 2;
 
    @Resource
    private ChargingOrderClient chargingOrderClient;
 
    @Override public IPage<TVinManagement> selectPageList(VinManagementQueryDTO query) {
        VinManagementQueryDTO safe = query == null ? new VinManagementQueryDTO() : query;
        long page = safe.getPageCurr() == null || safe.getPageCurr() < 1 ? 1 : safe.getPageCurr();
        long size = safe.getPageSize() == null || safe.getPageSize() < 1 ? 10 : safe.getPageSize();
        return baseMapper.selectPageList(new Page<>(page, size), safe);
    }
    @Override public boolean saveVin(VinManagementSaveDTO dto) { validate(dto, false); TVinManagement item = from(dto); item.setDelFlag(0); item.setCreateTime(LocalDateTime.now()); item.setCreateBy(SecurityUtils.getUserId()); return save(item); }
    @Override public boolean updateVin(VinManagementSaveDTO dto) { validate(dto, true); if (getById(dto.getId()) == null) throw new ServiceException("VIN码不存在或已删除"); TVinManagement item = from(dto); item.setId(dto.getId()); item.setUpdateTime(LocalDateTime.now()); item.setUpdateBy(SecurityUtils.getUserId()); return updateById(item); }
    @Override public boolean deleteVins(List<Long> ids) { if (ids == null || ids.isEmpty()) throw new ServiceException("请选择需要删除的VIN码"); List<Long> distinct = new ArrayList<>(new HashSet<>(ids)); if (listByIds(distinct).size() != distinct.size()) throw new ServiceException("部分VIN码不存在或已删除"); return removeByIds(distinct); }
    @Override public boolean updateStatus(Long id, Integer status) { if (id == null || !validStatus(status)) throw new ServiceException("VIN码状态参数错误"); if (getById(id) == null) throw new ServiceException("VIN码不存在或已删除"); TVinManagement item = new TVinManagement(); item.setId(id); item.setStatus(status); item.setUpdateTime(LocalDateTime.now()); item.setUpdateBy(SecurityUtils.getUserId()); return updateById(item); }
    @Override public List<VinManagementExcelDTO> selectExportList(VinManagementQueryDTO query) { return baseMapper.selectExportList(query == null ? new VinManagementQueryDTO() : query); }
    @Override public List<TVinManagement> selectAppletVehicleList(Long appUserId) {
        List<TVinManagement> vehicles = baseMapper.selectAppletVehicleList(appUserId);
        if (vehicles == null || vehicles.isEmpty()) return vehicles;
        vehicles.forEach(vehicle -> vehicle.setCharging(false));
        List<Long> vinIds = new ArrayList<>();
        for (TVinManagement vehicle : vehicles) {
            if (vehicle != null && vehicle.getId() != null) vinIds.add(vehicle.getId());
        }
        if (vinIds.isEmpty()) return vehicles;
        try {
            R<List<VinChargingStatusVO>> response = chargingOrderClient.getChargingVinStatus(vinIds);
            if (response == null || !R.isSuccess(response) || response.getData() == null) return vehicles;
            Map<Long, Integer> chargingGunMap = new HashMap<>();
            for (VinChargingStatusVO status : response.getData()) {
                if (status != null && status.getVinId() != null) chargingGunMap.put(status.getVinId(), status.getChargingGunId());
            }
            for (TVinManagement vehicle : vehicles) {
                if (vehicle != null && chargingGunMap.containsKey(vehicle.getId())) {
                    vehicle.setCharging(true);
                    vehicle.setChargingGunId(chargingGunMap.get(vehicle.getId()));
                }
            }
        } catch (Exception ex) {
            log.warn("查询 VIN 车辆充电状态失败,按未充电返回,appUserId={}", appUserId, ex);
        }
        return vehicles;
    }
    @Override @Transactional(rollbackFor = Exception.class) public boolean bindAppletVehicle(Long appUserId, String keyword) {
        String exactKeyword = trim(keyword);
        if (StringUtils.isEmpty(exactKeyword)) throw new ServiceException("请输入VIN码或车牌号");
        TVinManagement vehicle = baseMapper.selectEnabledVehicle(exactKeyword);
        if (vehicle == null) throw new ServiceException("该车辆不存在");
        if (appUserId.equals(vehicle.getAppUserId())) throw new ServiceException("该车辆已绑定当前用户");
        if (vehicle.getAppUserId() != null) throw new ServiceException("该车辆已被其他用户绑定");
        if (baseMapper.bindAppletVehicle(vehicle.getId(), appUserId) > 0) return true;
        TVinManagement latest = baseMapper.selectById(vehicle.getId());
        if (latest != null && appUserId.equals(latest.getAppUserId())) throw new ServiceException("该车辆已绑定当前用户");
        throw new ServiceException("该车辆已被其他用户绑定");
    }
    @Override @Transactional(rollbackFor = Exception.class) public boolean unbindAppletVehicle(Long id, Long appUserId) {
        if (id == null || baseMapper.unbindAppletVehicle(id, appUserId) == 0) throw new ServiceException("该车辆不存在");
        return true;
    }
    @Override public List<Long> getVinIdsByAppUserId(Long appUserId) { return baseMapper.selectIdsByAppUserId(appUserId); }
    @Override @Transactional(rollbackFor = Exception.class) public String importVins(List<VinManagementExcelDTO> items) { if (items == null || items.isEmpty()) throw new ServiceException("导入数据不能为空"); Set<String> vins = new HashSet<>(); int row = 1; for (VinManagementExcelDTO item : items) { row++; if (item == null || StringUtils.isEmpty(item.getVin())) throw new ServiceException("第" + row + "行VIN码不能为空"); String vin = item.getVin().trim(); if (vin.length() > 64) throw new ServiceException("第" + row + "行VIN码不能超过64个字符"); if (!vins.add(vin) || baseMapper.countByVin(vin, null) > 0) throw new ServiceException("第" + row + "行VIN码已存在或重复"); parseStatus(item.getStatus(), row); } Long userId = SecurityUtils.getUserId(); LocalDateTime now = LocalDateTime.now(); for (VinManagementExcelDTO item : items) { TVinManagement v = new TVinManagement(); v.setVin(item.getVin().trim()); v.setPlateNumber(trim(item.getPlateNumber())); v.setPhone(trim(item.getPhone())); v.setCompanyName(trim(item.getCompanyName())); v.setRemark(trim(item.getRemark())); v.setStatus(parseStatus(item.getStatus(), 0)); v.setDelFlag(0); v.setCreateBy(userId); v.setCreateTime(now); save(v); } return "成功导入" + items.size() + "条VIN码数据"; }
    private void validate(VinManagementSaveDTO dto, boolean update) { if (dto == null || StringUtils.isEmpty(dto.getVin())) throw new ServiceException("VIN码不能为空"); if (update && dto.getId() == null) throw new ServiceException("VIN码ID不能为空"); String vin = dto.getVin().trim(); if (vin.length() > 64) throw new ServiceException("VIN码不能超过64个字符"); if (!validStatus(dto.getStatus() == null ? ENABLED : dto.getStatus())) throw new ServiceException("VIN码状态参数错误"); if (baseMapper.countByVin(vin, dto.getId()) > 0) throw new ServiceException("VIN码已存在"); }
    private TVinManagement from(VinManagementSaveDTO d) { TVinManagement v = new TVinManagement(); v.setVin(d.getVin().trim()); v.setPlateNumber(trim(d.getPlateNumber())); v.setPhone(trim(d.getPhone())); v.setCompanyName(trim(d.getCompanyName())); v.setRemark(trim(d.getRemark())); v.setStatus(d.getStatus() == null ? ENABLED : d.getStatus()); return v; }
    private String trim(String value) { return value == null ? null : value.trim(); }
    private boolean validStatus(Integer status) { return status != null && (status == ENABLED || status == DISABLED); }
    private Integer parseStatus(String value, int row) { if (StringUtils.isEmpty(value) || "1".equals(value.trim()) || "启用".equals(value.trim())) return ENABLED; if ("2".equals(value.trim()) || "禁用".equals(value.trim())) return DISABLED; throw new ServiceException((row > 0 ? "第" + row + "行" : "") + "启用状态错误"); }
}