|
@@ -1,10 +1,14 @@
|
1
|
1
|
package com.yunzhi.niucai.service.impl;
|
2
|
2
|
|
3
|
3
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
4
|
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
5
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
6
|
+import com.yunzhi.niucai.common.BizUtils;
|
4
|
7
|
import com.yunzhi.niucai.common.DateUtils;
|
5
|
8
|
import com.yunzhi.niucai.entity.*;
|
6
|
9
|
import com.yunzhi.niucai.enums.SportOpeningStatusEnum;
|
7
|
10
|
import com.yunzhi.niucai.enums.SportStatusEnum;
|
|
11
|
+import com.yunzhi.niucai.mapper.TaCustomerBettingMapper;
|
8
|
12
|
import com.yunzhi.niucai.mapper.TaMatchMapper;
|
9
|
13
|
import com.yunzhi.niucai.mapper.TaMatchOddsMapper;
|
10
|
14
|
import com.yunzhi.niucai.service.*;
|
|
@@ -45,12 +49,21 @@ public class TaMatchServiceImpl extends ServiceImpl<TaMatchMapper, TaMatch> impl
|
45
|
49
|
@Autowired
|
46
|
50
|
ITaCustomerBettingSportService iTaCustomerBettingSportService;
|
47
|
51
|
|
|
52
|
+ @Autowired
|
|
53
|
+ ITaBettingPlanService iTaBettingPlanService;
|
|
54
|
+
|
|
55
|
+ @Autowired
|
|
56
|
+ ITdSportPassService iTdSportPassService;
|
|
57
|
+
|
48
|
58
|
@Autowired
|
49
|
59
|
TaMatchMapper taMatchMapper;
|
50
|
60
|
|
51
|
61
|
@Autowired
|
52
|
62
|
TaMatchOddsMapper taMatchOddsMapper;
|
53
|
63
|
|
|
64
|
+ @Autowired
|
|
65
|
+ TaCustomerBettingMapper taCustomerBettingMapper;
|
|
66
|
+
|
54
|
67
|
@Override
|
55
|
68
|
public List<TaMatch> getMixedMatch(String lottery) throws Exception {
|
56
|
69
|
List<TaMatch> taMatches = taMatchMapper.getMixedMatch(lottery, SportStatusEnum.SALE.getCode());
|
|
@@ -90,6 +103,19 @@ public class TaMatchServiceImpl extends ServiceImpl<TaMatchMapper, TaMatch> impl
|
90
|
103
|
return taMatchMapper.getLastResult();
|
91
|
104
|
}
|
92
|
105
|
|
|
106
|
+ @Override
|
|
107
|
+ public IPage<TaMatch> getResult(IPage<TaMatch> page, String lotteryId) throws Exception {
|
|
108
|
+ IPage<TaMatch> result = taMatchMapper.getResult(page, lotteryId);
|
|
109
|
+
|
|
110
|
+ if (null != result.getRecords() && result.getRecords().size() > 0) {
|
|
111
|
+ for (TaMatch taMatch : result.getRecords()) {
|
|
112
|
+
|
|
113
|
+ }
|
|
114
|
+ }
|
|
115
|
+
|
|
116
|
+ return null;
|
|
117
|
+ }
|
|
118
|
+
|
93
|
119
|
/**
|
94
|
120
|
* 体彩是否中奖
|
95
|
121
|
* @throws Exception
|
|
@@ -104,19 +130,7 @@ public class TaMatchServiceImpl extends ServiceImpl<TaMatchMapper, TaMatch> impl
|
104
|
130
|
try {
|
105
|
131
|
taMatch.setOpeningStatus(SportOpeningStatusEnum.DOING.getCode());
|
106
|
132
|
updateById(taMatch);
|
107
|
|
-
|
108
|
|
- String lotteryId = taMatch.getLotteryId();
|
109
|
|
- switch (lotteryId) {
|
110
|
|
- case "football":
|
111
|
|
- setFootballPrize(taMatch);
|
112
|
|
- break;
|
113
|
|
- case "basketball":
|
114
|
|
- setBasketballPrize(taMatch);
|
115
|
|
- break;
|
116
|
|
- default:
|
117
|
|
- break;
|
118
|
|
- }
|
119
|
|
-
|
|
133
|
+ validateMatch(taMatch);
|
120
|
134
|
} catch (Exception e) {
|
121
|
135
|
// TODO 比如错误日志记录
|
122
|
136
|
taMatch.setOpeningStatus(SportOpeningStatusEnum.READY.getCode());
|
|
@@ -126,12 +140,12 @@ public class TaMatchServiceImpl extends ServiceImpl<TaMatchMapper, TaMatch> impl
|
126
|
140
|
}
|
127
|
141
|
|
128
|
142
|
/**
|
129
|
|
- * 足球开奖
|
|
143
|
+ * 校验比赛
|
130
|
144
|
* @param taMatch
|
131
|
145
|
* @throws Exception
|
132
|
146
|
*/
|
133
|
147
|
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
134
|
|
- private void setFootballPrize(TaMatch taMatch) throws Exception {
|
|
148
|
+ private void validateMatch (TaMatch taMatch) throws Exception {
|
135
|
149
|
// 获取当前比赛的投注列表
|
136
|
150
|
List<TaCustomerBettingItem> bettingItemList = iTaCustomerBettingItemService.getByMatch(taMatch);
|
137
|
151
|
if (null == bettingItemList || bettingItemList.size() == 0) {
|
|
@@ -165,6 +179,12 @@ public class TaMatchServiceImpl extends ServiceImpl<TaMatchMapper, TaMatch> impl
|
165
|
179
|
}
|
166
|
180
|
}
|
167
|
181
|
|
|
182
|
+ /**
|
|
183
|
+ * 校验投注
|
|
184
|
+ * @param betting
|
|
185
|
+ * @param item
|
|
186
|
+ * @throws Exception
|
|
187
|
+ */
|
168
|
188
|
private void checkAndSetBetting(TaCustomerBetting betting, TaCustomerBettingItem item) throws Exception {
|
169
|
189
|
List<TaCustomerBettingItem> itemList = iTaCustomerBettingItemService.getByBetting(betting);
|
170
|
190
|
if (null == itemList || itemList.size() == 0) {
|
|
@@ -172,12 +192,23 @@ public class TaMatchServiceImpl extends ServiceImpl<TaMatchMapper, TaMatch> impl
|
172
|
192
|
}
|
173
|
193
|
|
174
|
194
|
boolean done = true;
|
175
|
|
- for (TaCustomerBettingItem bettingItem : itemList) {
|
|
195
|
+ boolean existWinningRec = false;
|
|
196
|
+ for (int i = 0; i < itemList.size(); i++) {
|
|
197
|
+ TaCustomerBettingItem bettingItem = itemList.get(0);
|
176
|
198
|
if (bettingItem.getItemNo().equals(item.getItemNo())) {
|
177
|
|
- bettingItem = item;
|
|
199
|
+ itemList.set(i, item);
|
|
200
|
+
|
|
201
|
+ if (item.getIsWinning()) {
|
|
202
|
+ existWinningRec = true;
|
|
203
|
+ }
|
|
204
|
+
|
178
|
205
|
continue;
|
179
|
206
|
}
|
180
|
207
|
|
|
208
|
+ if (bettingItem.getIsWinning()) {
|
|
209
|
+ existWinningRec = true;
|
|
210
|
+ }
|
|
211
|
+
|
181
|
212
|
// 如果还有未处理完成的, 跳出循环
|
182
|
213
|
if (!SportOpeningStatusEnum.FINISHED.getCode().equals(bettingItem.getOpeningStatus())) {
|
183
|
214
|
done = false;
|
|
@@ -190,6 +221,27 @@ public class TaMatchServiceImpl extends ServiceImpl<TaMatchMapper, TaMatch> impl
|
190
|
221
|
return;
|
191
|
222
|
}
|
192
|
223
|
|
|
224
|
+ // 所有奖都开了
|
|
225
|
+ betting.setIsOpen(true);
|
|
226
|
+ betting.setOpeningDate(DateUtils.today());
|
|
227
|
+ UpdateWrapper<TaCustomerBetting> updateWrapper = new UpdateWrapper<>();
|
|
228
|
+ updateWrapper.set("is_open", betting.getIsOpen());
|
|
229
|
+ updateWrapper.set("opening_date", betting.getOpeningDate());
|
|
230
|
+ updateWrapper.eq("betting_id", betting.getBettingId());
|
|
231
|
+ taCustomerBettingMapper.update(betting, updateWrapper);
|
|
232
|
+
|
|
233
|
+ // 如果一场都没中, 直接 pass
|
|
234
|
+ if (!existWinningRec) {
|
|
235
|
+ return;
|
|
236
|
+ }
|
|
237
|
+
|
|
238
|
+ // 投注方案
|
|
239
|
+ TaBettingPlan bettingPlan = iTaBettingPlanService.getById(betting.getPlanId());
|
|
240
|
+ if (null == bettingPlan) {
|
|
241
|
+ throw new Exception("校验投注方案失败");
|
|
242
|
+ }
|
|
243
|
+ betting.setBettingPlan(bettingPlan);
|
|
244
|
+
|
193
|
245
|
// 结算最终奖金
|
194
|
246
|
computePirzeAmount(betting, itemList);
|
195
|
247
|
}
|
|
@@ -223,26 +275,77 @@ public class TaMatchServiceImpl extends ServiceImpl<TaMatchMapper, TaMatch> impl
|
223
|
275
|
}
|
224
|
276
|
|
225
|
277
|
// 只有中奖的投注才会参与计算
|
226
|
|
- // 所以会出现 size = 0 情况
|
227
|
278
|
List<String> oddsOfNote = new ArrayList<>();
|
228
|
279
|
for (TaCustomerBettingSport sportItem : sportList) {
|
229
|
280
|
if (sportItem.getIsWinning()) {
|
230
|
281
|
oddsOfNote.add(sportItem.getOddsPrinted());
|
|
282
|
+ } else {
|
|
283
|
+ // 未中奖的赔率是 0
|
|
284
|
+ oddsOfNote.add("0");
|
231
|
285
|
}
|
232
|
286
|
}
|
233
|
287
|
|
234
|
288
|
noteList.add(oddsOfNote);
|
235
|
289
|
}
|
236
|
|
- }
|
237
|
290
|
|
238
|
|
- /**
|
239
|
|
- * 篮球开奖
|
240
|
|
- * @param taMatch
|
241
|
|
- * @throws Exception
|
242
|
|
- */
|
243
|
|
- @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
244
|
|
- private void setBasketballPrize(TaMatch taMatch) throws Exception {
|
|
291
|
+ // 玩法字典
|
|
292
|
+ if (null == betting.getBettingPlan().getPassCode()) {
|
|
293
|
+ throw new Exception("校验过关模式失败");
|
|
294
|
+ }
|
|
295
|
+ TdSportPass tdSportPass = iTdSportPassService.getById(betting.getBettingPlan().getPassCode());
|
|
296
|
+ if (null == tdSportPass) {
|
|
297
|
+ throw new Exception("校验过关模式失败");
|
|
298
|
+ }
|
|
299
|
+
|
|
300
|
+ List<List<List<String>>> mockCombList = BizUtils.mockAllCombination(noteList, tdSportPass);
|
|
301
|
+
|
|
302
|
+ // 计算方法: https://www.lottery.gov.cn/bzzx/yxgz/20191119/1273604.html
|
|
303
|
+ float totalCharge = 0.0f;
|
|
304
|
+ for (List<List<String>> notes : mockCombList) {
|
|
305
|
+
|
|
306
|
+ // 多种可能的结果会直接相加
|
|
307
|
+ float perCombCharge = 0.0f;
|
|
308
|
+ for (List<String> oddsList : notes) {
|
|
309
|
+
|
|
310
|
+ // 比如购买的 3串4
|
|
311
|
+ // 3串4的金额是 2串1 + 2串1 + 2串1 + 3串1
|
|
312
|
+ float perNoteCharge = 0.0f;
|
|
313
|
+ for (String oddsStr : oddsList) {
|
|
314
|
+
|
|
315
|
+ // 比如2串1
|
|
316
|
+ // 2串1的金额是 第一场比赛赔率*第二次比赛赔率
|
|
317
|
+ // 依次类推, 如果是 3串1 则是3场相乘
|
|
318
|
+ float odds = Float.parseFloat(oddsStr);
|
|
319
|
+
|
|
320
|
+ // 此处判断是否第一次循环, float 不能用 == 判断
|
|
321
|
+ if (perNoteCharge < 0.01f) {
|
|
322
|
+ perNoteCharge = odds;
|
|
323
|
+ } else {
|
|
324
|
+ perNoteCharge += odds;
|
|
325
|
+ }
|
|
326
|
+ }
|
|
327
|
+
|
|
328
|
+ perCombCharge += perNoteCharge;
|
|
329
|
+ }
|
|
330
|
+
|
|
331
|
+ // 金额 = 2块(200分) * 赔率 * 投注倍数
|
|
332
|
+ totalCharge += 200 * perCombCharge * betting.getBettingTimes();
|
|
333
|
+ }
|
|
334
|
+
|
|
335
|
+ // 如果没有中奖
|
|
336
|
+ if (totalCharge < 0.01f) {
|
|
337
|
+ return;
|
|
338
|
+ }
|
|
339
|
+
|
|
340
|
+ betting.setIsWinning(true);
|
|
341
|
+ betting.setWinAmount((int) totalCharge);
|
|
342
|
+ UpdateWrapper<TaCustomerBetting> updateWrapper = new UpdateWrapper<>();
|
|
343
|
+ updateWrapper.set("is_winning", betting.getIsWinning());
|
|
344
|
+ updateWrapper.set("win_amount", betting.getWinAmount());
|
|
345
|
+ updateWrapper.eq("betting_id", betting.getBettingId());
|
|
346
|
+ taCustomerBettingMapper.update(betting, updateWrapper);
|
245
|
347
|
|
|
348
|
+ // TODO 发送通知
|
246
|
349
|
}
|
247
|
350
|
|
248
|
351
|
private boolean isWining(TaMatch taMatch, TaCustomerBettingSport bettingSport) {
|