From 6cff7f185bfba6f8a2affb66c122f14ef9fef375 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期二, 01 九月 2026 14:07:12 +0800
Subject: [PATCH] feat: add VIN charging orders

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TVinChargingOrderMapper.java             |   23 +
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java  |  181 ++++++++++++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TVinChargingOrderService.java           |   23 +
 ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TVinChargingOrderMapper.xml                   |   60 ++++
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/query/VinChargingOrderQuery.java            |   54 +++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TVinChargingOrderController.java     |  120 ++++++++
 sql/20260901_vin_charging_order.sql                                                                     |  243 +++++++++++++++++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/export/VinChargingOrderExport.java              |   43 +++
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TVinChargingOrder.java                |   23 +
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/vo/ChargingOrderVO.java                     |    2 
 ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/mapper/VinChargingOrderMapperStructureTest.java |   35 ++
 11 files changed, 807 insertions(+), 0 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TVinChargingOrder.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TVinChargingOrder.java
new file mode 100644
index 0000000..fb532f4
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TVinChargingOrder.java
@@ -0,0 +1,23 @@
+package com.ruoyi.order.api.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("t_vin_charging_order")
+@ApiModel("VIN码充电订单")
+public class TVinChargingOrder extends TChargingOrder {
+
+    @ApiModelProperty("VIN管理记录ID(分片键)")
+    @TableField("vin_id")
+    private Long vinId;
+
+    @ApiModelProperty("VIN码快照")
+    @TableField("vin")
+    private String vin;
+}
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/query/VinChargingOrderQuery.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/query/VinChargingOrderQuery.java
new file mode 100644
index 0000000..09d21c1
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/query/VinChargingOrderQuery.java
@@ -0,0 +1,54 @@
+package com.ruoyi.order.api.query;
+
+import com.ruoyi.common.core.web.page.BasePage;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "VinChargingOrderQuery VIN码充电订单查询对象")
+public class VinChargingOrderQuery extends BasePage {
+
+    @ApiModelProperty("订单编号")
+    private String code;
+
+    @ApiModelProperty("VIN码")
+    private String vin;
+
+    @ApiModelProperty("车牌号")
+    private String plateNum;
+
+    @ApiModelProperty("手机号")
+    private String phone;
+
+    @ApiModelProperty("站点ids(权限过滤,前端忽略)")
+    private List<Integer> siteIds;
+
+    @ApiModelProperty("订单状态")
+    private Integer status;
+
+    @ApiModelProperty("站点ID")
+    private Integer siteId;
+
+    @ApiModelProperty("充电桩ID")
+    private Integer pileId;
+
+    @ApiModelProperty("充电枪ID")
+    private Integer gunId;
+
+    @ApiModelProperty("充电开始时间范围的开始时间")
+    private String startTime1;
+
+    @ApiModelProperty("充电开始时间范围的结束时间")
+    private String startTime2;
+
+    @ApiModelProperty("充电结束时间范围的开始时间")
+    private String endTime1;
+
+    @ApiModelProperty("充电结束时间范围的结束时间")
+    private String endTime2;
+}
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/vo/ChargingOrderVO.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/vo/ChargingOrderVO.java
index 8c14e43..f06c9e9 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/vo/ChargingOrderVO.java
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/vo/ChargingOrderVO.java
@@ -48,6 +48,8 @@
 
     @ApiModelProperty(value = "刷卡开卡号")
     private String cardNo;
