xuekang
2024-05-13 15a0280ae9e7db96fdf0744c722d214d2cb5a0e5
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
package com.nuvole.four.service.impl;
 
import com.nuvole.base.domain.SysUser;
import com.nuvole.four.contants.Contants;
import com.nuvole.four.domain.ActivityDistributeRecord;
import com.nuvole.four.domain.ActivityFee;
import com.nuvole.four.domain.SysOrg;
import com.nuvole.four.domain.dto.ActivityDistributeBudgetDto;
import com.nuvole.four.domain.query.ActivityDistributeRecordQuery;
import com.nuvole.four.mapper.ActivityDistributeRecordMapper;
import com.nuvole.four.mapper.ActivityFeeMapper;
import com.nuvole.four.mapper.SysOrgMapper;
import com.nuvole.four.service.ActivityDistributeRecordService;
import com.nuvole.four.util.SystemUtil;
import com.nuvole.util.IdGenerator;
import com.walker.infrastructure.utils.CollectionUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
/**
 * @Description 活动预算分配Service实现类
 * @Author dqh
 * @Date 2024-04-13 21:36:24
 */
@Service
@RequiredArgsConstructor
public class ActivityDistributeRecordServiceImpl implements ActivityDistributeRecordService {
 
    private final ActivityDistributeRecordMapper activityDistributeRecordMapper;
    private final ActivityFeeMapper activityFeeMapper;
 
    private final SysOrgMapper sysOrgMapper;
 
 
 
 
 
    @Override
    public int addSelective(ActivityDistributeRecord entity){
        return activityDistributeRecordMapper.insertSelective(entity);
    }
 
    @Override
    public int editSelective(ActivityDistributeRecord entity){
        return activityDistributeRecordMapper.updateByPrimaryKeySelective(entity);
    }
     @Override
     public ActivityDistributeRecord get(Long  id){
        return activityDistributeRecordMapper.selectByPrimaryKey(id);
     }
 
    @Override
    public ActivityDistributeRecord getFeeByCondition(Long activityId,Long orgId){
         ActivityDistributeRecord record = activityDistributeRecordMapper.getFeeByCondition(activityId,orgId);
         if(record != null){
             return record;
         }
         return null;
    }
 
    @Override
    public ActivityFee getActivityFeeByIdAndOrgId(Long activityId,Long orgId){
        ActivityFee fee = activityFeeMapper.getActivityFeeByIdAndOrgId(activityId,orgId);
        return fee;
    }
 
 
     @Override
     public int del(Long  id){
        return activityDistributeRecordMapper.deleteByPrimaryKey(id);
     }
 
 
    @Override
    public List<ActivityDistributeRecord> getList(ActivityDistributeRecordQuery query) {
        return activityDistributeRecordMapper.selectList(query);
    }
 
    /**
     * 方法描述: 分配预算查询
     * 默认仅查询当前登录人的机构下级。不包含下下级
     * @date  2024-04-14 11:31
     **/
    @Override
    public List<ActivityDistributeBudgetDto> getActivityDistributeRecordDetail(Long activityId) {
        SysUser user = SystemUtil.getLoginUser(Contants.LOGIN_TYPE_PC);
        Long orgId = user.getOrgId();
        if(!user.getLoginName().equalsIgnoreCase("super") && orgId == null){
            throw new IllegalArgumentException("当前登录人无权限分配");
        }
        SysOrg sysOrg = sysOrgMapper.selectByPrimaryKey(orgId);
        if(sysOrg != null && sysOrg.getLv() == null){
            throw new IllegalArgumentException("当前选择的机构层级为空");
        }
        List<ActivityDistributeBudgetDto> dtoList = new ArrayList<>();
        dtoList = activityDistributeRecordMapper.getActivityDistributeRecordDetail(orgId,activityId);
        return dtoList;
    }
 
