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