From 372107864f52452727ea34125132a33c3f096612 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期二, 22 九月 2026 17:11:01 +0800
Subject: [PATCH] 添加集团和分公司部分功能

---
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TGroupCompany.java              |   81 +++++++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/GroupTreeVo.java                        |   33 +++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/GroupCompanyVo.java                     |   36 +++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TGroupCompanyServiceImpl.java |   20 +
 sql/20260922_group_company.sql                                                                     |   23 ++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TGroupCompanyService.java          |   16 +
 sql/20260903_complete_database_comments.sql                                                        |    2 
 doc/耗时统计.md                                                                                        |    1 
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TGroup.java                     |   37 +++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/TGroupCompanyMapper.java            |   16 +
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TGroupService.java                 |   26 ++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGroupController.java           |  125 +++++++++++
 sql/20260922_group_management.sql                                                                  |   12 +
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/TGroupMapper.java                   |   16 +
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGroupCompanyController.java    |  144 +++++++++++++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TGroupServiceImpl.java        |   51 ++++
 16 files changed, 638 insertions(+), 1 deletions(-)

diff --git "a/doc/\350\200\227\346\227\266\347\273\237\350\256\241.md" "b/doc/\350\200\227\346\227\266\347\273\237\350\256\241.md"
index 8befe0e..7258f5a 100644
--- "a/doc/\350\200\227\346\227\266\347\273\237\350\256\241.md"
+++ "b/doc/\350\200\227\346\227\266\347\273\237\350\256\241.md"
@@ -12,3 +12,4 @@
 | 2026-09-01 13:46:42 | 2026-09-01 14:07:44 | 1262 | 推送代码 | 是:仅提交 VIN 码充电订单功能,精确排除刷卡订单统计未完成改动;隔离暂存快照回归后普通推送前后端分支 | 提交并推送 VIN 独立订单表、列表/汇总/详情/计费明细/导出、菜单权限,以及管理后台 VIN 订单页面;服务端提交 `6cff7f18`,管理后台提交 `50a2bbbd` | 服务端 11 个 VIN 业务、测试及 SQL 文件;管理后台 7 个 VIN 页面、路由与权限文件;本统计文件 | 后端订单模块及依赖 Maven `clean test` BUILD SUCCESS、VIN 聚焦测试 BUILD SUCCESS;前端 `tsc`、Jest 12 套件/44 用例、生产构建、UTF-8、`git diff --cached --check`、远端引用核验全部通过 | 未执行数据库脚本;刷卡订单统计改动继续保留本地;既存 Maven 模型、React act、Jest open handle、Browserslist 警告不影响结果 |
 | 2026-09-15 09:41:00(估算) | 2026-09-15 10:33:37 | 3157(估算) | 请继续执行未完成的任务。(续作:VIN 订单首末 SOC 回填) | 是:统一结算首次处理时按监控创建时间升/降序取首末 SOC,空数据或查询异常不阻断,重复账单保持幂等 | 在 VD 正常交易记录及充电超时补偿共用结算入口中回填 `start_soc/end_soc`;增加正常映射、空监控数据及重复账单不查询 Mongo 的回归断言 | `ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java`;`ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/CardVinSettlementTimeAlignmentTest.java`;`ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/CardVinOrderCompensationTest.java`;`doc/耗时统计.md` | UTF-8、IDE lint、`git diff --check` 通过;reactor `mvn -o -pl ruoyi-service/ruoyi-order -am install -DskipTests` BUILD SUCCESS;定向 20/20、ruoyi-order 全量 178/178 JUnit 5 全部通过;代码走查通过 | 开始时间依据当天分析记录估算,耗时包含方案分析及等待续作;首轮 Maven 在工作区根目录因 reactor 路径错误未执行构建,进入 `ChargingPile` 后重跑通过 |
 | 2026-09-15 17:39:31 | 2026-09-15 17:52:02 | 751 | 请继续执行未完成的任务。(续作:SD 已结束未扣款补偿) | 是:账户侧新增批量扣款流水查询接口,订单侧扫描状态5且应扣款的刷卡订单,逐单复核无扣款流水后条件回退为停止中交由既有补偿结算;本轮补齐“已有流水不回退”“账户查询失败不回退”“无候选不远程调用”“未抢到锁不回退”“定时任务异常隔离”5 个回归用例 | 完成 SD 已结束(状态5)订单无充电扣款流水的定时兜底回退,并补齐测试与全量回归;默认 surefire 版本无法执行 JUnit 5,改用本地仓库 surefire 2.22.2 执行 | `ruoyi-api/ruoyi-api-account/.../feignClient/ChargingCardClient.java`;`ruoyi-api/ruoyi-api-account/.../factory/ChargingCardFallbackFactory.java`;`ruoyi-service/ruoyi-account/.../controller/TChargingCardController.java`;`.../mapper/TChargingCardMapper.java`;`.../service/TChargingCardService.java`;`.../service/impl/TChargingCardServiceImpl.java`;`.../resources/mapper/account/TChargingCardMapper.xml`;`.../test/.../TChargingCardControllerTest.java`;`.../test/.../TChargingCardServiceImplTest.java`;`ruoyi-service/ruoyi-order/.../service/TCardChargingOrderService.java`;`.../service/impl/TCardChargingOrderServiceImpl.java`;`.../service/impl/TVinChargingOrderServiceImpl.java`;`.../util/task/TaskUtil.java`;`.../test/.../TCardChargingOrderAmountFieldsTest.java`;`.../test/.../TaskUtilCompensationTest.java`;`doc/耗时统计.md` | `mvn -o -pl ruoyi-api/ruoyi-api-account,ruoyi-service/ruoyi-account,ruoyi-service/ruoyi-order -am test-compile -DskipTests` BUILD SUCCESS;surefire 2.22.2 定向 14/14、ruoyi-order 全量 185/185、ruoyi-account 全量 103/103 全部通过;IDE lint 0 条;`git diff --check` 通过;代码走查通过 | 开始时间取本次续作会话首个命令时间,耗时仅统计续作会话(751 秒);实现主体在当天更早会话完成、时间未记录,故整体任务耗时未合并统计;新增用例首轮因在 thenReturn 参数内调用 Mockito 桩方法触发 UnfinishedStubbing,提取局部变量后修复 |