    /**
     * 方法描述:分配预算保存
     * 有id则进行更新;无则新增
     *
     * @date  2024-04-14 13:41
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer batchInsertOrUpdate(List<ActivityDistributeRecord> recordList) {
        if(CollectionUtils.isEmpty(recordList)){
            return 0;
        }
        SysUser user = SystemUtil.getLoginUser(Contants.LOGIN_TYPE_PC);
        //校验额度分配
        checkBudget(recordList);
        recordList.forEach( r -> {
            if (r.getId() == null) {
                //新增自动生成id
                r.setId(IdGenerator.getId());
                r.setCreateBy(user.getId());
                r.setCreateTime(new Date());
                r.setTotalFee(r.getTotalFee());
                r.setUseFee(0L);
                r.setSurplusFee(r.getTotalFee());
                //默认状态均=0(未开始)
                r.setStatus(0);
                r.setDeleted(0);
                SysOrg sysOrg = sysOrgMapper.selectByPrimaryKey(r.getOrgId());
                r.setOrgCode(sysOrg.getOrgCode());
                generateOrgLv(r, user.getOrgLv());
            }else{
                //todo surplusFee最好是从表里重新查询,使用total_fee - useFee = surplusFee;以预防活动开始后追加预算场景。
                //校验活动是否=0(未开始);否则无法修改
                checkActivityStatus(r.getActivityId(),recordList.indexOf(r));
                r.setDeleted(0);
                r.setTotalFee(r.getTotalFee());
                r.setSurplusFee(r.getTotalFee());
                r.setUpdateBy(user.getId());
                r.setUpdateTime(new Date());
            }
        });
        activityDistributeRecordMapper.batchInsertOrUpdate(recordList);
        //inputTotalFeeSum = 分配的下级额度(useFee)之和
        Long inputTotalFeeSum = recordList.stream().mapToLong(ActivityDistributeRecord::getTotalFee).sum();
        updateParentFee(inputTotalFeeSum, user.getOrgId(), recordList.get(0).getActivityId());
        return 1;
    }
    /**
     * 分配后处理父级(若有)、无父级则处理活动本身的userFee、surplusFee字段
     * @param inputTotalFeeSum        使用的额度
     * @param orgId         机构id
     * @param activityId    活动id
     */
    private void updateParentFee(Long inputTotalFeeSum,Long orgId,Long activityId){
        if(inputTotalFeeSum == 0L){
            return;
        }
        ActivityDistributeRecord record = activityDistributeRecordMapper.getFeeByCondition(activityId,orgId);
        if(record != null){
            record.setUseFee(inputTotalFeeSum);
            record.setSurplusFee(record.getTotalFee() - inputTotalFeeSum);
            activityDistributeRecordMapper.updateByPrimaryKeySelective(record);
        }else{
            //更新活动本身
            ActivityFee activityFee = activityFeeMapper.getActivityFeeByIdAndOrgId(activityId,orgId);
            if(activityFee != null){
                activityFee.setUseFee(inputTotalFeeSum);
                activityFee.setSurplusFee(activityFee.getTotalFee() - inputTotalFeeSum);
                activityFeeMapper.updateByPrimaryKeySelective(activityFee);
            }
        }
    }
 
    /**
     * 预算分配额度校验
     * useFee(当前请求集合中所有分配额度累加) + surplusFee ≤ totalFee(活动的总额度)
     * @param recordList    待保存的 预算分配集合
     */
    private void checkBudget(List<ActivityDistributeRecord> recordList){
        Long activityId = recordList.get(0).getActivityId();
        Long totalFee = 0L;
        SysUser user = SystemUtil.getLoginUser(Contants.LOGIN_TYPE_PC);
        Long orgId = user.getOrgId();
        ActivityDistributeRecord record = activityDistributeRecordMapper.getFeeByCondition(activityId,orgId);
        if (record == null) {
            ActivityFee activityFee = activityFeeMapper.getActivityFeeByIdAndOrgId(activityId,orgId);
            totalFee = activityFee.getTotalFee();
        }else{
            totalFee = record.getTotalFee();
        }
        Long inputTotalFeeSum = recordList.stream().mapToLong(ActivityDistributeRecord::getTotalFee).sum();
        long surplusFee = totalFee - inputTotalFeeSum;
        if(surplusFee < 0 ){
            throw new IllegalArgumentException("预算分配超出总额度,分配失败");
        }
    }
 
    /**
     * 生成机orglv对应的枚举值
     * @param loginUserOrgLv    当前登录人的orgLv
     */
    private void generateOrgLv(ActivityDistributeRecord entity,Integer loginUserOrgLv){
        if(loginUserOrgLv == null){
            return;
        }
        switch (loginUserOrgLv){
            case 0:
                entity.setLv1Id(1L);
                break;
            case 1:
                entity.setLv2Id(2L);
                break;
            case 2:
                entity.setLv3Id(3L);
            case 3:
                entity.setLv4Id(4L);
            default:
        }
    }
 
    /**
     * 校验活动是否=0(未开始);否则无法修改
     * @param activityId    活动ID
     * @param index     当前第几条
     */
    private void checkActivityStatus(Long activityId,int index){
        ActivityFee activityFee = activityFeeMapper.selectByPrimaryKey(activityId);
        if(activityFee.getStatus() != 0){
            String errMsg = String.format("第 {%s} 条活动已开始,无法分配", index + 1);
            throw new IllegalArgumentException(errMsg);
        }
    }
 
 
}