admin
2022-05-10 2922e51a7a8e657a8467c818ae16700e41ddac77
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
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
package com.yeshi.makemoney.app.service.impl.goldcorn;
 
import com.ks.lib.common.exception.ParamsException;
import com.yeshi.makemoney.app.dto.goldcorn.GoldCornMakeResultDTO;
import com.yeshi.makemoney.app.entity.config.SystemConfigKey;
import com.yeshi.makemoney.app.entity.goldcorn.*;
import com.yeshi.makemoney.app.entity.money.UserMoneyRecord;
import com.yeshi.makemoney.app.entity.user.UserInfo;
import com.yeshi.makemoney.app.exception.goldcorn.GoldCornGetFrequencyConfigException;
import com.yeshi.makemoney.app.exception.goldcorn.GoldCornGetPriceException;
import com.yeshi.makemoney.app.exception.goldcorn.GoldCornGetRecordException;
import com.yeshi.makemoney.app.exception.goldcorn.GoldCornMakeException;
import com.yeshi.makemoney.app.exception.user.UserInfoException;
import com.yeshi.makemoney.app.service.inter.config.SystemConfigService;
import com.yeshi.makemoney.app.service.inter.goldcorn.GoldCornGetFrequencyConfigService;
import com.yeshi.makemoney.app.service.inter.goldcorn.GoldCornGetPriceService;
import com.yeshi.makemoney.app.service.inter.goldcorn.GoldCornGetRecordService;
import com.yeshi.makemoney.app.service.inter.goldcorn.GoldCornMakeService;
import com.yeshi.makemoney.app.service.inter.money.UserMoneyRecordService;
import com.yeshi.makemoney.app.service.inter.team.TeamInviteRelationService;
import com.yeshi.makemoney.app.service.inter.user.UserInfoService;
import com.yeshi.makemoney.app.service.query.goldcorn.GoldCornGetRecordQuery;
import com.yeshi.makemoney.app.utils.factory.UserMoneyRecordFactory;
import com.yeshi.makemoney.app.utils.factory.goldcorn.GoldCornConsumeRecordFactory;
import com.yeshi.makemoney.app.utils.goldcorn.GoldCornUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.TimeUtil;
import org.yeshi.utils.annotation.RequestSerializableByKey;
 
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
 
/**
 * @author hxh
 * @title: GoldCornMakeServiceImpl
 * @description: 挣金币服务
 * @date 2022/4/6 16:56
 */
@Service
public class GoldCornMakeServiceImpl implements GoldCornMakeService {
 
    @Resource
    private GoldCornGetFrequencyConfigService goldCornGetFrequencyConfigService;
 
    @Resource
    private GoldCornGetRecordService goldCornGetRecordService;
 
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
 
    @Resource
    private GoldCornGetPriceService goldCornGetPriceService;
 
    @Resource
    private UserInfoService userInfoService;
 
    @Resource
    private TeamInviteRelationService teamInviteRelationService;
 
    @Resource
    private SystemConfigService systemConfigService;
 
