Administrator
2025-05-27 7ca7d0907e413945b4960ec3e7af7fde218ed875
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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
package cc.mrbird.febs.mall.service.impl;
 
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
import cc.mrbird.febs.common.utils.LoginUserUtil;
import cc.mrbird.febs.mall.dto.ScoreSettingDto;
import cc.mrbird.febs.mall.dto.sale.ApiSaleListInfoDto;
import cc.mrbird.febs.mall.dto.sale.ApiSaleRecordInfoDto;
import cc.mrbird.febs.mall.dto.sale.ApiTeamListInfoDto;
import cc.mrbird.febs.mall.entity.*;
import cc.mrbird.febs.mall.mapper.*;
import cc.mrbird.febs.mall.service.ApiSaleService;
import cc.mrbird.febs.mall.vo.memberLevel.ApiMemberLevelListInfoVo;
import cc.mrbird.febs.mall.vo.sale.*;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
 
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
 
@Slf4j
@Service
@RequiredArgsConstructor
public class ApiSaleServiceImpl extends ServiceImpl<MallMemberMapper, MallMember> implements ApiSaleService {
 
    private final HappySaleLevelMapper happySaleLevelMapper;
    private final HappyMemberLevelMapper happyMemberLevelMapper;
    private final MallAchieveRecordMapper mallAchieveRecordMapper;
    private final MallMemberWalletMapper mallMemberWalletMapper;
    private final MallMemberMapper mallMemberMapper;
    private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
    @Override
    public FebsResponse saleInfo() {
        ApiSaleInfoVo apiSaleInfoVo = new ApiSaleInfoVo();
 
        Long id = LoginUserUtil.getLoginUser().getId();
        MallMember mallMember = this.baseMapper.selectById(id);
        apiSaleInfoVo.setId(mallMember.getId());
        apiSaleInfoVo.setName(mallMember.getName());
        apiSaleInfoVo.setAvatar(mallMember.getAvatar());
        apiSaleInfoVo.setInviteId(mallMember.getInviteId());
        apiSaleInfoVo.setStoreMaster(mallMember.getStoreMaster());
 
        HappySaleLevel happySaleLevel = happySaleLevelMapper.selectOne(
                new LambdaQueryWrapper<HappySaleLevel>()
                        .eq(HappySaleLevel::getCode, mallMember.getStoreMaster())
                        .last("limit 1")
        );
        if (happySaleLevel != null) {
            apiSaleInfoVo.setStoreMasterName(happySaleLevel.getName());
            apiSaleInfoVo.setStoreMasterPng(happySaleLevel.getIconPng());
        }
 
        List<MallAchieveRecord> mallAchieveRecords = mallAchieveRecordMapper.selectList(
                new LambdaQueryWrapper<MallAchieveRecord>()
                        .eq(MallAchieveRecord::getMemberId, id)
        );
        apiSaleInfoVo.setTotalSaleAmount(
                CollUtil.isNotEmpty(mallAchieveRecords)
                        ? mallAchieveRecords.stream().map(MallAchieveRecord::getCostAmount).reduce(BigDecimal.ZERO, BigDecimal::add)
                        : BigDecimal.ZERO);
        apiSaleInfoVo.setOrderCnt(CollUtil.isNotEmpty(mallAchieveRecords) ? mallAchieveRecords.size() : 0);
 
        List<MallMember> mallMembers = this.baseMapper.selectByRefererId(mallMember.getInviteId());
        apiSaleInfoVo.setTotalCnt(CollUtil.isNotEmpty(mallMembers) ? mallMembers.size() : 0);
 
        MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(id);
        apiSaleInfoVo.setAvaAmount(mallMemberWallet.getCommission());
 
        return new FebsResponse().success().data(apiSaleInfoVo);
    }
 