+| 2026-09-21 15:19:30(估算) | 2026-09-21 15:23:29 | 约 240(估算) | 分析代码,汇总下已完成三方对接的品牌:光伏:科士达、华为、隆基、晶科、通威;储能:利普芯储能、华为、宁德时代、阳光电源;监控:海康、萤石、大华;道闸:吉莲、顺捷 | 否(只读分析任务,未涉及代码修改,无需授权口令) | 全项目盘点光伏/储能/视频监控/道闸四类三方对接实现,逐品牌核对真实完成情况,区分「已完成对接 / 仅枚举占位 / 代码中不存在」,并核对数据表品牌字段与同步任务 | `.codebuddy/memory/2026-09-21.md`(新建);`.codebuddy/memory/MEMORY.md`;`doc/耗时统计.md`(未修改任何业务代码) | 只读分析,未执行构建与测试;通过全库关键词检索、类与 SQL 文件走查、调用链核对交叉验证(含 2 个子代理并行探索) | 开始时间因本会话首条命令时间戳不可得而估算;结论:已真实完成对接为科士达、华为(仅光伏)、利普芯(eMind2000)、萤石、通用 HTTP 道闸平台,以及清单外的优旦储能;阳光电源/古瑞瓦特/海康/大华/顺捷、吉联、舜杰、捷联均为枚举占位;隆基、晶科、通威、宁德时代、吉莲在代码中不存在 |
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TGroup.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TGroup.java
new file mode 100644
index 0000000..a1538fd
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TGroup.java
@@ -0,0 +1,37 @@
+package com.ruoyi.other.api.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.web.domain.BasePojo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 集团管理实体(t_group)
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("t_group")
+@ApiModel(value = "TGroup对象", description = "集团管理")
+public class TGroup extends BasePojo {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "集团名称")
+    @TableField("group_name")
+    private String groupName;
+
+}
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TGroupCompany.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TGroupCompany.java
new file mode 100644
index 0000000..59a1c7d
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/domain/TGroupCompany.java
@@ -0,0 +1,81 @@
+package com.ruoyi.other.api.domain;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.web.domain.BasePojo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 公司(企业)管理实体(t_group_company)
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("t_group_company")
+@ApiModel(value = "TGroupCompany对象", description = "公司管理")
+public class TGroupCompany extends BasePojo {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "集团ID(关联t_group.id)")
+    @TableField("group_id")
+    private Integer groupId;
+
+    @ApiModelProperty(value = "公司名称")
+    @TableField("name")
+    private String name;
+
+    @ApiModelProperty(value = "公司编码")
+    @TableField("code")
+    private String code;
+
+    @ApiModelProperty(value = "联系人")
+    @TableField("contact_name")
+    private String contactName;
+
+    @ApiModelProperty(value = "联系人电话")
+    @TableField("contact_phone")
+    private String contactPhone;
+
+    @ApiModelProperty(value = "账户模式(1=预充值,2=后付费)")
+    @TableField("account_mode")
+    private Integer accountMode;
+
+    @ApiModelProperty(value = "月充值金额")
+    @TableField("month_recharge_amount")
+    private BigDecimal monthRechargeAmount;
+
+    @ApiModelProperty(value = "当前可用余额")
+    @TableField("available_balance")
+    private BigDecimal availableBalance;
+
+    @ApiModelProperty(value = "公司状态(1=启用,0=停用)")
+    @TableField("status")
+    private Integer status;
+
+    @ApiModelProperty(value = "备注")
+    @TableField("remark")
+    private String remark;
+
+    @ApiModelProperty(value = "更新时间")
+    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGroupCompanyController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGroupCompanyController.java
new file mode 100644
index 0000000..10e3585
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGroupCompanyController.java
@@ -0,0 +1,144 @@
+package com.ruoyi.other.controller;
+
+import com.ruoyi.common.core.web.domain.AjaxResult;
+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.Logical;
+import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.ruoyi.other.api.domain.TGroupCompany;
+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.PostMapping;
+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;
+
+/**
+ * <p>
+ * 公司(企业)管理 前端控制器
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+@RestController
+@RequestMapping("/group-company")
+public class TGroupCompanyController {
+
+    @Resource
+    private TGroupCompanyService groupCompanyService;
+
+    /**
+     * 分页查询公司
+     */
+    @RequiresPermissions(value = {"/companyManagement/list"}, logical = Logical.OR)
+    @GetMapping("/page")
+    @ApiOperation(value = "分页查询公司", tags = {"管理后台-公司管理"})
+    public AjaxResult<PageInfo<TGroupCompany>> page(@RequestParam(value = "current", defaultValue = "1") Integer current,
+                                                     @RequestParam(value = "size", defaultValue = "10") Integer size,
+                                                     @RequestParam(value = "groupId", required = false) Integer groupId,
+                                                     @RequestParam(value = "name", required = false) String name,
+                                                     @RequestParam(value = "contactName", required = false) String contactName,
+                                                     @RequestParam(value = "contactPhone", required = false) String contactPhone,
+                                                     @RequestParam(value = "status", required = false) Integer status) {
+        PageInfo<TGroupCompany> page = new PageInfo<>(current, size);
+        groupCompanyService.lambdaQuery()
+                .eq(groupId != null, TGroupCompany::getGroupId, groupId)
+                .like(StringUtils.hasText(name), TGroupCompany::getName, name)
+                .like(StringUtils.hasText(contactName), TGroupCompany::getContactName, contactName)
+                .like(StringUtils.hasText(contactPhone), TGroupCompany::getContactPhone, contactPhone)
+                .eq(status != null, TGroupCompany::getStatus, status)
+                .orderByDesc(TGroupCompany::getId)
+                .page(page);
+        return AjaxResult.success(page);
+    }
+
+    /**
+     * 公司详情
+     */
+    @RequiresPermissions(value = {"/companyManagement/list"}, logical = Logical.OR)
+    @GetMapping("/detail")
+    @ApiOperation(value = "公司详情", tags = {"管理后台-公司管理"})
+    public AjaxResult<TGroupCompany> detail(@RequestParam("id") Integer id) {
+        return AjaxResult.success(groupCompanyService.getById(id));
+    }
+
+    /**
+     * 添加公司
+     */
+    @RequiresPermissions(value = {"/companyManagement/list"}, logical = Logical.OR)
+    @PostMapping("/add")
+    @ApiOperation(value = "添加公司", tags = {"管理后台-公司管理"})
+    @Log(title = "【公司管理】添加公司", businessType = BusinessType.INSERT)
+    public AjaxResult add(@RequestBody TGroupCompany company) {
+        if (company.getGroupId() == null) {
+            return AjaxResult.error("所属集团不能为空");
+        }
+        if (!StringUtils.hasText(company.getName())) {
+            return AjaxResult.error("公司名称不能为空");
+        }
+        company.setId(null);
+        company.setDelFlag(false);
+        if (company.getStatus() == null) {
+            company.setStatus(1);
+        }
+        groupCompanyService.save(company);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 编辑公司
+     */
+    @RequiresPermissions(value = {"/companyManagement/list"}, logical = Logical.OR)
+    @PostMapping("/edit")
+    @ApiOperation(value = "编辑公司", tags = {"管理后台-公司管理"})
+    @Log(title = "【公司管理】编辑公司", businessType = BusinessType.UPDATE)
+    public AjaxResult edit(@RequestBody TGroupCompany company) {
+        if (company.getId() == null) {
+            return AjaxResult.error("公司ID不能为空");
+        }
+        groupCompanyService.updateById(company);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 删除公司
+     */
+    @RequiresPermissions(value = {"/companyManagement/list"}, logical = Logical.OR)
+    @DeleteMapping("/del")
+    @ApiOperation(value = "删除公司", tags = {"管理后台-公司管理"})
+    @Log(title = "【公司管理】删除公司", businessType = BusinessType.DELETE)
+    public AjaxResult del(@RequestParam("id") Integer id) {
+        if (id == null) {
+            return AjaxResult.error("公司ID不能为空");
+        }
+        groupCompanyService.removeById(id);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 切换公司启用状态
+     */
+    @RequiresPermissions(value = {"/companyManagement/list"}, logical = Logical.OR)
+    @PostMapping("/status")
+    @ApiOperation(value = "切换公司启用状态", tags = {"管理后台-公司管理"})
+    @Log(title = "【公司管理】切换公司状态", businessType = BusinessType.UPDATE)
+    public AjaxResult status(@RequestParam("id") Integer id, @RequestParam("status") Integer status) {
+        if (id == null) {
+            return AjaxResult.error("公司ID不能为空");
+        }
+        TGroupCompany update = new TGroupCompany();
+        update.setId(id);
+        update.setStatus(status);
+        groupCompanyService.updateById(update);
+        return AjaxResult.success();
+    }
+
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGroupController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGroupController.java
new file mode 100644
index 0000000..7ee8bed
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGroupController.java
@@ -0,0 +1,125 @@
+package com.ruoyi.other.controller;
+
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.log.annotation.Log;
+import com.ruoyi.common.log.enums.BusinessType;
+import com.ruoyi.common.security.annotation.Logical;
+import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.ruoyi.other.api.domain.TGroup;
+import com.ruoyi.other.api.domain.TGroupCompany;
+import com.ruoyi.other.service.TGroupCompanyService;
+import com.ruoyi.other.service.TGroupService;
+import com.ruoyi.other.vo.GroupTreeVo;
+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.PostMapping;
+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 java.util.List;
+
+/**
+ * <p>
+ * 集团管理 前端控制器
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+@RestController
+@RequestMapping("/group")
+public class TGroupController {
+
+    @Resource
+    private TGroupService groupService;
+
+    @Resource
+    private TGroupCompanyService groupCompanyService;
+
+    /**
+     * 获取组织树(第一层集团,第二层企业)
+     */
+    @RequiresPermissions(value = {"/companyManagement/list"}, logical = Logical.OR)
+    @GetMapping("/tree")
+    @ApiOperation(value = "获取组织树", tags = {"管理后台-公司管理"})
+    public AjaxResult<List<GroupTreeVo>> tree() {
+        return AjaxResult.success(groupService.groupTree());
+    }
+
+    /**
+     * 添加集团
+     */
+    @RequiresPermissions(value = {"/companyManagement/list"}, logical = Logical.OR)
+    @PostMapping("/add")
+    @ApiOperation(value = "添加集团", tags = {"管理后台-公司管理"})
+    @Log(title = "【公司管理】添加集团", businessType = BusinessType.INSERT)
+    public AjaxResult add(@RequestBody TGroup group) {
+        if (!StringUtils.hasText(group.getGroupName())) {
+            return AjaxResult.error("集团名称不能为空");
+        }
+        String groupName = group.getGroupName().trim();
+        long count = groupService.lambdaQuery().eq(TGroup::getGroupName, groupName).count();
+        if (count > 0) {
+            return AjaxResult.error("集团名称已存在");
+        }
+        group.setId(null);
+        group.setGroupName(groupName);
+        group.setDelFlag(false);
+        groupService.save(group);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 编辑集团
+     */
+    @RequiresPermissions(value = {"/companyManagement/list"}, logical = Logical.OR)
+    @PostMapping("/edit")
+    @ApiOperation(value = "编辑集团", tags = {"管理后台-公司管理"})
+    @Log(title = "【公司管理】编辑集团", businessType = BusinessType.UPDATE)
+    public AjaxResult edit(@RequestBody TGroup group) {
+        if (group.getId() == null) {
+            return AjaxResult.error("集团ID不能为空");
+        }
+        if (!StringUtils.hasText(group.getGroupName())) {
+            return AjaxResult.error("集团名称不能为空");
+        }
+        String groupName = group.getGroupName().trim();
+        long count = groupService.lambdaQuery()
+                .eq(TGroup::getGroupName, groupName)
+                .ne(TGroup::getId, group.getId())
+                .count();
+        if (count > 0) {
+            return AjaxResult.error("集团名称已存在");
+        }
+        TGroup update = new TGroup();
+        update.setId(group.getId());
+        update.setGroupName(groupName);
+        groupService.updateById(update);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 删除集团(集团下存在企业时禁止删除)
+     */
+    @RequiresPermissions(value = {"/companyManagement/list"}, logical = Logical.OR)
+    @DeleteMapping("/del")
+    @ApiOperation(value = "删除集团", tags = {"管理后台-公司管理"})
+    @Log(title = "【公司管理】删除集团", businessType = BusinessType.DELETE)
+    public AjaxResult del(@RequestParam("id") Integer id) {
+        if (id == null) {
+            return AjaxResult.error("集团ID不能为空");
+        }
+        long companyCount = groupCompanyService.lambdaQuery().eq(TGroupCompany::getGroupId, id).count();
+        if (companyCount > 0) {
+            return AjaxResult.error("该集团下存在企业,无法删除");
+        }
+        groupService.removeById(id);
+        return AjaxResult.success();
+    }
+
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/TGroupCompanyMapper.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/TGroupCompanyMapper.java
new file mode 100644
index 0000000..d8850b9
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/TGroupCompanyMapper.java
@@ -0,0 +1,16 @@
+package com.ruoyi.other.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.other.api.domain.TGroupCompany;
+
+/**
+ * <p>
+ * 公司(企业)管理 Mapper 接口
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+public interface TGroupCompanyMapper extends BaseMapper<TGroupCompany> {
+
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/TGroupMapper.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/TGroupMapper.java
new file mode 100644
index 0000000..84cd8cb
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/mapper/TGroupMapper.java
@@ -0,0 +1,16 @@
+package com.ruoyi.other.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.other.api.domain.TGroup;
+
+/**
+ * <p>
+ * 集团管理 Mapper 接口
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+public interface TGroupMapper extends BaseMapper<TGroup> {
+
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TGroupCompanyService.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TGroupCompanyService.java
new file mode 100644
index 0000000..fc291f1
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TGroupCompanyService.java
@@ -0,0 +1,16 @@
+package com.ruoyi.other.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.other.api.domain.TGroupCompany;
+
+/**
+ * <p>
+ * 公司(企业)管理 服务类
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+public interface TGroupCompanyService extends IService<TGroupCompany> {
+
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TGroupService.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TGroupService.java
new file mode 100644
index 0000000..bcd277e
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TGroupService.java
@@ -0,0 +1,26 @@
+package com.ruoyi.other.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.other.api.domain.TGroup;
+import com.ruoyi.other.vo.GroupTreeVo;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 集团管理 服务类
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+public interface TGroupService extends IService<TGroup> {
+
+    /**
+     * 查询组织树(第一层集团,第二层企业)
+     *
+     * @return 组织树
+     */
+    List<GroupTreeVo> groupTree();
+
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TGroupCompanyServiceImpl.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TGroupCompanyServiceImpl.java
new file mode 100644
index 0000000..676e2f1
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TGroupCompanyServiceImpl.java
@@ -0,0 +1,20 @@
+package com.ruoyi.other.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.other.api.domain.TGroupCompany;
+import com.ruoyi.other.mapper.TGroupCompanyMapper;
+import com.ruoyi.other.service.TGroupCompanyService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 公司(企业)管理 服务实现类
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+@Service
+public class TGroupCompanyServiceImpl extends ServiceImpl<TGroupCompanyMapper, TGroupCompany> implements TGroupCompanyService {
+
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TGroupServiceImpl.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TGroupServiceImpl.java
new file mode 100644
index 0000000..d5732be
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TGroupServiceImpl.java
@@ -0,0 +1,51 @@
+package com.ruoyi.other.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.other.api.domain.TGroup;
+import com.ruoyi.other.api.domain.TGroupCompany;
+import com.ruoyi.other.mapper.TGroupMapper;
+import com.ruoyi.other.service.TGroupCompanyService;
+import com.ruoyi.other.service.TGroupService;
+import com.ruoyi.other.vo.GroupCompanyVo;
+import com.ruoyi.other.vo.GroupTreeVo;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 集团管理 服务实现类
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+@Service
+public class TGroupServiceImpl extends ServiceImpl<TGroupMapper, TGroup> implements TGroupService {
+
+    @Resource
+    private TGroupCompanyService groupCompanyService;
+
+    @Override
+    public List<GroupTreeVo> groupTree() {
+        List<TGroup> groups = lambdaQuery().orderByAsc(TGroup::getId).list();
+        if (groups.isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<TGroupCompany> companies = groupCompanyService.lambdaQuery().orderByAsc(TGroupCompany::getId).list();
+        return groups.stream().map(group -> {
+            GroupTreeVo vo = new GroupTreeVo();
+            vo.setId(group.getId());
+            vo.setGroupName(group.getGroupName());
+            vo.setChildren(companies.stream()
+                    .filter(company -> company.getGroupId() != null && company.getGroupId().equals(group.getId()))
+                    .map(company -> new GroupCompanyVo(company.getId(), company.getName(), company.getGroupId()))
+                    .collect(Collectors.toList()));
+            return vo;
+        }).collect(Collectors.toList());
+    }
+
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/GroupCompanyVo.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/GroupCompanyVo.java
new file mode 100644
index 0000000..9708b2a
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/GroupCompanyVo.java
@@ -0,0 +1,36 @@
+package com.ruoyi.other.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 组织树-企业节点(第二层)
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ApiModel(value = "GroupCompanyVo对象", description = "组织树-企业节点")
+public class GroupCompanyVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "企业ID")
+    private Integer id;
+
+    @ApiModelProperty(value = "企业名称")
+    private String name;
+
+    @ApiModelProperty(value = "集团ID")
+    private Integer groupId;
+
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/GroupTreeVo.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/GroupTreeVo.java
new file mode 100644
index 0000000..2708e85
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/GroupTreeVo.java
@@ -0,0 +1,33 @@
+package com.ruoyi.other.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * <p>
+ * 组织树-集团节点(第一层)
+ * </p>
+ *
+ * @author mxcd
+ * @since 2026-09-22
+ */
+@Data
+@ApiModel(value = "GroupTreeVo对象", description = "组织树-集团节点")
+public class GroupTreeVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "集团ID")
+    private Integer id;
+
+    @ApiModelProperty(value = "集团名称")
+    private String groupName;
+
+    @ApiModelProperty(value = "企业列表")
+    private List<GroupCompanyVo> children;
+
+}
diff --git a/sql/20260903_complete_database_comments.sql b/sql/20260903_complete_database_comments.sql
index feae06b..db7e118 100644
--- a/sql/20260903_complete_database_comments.sql
+++ b/sql/20260903_complete_database_comments.sql
@@ -158,7 +158,7 @@
 ALTER TABLE `charging_pile_service`.`t_site` MODIFY COLUMN `venue_partner_id` int NULL DEFAULT NULL COMMENT '场地方合作商ID';
 ALTER TABLE `charging_pile_service`.`t_partner` MODIFY COLUMN `partner_type` int NULL DEFAULT NULL COMMENT '合作商类型:1普通合作商,2场地方,3服务商';
 ALTER TABLE `charging_pile_service`.`t_partner` MODIFY COLUMN `venue_share_amount` decimal(10,2) NULL DEFAULT NULL COMMENT '场地方合作商分账金额(元)';
-ALTER TABLE `charging_pile_service`.`t_parking_lot` MODIFY COLUMN `barrier_brand` int NULL DEFAULT NULL COMMENT '道闸品牌:1舜杰,2捷联';
+ALTER TABLE `charging_pile_service`.`t_parking_lot` MODIFY COLUMN `barrier_brand` int NULL DEFAULT NULL COMMENT '道闸品牌:1顺捷,2吉莲';
 
 
 ALTER TABLE `charging_pile_account`.`t_app_user_car` MODIFY COLUMN `pic` varchar(255) NULL COMMENT '车辆图片';
diff --git a/sql/20260922_group_company.sql b/sql/20260922_group_company.sql
new file mode 100644
index 0000000..905f9b1
--- /dev/null
+++ b/sql/20260922_group_company.sql
@@ -0,0 +1,23 @@
+-- ----------------------------
+-- 公司管理表
+-- 创建日期: 2026-09-22
+-- 库: charging_pile_other
+-- ----------------------------
+CREATE TABLE `t_group_company` (
+  `id`                    int           NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `group_id`              int           NULL DEFAULT NULL COMMENT '集团ID(关联t_group.id)',
+  `name`                  varchar(255)  NULL DEFAULT NULL COMMENT '公司名称',
+  `code`                  varchar(255)  NULL DEFAULT NULL COMMENT '公司编码',
+  `contact_name`          varchar(64)   NULL DEFAULT NULL COMMENT '联系人',
+  `contact_phone`         varchar(32)   NULL DEFAULT NULL COMMENT '联系人电话',
+  `account_mode`          tinyint       NULL DEFAULT NULL COMMENT '账户模式(1=预充值,2=后付费)',
+  `month_recharge_amount` decimal(12,2) NULL DEFAULT NULL COMMENT '月充值金额',
+  `available_balance`     decimal(12,2) NULL DEFAULT NULL COMMENT '当前可用余额',
+  `status`                tinyint       NULL DEFAULT NULL COMMENT '公司状态(1=启用,0=停用)',
+  `remark`                varchar(255)  NULL DEFAULT NULL COMMENT '备注',
+  `create_time`           datetime(0)   NULL DEFAULT NULL COMMENT '创建时间',
+  `update_time`           datetime(0)   NULL DEFAULT NULL COMMENT '更新时间',
+  `del_flag`              int           NULL DEFAULT NULL COMMENT '删除(0=否,1=是)',
+  PRIMARY KEY (`id`),
+  KEY `idx_group_id` (`group_id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='公司管理';
diff --git a/sql/20260922_group_management.sql b/sql/20260922_group_management.sql
new file mode 100644
index 0000000..2bd9496
--- /dev/null
+++ b/sql/20260922_group_management.sql
@@ -0,0 +1,12 @@
+-- ----------------------------
+-- 集团管理表(2026-09-22)
+-- 库:charging_pile_other
+-- 仅存储集团名称,业务字段只有 group_name
+-- ----------------------------
+CREATE TABLE `t_group`  (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `group_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '集团名称',
+  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
+  `del_flag` int NULL DEFAULT NULL COMMENT '删除(0=否,1=是)',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '集团管理' ROW_FORMAT = DYNAMIC;

--
Gitblit v1.7.1