package com.ruoyi.other.controller;
|
|
import com.ruoyi.common.core.domain.R;
|
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.CompanyAccountAccessService;
|
import com.ruoyi.other.service.TGroupCompanyService;
|
import io.swagger.annotations.ApiOperation;
|
import org.springframework.util.StringUtils;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.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.math.BigDecimal;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.stream.Collectors;
|
|
/**
|
* <p>
|
* 公司(企业)管理 前端控制器
|
* </p>
|
*
|
* @author mxcd
|
* @since 2026-09-22
|
*/
|
@RestController
|
@RequestMapping("/group-company")
|
public class TGroupCompanyController {
|
|
@Resource
|
private TGroupCompanyService groupCompanyService;
|
@Resource
|
private CompanyAccountAccessService companyAccountAccessService;
|
|
/**
|
* 分页查询公司
|
* <p>公司账号(roleType=5)只返回本公司数据,非公司账号保持原有查询范围</p>
|
*/
|
@RequiresPermissions(value = {"/companyManagement/list", "/fleet/list", "/vinManagement/list", "/chargingCard/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);
|
// 公司账号(roleType=5)只返回本公司数据;平台/合作商等账号保持原查询范围
|
Integer currentCompanyId = companyAccountAccessService.getCurrentCompanyId();
|
groupCompanyService.lambdaQuery()
|
.eq(currentCompanyId != null, TGroupCompany::getId, currentCompanyId)
|
.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.getDetailWithChargingUsers(id));
|
}
|
|
/**
|
* 添加公司(同步创建登录账号,roleType=5)
|
*/
|
@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("公司名称不能为空");
|
}
|
if (!StringUtils.hasText(company.getAccount())) {
|
return AjaxResult.error("登录账号不能为空");
|
}
|
if (!StringUtils.hasText(company.getPassword())) {
|
return AjaxResult.error("登录密码不能为空");
|
}
|
company.setId(null);
|
company.setDelFlag(false);
|
if (company.getStatus() == null) {
|
company.setStatus(1);
|
}
|
return groupCompanyService.addCompany(company);
|
}
|
|
/**
|
* 编辑公司(同步登录账号资料,密码不可修改)
|
*/
|
@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不能为空");
|
}
|
return groupCompanyService.editCompany(company);
|
}
|
|
/**
|
* 删除公司(同步停用其登录账号 delFlag=2)
|
*/
|
@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不能为空");
|
}
|
return groupCompanyService.delCompany(id);
|
}
|
|
/**
|
* 切换公司启用状态
|
*/
|
@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();
|
}
|
|
/**
|
* 修改公司账户模式(公司管理-账户模式弹窗使用,1=共享模式,2=分配模式)
|
*/
|
@RequiresPermissions(value = {"/companyManagement/list"}, logical = Logical.OR)
|
@PostMapping("/account-mode")
|
@ApiOperation(value = "修改公司账户模式", tags = {"管理后台-公司管理"})
|
@Log(title = "【公司管理】修改账户模式", businessType = BusinessType.UPDATE)
|
public AjaxResult accountMode(@RequestParam("id") Integer id, @RequestParam("accountMode") Integer accountMode) {
|
return groupCompanyService.updateAccountMode(id, accountMode);
|
}
|
|
/**
|
* 远程接口:公司详情(VIN码车辆所属公司、可用余额校验、卡片额度分配概览使用,内部调用)
|
* 返回含车队数量、月充值金额、累计充值到账金额(统计值,非表字段)
|
*/
|
@PostMapping("/remote/get/{id}")
|
@ApiOperation(value = "远程-公司详情", tags = {"内部调用"})
|
public R<TGroupCompany> remoteGet(@PathVariable("id") Integer id) {
|
if (id == null) {
|
return R.fail("公司ID不能为空");
|
}
|
return R.ok(groupCompanyService.getDetail(id));
|
}
|
|
/**
|
* 远程接口:扣减公司可用余额(条件更新保证余额充足,返回扣减后余额,内部调用)
|
*/
|
@PostMapping("/remote/deduct-balance")
|
@ApiOperation(value = "远程-扣减公司可用余额", tags = {"内部调用"})
|
public R<BigDecimal> remoteDeductBalance(@RequestParam("companyId") Integer companyId,
|
@RequestParam("amount") BigDecimal amount) {
|
if (companyId == null) {
|
return R.fail("公司ID不能为空");
|
}
|
if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
|
return R.fail("扣减金额必须大于0");
|
}
|
if (amount.scale() > 2) {
|
return R.fail("扣减金额最多保留2位小数");
|
}
|
TGroupCompany company = groupCompanyService.getById(companyId);
|
if (company == null) {
|
return R.fail("公司不存在或已删除");
|
}
|
if (!Integer.valueOf(1).equals(company.getStatus())) {
|
return R.fail("公司已停用,无法扣减可用余额");
|
}
|
boolean updated = groupCompanyService.lambdaUpdate()
|
.eq(TGroupCompany::getId, companyId)
|
.ge(TGroupCompany::getAvailableBalance, amount)
|
.setSql("available_balance = available_balance - " + amount.toPlainString())
|
.update();
|
if (!updated) {
|
return R.fail("公司可用余额不足");
|
}
|
TGroupCompany latest = groupCompanyService.getById(companyId);
|
return R.ok(latest == null ? null : latest.getAvailableBalance());
|
}
|
|
/**
|
* 远程接口:退还公司可用余额(返回退还后余额,内部调用)
|
*/
|
@PostMapping("/remote/refund-balance")
|
@ApiOperation(value = "远程-退还公司可用余额", tags = {"内部调用"})
|
public R<BigDecimal> remoteRefundBalance(@RequestParam("companyId") Integer companyId,
|
@RequestParam("amount") BigDecimal amount) {
|
if (companyId == null) {
|
return R.fail("公司ID不能为空");
|
}
|
if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
|
return R.fail("退还金额必须大于0");
|
}
|
if (amount.scale() > 2) {
|
return R.fail("退还金额最多保留2位小数");
|
}
|
boolean updated = groupCompanyService.lambdaUpdate()
|
.eq(TGroupCompany::getId, companyId)
|
.setSql("available_balance = IFNULL(available_balance, 0) + " + amount.toPlainString())
|
.update();
|
if (!updated) {
|
return R.fail("公司不存在或已删除");
|
}
|
TGroupCompany latest = groupCompanyService.getById(companyId);
|
return R.ok(latest == null ? null : latest.getAvailableBalance());
|
}
|
|
/**
|
* 远程接口:锁定公司金额(VIN码充电申请,共享模式实扣冻结:可用余额立即扣减并计入锁定金额,内部调用)
|
* <p>按「可用余额 >= 锁定金额」条件更新,余额不足返回失败;返回锁定后剩余可用金额。</p>
|
*/
|
@PostMapping("/remote/lock-balance")
|
@ApiOperation(value = "远程-锁定公司金额", tags = {"内部调用"})
|
public R<BigDecimal> remoteLockBalance(@RequestParam("companyId") Integer companyId,
|
@RequestParam("amount") BigDecimal amount) {
|
if (companyId == null) {
|
return R.fail("公司ID不能为空");
|
}
|
if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
|
return R.fail("锁定金额必须大于0");
|
}
|
if (amount.scale() > 2) {
|
return R.fail("锁定金额最多保留2位小数");
|
}
|
TGroupCompany company = groupCompanyService.getById(companyId);
|
if (company == null) {
|
return R.fail("公司不存在或已删除");
|
}
|
if (!Integer.valueOf(1).equals(company.getStatus())) {
|
return R.fail("公司已停用,无法锁定金额");
|
}
|
boolean updated = groupCompanyService.lambdaUpdate()
|
.eq(TGroupCompany::getId, companyId)
|
.ge(TGroupCompany::getAvailableBalance, amount)
|
.setSql("available_balance = available_balance - " + amount.toPlainString()
|
+ ", locked_amount = IFNULL(locked_amount, 0) + " + amount.toPlainString())
|
.update();
|
if (!updated) {
|
return R.fail("公司可用余额不足");
|
}
|
TGroupCompany latest = groupCompanyService.getById(companyId);
|
return R.ok(latest == null ? null : latest.getAvailableBalance());
|
}
|
|
/**
|
* 远程接口:结算公司金额(解锁锁定额并按实际消费扣减,允许扣成负数,内部调用)
|
* <p>orderCode 非空时按订单号幂等:账户侧消费流水作为结算幂等标记,补偿重试不会重复结算</p>
|
*/
|
@PostMapping("/remote/settle-balance")
|
@ApiOperation(value = "远程-结算公司金额", tags = {"内部调用"})
|
public R<BigDecimal> remoteSettleBalance(@RequestParam("companyId") Integer companyId,
|
@RequestParam("lockedAmount") BigDecimal lockedAmount,
|
@RequestParam("actualAmount") BigDecimal actualAmount,
|
@RequestParam(value = "orderCode", required = false) String orderCode,
|
@RequestParam(value = "userInfo", required = false) String userInfo,
|
@RequestParam(value = "userName", required = false) String userName,
|
@RequestParam(value = "remark", required = false) String remark) {
|
try {
|
return R.ok(groupCompanyService.settleBalance(companyId, lockedAmount, actualAmount, orderCode, userInfo,
|
userName, remark));
|
} catch (RuntimeException ex) {
|
return R.fail(ex.getMessage());
|
}
|
}
|
|
/**
|
* 远程接口:释放公司锁定金额(未产生消费时使用,内部调用)
|
*/
|
@PostMapping("/remote/unlock-balance")
|
@ApiOperation(value = "远程-释放公司锁定金额", tags = {"内部调用"})
|
public R<BigDecimal> remoteUnlockBalance(@RequestParam("companyId") Integer companyId,
|
@RequestParam("amount") BigDecimal amount) {
|
if (companyId == null) {
|
return R.fail("公司ID不能为空");
|
}
|
if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
|
return R.fail("释放金额必须大于0");
|
}
|
if (amount.scale() > 2) {
|
return R.fail("释放金额最多保留2位小数");
|
}
|
boolean updated = groupCompanyService.lambdaUpdate()
|
.eq(TGroupCompany::getId, companyId)
|
.setSql("locked_amount = GREATEST(IFNULL(locked_amount, 0) - " + amount.toPlainString() + ", 0)"
|
+ ", available_balance = IFNULL(available_balance, 0) + " + amount.toPlainString())
|
.update();
|
if (!updated) {
|
return R.fail("公司不存在或已删除");
|
}
|
TGroupCompany latest = groupCompanyService.getById(companyId);
|
return R.ok(latest == null ? null : latest.getAvailableBalance());
|
}
|
|
/**
|
* 远程接口:按ID批量查询公司(VIN 码充电订单列表回填公司名称使用,内部调用)
|
*/
|
@PostMapping("/remote/list-by-ids")
|
@ApiOperation(value = "远程-按ID批量查询公司", tags = {"内部调用"})
|
public R<List<TGroupCompany>> remoteListByIds(@RequestBody List<Integer> ids) {
|
if (ids == null || ids.isEmpty()) {
|
return R.ok(new ArrayList<>());
|
}
|
List<Integer> distinct = ids.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
|
if (distinct.isEmpty()) {
|
return R.ok(new ArrayList<>());
|
}
|
return R.ok(groupCompanyService.listByIds(distinct));
|
}
|
|
}
|