    @Override
    public FebsResponse teamHeader() {
        ApiTeamHeaderInfoVo apiTeamHeaderInfoVo = new ApiTeamHeaderInfoVo();
 
        Long id = LoginUserUtil.getLoginUser().getId();
        MallMember mallMember = this.baseMapper.selectById(id);
 
        List<MallMember> mallMembers = this.baseMapper.selectAllChildAgentListByInviteId(mallMember.getInviteId());
        if(CollUtil.isEmpty(mallMembers)){
            apiTeamHeaderInfoVo.setTotalCnt(0);
            apiTeamHeaderInfoVo.setTotalAmount(BigDecimal.ZERO);
        }else {
            apiTeamHeaderInfoVo.setTotalCnt(mallMembers.size());
            List<MallAchieveRecord> mallAchieveRecords = mallAchieveRecordMapper.selectList(
                    new LambdaQueryWrapper<MallAchieveRecord>()
                            .eq(MallAchieveRecord::getMemberId, id)
            );
            apiTeamHeaderInfoVo.setTotalAmount(
                    CollUtil.isNotEmpty(mallAchieveRecords)
                            ? mallAchieveRecords.stream().map(MallAchieveRecord::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add)
                            : BigDecimal.ZERO);
        }
        return new FebsResponse().success().data(apiTeamHeaderInfoVo);
    }
 
    @Override
    public FebsResponse teamList(ApiTeamListInfoDto dto) {
        Long id = LoginUserUtil.getLoginUser().getId();
        MallMember mallMember = this.baseMapper.selectById(id);
        dto.setInviteId(mallMember.getInviteId());
 
        Page<ApiTeamListInfoVo> page = new Page<>(dto.getPageNow(), dto.getPageSize());
        IPage<ApiTeamListInfoVo> apiTeamListInfoVoIPage = this.baseMapper.selectTeamPage(page, dto);
        return new FebsResponse().success().data(apiTeamListInfoVoIPage);
    }
 
    @Override
    public FebsResponse saleHeader() {
 
        ApiSaleHeaderInfoVo apiSaleHeaderInfoVo = new ApiSaleHeaderInfoVo();
 
        Long id = LoginUserUtil.getLoginUser().getId();
        List<MallAchieveRecord> mallAchieveRecords = mallAchieveRecordMapper.selectList(
                new LambdaQueryWrapper<MallAchieveRecord>()
                        .eq(MallAchieveRecord::getMemberId, id)
        );
        apiSaleHeaderInfoVo.setTotalSaleAmount(
                CollUtil.isNotEmpty(mallAchieveRecords)
                        ? mallAchieveRecords.stream().map(MallAchieveRecord::getCostAmount).reduce(BigDecimal.ZERO, BigDecimal::add)
                        : BigDecimal.ZERO);
        apiSaleHeaderInfoVo.setOrderCnt(CollUtil.isNotEmpty(mallAchieveRecords) ? mallAchieveRecords.size() : 0);
        return new FebsResponse().success().data(apiSaleHeaderInfoVo);
    }
 
    @Override
    public FebsResponse saleList(ApiSaleListInfoDto dto) {
 
        Long id = LoginUserUtil.getLoginUser().getId();
        Page<ApiSaleListInfoVo> objectPage = new Page<>(dto.getPageNow(), dto.getPageSize());
        dto.setMemberId(id);
        Page<ApiSaleListInfoVo> mallAchieveRecordPage = this.baseMapper.selectSalePage(objectPage, dto);
        return new FebsResponse().success().data(mallAchieveRecordPage);
    }
 
    @Override
    public FebsResponse levelInfoList() {
        ArrayList<ApiLevelListInfoVo> apiLevelListInfoVos = new ArrayList<>();
 
        // 获取当前登录用户的ID
        Long memberId = LoginUserUtil.getLoginUser().getId();
        MallMember mallMember = this.baseMapper.selectById(memberId);
 
        List<HappySaleLevel> happySaleLevels = happySaleLevelMapper.selectList(
                new LambdaQueryWrapper<HappySaleLevel>()
                        .orderByAsc(HappySaleLevel::getCode)
        );
 
        List<MallMember> directMembers = mallMemberMapper.selectByRefererId(mallMember.getInviteId());
        List<MallMember> teamMembers = mallMemberMapper.selectAllChildAgentListByInviteId(mallMember.getInviteId());
        List<MallAchieveRecord> mallAchieveRecords = mallAchieveRecordMapper.selectList(
                new LambdaQueryWrapper<MallAchieveRecord>()
                        .eq(MallAchieveRecord::getMemberId, memberId)
        );
        if (CollUtil.isNotEmpty(happySaleLevels)) {
            happySaleLevels.forEach(happySaleLevel -> {
                ApiLevelListInfoVo apiLevelListInfoVo = new ApiLevelListInfoVo();
                apiLevelListInfoVo.setName(happySaleLevel.getName());
                apiLevelListInfoVo.setMemberCode(mallMember.getStoreMaster());
                apiLevelListInfoVo.setCode(happySaleLevel.getCode());
                apiLevelListInfoVo.setContent(happySaleLevel.getContent());
                apiLevelListInfoVo.setHeaderPng(happySaleLevel.getHeaderPng());
                apiLevelListInfoVo.setTeamCnt(happySaleLevel.getTeamCnt());
                apiLevelListInfoVo.setTeamCntNow(CollUtil.isNotEmpty(teamMembers) ? teamMembers.size() : 0);
                apiLevelListInfoVo.setDirectCnt(happySaleLevel.getDirectCnt());
                apiLevelListInfoVo.setDirectCntNow(CollUtil.isNotEmpty(directMembers) ? directMembers.size() : 0);
                apiLevelListInfoVo.setTeamAmount(happySaleLevel.getTeamAmount());
                apiLevelListInfoVo.setTeamAmountNow(
                        CollUtil.isNotEmpty(mallAchieveRecords)
                                ? mallAchieveRecords.stream().map(MallAchieveRecord::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add)
                                : BigDecimal.ZERO);
                apiLevelListInfoVos.add(apiLevelListInfoVo);
            });
        }
        return new FebsResponse().success().data(apiLevelListInfoVos);
    }
 