    @Resource
    private UserMoneyRecordService userMoneyRecordService;
 
 
    /**
     * @return int 当前时间段还剩余的事件数量
     * @author hxh
     * @description 频率限制
     * @date 11:02 2022/4/28
     * @param: user
     * @param: type
     * @param: time
     **/
    @Override
    public long frequencyVerify(UserInfo user, GoldCornGetType type, Date time) throws GoldCornGetFrequencyConfigException, GoldCornMakeException {
        GoldCornGetFrequencyConfig config = goldCornGetFrequencyConfigService.getConfig(user.getSystem(), type, time);
        if (config == null) {
            throw new GoldCornGetFrequencyConfigException(GoldCornGetFrequencyConfigException.CODE_NOT_EXIST, "频率配置不存在");
        }
 
 
        GoldCornGetRecordQuery query = new GoldCornGetRecordQuery();
        query.setUid(user.getId());
        query.setType(type);
 
        //间隔判断
        if (config.getMinSpaceTime() != null) {
            List<GoldCornGetRecord> list = goldCornGetRecordService.list(query, 1, 1);
            if (list != null && list.size() > 0 && time.getTime() - list.get(0).getCreateTime().getTime() < config.getMinSpaceTime() * 1000L) {
                String msg = String.format("需要间隔%s秒以上", config.getMinSpaceTime());
                throw new GoldCornMakeException(GoldCornMakeException.CODE_GET_FREQUENCY_TIME_LIMIT, msg);
            }
        }
 
        Date startTime = null;
        Date endTime = time;
        if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.minute) {
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd HHmm"), "yyyyMMdd HHmm"));
        } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.hour) {
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd HH"), "yyyyMMdd HH"));
        } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.day) {
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMMdd"), "yyyyMMdd"));
        } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.week) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(endTime.getTime());
            int subDay = (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 2 + 7) % 7;
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime() - 1000 * 60 * 60 * 24L * subDay, "yyyyMMdd"), "yyyyMMdd"));
        } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.month) {
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyyMM"), "yyyyMM"));
        } else if (config.getTimeUnit() == GoldCornGetFrequencyConfig.GoldCornGetFrequencyTimeUnit.year) {
            startTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(endTime.getTime(), "yyyy"), "yyyy"));
        }
        query.setFormat("yyyyMMdd HH:mm:ss");
        query.setStartTime(TimeUtil.getGernalTime(startTime.getTime(), query.getFormat()));
        //service里面有减去1天
        query.setEndTime(TimeUtil.getGernalTime(endTime.getTime() - 1000 * 60 * 60 * 24L, query.getFormat()));
 
        Map<GoldCornGetType, Long> countMap = goldCornGetRecordService.sumEventCount(query);
        if (countMap.get(type) != null && (countMap.get(type) >= config.getLimitCount())) {
            String msg = String.format("超出%s次/%s的限制", config.getLimitCount(), config.getTimeUnit().getName());
            throw new GoldCornMakeException(GoldCornMakeException.CODE_GET_FREQUENCY_COUNT_LIMIT, msg);
        }
        return config.getLimitCount() - (countMap.get(type) != null ? countMap.get(type) : 0);
    }
 
 
    @RequestSerializableByKey(key = "'addgoldcorn-'+#uid+'-'+#type")
    @Override
    public GoldCornGetRecord addGoldCorn(Long uid, GoldCornGetType type, boolean isDouble, Date currentTime, Integer price, Long eventCount) throws UserInfoException, GoldCornGetFrequencyConfigException, GoldCornMakeException {
        if (uid == null || type == null || currentTime == null) {
            throw new GoldCornMakeException(GoldCornMakeException.CODE_PARAMS_NOT_ENOUGH, "参数不完整");
        }
        UserInfo user = userInfoService.get(uid);
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
        GoldCornGetPrice getPrice = goldCornGetPriceService.getPrice(user.getSystem(), GoldCornGetType.watchVideo, currentTime);
 
 
        //单价由外面传入
        int baseCornNum = price;
 
        GoldCornGetRecord record = new GoldCornGetRecord();
        record.setCornNum(baseCornNum);
        record.setDay(TimeUtil.getGernalTime(currentTime.getTime(), "yyyy-MM-dd"));
        record.setType(type);
        record.setUid(uid);
        record.setSystem(user.getSystem());
        record.setLevel(GoldCornGetRecord.LEVEL_OWN);
        record.setCreateTime(currentTime);
        record.setEventCount(eventCount);
        GoldCornGetRecord recordD = null;
        if (isDouble) {
            recordD = new GoldCornGetRecord();
            recordD.setCornNum(baseCornNum);
            record.setSystem(user.getSystem());
            recordD.setDay(TimeUtil.getGernalTime(currentTime.getTime(), "yyyy-MM-dd"));
            recordD.setType(type);
            recordD.setUid(uid);
            recordD.setLevel(GoldCornGetRecord.LEVEL_OWN);
            recordD.setCreateTime(currentTime);
            recordD.setDubble(true);
            recordD.setEventCount(eventCount);
        }
 
        //允许上级提成
 
        try {
            goldCornGetRecordService.add(record);
            if (recordD != null) {
                goldCornGetRecordService.add(recordD);
            }
            //是否有上级
            if (getPrice.getTeamDivide() != null && getPrice.getTeamDivide()) {
                Long bossUid = teamInviteRelationService.getBossUid(user.getId());
                if (bossUid != null) {
                    BigDecimal rate = new BigDecimal(systemConfigService.getValueCache(user.getSystem(), SystemConfigKey.teamFirstDivideRate));
                    GoldCornGetRecord cRecord = new GoldCornGetRecord();
                    cRecord.setDay(record.getDay());
                    cRecord.setType(type);
                    cRecord.setUid(bossUid);
                    record.setSystem(user.getSystem());
                    cRecord.setCornNum(new BigDecimal(baseCornNum).multiply(rate).intValue());
                    cRecord.setFromId(record.getId());
                    cRecord.setFromUid(record.getUid());
                    cRecord.setLevel(GoldCornGetRecord.LEVEL_FIRST);
                    cRecord.setCreateTime(currentTime);
                    if (cRecord.getCornNum() > 0) {
                        goldCornGetRecordService.add(cRecord);
                    }
                    //是否有上上级
//                    bossUid = teamInviteRelationService.getBossUid(bossUid);
//                    if (bossUid != null) {
//                        rate = new BigDecimal(systemConfigService.getValueCache(user.getSystem(), SystemConfigKey.teamSecondDivideRate));
//                        GoldCornGetRecord ccRecord = new GoldCornGetRecord();
//                        ccRecord.setDay(record.getDay());
//                        ccRecord.setType(type);
//                        ccRecord.setUid(bossUid);
//                        ccRecord.setFromId(record.getId());
//                        ccRecord.setFromUid(record.getUid());
//                        ccRecord.setCornNum(new BigDecimal(baseCornNum).multiply(rate).intValue());
//                        ccRecord.setLevel(GoldCornGetRecord.LEVEL_SECOND);
//                        ccRecord.setCreateTime(currentTime);
//                        if (ccRecord.getCornNum() > 0) {
//                            goldCornGetRecordService.add(ccRecord);
//                        }
//                    }
                }
            }
        } catch (GoldCornGetRecordException e) {
            throw new GoldCornMakeException(GoldCornMakeException.CODE_ADD_RECORD_ERROR, e.getMsg());
        }
 
        return record;
    }
 
    @Override
    public Long getGoldCornByDay(Long uid, Date day) {
        //TODO redis缓存
        return goldCornGetRecordService.getGoldCornByDay(uid, day);
    }
 
    @Override
    public Long getExchangingGoldCorn(Long uid, int dayCount) {
        long goldCornNum = 0;
        long now = System.currentTimeMillis();
        //查询最近3天未兑换的金币数量,
        for (int i = 1; i <= dayCount; i++) {
            Date date = new Date(now - 1000 * 60 * 60 * 24L * i);
            long count = getGoldCornByDay(uid, date);
            if (count == 0L) {
                continue;
            }
            //获取兑换记录的主键ID,不需要多余的数据
            GoldCornConsumeRecord record = GoldCornConsumeRecordFactory.createExchange(uid, GoldCornUtil.getFormatDay(date), 0, new BigDecimal(0.1),null);
            //查询资金记录是否有该记录
            try {
                UserMoneyRecord userMoneyRecord = UserMoneyRecordFactory.createGoldCornExchange(record);
                //查询记录
                userMoneyRecord = userMoneyRecordService.selectBySerialNo(userMoneyRecord.getSerialNo());
 
                if (userMoneyRecord == null) {
                    //未兑换
                    goldCornNum += count;
                }
 
            } catch (ParamsException e) {
                e.printStackTrace();
            }
        }
        return goldCornNum;
    }
 
    @Override
    public int getContinueSignDay(Long uid) {
        Date now = new Date();
        //查询今日是否已经签到
        boolean isSignIn = isSignIn(uid, now);
        Date deadDate = now;
        if (!isSignIn) {
            deadDate = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now.getTime(), "yyyyMMdd"), "yyyyMMdd"));
        }
 
        //今日未签到的,查询连续签到次数应该从前一天开始计算
        int continueDay = goldCornGetRecordService.getContinueDay(uid, GoldCornGetType.signIn, deadDate);
        return continueDay;
    }
 
    @Override
    public boolean isSignIn(Long uid, Date date) {
        GoldCornGetRecordQuery query = new GoldCornGetRecordQuery();
        query.setUid(uid);
        query.setType(GoldCornGetType.signIn);
        query.setDay(GoldCornUtil.getFormatDay(date));
        long count = goldCornGetRecordService.count(query);
        return count > 0L;
    }
 
    @Override
    public GoldCornGetRecord signIn(Long uid) throws GoldCornGetFrequencyConfigException, UserInfoException, GoldCornGetPriceException, GoldCornMakeException {
 
        UserInfo user = userInfoService.get(uid);
 
        Date now = new Date();
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.signIn, now);
        //获取连续签到次数
        Integer price = goldCornGetPriceService.getSingInPrice(user.getSystem(), getContinueSignDay(uid) + 1);
        return addGoldCorn(uid, GoldCornGetType.signIn, false, now, price, 1L);
    }
 
    @Transactional(rollbackFor = Exception.class)
    @Override
    public GoldCornMakeResultDTO watchVideo(Long uid, boolean isDouble, Date time, long timeSeconds) throws GoldCornGetPriceException, UserInfoException, GoldCornMakeException, GoldCornGetFrequencyConfigException {
        UserInfo user = userInfoService.get(uid);
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
 
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.watchVideo, time);
        timeSeconds = timeSeconds > leftCount ? leftCount : timeSeconds;
 
        Integer price = goldCornGetPriceService.getCountPrice(GoldCornGetType.watchVideo, user, user.getSystem(), time, timeSeconds);
        //价格为0时不加入记录
        if (price == 0) {
            return new GoldCornMakeResultDTO(0, leftCount);
        }
 
        GoldCornGetRecord record = addGoldCorn(uid, GoldCornGetType.watchVideo, isDouble, time, price, (long) timeSeconds);
        return new GoldCornMakeResultDTO(record.getCornNum() * (isDouble ? 2 : 1), leftCount - timeSeconds);
    }
 
    @Transactional(rollbackFor = Exception.class)
    @Override
    public GoldCornMakeResultDTO readNovel(Long uid, boolean isDouble, Date time, long timeSeconds) throws GoldCornGetPriceException, UserInfoException, GoldCornMakeException, GoldCornGetFrequencyConfigException {
 
        String readNovelCacheKey = "task-n-" + uid + "-" + TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyyMMdd");
        long readNovelNowSeconds = timeSeconds;
 
        Integer start = (Integer) redisTemplate.opsForValue().get(readNovelCacheKey);
        if (start == null) {
            start = 0;
        }
 
        timeSeconds = timeSeconds - start;
 
        UserInfo user = userInfoService.get(uid);
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
 
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.readNovel, time);
        timeSeconds = timeSeconds > leftCount ? leftCount : timeSeconds;
 
        Integer price = goldCornGetPriceService.getCountPrice(GoldCornGetType.readNovel, user, user.getSystem(), time, timeSeconds);
        //价格为0时不加入记录
        if (price == 0) {
            return new GoldCornMakeResultDTO(0, leftCount);
        }
 
        GoldCornGetRecord record = addGoldCorn(uid, GoldCornGetType.readNovel, isDouble, time, price, (long) timeSeconds);
 
        //记录当天的实时阅读分钟数
        redisTemplate.opsForValue().set(readNovelCacheKey, readNovelNowSeconds, 60 * 60 * 24, TimeUnit.SECONDS);
        return new GoldCornMakeResultDTO(record.getCornNum() * (isDouble ? 2 : 1), leftCount - timeSeconds);
    }
 
    @Transactional(rollbackFor = Exception.class)
    @Override
    public GoldCornMakeResultDTO scanNews(Long uid, boolean isDouble, Date time, int num) throws GoldCornGetPriceException, UserInfoException, GoldCornMakeException, GoldCornGetFrequencyConfigException {
        UserInfo user = userInfoService.get(uid);
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
 
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.scanNews, time);
 
        Integer price = goldCornGetPriceService.getCountPrice(GoldCornGetType.scanNews, user, user.getSystem(), time, num);
        //价格为0时不加入记录
        if (price == 0) {
            return new GoldCornMakeResultDTO(0, leftCount);
        }
 
        GoldCornGetRecord record = addGoldCorn(uid, GoldCornGetType.scanNews, isDouble, time, price, (long) num);
        return new GoldCornMakeResultDTO(record.getCornNum() * (isDouble ? 2 : 1), leftCount - num);
    }
 
    @Override
    public GoldCornMakeResultDTO inviteFriends(Long uid, UserInfo friendInfo, Date time) throws UserInfoException, GoldCornGetPriceException, GoldCornMakeException, GoldCornGetFrequencyConfigException {
        UserInfo user = userInfoService.get(uid);
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
 
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.invite, time);
 
        Integer price = goldCornGetPriceService.getCountPrice(GoldCornGetType.invite, user, user.getSystem(), time, 1);
        //价格为0时不加入记录
        if (price == 0) {
            return new GoldCornMakeResultDTO(0, leftCount);
        }
 
        GoldCornGetRecord record = addGoldCorn(uid, GoldCornGetType.invite, false, time, price, (long) price);
        return new GoldCornMakeResultDTO(record.getCornNum(), leftCount - 1);
    }
 
    @Override
    public GoldCornMakeResultDTO extract(Long uid, Date time) throws UserInfoException, GoldCornGetPriceException, GoldCornMakeException, GoldCornGetFrequencyConfigException {
 
        UserInfo user = userInfoService.get(uid);
        if (user == null) {
            throw new UserInfoException(UserInfoException.CODE_NOT_EXIST, "用户不存在");
        }
 
        //判断是否超出了次数限制
        long leftCount = frequencyVerify(user, GoldCornGetType.extract, time);
 
        Integer price = goldCornGetPriceService.getCountPrice(GoldCornGetType.extract, user, user.getSystem(), time, 1);
        //价格为0时不加入记录
        if (price == 0) {
            return new GoldCornMakeResultDTO(0, leftCount);
        }
 
        GoldCornGetRecord record = addGoldCorn(uid, GoldCornGetType.extract, false, time, price, (long) price);
        return new GoldCornMakeResultDTO(record.getCornNum(), leftCount - 1);
    }
 
 
}