puzhibing
4 天以前 3650ce7f5d42d1bef58abea9693f20d1f209d3b0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
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;
 
/**
 * <p>
 * 公司余额预警配置 服务实现类
 * </p>
 *
 * @author mxcd
 * @since 2026-09-26
 */
@Service
public class TCompanyBalanceWarningServiceImpl
        extends ServiceImpl<TCompanyBalanceWarningMapper, TCompanyBalanceWarning>
        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.<TCompanyBalanceWarning>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;
    }
 
}