+    @ApiModelProperty(value = "VIN码快照")
+    private String vin;
     @ApiModelProperty(value = "时段数")
     private Integer count;
     @ApiModelProperty(value = "充电结束原因")
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TVinChargingOrderController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TVinChargingOrderController.java
new file mode 100644
index 0000000..48e691e
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TVinChargingOrderController.java
@@ -0,0 +1,120 @@
+package com.ruoyi.order.controller;
+
+import cn.afterturn.easypoi.excel.ExcelExportUtil;
+import cn.afterturn.easypoi.excel.entity.ExportParams;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.utils.DateUtils;
+import com.ruoyi.common.core.utils.WebUtils;
+import com.ruoyi.common.core.web.page.PageInfo;
+import com.ruoyi.common.log.annotation.Log;
+import com.ruoyi.common.log.enums.BusinessType;
+import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.ruoyi.order.api.query.VinChargingOrderQuery;
+import com.ruoyi.order.api.vo.ChargingOrderVO;
+import com.ruoyi.order.export.VinChargingOrderExport;
+import com.ruoyi.order.service.TVinChargingOrderService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.beans.BeanUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+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.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/t-vin-charging-order")
+@Api(tags = "管理后台-VIN码充电订单")
+public class TVinChargingOrderController {
+
+    @Resource
+    private TVinChargingOrderService vinChargingOrderService;
+
+    @RequiresPermissions("/vinChargingOrder/list")
+    @GetMapping("/list")
+    @ApiOperation("VIN码充电订单列表")
+    public R<PageInfo<ChargingOrderVO>> list(VinChargingOrderQuery query) {
+        return R.ok(vinChargingOrderService.pageList(query));
+    }
+
+    @RequiresPermissions("/vinChargingOrder/list")
+    @GetMapping("/summary")
+    @ApiOperation("VIN码充电订单汇总")
+    public R<Map<String, Object>> summary(VinChargingOrderQuery query) {
+        Map<String, Object> summary = vinChargingOrderService.summary(query);
+        return R.ok(summary == null ? Collections.emptyMap() : summary);
+    }
+
+    @RequiresPermissions("/vinChargingOrder/detail")
+    @GetMapping("/detail")
+    @ApiOperation("VIN码充电订单详情")
+    public R<Map<String, Object>> detail(@RequestParam("chargingOrderId") Long chargingOrderId) {
+        return R.ok(vinChargingOrderService.detail(chargingOrderId));
+    }
+
+    @RequiresPermissions("/vinChargingOrder/detail")
+    @GetMapping("/accounting-strategy")
+    @ApiOperation("VIN码充电订单计费明细")
+    public R<Map<String, Object>> accountingStrategy(@RequestParam("chargingOrderId") Long chargingOrderId) {
+        return R.ok(Collections.singletonMap("list", vinChargingOrderService.accountingStrategyList(chargingOrderId)));
+    }
+
+    @RequiresPermissions("/vinChargingOrder/export")
+    @PutMapping("/export")
+    @ApiOperation("VIN码充电订单导出")
+    @Log(title = "VIN码充电订单导出", businessType = BusinessType.EXPORT)
+    public void export(@RequestBody VinChargingOrderQuery query) {
+        List<VinChargingOrderExport> exports = new ArrayList<>();
+        for (ChargingOrderVO order : vinChargingOrderService.exportList(query)) {
+            VinChargingOrderExport export = new VinChargingOrderExport();
+            BeanUtils.copyProperties(order, export);
+            export.setVin(order.getActualVin() != null ? order.getActualVin()
+                    : (order.getExpectedVin() != null ? order.getExpectedVin() : order.getVin()));
+            export.setPlateNum(order.getPlateNum());
+            export.setStartTime(formatTime(order.getStartTime()));
+            export.setEndTime(formatTime(order.getEndTime()));
+            exports.add(export);
+        }
+        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), VinChargingOrderExport.class, exports);
+        writeWorkbook(workbook, "VIN码充电订单导出.xls");
+    }
+
+    private String formatTime(LocalDateTime time) {
+        return time == null ? "" : DateUtils.localDateTimeToString(time);
+    }
+
+    private void writeWorkbook(Workbook workbook, String exportFileName) {
+        HttpServletResponse response = WebUtils.response();
+        response.setCharacterEncoding("utf-8");
+        ServletOutputStream outputStream = null;
+        try {
+            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(exportFileName, "utf-8"));
+            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
+            outputStream = response.getOutputStream();
+            workbook.write(outputStream);
+        } catch (IOException e) {
+            throw new IllegalStateException("导出VIN码充电订单失败", e);
+        } finally {
+            try {
+                workbook.close();
+                if (outputStream != null) {
+                    outputStream.close();
+                }
+            } catch (IOException ignored) {
+            }
+        }
+    }
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/export/VinChargingOrderExport.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/export/VinChargingOrderExport.java
new file mode 100644
index 0000000..15bedd5
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/export/VinChargingOrderExport.java
@@ -0,0 +1,43 @@
+package com.ruoyi.order.export;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+@ApiModel(value = "VIN码充电订单导出")
+public class VinChargingOrderExport implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @Excel(name = "订单编号", width = 26)
+    private String code;
+    @Excel(name = "VIN码", width = 24)
+    private String vin;
+    @Excel(name = "车牌号", width = 16)
+    private String plateNum;
+    @Excel(name = "手机号", width = 18)
+    private String phone;
+    @Excel(name = "站点名称", width = 24)
+    private String siteName;
+    @Excel(name = "充电终端名称", width = 24)
+    private String terminalName;
+    @Excel(name = "状态", width = 16, replace = {"未知_0", "等待中/已插枪_1", "启动中_2", "充电中_3", "停止中_4", "已结束_5"})
+    private Integer status;
+    @Excel(name = "充电时长(秒)", width = 16)
+    private Long chargingSecond;
+    @Excel(name = "实付", width = 12, numFormat = "0.00")
+    private BigDecimal paymentAmount;
+    @Excel(name = "开始时间", width = 22)
+    private String startTime;
+    @Excel(name = "最后时间", width = 22)
+    private String endTime;
+    @Excel(name = "累计充电量", width = 14, numFormat = "0.0000")
+    private BigDecimal chargingCapacity;
+    @Excel(name = "累计电费", width = 14, numFormat = "0.0000")
+    private BigDecimal electrovalence;
+    @Excel(name = "累计服务费", width = 14, numFormat = "0.0000")
+    private BigDecimal serviceCharge;
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TVinChargingOrderMapper.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TVinChargingOrderMapper.java
new file mode 100644
index 0000000..79611e4
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TVinChargingOrderMapper.java
@@ -0,0 +1,23 @@
+package com.ruoyi.order.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.order.api.model.TVinChargingOrder;
+import com.ruoyi.order.api.query.VinChargingOrderQuery;
+import com.ruoyi.order.api.vo.ChargingOrderVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+public interface TVinChargingOrderMapper extends BaseMapper<TVinChargingOrder> {
+
+    List<ChargingOrderVO> pageList(@Param("query") VinChargingOrderQuery query,
+                                   @Param("offset") long offset,
+                                   @Param("pageSize") long pageSize);
+
+    long count(@Param("query") VinChargingOrderQuery query);
+
+    Map<String, Object> summary(@Param("query") VinChargingOrderQuery query);
+
+    List<Map<String, Object>> accountingStrategyList(@Param("chargingOrderId") Long chargingOrderId);
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TVinChargingOrderService.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TVinChargingOrderService.java
new file mode 100644
index 0000000..ac94189
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TVinChargingOrderService.java
@@ -0,0 +1,23 @@
+package com.ruoyi.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.common.core.web.page.PageInfo;
+import com.ruoyi.order.api.model.TVinChargingOrder;
+import com.ruoyi.order.api.query.VinChargingOrderQuery;
+import com.ruoyi.order.api.vo.ChargingOrderVO;
+
+import java.util.List;
+import java.util.Map;
+
+public interface TVinChargingOrderService extends IService<TVinChargingOrder> {
+
+    PageInfo<ChargingOrderVO> pageList(VinChargingOrderQuery query);
+
+    List<ChargingOrderVO> exportList(VinChargingOrderQuery query);
+
+    Map<String, Object> summary(VinChargingOrderQuery query);
+
+    Map<String, Object> detail(Long chargingOrderId);
+
+    List<Map<String, Object>> accountingStrategyList(Long chargingOrderId);
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java
new file mode 100644
index 0000000..d118a24
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java
@@ -0,0 +1,181 @@
+package com.ruoyi.order.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.chargingPile.api.dto.GetSiteListDTO;
+import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient;
+import com.ruoyi.chargingPile.api.feignClient.SiteClient;
+import com.ruoyi.chargingPile.api.model.Site;
+import com.ruoyi.chargingPile.api.model.TChargingGun;
+import com.ruoyi.common.core.web.page.PageInfo;
+import com.ruoyi.common.security.service.TokenService;
+import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData;
+import com.ruoyi.order.api.model.TVinChargingOrder;
+import com.ruoyi.order.api.query.VinChargingOrderQuery;
+import com.ruoyi.order.api.vo.ChargingOrderVO;
+import com.ruoyi.order.mapper.TVinChargingOrderMapper;
+import com.ruoyi.order.service.TVinChargingOrderService;
+import com.ruoyi.order.util.mongodb.service.UploadRealTimeMonitoringDataService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Service
+public class TVinChargingOrderServiceImpl extends ServiceImpl<TVinChargingOrderMapper, TVinChargingOrder>
+        implements TVinChargingOrderService {
+
+    @Resource
+    private TokenService tokenService;
+    @Resource
+    private SiteClient siteClient;
+    @Resource
+    private ChargingGunClient chargingGunClient;
+    @Resource
+    private UploadRealTimeMonitoringDataService monitoringDataService;
+
+    @Override
+    public PageInfo<ChargingOrderVO> pageList(VinChargingOrderQuery query) {
+        int pageCurr = query.getPageCurr() == null || query.getPageCurr() < 1 ? 1 : query.getPageCurr();
+        int pageSize = query.getPageSize() == null || query.getPageSize() < 1 ? 50 : query.getPageSize();
+        setAuthSiteIds(query);
+        PageInfo<ChargingOrderVO> page = new PageInfo<>(pageCurr, pageSize);
+        long total = baseMapper.count(query);
+        page.setTotal(total);
+        List<ChargingOrderVO> records = total == 0 ? Collections.emptyList()
+                : baseMapper.pageList(query, (long) (pageCurr - 1) * pageSize, pageSize);
+        fillExtra(records);
+        page.setRecords(records);
+        return page;
+    }
+
+    @Override
+    public List<ChargingOrderVO> exportList(VinChargingOrderQuery query) {
+        setAuthSiteIds(query);
+        long total = baseMapper.count(query);
+        List<ChargingOrderVO> result = new ArrayList<>();
+        for (long offset = 0; offset < total; offset += 5000) {
+            List<ChargingOrderVO> batch = baseMapper.pageList(query, offset, 5000);
+            if (batch == null || batch.isEmpty()) {
+                break;
+            }
+            result.addAll(batch);
+        }
+        fillExtra(result);
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> summary(VinChargingOrderQuery query) {
+        setAuthSiteIds(query);
+        Map<String, Object> result = baseMapper.summary(query);
+        return result == null ? new HashMap<>() : result;
+    }
+
+    @Override
+    public Map<String, Object> detail(Long chargingOrderId) {
+        TVinChargingOrder order = getAuthorizedOrder(chargingOrderId);
+        if (order == null) {
+            return Collections.emptyMap();
+        }
+        Map<String, Object> result = new HashMap<>();
+        result.put("id", order.getId());
+        result.put("code", order.getCode());
+        result.put("vin", order.getVin());
+        result.put("actualVin", order.getActualVin());
+        result.put("expectedVin", order.getExpectedVin());
+        result.put("plateNum", order.getPlateNum());
+        result.put("phone", order.getPhone());
+        result.put("status", order.getStatus());
+        result.put("siteId", order.getSiteId());
+        result.put("chargingPileId", order.getChargingPileId());
+        result.put("chargingGunId", order.getChargingGunId());
+        result.put("startTime", order.getStartTime());
+        result.put("endTime", order.getEndTime());
+        result.put("chargingCapacity", order.getChargingCapacity());
+        result.put("paymentAmount", order.getPaymentAmount());
+        result.put("electrovalence", order.getElectrovalence());
+        result.put("serviceCharge", order.getServiceCharge());
+        List<UploadRealTimeMonitoringData> monitoring = monitoringDataService.getDataByOrderCodeAsc(order.getCode());
+        result.put("list", monitoring == null ? Collections.emptyList() : monitoring);
+        result.put("list1", baseMapper.accountingStrategyList(order.getId()));
+        return result;
+    }
+
+    @Override
+    public List<Map<String, Object>> accountingStrategyList(Long chargingOrderId) {
+        TVinChargingOrder order = getAuthorizedOrder(chargingOrderId);
+        return order == null ? Collections.emptyList() : baseMapper.accountingStrategyList(chargingOrderId);
+    }
+
+    private void setAuthSiteIds(VinChargingOrderQuery query) {
+        List<Integer> authorizedSiteIds = getAuthorizedSiteIds();
+        if (query.getSiteId() != null) {
+            authorizedSiteIds = authorizedSiteIds.contains(query.getSiteId())
+                    ? Collections.singletonList(query.getSiteId()) : Collections.singletonList(-1);
+        }
+        if (authorizedSiteIds.isEmpty()) {
+            authorizedSiteIds = Collections.singletonList(-1);
+        }
+        query.setSiteIds(authorizedSiteIds);
+    }
+
+    private TVinChargingOrder getAuthorizedOrder(Long chargingOrderId) {
+        if (chargingOrderId == null) {
+            return null;
+        }
+        TVinChargingOrder order = getById(chargingOrderId);
+        if (order == null || order.getSiteId() == null || !getAuthorizedSiteIds().contains(order.getSiteId())) {
+            return null;
+        }
+        return order;
+    }
+
+    private List<Integer> getAuthorizedSiteIds() {
+        Long userId = tokenService.getLoginUser().getUserid();
+        if (userId == null) {
+            return Collections.emptyList();
+        }
+        return Optional.ofNullable(siteClient.getSiteListByUserId(userId).getData())
+                .orElse(Collections.emptyList()).stream().map(GetSiteListDTO::getId).collect(Collectors.toList());
+    }
+
+    private void fillExtra(List<ChargingOrderVO> list) {
+        if (list == null || list.isEmpty()) {
+            return;
+        }
+        List<Integer> siteIds = list.stream().map(ChargingOrderVO::getSiteId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        List<Integer> gunIds = list.stream().map(ChargingOrderVO::getChargingGunId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        Map<Integer, Site> sites = siteIds.isEmpty() ? Collections.emptyMap()
+                : Optional.ofNullable(siteClient.getSiteByIds(siteIds).getData()).orElse(Collections.emptyList()).stream()
+                .collect(Collectors.toMap(Site::getId, item -> item, (a, b) -> a));
+        Map<Integer, TChargingGun> guns = gunIds.isEmpty() ? Collections.emptyMap()
+                : Optional.ofNullable(chargingGunClient.getChargingGunByIds(gunIds).getData()).orElse(Collections.emptyList()).stream()
+                .collect(Collectors.toMap(TChargingGun::getId, item -> item, (a, b) -> a));
+        for (ChargingOrderVO item : list) {
+            Site site = sites.get(item.getSiteId());
+            item.setSiteName(site == null ? null : site.getName());
+            TChargingGun gun = guns.get(item.getChargingGunId());
+            item.setTerminalName(gun == null ? null : gun.getName());
+            if (item.getStartTime() != null && item.getEndTime() != null) {
+                item.setChargingSecond(ChronoUnit.SECONDS.between(item.getStartTime(), item.getEndTime()));
+            }
+            UploadRealTimeMonitoringData data = monitoringDataService.getLastDataById(item.getCode());
+            if (data != null) {
+                item.setChargeCurrent(data.getOutput_current());
+                item.setChargeVoltage(data.getOutput_voltage());
+                item.setChargePower(data.getPower());
+            }
+            item.setPlatformIncome(BigDecimal.ZERO);
+            item.setPartnerIncome(BigDecimal.ZERO);
+        }
+    }
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TVinChargingOrderMapper.xml b/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TVinChargingOrderMapper.xml
new file mode 100644
index 0000000..dd54e80
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TVinChargingOrderMapper.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.order.mapper.TVinChargingOrderMapper">
+
+    <sql id="queryCondition">
+        <where>
+            o.del_flag = 0
+            <if test="query.siteIds != null and query.siteIds.size() > 0">
+                AND o.site_id IN
+                <foreach collection="query.siteIds" item="siteId" open="(" separator="," close=")">#{siteId}</foreach>
+            </if>
+            <if test="query.code != null and query.code != ''">AND o.code LIKE CONCAT('%', #{query.code}, '%')</if>
+            <if test="query.vin != null and query.vin != ''">
+                AND (o.vin LIKE CONCAT('%', #{query.vin}, '%') OR o.actual_vin LIKE CONCAT('%', #{query.vin}, '%') OR o.expected_vin LIKE CONCAT('%', #{query.vin}, '%'))
+            </if>
+            <if test="query.plateNum != null and query.plateNum != ''">AND o.plate_num LIKE CONCAT('%', #{query.plateNum}, '%')</if>
+            <if test="query.phone != null and query.phone != ''">AND o.phone LIKE CONCAT('%', #{query.phone}, '%')</if>
+            <if test="query.status != null">AND o.status = #{query.status}</if>
+            <if test="query.siteId != null">AND o.site_id = #{query.siteId}</if>
+            <if test="query.pileId != null">AND o.charging_pile_id = #{query.pileId}</if>
+            <if test="query.gunId != null">AND o.charging_gun_id = #{query.gunId}</if>
+            <if test="query.startTime1 != null and query.startTime1 != ''">AND o.start_time BETWEEN #{query.startTime1} AND #{query.startTime2}</if>
+            <if test="query.endTime1 != null and query.endTime1 != ''">AND o.end_time BETWEEN #{query.endTime1} AND #{query.endTime2}</if>
+        </where>
+    </sql>
+
+    <select id="pageList" resultType="com.ruoyi.order.api.vo.ChargingOrderVO">
+        SELECT o.*, COALESCE(o.actual_vin, o.expected_vin, o.vin) AS actual_vin, o.plate_num AS license_plate
+        FROM t_vin_charging_order o
+        <include refid="queryCondition"/>
+        ORDER BY o.create_time DESC, o.id DESC
+        LIMIT #{offset}, #{pageSize}
+    </select>
+
+    <select id="count" resultType="long">
+        SELECT COUNT(1) FROM t_vin_charging_order o <include refid="queryCondition"/>
+    </select>
+
+    <select id="summary" resultType="java.util.LinkedHashMap">
+        SELECT COUNT(1) AS orderCount,
+               IFNULL(SUM(o.charging_capacity), 0) AS total,
+               IFNULL(SUM(CASE WHEN o.start_time IS NOT NULL AND o.end_time IS NOT NULL THEN UNIX_TIMESTAMP(o.end_time) - UNIX_TIMESTAMP(o.start_time) ELSE 0 END), 0) AS time,
+               IFNULL(SUM(o.payment_amount), 0) AS income,
+               IFNULL(SUM(o.electrovalence), 0) AS electronicMoney,
+               IFNULL(SUM(o.service_charge), 0) AS serviceMoney
+        FROM t_vin_charging_order o
+        <include refid="queryCondition"/>
+    </select>
+
+    <select id="accountingStrategyList" resultType="java.util.LinkedHashMap">
+        SELECT id, charging_order_id AS chargingOrderId, accounting_strategy_detail_id AS accountingStrategyDetailId,
+               start_time AS startTime, end_time AS endTime, type, electrovalence,
+               service_charge AS serviceCharge, cost_service_charge AS costServiceCharge,
+               charging_capacity AS chargingCapacity, period_electric_price AS periodElectricPrice,
+               period_service_price AS periodServicePrice, create_time AS createTime
+        FROM t_vin_charging_order_accounting_strategy
+        WHERE charging_order_id = #{chargingOrderId}
+        ORDER BY start_time ASC, id ASC
+    </select>
+</mapper>
diff --git a/ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/mapper/VinChargingOrderMapperStructureTest.java b/ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/mapper/VinChargingOrderMapperStructureTest.java
new file mode 100644
index 0000000..4dab738
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/mapper/VinChargingOrderMapperStructureTest.java
@@ -0,0 +1,35 @@
+package com.ruoyi.order.mapper;
+
+import org.junit.jupiter.api.Test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.stream.Collectors;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class VinChargingOrderMapperStructureTest {
+
+    @Test
+    void usesOnlyVinOrderTablesAndSupportsRequiredFilters() throws IOException {
+        InputStream input = getClass().getClassLoader().getResourceAsStream("mapper/order/TVinChargingOrderMapper.xml");
+        assertNotNull(input);
+        String mapper;
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8))) {
+            mapper = reader.lines().collect(Collectors.joining("\n")).toLowerCase();
+        }
+        assertTrue(mapper.contains("from t_vin_charging_order o"));
+        assertTrue(mapper.contains("from t_vin_charging_order_accounting_strategy"));
+        assertTrue(mapper.contains("query.vin"));
+        assertTrue(mapper.contains("query.platenum"));
+        assertTrue(mapper.contains("query.phone"));
+        assertTrue(mapper.contains("query.siteids"));
+        assertFalse(mapper.contains("t_card_"));
+        assertFalse(mapper.contains("from t_charging_order "));
+    }
+}
diff --git a/sql/20260901_vin_charging_order.sql b/sql/20260901_vin_charging_order.sql
new file mode 100644
index 0000000..d49929b
--- /dev/null
+++ b/sql/20260901_vin_charging_order.sql
@@ -0,0 +1,243 @@
+-- VIN码充电订单独立存储增量脚本
+-- MyCat 环境请分逻辑库执行:订单表在 charging_pile_order,菜单在 charging_pile_other。
+
+USE charging_pile_order;
+
+CREATE TABLE IF NOT EXISTS `t_vin_charging_order` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '订单编号',
+  `vin_id` bigint NOT NULL COMMENT 'VIN管理记录ID(分片键)',
+  `vin` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'VIN码快照',
+  `order_type` int DEFAULT '2' COMMENT '订单类型(VIN码充电订单)',
+  `order_classification` int DEFAULT NULL COMMENT '订单分类(1=线上,2=线下)',
+  `app_user_id` bigint DEFAULT NULL COMMENT '用户id',
+  `app_user_car_id` bigint DEFAULT NULL COMMENT '充电车辆id',
+  `plate_num` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '车牌号',
+  `reservation_time` datetime DEFAULT NULL COMMENT '预约充电时间',
+  `expected_vin` varchar(64) DEFAULT NULL COMMENT '支付车辆VIN快照',
+  `actual_vin` varchar(64) DEFAULT NULL COMMENT '启动时设备识别VIN',
+  `site_id` int DEFAULT NULL COMMENT '站点id',
+  `parking_lot_id` int DEFAULT NULL COMMENT '停车场id',
+  `charging_pile_id` int DEFAULT NULL COMMENT '充电桩id',
+  `charging_gun_id` int DEFAULT NULL COMMENT '充电枪id',
+  `charging_capacity` decimal(10,5) DEFAULT '0.00000' COMMENT '充电总度数',
+  `charging_power` decimal(10,4) DEFAULT NULL COMMENT '充电功率',
+  `start_time` datetime DEFAULT NULL COMMENT '充电开始时间',
+  `end_time` datetime DEFAULT NULL COMMENT '充电结束时间',
+  `status` int DEFAULT NULL COMMENT '订单状态',
+  `end_mode` int DEFAULT NULL COMMENT '结束方式',
+  `recharge_amount` decimal(10,4) DEFAULT '0.0000' COMMENT '充值金额',
+  `recharge_payment_type` int DEFAULT NULL COMMENT '充值支付方式',
+  `recharge_payment_status` int DEFAULT NULL COMMENT '充值支付状态',
+  `pay_method` int DEFAULT NULL COMMENT '充电支付模式',
+  `balance_pay_amount` decimal(10,2) DEFAULT '0.00' COMMENT '余额支付金额',
+  `third_pay_amount` decimal(10,2) DEFAULT '0.00' COMMENT '第三方支付金额',
+  `balance_refund_amount` decimal(10,2) DEFAULT '0.00' COMMENT '余额退款金额',
+  `third_refund_amount` decimal(10,2) DEFAULT '0.00' COMMENT '第三方退款金额',
+  `recharge_serial_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '充值支付第三方流水号',
+  `charge_amount` decimal(10,2) DEFAULT NULL COMMENT '充电金额',
+  `residual_amount` decimal(10,2) DEFAULT NULL COMMENT '充值剩余金额',
+  `order_amount` decimal(10,4) DEFAULT NULL COMMENT '订单金额',
+  `payment_amount` decimal(10,4) DEFAULT NULL COMMENT '支付金额',
+  `refund_amount` decimal(10,4) DEFAULT '0.0000' COMMENT '退款金额',
+  `app_coupon_id` bigint DEFAULT NULL COMMENT '优惠券id',
+  `coupon_discount_amount` decimal(10,4) DEFAULT NULL COMMENT '优惠金额',
+  `is_whitelist` tinyint NOT NULL DEFAULT '0' COMMENT '是否白名单订单',
+  `whitelist_id` bigint DEFAULT NULL COMMENT '白名单用户ID',
+  `whitelist_benefit_type` tinyint DEFAULT NULL COMMENT '白名单权益',
+  `whitelist_discount_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '白名单减免金额',
+  `whitelist_electric_refund_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '白名单电费退款金额',
+  `whitelist_service_refund_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '白名单服务费退款金额',
+  `vip_discount` decimal(10,2) DEFAULT NULL COMMENT '会员折扣',
+  `vip_discount_amount` decimal(10,4) DEFAULT NULL COMMENT '会员优惠金额',
+  `refund_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '退款流水号',
+  `refund_status` int DEFAULT NULL COMMENT '退款状态',
+  `refund_serial_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '退款第三方流水号',
+  `refund_time` datetime DEFAULT NULL COMMENT '退款成功时间',
+  `create_time` datetime DEFAULT NULL COMMENT '添加时间',
+  `del_flag` tinyint(1) DEFAULT '0' COMMENT '删除标记',
+  `order_source` int DEFAULT '1' COMMENT '订单来源',
+  `source_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '平台名称',
+  `operator_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '运营商ID',
+  `tripartite_platform_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '三方平台名称',
+  `start_charge_seq` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '三方平台充电订单号',
+  `commission_amount` decimal(10,4) DEFAULT '0.0000' COMMENT '手续费',
+  `sharing_amount` decimal(10,4) DEFAULT '0.0000' COMMENT '分佣',
+  `service_charge` decimal(10,4) DEFAULT NULL COMMENT '累计服务费',
+  `electrovalence` decimal(10,4) DEFAULT NULL COMMENT '累计电费',
+  `current` decimal(10,2) DEFAULT NULL COMMENT '电流',
+  `voltage` decimal(10,2) DEFAULT NULL COMMENT '电压',
+  `electricity` decimal(10,2) DEFAULT NULL COMMENT '电量',
+  `power` decimal(10,2) DEFAULT NULL COMMENT '功率',
+  `pay_time` datetime DEFAULT NULL COMMENT '最后支付时间',
+  `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '电话',
+  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '订单标题',
+  `need_elec` decimal(10,2) DEFAULT NULL COMMENT '实时需求电流',
+  `total_electricity` double DEFAULT NULL COMMENT '剩余电量',
+  `start_soc` decimal(10,2) DEFAULT '0.00' COMMENT '开始SOC',
+  `end_soc` decimal(10,2) DEFAULT NULL COMMENT '结束SOC',
+  PRIMARY KEY USING BTREE (`id`),
+  KEY `idx_vin_id` USING BTREE (`vin_id`),
+  KEY `idx_vin` USING BTREE (`vin`),
+  KEY `idx_code` USING BTREE (`code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC COMMENT='VIN码充电订单'
+TBPARTITION BY MOD_HASH(vin_id) TBPARTITIONS 20;
+
+CREATE TABLE IF NOT EXISTS `t_vin_accounting_strategy_detail_order` (
+  `id` int NOT NULL COMMENT '计费策略明细主键id',
+  `accounting_strategy_id` int DEFAULT NULL COMMENT '策略id',
+  `type` int DEFAULT NULL COMMENT '阶段',
+  `start_time` varchar(100) DEFAULT NULL COMMENT '开始时间',
+  `end_time` varchar(100) DEFAULT NULL COMMENT '结束时间',
+  `electrovalence` double(10,4) DEFAULT NULL COMMENT '电价',
+  `service_charge` double(10,4) DEFAULT NULL COMMENT '服务费',
+  `cost_service_charge` double(10,4) DEFAULT NULL COMMENT '原价服务费',
+  `charging_order_id` bigint NOT NULL COMMENT 'VIN码充电订单id(分片键)',
+  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
+  `del_flag` int DEFAULT '0'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='VIN码订单计费策略明细快照'
+TBPARTITION BY MOD_HASH(charging_order_id) TBPARTITIONS 20;
+
+CREATE TABLE IF NOT EXISTS `t_vin_accounting_strategy_order` (
+  `id` int NOT NULL COMMENT '策略id',
+  `site_id` int DEFAULT NULL COMMENT '站点id',
+  `name` varchar(255) DEFAULT NULL COMMENT '策略名称',
+  `description` varchar(255) DEFAULT NULL COMMENT '策略说明',
+  `discount` double(10,2) DEFAULT NULL COMMENT '会员折扣',
+  `create_time` datetime DEFAULT NULL COMMENT '添加时间',
+  `del_flag` int DEFAULT '0' COMMENT '删除状态',
+  `first_user_id` bigint DEFAULT NULL COMMENT '一级审核用户id',
+  `two_user_id` bigint DEFAULT NULL COMMENT '二级审核用户id',
+  `first_remark` varchar(255) DEFAULT NULL COMMENT '一级审核备注',
+  `two_remark` varchar(255) DEFAULT NULL COMMENT '二级审核备注',
+  `audit_status` int DEFAULT '1' COMMENT '审核状态',
+  `first_audit_time` datetime DEFAULT NULL COMMENT '一级审核时间',
+  `two_audit_time` datetime DEFAULT NULL COMMENT '二级审核时间',
+  `user_id` bigint DEFAULT NULL COMMENT '申请人ID',
+  `parent_id` int DEFAULT NULL COMMENT '父级id',
+  `charging_order_id` bigint NOT NULL COMMENT 'VIN码充电订单id(分片键)'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='VIN码订单计费策略快照'
+TBPARTITION BY MOD_HASH(charging_order_id) TBPARTITIONS 20;
+
+CREATE TABLE IF NOT EXISTS `t_vin_charging_order_accounting_strategy` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `charging_order_id` bigint NOT NULL COMMENT 'VIN码充电订单id(分片键)',
+  `accounting_strategy_detail_id` bigint DEFAULT NULL COMMENT '计费策略明细id',
+  `type` int DEFAULT NULL COMMENT '阶段',
+  `start_time` varchar(100) DEFAULT NULL COMMENT '开始时间',
+  `end_time` varchar(100) DEFAULT NULL COMMENT '结束时间',
+  `electrovalence` double(10,4) DEFAULT NULL COMMENT '电价',
+  `service_charge` double(10,4) DEFAULT NULL COMMENT '服务费',
+  `cost_service_charge` double(10,4) DEFAULT NULL COMMENT '原价服务费',
+  `charging_capacity` decimal(10,4) DEFAULT NULL COMMENT '充电度数',
+  `create_time` datetime DEFAULT NULL COMMENT '首次添加时间',
+  `period_electric_price` decimal(10,4) DEFAULT NULL COMMENT '时段电费',
+  `period_service_price` decimal(10,4) DEFAULT NULL COMMENT '时段服务费',
+  `period_original_service_price` decimal(10,4) DEFAULT NULL COMMENT '时段原服务费',
+  `vip_discount_amount` decimal(10,4) DEFAULT NULL COMMENT '会员折扣金额',
+  `coupon_discount_amount` decimal(10,4) DEFAULT NULL COMMENT '优惠券抵扣金额',
+  PRIMARY KEY USING BTREE (`id`),
+  KEY `idx_vin_order_id` USING BTREE (`charging_order_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='VIN码充电订单计费明细'
+TBPARTITION BY MOD_HASH(charging_order_id) TBPARTITIONS 20;
+
+CREATE TABLE IF NOT EXISTS `t_vin_charging_order_refund` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `charging_order_id` bigint NOT NULL COMMENT 'VIN码充电订单id(分片键)',
+  `refund_code` varchar(255) DEFAULT NULL COMMENT '退款流水号',
+  `refund_amount` decimal(10,2) DEFAULT NULL COMMENT '退款金额',
+  `balance_refund_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '余额退款金额',
+  `third_refund_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '第三方退款金额',
+  `refund_status` int DEFAULT NULL COMMENT '退款状态',
+  `refund_serial_number` varchar(255) DEFAULT NULL COMMENT '退款第三方流水号',
+  `refund_time` datetime DEFAULT NULL COMMENT '退款成功时间',
+  `code` varchar(255) DEFAULT NULL COMMENT '订单编号',
+  `refund_title` varchar(255) DEFAULT NULL COMMENT '退款标题',
+  `refund_content` varchar(255) DEFAULT NULL COMMENT '退款内容',
+  `refund_reason` varchar(255) DEFAULT NULL COMMENT '退款原因',
+  `refund_remark` varchar(255) DEFAULT NULL COMMENT '退款备注',
+  `refund_total_amount` decimal(10,2) DEFAULT NULL COMMENT '累计退款金额',
+  `refund_fee` decimal(10,2) DEFAULT '0.00' COMMENT '手续费',
+  `pay_amount` decimal(10,2) DEFAULT NULL COMMENT '支付金额',
+  `pay_type` int DEFAULT NULL COMMENT '支付类型',
+  `create_time` datetime DEFAULT NULL,
+  `del_flag` int DEFAULT '0'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='VIN码充电退款明细'
+TBPARTITION BY MOD_HASH(charging_order_id) TBPARTITIONS 20;
+
+CREATE TABLE IF NOT EXISTS `t_vin_charging_order_share_record` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `charging_order_id` bigint DEFAULT NULL COMMENT 'VIN码充电订单ID',
+  `charging_order_code` varchar(64) NOT NULL COMMENT 'VIN码充电订单号',
+  `site_id` int DEFAULT NULL COMMENT '站点ID',
+  `partner_id` int DEFAULT NULL COMMENT '合作商ID',
+  `pay_channel` varchar(16) NOT NULL COMMENT '支付渠道',
+  `channel_pay_amount` decimal(10,2) NOT NULL DEFAULT '0.00',
+  `channel_gift_amount` decimal(10,2) NOT NULL DEFAULT '0.00',
+  `channel_pay_ratio` decimal(10,6) NOT NULL DEFAULT '0.000000',
+  `channel_electricity_amount` decimal(10,2) NOT NULL DEFAULT '0.00',
+  `channel_service_amount` decimal(10,2) NOT NULL DEFAULT '0.00',
+  `electricity_share_ratio` decimal(5,2) DEFAULT NULL,
+  `service_share_ratio` decimal(5,2) DEFAULT NULL,
+  `electricity_share_amount` decimal(10,2) NOT NULL DEFAULT '0.00',
+  `service_share_amount` decimal(10,2) NOT NULL DEFAULT '0.00',
+  `share_amount` decimal(10,2) NOT NULL DEFAULT '0.00',
+  `need_online_share` tinyint(1) NOT NULL DEFAULT '0',
+  `online_share_status` varchar(16) NOT NULL DEFAULT 'RECORDED',
+  `seq_no` varchar(50) DEFAULT NULL,
+  `busi_type` varchar(1) DEFAULT NULL,
+  `ori_mer_id` varchar(20) DEFAULT NULL,
+  `ori_trx_date` date DEFAULT NULL,
+  `sub_order_id` varchar(50) DEFAULT NULL,
+  `sub_mer_id` varchar(20) DEFAULT NULL,
+  `sub_mer_prtcl_no` varchar(20) DEFAULT NULL,
+  `mer_acct` varchar(34) DEFAULT NULL,
+  `icbc_order_id` varchar(64) DEFAULT NULL,
+  `sub_order_seq` varchar(32) DEFAULT NULL,
+  `sub_order_trxid` varchar(64) DEFAULT NULL,
+  `rec_result` varchar(8) DEFAULT NULL,
+  `request_json` text,
+  `response_json` text,
+  `fail_reason` varchar(512) DEFAULT NULL,
+  `retry_count` int NOT NULL DEFAULT '0',
+  `last_retry_time` datetime DEFAULT NULL,
+  `create_time` datetime DEFAULT NULL,
+  `del_flag` int DEFAULT '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `uk_order_channel` (`charging_order_code`,`pay_channel`),
+  KEY `idx_share_status` (`online_share_status`),
+  KEY `idx_share_sub_order_id` (`sub_order_id`),
+  KEY `idx_share_partner` (`partner_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='VIN码充电订单全渠道分账记录';
+
+USE charging_pile_other;
+
+INSERT INTO `sys_menu`
+(`menu_name`,`parent_id`,`order_num`,`path`,`component`,`query`,`is_frame`,`is_cache`,`menu_type`,`visible`,`status`,`perms`,`icon`,`create_by`,`create_time`,`update_by`,`update_time`,`remark`)
+SELECT 'VIN码充电订单', parent.menu_id, 2, 'vinChargingOrder', 'order/vinChargingOrder/index', '', 1, 0, 'C', '0', '0', '/vinChargingOrder/list', 'transaction', 'admin', NOW(), '', NULL, 'VIN码充电订单独立查询'
+FROM `sys_menu` parent
+WHERE parent.perms = '/vinManagement'
+  AND NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `perms` = '/vinChargingOrder/list');
+
+INSERT INTO `sys_menu`
+(`menu_name`,`parent_id`,`order_num`,`path`,`component`,`query`,`is_frame`,`is_cache`,`menu_type`,`visible`,`status`,`perms`,`icon`,`create_by`,`create_time`,`update_by`,`update_time`,`remark`)
+SELECT 'VIN订单详情', parent.menu_id, 1, '#', '', '', 1, 0, 'F', '0', '0', '/vinChargingOrder/detail', '#', 'admin', NOW(), '', NULL, ''
+FROM `sys_menu` parent
+WHERE parent.perms = '/vinChargingOrder/list'
+  AND NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `perms` = '/vinChargingOrder/detail');
+
+INSERT INTO `sys_menu`
+(`menu_name`,`parent_id`,`order_num`,`path`,`component`,`query`,`is_frame`,`is_cache`,`menu_type`,`visible`,`status`,`perms`,`icon`,`create_by`,`create_time`,`update_by`,`update_time`,`remark`)
+SELECT 'VIN订单导出', parent.menu_id, 2, '#', '', '', 1, 0, 'F', '0', '0', '/vinChargingOrder/export', '#', 'admin', NOW(), '', NULL, ''
+FROM `sys_menu` parent
+WHERE parent.perms = '/vinChargingOrder/list'
+  AND NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `perms` = '/vinChargingOrder/export');
+
+INSERT INTO `sys_role_menu` (`role_id`,`menu_id`)
+SELECT 1, menu.menu_id
+FROM `sys_menu` menu
+WHERE menu.perms IN ('/vinChargingOrder/list','/vinChargingOrder/detail','/vinChargingOrder/export')
+  AND NOT EXISTS (
+    SELECT 1 FROM `sys_role_menu` role_menu
+    WHERE role_menu.role_id = 1 AND role_menu.menu_id = menu.menu_id
+  );

--
Gitblit v1.7.1