package com.ruoyi.other.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.other.api.domain.TCompanyBalanceWarning;
import com.ruoyi.other.api.domain.TGroupCompany;
import com.ruoyi.other.api.dto.BalanceWarningDTO;
import com.ruoyi.other.mapper.TCompanyBalanceWarningMapper;
import com.ruoyi.other.mapper.TGroupCompanyMapper;
import com.ruoyi.other.service.TCompanyBalanceWarningService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
*
* 公司余额预警配置 服务实现类
*
*
* @author mxcd
* @since 2026-09-26
*/
@Service
public class TCompanyBalanceWarningServiceImpl
extends ServiceImpl
implements TCompanyBalanceWarningService {
/** 通知对象:集团联系人 */
private static final int NOTIFY_OBJECT_GROUP_CONTACT = 1;
/** 通知对象:公司联系人 */
private static final int NOTIFY_OBJECT_COMPANY_CONTACT = 2;
/** 通知方式:短信 */
private static final int NOTIFY_TYPE_SMS = 1;
/** 预警线金额上限(与前端 InputNumber 上限保持一致) */
private static final BigDecimal MAX_WARN_AMOUNT = new BigDecimal("99999999.99");
/** 账户模式:共享模式(公司下无子账户,子账户预警线不适用) */
private static final int ACCOUNT_MODE_SHARED = 1;
/** 公司 Mapper(校验配置所属公司是否存在、详情返回账户模式) */
@Resource
private TGroupCompanyMapper groupCompanyMapper;
@Override
public BalanceWarningDTO getBalanceWarning(Integer companyId) {
if (companyId == null) {
return null;
}
BalanceWarningDTO dto = new BalanceWarningDTO();
dto.setCompanyId(companyId);
// 未配置时仅返回公司账户模式,预警字段保持为空,由前端置默认值
TCompanyBalanceWarning entity = getByCompanyId(companyId);
if (entity != null) {
dto.setCompanyWarnAmount(entity.getCompanyWarnAmount());
dto.setSubWarnAmount(entity.getSubWarnAmount());
dto.setNotifyObject(defaultIfNull(entity.getNotifyObject(), NOTIFY_OBJECT_GROUP_CONTACT));
dto.setNotifyType(defaultIfNull(entity.getNotifyType(), NOTIFY_TYPE_SMS));
}
TGroupCompany company = groupCompanyMapper.selectById(companyId);
Integer accountMode = company == null ? null : company.getAccountMode();
dto.setAccountMode(accountMode);
// 共享模式下公司无子账户,子账户预警线不适用,不回显历史值
if (isSharedMode(accountMode)) {
dto.setSubWarnAmount(null);
}
return dto;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Integer saveBalanceWarning(BalanceWarningDTO dto) {
if (dto == null || dto.getCompanyId() == null) {
throw new IllegalArgumentException("配置所属公司不能为空");
}
TGroupCompany company = groupCompanyMapper.selectById(dto.getCompanyId());
if (company == null) {
throw new IllegalArgumentException("公司不存在");
}
// 校验并规范化各配置项(不合法直接抛出业务提示)
BigDecimal companyWarnAmount = normalizeWarnAmount(dto.getCompanyWarnAmount(), "公司预警线");
// 共享模式无子账户:忽略传入值并落库为空;分配模式(及其他模式)子账户预警线仍必填
BigDecimal subWarnAmount = isSharedMode(company.getAccountMode())
? null
: normalizeWarnAmount(dto.getSubWarnAmount(), "子账户预警线");
Integer notifyObject = normalizeNotifyObject(dto.getNotifyObject());
Integer notifyType = normalizeNotifyType(dto.getNotifyType());
// 一个公司一条配置:存在则覆盖,不存在则新增
TCompanyBalanceWarning entity = getByCompanyId(dto.getCompanyId());
if (entity == null) {
entity = new TCompanyBalanceWarning();
entity.setCompanyId(dto.getCompanyId());
entity.setDelFlag(false);
}
entity.setCompanyWarnAmount(companyWarnAmount);
entity.setSubWarnAmount(subWarnAmount);
entity.setNotifyObject(notifyObject);
entity.setNotifyType(notifyType);
saveOrUpdate(entity);
return entity.getId();
}
/**
* 按公司查询配置(唯一索引保障最多一条,多余数据取首条不抛异常)
*/
private TCompanyBalanceWarning getByCompanyId(Integer companyId) {
return getOne(Wrappers.lambdaQuery()
.eq(TCompanyBalanceWarning::getCompanyId, companyId), false);
}
/**
* 是否为共享模式(账户模式为 1;为空或未知模式按非共享处理,子账户预警线仍必填)
*/
private boolean isSharedMode(Integer accountMode) {
return accountMode != null && accountMode == ACCOUNT_MODE_SHARED;
}
/**
* 校验并规范化预警线金额(必填,0~99999999.99,统一保留2位小数)
*/
private BigDecimal normalizeWarnAmount(BigDecimal amount, String label) {
if (amount == null) {
throw new IllegalArgumentException("请输入" + label);
}
if (amount.compareTo(BigDecimal.ZERO) < 0 || amount.compareTo(MAX_WARN_AMOUNT) > 0) {
throw new IllegalArgumentException(label + "需在0~" + MAX_WARN_AMOUNT + "之间");
}
return amount.setScale(2, RoundingMode.HALF_UP);
}
/**
* 校验通知对象(必填,1=集团联系人,2=公司联系人)
*/
private Integer normalizeNotifyObject(Integer notifyObject) {
if (notifyObject == null) {
throw new IllegalArgumentException("请选择通知对象");
}
if (notifyObject != NOTIFY_OBJECT_GROUP_CONTACT && notifyObject != NOTIFY_OBJECT_COMPANY_CONTACT) {
throw new IllegalArgumentException("通知对象不合法");
}
return notifyObject;
}
/**
* 校验通知方式(当前仅支持短信,为空时默认短信)
*/
private Integer normalizeNotifyType(Integer notifyType) {
if (notifyType == null) {
return NOTIFY_TYPE_SMS;
}
if (notifyType != NOTIFY_TYPE_SMS) {
throw new IllegalArgumentException("通知方式不合法");
}
return notifyType;
}
/**
* 空值兜底(历史数据未写入通知项时按默认值返回)
*/
private Integer defaultIfNull(Integer value, int defaultValue) {
return value == null ? defaultValue : value;
}
}