    /**
     * 处理销售记录信息
     *
     * 根据提供的类型参数,查询并统计指定时间范围内的销售记录,并返回相关会员的销售总额信息
     * 类型参数为1时,查询本月的销售记录;类型参数为2时,查询本周的销售记录
     *
     * @param dto 包含类型信息的ApiSaleRecordInfoDto对象,用于指定查询类型
     * @return 返回包含销售记录信息的FebsResponse对象,包括会员名称、头像和消费金额
     */
    @Override
    public FebsResponse saleRecord(ApiSaleRecordInfoDto dto) {
        // 初始化结果列表
        ApiSaleRecordInfoVo apiSaleRecordInfoVo = new ApiSaleRecordInfoVo();
        List<ApiSaleRecordInfoVo> apiSaleRecordInfoVos = new ArrayList<>();
 
        // 获取当前登录用户的ID
        Long memberId = LoginUserUtil.getLoginUser().getId();
        // 根据ID查询会员信息
        MallMember mallMember = this.baseMapper.selectById(memberId);
        // 设置会员名称、头像、排序号和消费金额初始值
        apiSaleRecordInfoVo.setName(mallMember.getName());
        apiSaleRecordInfoVo.setAvatar(mallMember.getAvatar());
        apiSaleRecordInfoVo.setSortCnt(0);
        apiSaleRecordInfoVo.setCostAmount(BigDecimal.ZERO);
 
        // 获取类型参数
        Integer type = dto.getType();
        // 校验类型参数,确保其为1(月)或2(周)
        if (type == null || (type != 1 && type != 2)) {
            return new FebsResponse().fail().message("非法的类型参数");
        }
 
        // 根据类型参数确定开始时间
        DateTime startTime = type == 1 ? DateUtil.beginOfMonth(new Date()) : DateUtil.beginOfWeek(new Date());
 
        // 查询指定时间范围内的商城销售记录
        List<MallAchieveRecord> mallAchieveRecords = mallAchieveRecordMapper.selectList(
                new LambdaQueryWrapper<MallAchieveRecord>()
                        .select(MallAchieveRecord::getMemberId, MallAchieveRecord::getCostAmount)
                        .ge(MallAchieveRecord::getCreatedTime, startTime)
        );
 
        // 如果查询到销售记录,则进行处理
        if (CollUtil.isNotEmpty(mallAchieveRecords)) {
            // 提取 memberId 集合,避免重复 stream
            Set<Long> memberIds = mallAchieveRecords.stream()
                    .map(MallAchieveRecord::getMemberId)
                    .collect(Collectors.toSet());
 
            // 分组求和
            Map<Long, BigDecimal> memberIdToCostAmount = mallAchieveRecords.stream()
                    .collect(Collectors.groupingBy(
                            MallAchieveRecord::getMemberId,
                            Collectors.mapping(
                                    MallAchieveRecord::getCostAmount,
                                    Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)
                            )
                    ));
 
            // 查询会员信息
            List<MallMember> mallMembers = this.baseMapper.selectList(
                    new LambdaQueryWrapper<MallMember>()
                            .select(MallMember::getId, MallMember::getName, MallMember::getAvatar)
                            .in(MallMember::getId, memberIds)
            );
 
            // 构建会员信息映射表
            Map<Long, MallMember> mallMemberMap = mallMembers.stream()
                    .collect(Collectors.toMap(MallMember::getId, m -> m));
 
            // 构建结果列表并避免空指针
            for (Map.Entry<Long, BigDecimal> entry : memberIdToCostAmount.entrySet()) {
                MallMember member = mallMemberMap.get(entry.getKey());
                if (member == null) {
                    continue; // 忽略不存在的会员
                }
                ApiSaleRecordInfoVo vo = new ApiSaleRecordInfoVo();
                vo.setId(member.getId());
                vo.setName(member.getName());
                vo.setAvatar(member.getAvatar());
                vo.setCostAmount(entry.getValue());
                apiSaleRecordInfoVos.add(vo);
            }
 
            // 排序
            apiSaleRecordInfoVos.sort(Comparator.comparing(ApiSaleRecordInfoVo::getCostAmount).reversed());
 
            //stream流操作apiSaleRecordInfoVos获取id等于memberId的数据,并且返回第一个数据和在数组中的下标索引
            ApiSaleRecordInfoVo memberSale = apiSaleRecordInfoVos.stream()
                    .filter(vo -> vo.getId().equals(memberId))
                    .findFirst()
                    .orElse(null);
            if (memberSale != null) {
                apiSaleRecordInfoVo.setSortCnt(apiSaleRecordInfoVos.indexOf(memberSale)+1);
                apiSaleRecordInfoVo.setCostAmount(memberSale.getCostAmount());
            }
        }
        apiSaleRecordInfoVo.setSaleRecord(apiSaleRecordInfoVos);
 
        // 返回成功响应,包含销售记录信息
        return new FebsResponse().success().data(apiSaleRecordInfoVo);
    }
 
    @Override
    public FebsResponse memberLevelList() {
        ArrayList<ApiMemberLevelListInfoVo> apiLevelListInfoVos = new ArrayList<>();
 
        // 获取当前登录用户的ID
        Long memberId = LoginUserUtil.getLoginUser().getId();
        MallMember mallMember = this.baseMapper.selectById(memberId);
        MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId);
 
        List<HappyMemberLevel> happyMemberLevels = happyMemberLevelMapper.selectList(
                new LambdaQueryWrapper<HappyMemberLevel>()
                        .orderByAsc(HappyMemberLevel::getCode)
        );
        //Stream  操作 happyMemberLevels,返回一个Map<code,HappyMemberLevel>
        Map<Integer, HappyMemberLevel> happyMemberLevelMap = happyMemberLevels.stream()
                .collect(Collectors.toMap(HappyMemberLevel::getCode, happyMemberLevel -> happyMemberLevel));
        if (CollUtil.isNotEmpty(happyMemberLevels)) {
            int mostSignIn = 1;
            DataDictionaryCustom dic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(
                    DataDictionaryEnum.SCORE_SIGN_SETTING.getType(),
                    DataDictionaryEnum.SCORE_SIGN_SETTING.getCode());
            if (dic != null) {
                ScoreSettingDto scoreSettingDto = JSONObject.parseObject(dic.getValue(), ScoreSettingDto.class);
                mostSignIn = ObjectUtil.isEmpty(scoreSettingDto.getMostSignIn()) ? 1 : scoreSettingDto.getMostSignIn();
            }
            for (HappyMemberLevel happyMemberLevel : happyMemberLevels) {
                ApiMemberLevelListInfoVo vo = new ApiMemberLevelListInfoVo();
                BeanUtil.copyProperties(happyMemberLevel, vo);
                vo.setMostSignIn(mostSignIn);
                vo.setMemberCode(mallMember.getDirector());
                vo.setMemberScore(mallMemberWallet.getScore());
                vo.setUpgradeScore(
                        ObjectUtil.isEmpty(happyMemberLevelMap.get(happyMemberLevel.getCode())) ?
                                0 : happyMemberLevelMap.get(happyMemberLevel.getCode()).getUpgradeScore()
                );
                apiLevelListInfoVos.add(vo);
            }
        }
        return new FebsResponse().success().data(apiLevelListInfoVos);
    }
 
 
}