swagger 推广后台 优化对战百佳历史接口
This commit is contained in:
+14
-10
@@ -19,7 +19,7 @@
|
||||
| 缓存 | Redis(Spring Data Redis + Lettuce) |
|
||||
| 消息 | RabbitMQ(业务侧配置虚拟主机等,详见各 profile) |
|
||||
| 实时 | WebSocket(如 `/ws/**` 等路径,与安全放行配置保持一致) |
|
||||
| API 文档 | **Springfox 3.x**(主用,Swagger / OAS3 分组);另引入 **springdoc-openapi** Starter,可与 Springfox 并行存在 |
|
||||
| API 文档 | 已移除(不再依赖 Springfox / springdoc,仓库内无 Swagger UI 与 OpenAPI 端点) |
|
||||
|
||||
---
|
||||
|
||||
@@ -81,7 +81,7 @@ chengdu-backend/
|
||||
|
||||
### 对外匿名接口(简述)
|
||||
|
||||
与安全配置对齐的常见分类包括:`/login`、`/register`、`/captchaImage`,以及业务侧的 `/api/**`、`/admin/**`、WebSocket、部分 Swagger 与 Druid 监控路径等。具体请以 `ruoyi-framework` 中 **SecurityFilterChain** 与白名单配置为准。
|
||||
与安全配置对齐的常见分类包括:`/login`、`/register`、`/captchaImage`,以及业务侧的 `/api/**`、`/admin/**`、WebSocket、Druid 监控路径等。具体请以 `ruoyi-framework` 中 **SecurityFilterChain** 与白名单配置为准。
|
||||
|
||||
---
|
||||
|
||||
@@ -130,7 +130,7 @@ mvn -pl ruoyi-admin -am spring-boot:run -DskipTests
|
||||
- 技术栈:Vue CLI、Element UI(`package.json` 声明 Node `>=8.9`,实际开发建议 Node **16 LTS** 或 **18 LTS**,并按需开启 OpenSSL 兼容)。
|
||||
- 脚本见 `ruoyi-ui/package.json`(Windows 脚本含 `set NODE_OPTIONS=--openssl-legacy-provider`;在 macOS/Linux 上需 `export NODE_OPTIONS=...` 或使用等价脚本)。
|
||||
- 开发与打包:`npm run dev`、`npm run build:prod` 等。
|
||||
- 系统工具内「Swagger」页当前 iframe 指向 **`/doc.html`**;若后端未部署对应聚合页,请改为与下文 **API 文档** 中实际地址一致(例如 `/swagger-ui.html`)。
|
||||
- 原「系统工具 → 系统接口」的 Swagger 页已随接口文档一并删除(`views/tool/swagger/index.vue`),若侧边栏仍有该菜单,执行 `DELETE FROM sys_menu WHERE component = 'tool/swagger/index';` 后重新登录。
|
||||
|
||||
### promo-ui2(Vue 3)
|
||||
|
||||
@@ -158,16 +158,14 @@ mvn -pl ruoyi-admin -am spring-boot:run -DskipTests
|
||||
|
||||
## API 文档
|
||||
|
||||
- **Springfox(当前主要使用)**:启动后访问(端口与 `server.port` 一致,仓库默认 **28081**)
|
||||
`http://localhost:28081/swagger-ui.html`
|
||||
在页面右上角切换分组(如 `user`、`thirdParty`、`playingMethod`、`task`、`promo` 等;与 `SwaggerConfig` 中 Docket 一致)。OpenAPI JSON 路径形如 `/<group>/api-docs`(Spring Security 已对 `/*/api-docs` 等放行,以实际配置为准)。
|
||||
- **springdoc-openapi**:`ruoyi-admin` 已引入依赖;若单独启用 SpringDoc UI,需确保 **Security** 对 `/swagger-ui/**`、`/v3/api-docs` 等路径放行,避免 401。
|
||||
- 项目已**移除全部接口文档能力**:删除 Springfox(`springfox-boot-starter`)、springdoc-openapi 依赖、`SwaggerConfig` 与源码中的 `@Api` / `@ApiOperation` / `@ApiModelProperty` 等注解,`SecurityConfig` 与 `ResourcesConfig` 里对应的放行与静态映射也已去掉。
|
||||
- 因此 `/swagger-ui.html`、`/v3/api-docs`、`/*/api-docs`、`/doc.html` 均不再对外提供服务(未认证访问会直接落到 401)。
|
||||
|
||||
---
|
||||
|
||||
## 版本信息
|
||||
|
||||
- 父 POM:`com.ruoyi:ruoyi:4.8.2`(`spring-boot.version` **4.0.3**,`springdoc.version` **3.0.2**,`swagger` / Springfox **3.0.0**)
|
||||
- 父 POM:`com.ruoyi:ruoyi:4.8.2`(`spring-boot.version` **4.0.3**)
|
||||
- 若依官网参考:<http://www.ruoyi.vip>
|
||||
|
||||
---
|
||||
@@ -175,7 +173,13 @@ mvn -pl ruoyi-admin -am spring-boot:run -DskipTests
|
||||
## 安全建议
|
||||
|
||||
1. 轮换并私有化所有第三方(支付宝、聚合支付、短信等)密钥;生产环境勿使用仓库内示例明文。
|
||||
2. 修改 JWT `token.secret` 与 Druid 监控口令等非默认值。
|
||||
3. 按需收紧 Druid、`/actuator`(若启用)及 Swagger 相关路径的访问范围。
|
||||
2. 修改 JWT `token.secret` 等非默认值。
|
||||
3. Druid 监控台:生产已关闭(`application-pro.yml` 的 `statViewServlet.enabled=false`,`/druid/**` 是匿名放行的,开着等于把全部 SQL 与连接信息暴露到公网);
|
||||
开发环境已限制 `allow: 127.0.0.1` 并改用非默认口令。临时排障如需开启,务必保持白名单 + 改口令,用完立即关回。
|
||||
4. **三端 token 互不通用**(游戏管理后台 / 推广后台 / 玩家端):三个端共用同一套 JWT 与会话存储,
|
||||
靠 `LoginUser.loginScope`(`admin` / `promo` / `player`)区分,判定在 `ruoyi-framework` 的 `SecurityConfig`:
|
||||
`/admin|/system|/monitor|/tool|/test` 只认后台账号、`/promo/**` 只认推广端签发的 token、`/api/**` 只认玩家端签发的 token。
|
||||
标记由 `ApiUserDetailsServiceImpl` 按登录账号前缀(`api_` / `promo_` / `promo_user_` / 无前缀)写入,随会话缓存在 Redis。
|
||||
**注意**:升级到该版本后,不带端标记的旧 token 会被拒绝,推广后台与玩家端需要重新登录一次(后台账号不受影响)。
|
||||
|
||||
如有与本说明不一致之处,以当前仓库代码及团队部署文档为准。
|
||||
|
||||
@@ -0,0 +1,405 @@
|
||||
"""麻将胡了 · 回合池生成器:把引擎跑出的回合写进 `game_mahjong_round` / `game_mahjong_step`。
|
||||
|
||||
两种模式:
|
||||
--mode natural (默认)自然形态:不干预,直接采样落库。**RTP≈5.25,只能测链路,不能当验收**。
|
||||
--mode quota 配额构造:先标定每桶池内实测均值 → 二分解出 16 桶配额(空转率锁 65%、目标 RTP 0.80)
|
||||
→ 按配额定量填充。**这才是能上线/能做 RTP 验收的池子**。
|
||||
|
||||
用法(在 mahjong-py 目录下):
|
||||
python generate_rounds.py --mode quota --per-box 1000 --dry-run
|
||||
python generate_rounds.py --mode quota --per-box 1000 --write
|
||||
python generate_rounds.py --mode natural --per-box 100 --dry-run
|
||||
python generate_rounds.py --boxes 1,2 --per-box 100 --write --mode quota
|
||||
|
||||
写库内容(两种模式一样):
|
||||
1. `game_mahjong_round`:每局一行(bucket_id / actual_mul / 旋数 / 波数 / has_fs / near_miss)
|
||||
2. `game_mahjong_step`:每帧一行(逐波;含 grid_state / ways_detail / 下落补位 / 阶梯 / 触发信息)
|
||||
3. `game_mahjong_box_bucket`:**配额就是 count**(3 个身份各一套,used=0)
|
||||
4. `game_mahjong_box_template`:每箱每身份一条生效模板(= 配额快照,供抽干补桶)
|
||||
5. `game_mahjong_box.total_rounds`:回写成本次生成的回合数
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import math
|
||||
import random
|
||||
import sys
|
||||
from collections import Counter
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
|
||||
from mahjong import config as C # noqa: E402
|
||||
from mahjong.engine import GRID_COLS, GRID_ROWS, play_round # noqa: E402
|
||||
|
||||
DB = dict(host="127.0.0.1", port=23306, user="henan", password="iTSJSPPZM3LSGAPC", database="henan")
|
||||
EMPTY_SHARE = 0.65 # 空转率(桶 1 配额占比,见设计文档 §3.9);未按箱分档时的统一值
|
||||
|
||||
# 按档调波动(用户 2026-09-22 定):**所有箱子 RTP 都锁 0.80**,但波动不同 ——
|
||||
# 低档(1~20):空转低 → 剩余配额必须更"平" → 小奖更多、手感热;
|
||||
# 高档(200~500):空转高 → 剩余配额更"陡" → 中大奖更多、博性更强。
|
||||
# 机制:`solve_quotas` 会把"剩余部分"的加权均值凑到 `0.80/(1-空转率)`,所以
|
||||
# **只改空转率就能同时改形状**,不用再单独调 power。
|
||||
VOLATILITY_LADDER = (
|
||||
(20, 0.62, "低档:空转 62%,小奖更多(热)"),
|
||||
(100, 0.65, "中档:空转 65%(设计基准)"),
|
||||
(10 ** 9, 0.68, "高档:空转 68%,中大奖更多(陡)"),
|
||||
)
|
||||
|
||||
|
||||
def empty_share_for(box_id: int) -> float:
|
||||
bet = C.bet_of(box_id)
|
||||
for upper, share, _ in VOLATILITY_LADDER:
|
||||
if bet <= upper:
|
||||
return share
|
||||
return EMPTY_SHARE
|
||||
TARGET_RTP = 0.80
|
||||
CALIB_ROUNDS = 6000 # 每箱标定样本(用来量每个桶的**池内实测**均值)
|
||||
MAX_TRIES = 400_000 # 单个桶的采样上限(防低概率桶把时间吃光)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 行构造
|
||||
def grid_rows(flat) -> list:
|
||||
"""扁平 20 格 → 4 行 × 5 列(接口用的 gridState 形状)。"""
|
||||
return [list(flat[r * GRID_COLS:(r + 1) * GRID_COLS]) for r in range(GRID_ROWS)]
|
||||
|
||||
|
||||
def build_steps(round_, round_id: int):
|
||||
"""把一局摊成逐帧行。"""
|
||||
rows, step_seq = [], 0
|
||||
spin_win = 0.0
|
||||
for spin in round_.spins:
|
||||
spin_win_before = spin_win
|
||||
acc_sym = Counter()
|
||||
winners = []
|
||||
rotations = spin.rotations
|
||||
frames = rotations or (None,) # 空旋也要发一帧(落定盘面),否则客户端无从渲染
|
||||
for i, rot in enumerate(frames, start=1):
|
||||
step_seq += 1
|
||||
if rot is None:
|
||||
grid_flat = spin.landing
|
||||
ways, removed, drops, fills, conv, gold = [], [], [], [], [], []
|
||||
base_mul, rot_mul = 0.0, C.ladder_mul(1, spin.is_fs)
|
||||
else:
|
||||
grid_flat = rot.grid_before
|
||||
gold = [{"pos": p, "symbol": rot.grid_before[p - 1]} for p in rot.golden_before]
|
||||
conv = [{"pos": p, "fromSymbol": s} for p, s in rot.converted]
|
||||
ways = [{"symbol": w.symbol, "reelCount": w.run, "counts": list(w.counts),
|
||||
"loc": list(w.loc), "ways": w.ways, "payBase": w.pay_base,
|
||||
"rotationMul": rot.rotation_mul,
|
||||
"win": round(w.pay_base * rot.rotation_mul, 4)}
|
||||
for w in rot.wins]
|
||||
seen = set()
|
||||
removed = [p for w in rot.wins for p in w.loc if not (p in seen or seen.add(p))]
|
||||
drops = [{"from": a, "to": b, "symbol": s} for a, b, s in rot.drops]
|
||||
fills = [{"pos": p, "symbol": s} for p, s in rot.fills]
|
||||
base_mul, rot_mul = rot.base_mul, rot.rotation_mul
|
||||
for w in rot.wins:
|
||||
acc_sym[w.symbol] += len(w.loc)
|
||||
winners.append({"symbol": w.symbol, "count": w.run,
|
||||
"win": round(w.pay_base * rot.rotation_mul, 4)})
|
||||
spin_win = spin_win_before + sum(r.win_mul for r in rotations[:i])
|
||||
is_last = (i == len(frames))
|
||||
scat = ({"scatterCount": spin.scatters, "freeSpins": spin.fs_awarded, "extraSpins": 0}
|
||||
if spin.index == 0 and i == 1 and spin.fs_awarded else None)
|
||||
retri = ({"scatterCount": spin.scatters, "extraSpins": C.fs_award(spin.scatters)}
|
||||
if spin.index > 0 and i == 1 and spin.retrigger else None)
|
||||
rows.append(dict(
|
||||
id=round_id * 100 + step_seq,
|
||||
round_id=round_id,
|
||||
reel_spin_id=spin.index,
|
||||
rotation_seq=i,
|
||||
grid_state=json.dumps(grid_rows(grid_flat), ensure_ascii=False) if grid_flat else None,
|
||||
golden_detail=json.dumps(gold, ensure_ascii=False) if gold else None,
|
||||
wild_converted=json.dumps(conv, ensure_ascii=False) if conv else None,
|
||||
ways_detail=json.dumps(ways, ensure_ascii=False) if ways else None,
|
||||
accumulated_symbols=json.dumps(dict(acc_sym), ensure_ascii=False),
|
||||
spin_winners=json.dumps(winners, ensure_ascii=False),
|
||||
removed_positions=json.dumps(removed),
|
||||
drop_data=json.dumps(drops, ensure_ascii=False) if drops else None,
|
||||
fill_data=json.dumps(fills, ensure_ascii=False) if fills else None,
|
||||
scatter_trigger=json.dumps(scat, ensure_ascii=False) if scat else None,
|
||||
retrigger_info=json.dumps(retri, ensure_ascii=False) if retri else None,
|
||||
base_score=round(base_mul, 4),
|
||||
win_amount=round(sum(r.win_mul for r in rotations[:i]), 4),
|
||||
rotation_mul=rot_mul,
|
||||
spin_win=round(spin_win, 4),
|
||||
win_capped=1 if (round_.capped and is_last and spin is round_.spins[-1]) else 0,
|
||||
bigwin_level=None,
|
||||
is_final=1 if is_last else 0,
|
||||
))
|
||||
spin_win = spin_win_before + sum(r.win_mul for r in rotations)
|
||||
return rows
|
||||
|
||||
|
||||
def make_round(box_id: int, seq: int, rng: random.Random):
|
||||
r = play_round(rng, box_id=box_id)
|
||||
round_id = box_id * 1_000_000 + seq
|
||||
steps = build_steps(r, round_id=round_id)
|
||||
row = dict(round_id=round_id, box_id=box_id, bucket_id=C.bucket_of(r.actual_mul),
|
||||
actual_mul=round(r.actual_mul, 4), free_spin_count=r.free_spins,
|
||||
total_rotations=sum(len(s.rotations) for s in r.spins),
|
||||
has_fs=1 if r.has_fs else 0, near_miss=1 if r.near_miss else 0)
|
||||
return row, steps
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 配额构造
|
||||
def calibrate(box_id: int, n: int, seed: int):
|
||||
"""小样本标定:每个桶的**池内实测均值**(自然均值与名义 expect_mul 差很多,必须实测)。"""
|
||||
rng = random.Random(seed)
|
||||
tot, cnt = Counter(), Counter()
|
||||
for _ in range(n):
|
||||
r = play_round(rng, box_id=box_id)
|
||||
b = C.bucket_of(r.actual_mul)
|
||||
tot[b] += r.actual_mul
|
||||
cnt[b] += 1
|
||||
means = {}
|
||||
for b in C.BUCKETS:
|
||||
means[b.id] = (tot[b.id] / cnt[b.id]) if cnt[b.id] else b.expect_mul
|
||||
return means, cnt
|
||||
|
||||
|
||||
def _quota_from_power(means, power: float, empty_share: float):
|
||||
"""w_b = 30×0.6^((b-1)×power)(b≥2),桶 1 锁 empty_share;返回 16 个配额(下标 1..16)。"""
|
||||
ws = {b.id: 30.0 * (0.6 ** ((b.id - 1) * power)) for b in C.BUCKETS if b.id >= 2}
|
||||
s = sum(ws.values())
|
||||
q = {b.id: 0.0 for b in C.BUCKETS}
|
||||
q[1] = empty_share
|
||||
for b_id, w in ws.items():
|
||||
q[b_id] = (1.0 - empty_share) * w / s
|
||||
return q
|
||||
|
||||
|
||||
def solve_quotas(means, target_rtp=TARGET_RTP, empty_share=EMPTY_SHARE):
|
||||
"""二分 power,使 Σ q_b × mean_b = target_rtp。power 越大越偏向低倍桶(期望越低)。"""
|
||||
def expected(power):
|
||||
q = _quota_from_power(means, power, empty_share)
|
||||
return sum(q[b.id] * means[b.id] for b in C.BUCKETS)
|
||||
lo, hi = 0.05, 8.0
|
||||
# expected(power) 随 power **递减**:power 越大越偏向低倍桶
|
||||
for _ in range(80):
|
||||
mid = (lo + hi) / 2
|
||||
if expected(mid) > target_rtp:
|
||||
lo = mid # 期望偏高 → 还要更大的 power
|
||||
else:
|
||||
hi = mid
|
||||
q = _quota_from_power(means, (lo + hi) / 2, empty_share)
|
||||
return q, expected((lo + hi) / 2)
|
||||
|
||||
|
||||
def _fill(box_id: int, targets: dict, seed: int, max_tries=MAX_TRIES):
|
||||
"""按桶目标条数填充:落进目标桶才收。返回 (pool, bucket_cnt, short)。"""
|
||||
rng = random.Random(seed)
|
||||
pool, tries, short = [], Counter(), []
|
||||
for b in C.BUCKETS:
|
||||
got = 0
|
||||
while got < targets[b.id] and tries[b.id] < max_tries:
|
||||
tries[b.id] += 1
|
||||
row, steps = make_round(box_id, len(pool) + 1, rng)
|
||||
if row["bucket_id"] == b.id:
|
||||
pool.append((row, steps))
|
||||
got += 1
|
||||
if got < targets[b.id]:
|
||||
short.append(f"桶{b.id} {got}/{targets[b.id]}")
|
||||
for i, (row, steps) in enumerate(pool, start=1):
|
||||
rid = box_id * 1_000_000 + i
|
||||
row["round_id"] = rid
|
||||
for j, st in enumerate(steps, start=1):
|
||||
st["round_id"] = rid
|
||||
st["id"] = rid * 100 + j
|
||||
cnt = Counter(row["bucket_id"] for row, _ in pool)
|
||||
return pool, cnt, short
|
||||
|
||||
|
||||
def quota_targets(per_box: int, quotas: dict):
|
||||
targets = {b.id: int(round(per_box * quotas[b.id])) for b in C.BUCKETS}
|
||||
diff = per_box - sum(targets.values())
|
||||
if diff:
|
||||
targets[1] += diff
|
||||
return targets
|
||||
|
||||
|
||||
def _sample_bucket(box_id: int, bucket_id: int, rng: random.Random, max_tries=MAX_TRIES):
|
||||
"""采一条落进指定桶的回合(低概率桶会多试几次)。"""
|
||||
for _ in range(max_tries):
|
||||
row, steps = make_round(box_id, 0, rng)
|
||||
if row["bucket_id"] == bucket_id:
|
||||
return row, steps
|
||||
return None
|
||||
|
||||
|
||||
def _tune(box_id: int, pool: list, target_rtp: float, per_box: int, seed: int, verbose=True):
|
||||
"""整数可执行的定向微调:配额算出来是小数,四舍五入会把「0.4 条」的尾部桶抹成 0 条,
|
||||
于是它本该贡献的期望就丢了(实测池内均值会系统性偏低 5~8pt)。
|
||||
|
||||
做法:拿空转局(桶 1,倍率 0)去换中高桶的回合,每换一条按**真实倍率**结账,
|
||||
直到池内均值落进目标 ±0.005 以内。空转率只会动几条(<0.5pt)。
|
||||
"""
|
||||
rng = random.Random(seed + 31337)
|
||||
cur = sum(r["actual_mul"] for r, _ in pool)
|
||||
need = target_rtp * per_box - cur # 还差多少(单位:倍率总和)
|
||||
empties = [i for i, (r, _) in enumerate(pool) if r["bucket_id"] == 1]
|
||||
ordered = sorted((x for x in C.BUCKETS if x.id >= 2), key=lambda x: -x.expect_mul)
|
||||
swaps = 0
|
||||
while need > 0.6 and empties and ordered:
|
||||
cand = next((b for b in ordered if b.expect_mul <= need), None)
|
||||
if cand is None:
|
||||
break
|
||||
got = None
|
||||
for _ in range(300): # 只收"不超过缺口"的回合,保证不会冲过头
|
||||
s = _sample_bucket(box_id, cand.id, rng)
|
||||
if s and s[0]["actual_mul"] <= need:
|
||||
got = s
|
||||
break
|
||||
if got is None: # 这一档试不出来,退一档
|
||||
ordered = [b for b in ordered if b.id != cand.id]
|
||||
continue
|
||||
row, steps = got
|
||||
pool[empties.pop()] = (row, steps)
|
||||
need -= row["actual_mul"]
|
||||
swaps += 1
|
||||
rng = random.Random(rng.random()) # 让后续采样换流
|
||||
if verbose and swaps:
|
||||
print(f" 微调:换入 {swaps} 条中高桶回合(空转率随之动 {swaps / per_box:.2%})")
|
||||
cnt = Counter(r["bucket_id"] for r, _ in pool)
|
||||
rtp = sum(r["actual_mul"] for r, _ in pool) / max(1, len(pool))
|
||||
if verbose:
|
||||
print(f" 微调后池内实测 RTP {rtp:.4f}(与目标差 {abs(rtp - target_rtp):.4f})")
|
||||
return pool, cnt
|
||||
|
||||
|
||||
def generate_quota(box_id: int, per_box: int, seed: int, empty_share: float, target_rtp: float,
|
||||
verbose=True):
|
||||
"""解配额 → 定条数 → 填充 → 整数微调 → 重排 id。
|
||||
|
||||
`empty_share`:桶 1 的配额占比。CLI 不传时按 `empty_share_for(box_id)` 取**按档波动**的值
|
||||
(低档 62% / 中档 65% / 高档 68%),这样各箱形状不同、但 RTP 都锁在 `target_rtp`。
|
||||
|
||||
为什么填完还要微调:运行时按库存消耗(一个 cycle 每条回合正好播一次)⇒ `cycle RTP = 池内均值`,
|
||||
而配额是连续解出来的小数,四舍五入会抹掉尾部桶(见 `_tune` 的注释)。
|
||||
"""
|
||||
means, _ = calibrate(box_id, CALIB_ROUNDS, seed)
|
||||
quotas, exp_rtp = solve_quotas(means, target_rtp, empty_share)
|
||||
targets = quota_targets(per_box, quotas)
|
||||
if verbose:
|
||||
print(f" 标定:配额理论期望 {exp_rtp:.4f}(目标 {target_rtp});桶1 配额 {quotas[1]:.2%};"
|
||||
f"桶条数(1/2/3/12/16) = {targets[1]}/{targets[2]}/{targets[3]}/{targets[12]}/{targets[16]}")
|
||||
pool, cnt, short = _fill(box_id, targets, seed + 999 + box_id * 7919)
|
||||
pool, cnt = _tune(box_id, pool, target_rtp, per_box, seed + box_id, verbose)
|
||||
for i, (row, steps) in enumerate(pool, start=1): # 重排 id(采样与微调都打乱了顺序)
|
||||
rid = box_id * 1_000_000 + i
|
||||
row["round_id"] = rid
|
||||
for j, st in enumerate(steps, start=1):
|
||||
st["round_id"] = rid
|
||||
st["id"] = rid * 100 + j
|
||||
return pool, quotas, means, exp_rtp, short
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 写库
|
||||
def write(conn, pool_by_box, per_box, audiences=C.AUDIENCES):
|
||||
cur = conn.cursor()
|
||||
total_r = total_s = 0
|
||||
for box, (pool, quotas, bucket_cnt) in pool_by_box.items():
|
||||
rounds = [row for row, _ in pool]
|
||||
steps = [st for _, sts in pool for st in sts]
|
||||
lo, hi = box * 1_000_000 + 1, box * 1_000_000 + per_box
|
||||
cur.execute(f"DELETE FROM game_mahjong_step WHERE round_id BETWEEN {lo} AND {hi}")
|
||||
cur.execute(f"DELETE FROM game_mahjong_round WHERE box_id={box}")
|
||||
cur.executemany(
|
||||
"INSERT INTO game_mahjong_round (round_id,box_id,bucket_id,actual_mul,free_spin_count,"
|
||||
"total_rotations,has_fs,near_miss) VALUES (%(round_id)s,%(box_id)s,%(bucket_id)s,"
|
||||
"%(actual_mul)s,%(free_spin_count)s,%(total_rotations)s,%(has_fs)s,%(near_miss)s)", rounds)
|
||||
cols = ("id", "round_id", "reel_spin_id", "rotation_seq", "grid_state", "golden_detail",
|
||||
"wild_converted", "ways_detail", "accumulated_symbols", "spin_winners",
|
||||
"removed_positions", "drop_data", "fill_data", "scatter_trigger", "retrigger_info",
|
||||
"base_score", "win_amount", "rotation_mul", "spin_win", "win_capped",
|
||||
"bigwin_level", "is_final")
|
||||
cur.executemany(
|
||||
f"INSERT INTO game_mahjong_step ({','.join(cols)}) "
|
||||
f"VALUES ({','.join('%(' + c + ')s' for c in cols)})", steps)
|
||||
for aud in audiences:
|
||||
cur.execute("DELETE FROM game_mahjong_box_bucket WHERE box_id=%s AND audience=%s", (box, aud))
|
||||
cur.executemany(
|
||||
"INSERT INTO game_mahjong_box_bucket (box_id,bucket_id,audience,count,used) "
|
||||
"VALUES (%s,%s,%s,%s,0)",
|
||||
[(box, b.id, aud, bucket_cnt.get(b.id, 0)) for b in C.BUCKETS])
|
||||
items = json.dumps([{"bucketId": b.id, "count": bucket_cnt.get(b.id, 0)} for b in C.BUCKETS],
|
||||
ensure_ascii=False)
|
||||
cur.execute("DELETE FROM game_mahjong_box_template WHERE box_id=%s AND audience=%s", (box, aud))
|
||||
cur.execute(
|
||||
"INSERT INTO game_mahjong_box_template (box_id,audience,name,total_rounds,items_json,is_active) "
|
||||
"VALUES (%s,%s,%s,%s,%s,1)",
|
||||
(box, aud, f"配额池-{per_box}局", per_box, items))
|
||||
cur.execute("UPDATE game_mahjong_box SET total_rounds=%s WHERE box_id=%s", (per_box, box))
|
||||
conn.commit()
|
||||
total_r += len(rounds)
|
||||
total_s += len(steps)
|
||||
rtp = sum(r["actual_mul"] for r in rounds) / max(1, len(rounds))
|
||||
print(f" 箱 {box:2d}(赌注 {C.bet_of(box):>3}):回合 {len(rounds):>5} 帧 {len(steps):>6} "
|
||||
f"**池内实测 RTP {rtp:.4f}** 空转 {bucket_cnt.get(1,0)/max(1,len(rounds)):.1%} "
|
||||
f"FS 局 {sum(r['has_fs'] for r in rounds)}")
|
||||
print(f"合计:回合 {total_r},帧 {total_s}")
|
||||
return total_r, total_s
|
||||
|
||||
|
||||
def build_natural(box_id, per_box, seed):
|
||||
rng = random.Random(seed + box_id)
|
||||
pool, cnt = [], Counter()
|
||||
for i in range(1, per_box + 1):
|
||||
row, steps = make_round(box_id, i, rng)
|
||||
pool.append((row, steps))
|
||||
cnt[row["bucket_id"]] += 1
|
||||
return pool, cnt
|
||||
|
||||
|
||||
def main() -> None:
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--mode", choices=("natural", "quota"), default="natural")
|
||||
ap.add_argument("--per-box", type=int, default=1000)
|
||||
ap.add_argument("--boxes", default="")
|
||||
ap.add_argument("--seed", type=int, default=20260922)
|
||||
ap.add_argument("--empty-share", type=float, default=None,
|
||||
help="空转率(桶 1 配额占比);不传=按档取(低档 0.62 / 中档 0.65 / 高档 0.68)")
|
||||
ap.add_argument("--target-rtp", type=float, default=TARGET_RTP)
|
||||
ap.add_argument("--write", action="store_true")
|
||||
ap.add_argument("--dry-run", action="store_true")
|
||||
ap.add_argument("--host", default=DB["host"]); ap.add_argument("--port", type=int, default=DB["port"])
|
||||
ap.add_argument("--user", default=DB["user"]); ap.add_argument("--password", default=DB["password"])
|
||||
ap.add_argument("--database", default=DB["database"])
|
||||
args = ap.parse_args()
|
||||
|
||||
boxes = [int(x) for x in args.boxes.split(",") if x.strip()] or list(C.BOX_IDS)
|
||||
print(f"==== {args.mode} 模式:{len(boxes)} 箱 × {args.per_box} 局"
|
||||
f"{'' if args.write and not args.dry_run else '(干跑,不写库)'} ====")
|
||||
pool_by_box = {}
|
||||
for box in boxes:
|
||||
if args.mode == "natural":
|
||||
pool, cnt = build_natural(box, args.per_box, args.seed)
|
||||
quotas = None
|
||||
pool_by_box[box] = (pool, quotas, cnt)
|
||||
else:
|
||||
share = args.empty_share if args.empty_share is not None else empty_share_for(box)
|
||||
pool, quotas, means, exp_rtp, short = generate_quota(
|
||||
box, args.per_box, args.seed, share, args.target_rtp)
|
||||
cnt = Counter(row["bucket_id"] for row, _ in pool)
|
||||
if short:
|
||||
print(f" 未填满:{';'.join(short)}")
|
||||
pool_by_box[box] = (pool, quotas, cnt)
|
||||
if not (args.write and not args.dry_run):
|
||||
rows = [r for r, _ in pool_by_box[box][0]]
|
||||
rtp = sum(r["actual_mul"] for r in rows) / max(1, len(rows))
|
||||
print(f" 箱 {box:2d}(赌注 {C.bet_of(box):>3}):回合 {len(rows):>5} "
|
||||
f"**池内实测 RTP {rtp:.4f}** 空转 {cnt.get(1,0)/max(1,len(rows)):.1%} "
|
||||
f"FS 局 {sum(r['has_fs'] for r in rows)}")
|
||||
if not (args.write and not args.dry_run):
|
||||
return
|
||||
import pymysql
|
||||
conn = pymysql.connect(host=args.host, port=args.port, user=args.user,
|
||||
password=args.password, database=args.database, charset="utf8mb4")
|
||||
write(conn, pool_by_box, args.per_box)
|
||||
conn.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -24,7 +24,6 @@
|
||||
<druid.version>1.2.28</druid.version>
|
||||
<yauaa.version>8.1.0</yauaa.version>
|
||||
<bitwalker.version>1.21</bitwalker.version>
|
||||
<swagger.version>3.0.0</swagger.version>
|
||||
<kaptcha.version>2.3.3</kaptcha.version>
|
||||
<tianai-captcha.version>1.5.5</tianai-captcha.version>
|
||||
<pagehelper.boot.version>2.1.1</pagehelper.boot.version>
|
||||
@@ -35,7 +34,6 @@
|
||||
<poi.version>4.1.2</poi.version>
|
||||
<velocity.version>2.3</velocity.version>
|
||||
<jwt.version>0.9.1</jwt.version>
|
||||
<springdoc.version>3.0.2</springdoc.version>
|
||||
</properties>
|
||||
|
||||
<!-- 依赖声明 -->
|
||||
@@ -149,26 +147,6 @@
|
||||
<version>${oshi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-doc -->
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Swagger3依赖 -->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-boot-starter</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
<!-- <exclusions>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>io.swagger</groupId>-->
|
||||
<!-- <artifactId>swagger-models</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- </exclusions>-->
|
||||
</dependency>
|
||||
|
||||
<!-- io常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
import request from '@/axios'
|
||||
import type { RegisterUserType, SmsLoginType, UserLoginType, UserType } from './types'
|
||||
import type { RegisterUserType, SmsLoginType, UserType } from './types'
|
||||
|
||||
interface RoleParams {
|
||||
roleName: string
|
||||
}
|
||||
|
||||
export const loginApi = (data: UserLoginType): Promise<IResponse<UserType>> => {
|
||||
return request.post({ url: '/promo/login', data })
|
||||
}
|
||||
|
||||
export const smsLoginApi = (data: SmsLoginType): Promise<IResponse<UserType>> => {
|
||||
return request.post({ url: '/promo/smsLogin', data })
|
||||
}
|
||||
@@ -34,6 +30,20 @@ export const getCodeApi = (
|
||||
})
|
||||
}
|
||||
|
||||
/** 点「获取验证码」时的账号前置校验:无推广后台权限的号在这一步就被拒绝,不用先拖滑块 */
|
||||
export const precheckPhoneApi = (
|
||||
phoneNumber: string,
|
||||
parentInvitationCode?: string
|
||||
): Promise<IResponse<UserType>> => {
|
||||
return request.post({
|
||||
url: '/promo/sms/precheck',
|
||||
data: {
|
||||
phoneNumber: phoneNumber,
|
||||
parentInvitationCode
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const loginOutApi = (): Promise<IResponse> => {
|
||||
return request.get({ url: '/mock/user/loginOut' })
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="tsx">
|
||||
import { getAdminRoleApi, getCodeApi, smsLoginApi } from '@/api/login'
|
||||
import { getAdminRoleApi, getCodeApi, precheckPhoneApi, smsLoginApi } from '@/api/login'
|
||||
import type { SmsLoginType, UserType } from '@/api/login/types'
|
||||
import { getMyMenus } from '@/api/permission'
|
||||
import { PATH_URL } from '@/axios/service'
|
||||
@@ -35,6 +35,7 @@ const loading = ref(false)
|
||||
const redirect = ref('')
|
||||
const getCodeTime = ref(60)
|
||||
const getCodeLoading = ref(false)
|
||||
const captchaCode = ref('')
|
||||
let tacInstance: any = null
|
||||
let codeTimer: ReturnType<typeof setInterval> | undefined
|
||||
|
||||
@@ -107,8 +108,17 @@ const schema = reactive<FormSchema[]>([
|
||||
if (event.key === 'Enter') signIn()
|
||||
}}
|
||||
/>
|
||||
<ElButton class="login-code-btn" disabled={unref(getCodeLoading)} onClick={getCode}>
|
||||
{unref(getCodeLoading) ? `${unref(getCodeTime)}s` : '获取验证码'}
|
||||
<ElButton
|
||||
class="login-code-btn"
|
||||
disabled={unref(getCodeLoading)}
|
||||
loading={unref(getCodeLoading) && !unref(captchaCode)}
|
||||
onClick={getCode}
|
||||
>
|
||||
{unref(getCodeLoading)
|
||||
? unref(captchaCode)
|
||||
? `${unref(getCodeTime)}s`
|
||||
: '发送中'
|
||||
: '获取验证码'}
|
||||
</ElButton>
|
||||
</div>
|
||||
)
|
||||
@@ -165,6 +175,32 @@ onBeforeUnmount(() => {
|
||||
if (codeTimer) clearInterval(codeTimer)
|
||||
})
|
||||
|
||||
// 点下按钮就开始倒计时:短信网关往返通常 1~3 秒,等接口返回再倒计时会像卡死
|
||||
const startCountdown = () => {
|
||||
if (codeTimer) clearInterval(codeTimer)
|
||||
captchaCode.value = ''
|
||||
getCodeTime.value = 60
|
||||
getCodeLoading.value = true
|
||||
codeTimer = setInterval(() => {
|
||||
getCodeTime.value--
|
||||
if (getCodeTime.value <= 0) {
|
||||
clearInterval(codeTimer)
|
||||
codeTimer = undefined
|
||||
getCodeTime.value = 60
|
||||
getCodeLoading.value = false
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 发送失败(限流/验证码失效/发送异常):解禁按钮,让用户能立刻重试
|
||||
const resetCountdown = () => {
|
||||
if (codeTimer) clearInterval(codeTimer)
|
||||
codeTimer = undefined
|
||||
getCodeTime.value = 60
|
||||
getCodeLoading.value = false
|
||||
captchaCode.value = ''
|
||||
}
|
||||
|
||||
const getCode = async () => {
|
||||
if (getCodeLoading.value) return
|
||||
const { username, parentInvitationCode } = await getFormData<SmsLoginType>()
|
||||
@@ -172,6 +208,10 @@ const getCode = async () => {
|
||||
ElMessage.error('请输入正确的手机号')
|
||||
return
|
||||
}
|
||||
// 先验账号再弹滑块:不是推广后台用户(与后台账号校验同一份规则)直接拒绝,
|
||||
// 避免用户白拖一次滑块才被告知没权限;接口失败/被限流时放行走原流程,发送时后端还会再验一次
|
||||
const phoneCheck = await precheckPhoneApi(username, parentInvitationCode).catch(() => null)
|
||||
if (!phoneCheck) return
|
||||
if (typeof window.TAC === 'undefined' || typeof window.CaptchaConfig === 'undefined') {
|
||||
ElMessage.error('滑块验证码未加载,请刷新页面')
|
||||
return
|
||||
@@ -187,19 +227,18 @@ const getCode = async () => {
|
||||
validSuccess: (_res: unknown, _config: unknown, tac: any) => {
|
||||
tac.destroyWindow()
|
||||
tacInstance = null
|
||||
getCodeApi(username, captchaId, '2', parentInvitationCode).then(() => {
|
||||
ElMessage.success('验证码已发送')
|
||||
getCodeLoading.value = true
|
||||
codeTimer = setInterval(() => {
|
||||
getCodeTime.value--
|
||||
if (getCodeTime.value <= 0) {
|
||||
clearInterval(codeTimer)
|
||||
codeTimer = undefined
|
||||
getCodeTime.value = 60
|
||||
getCodeLoading.value = false
|
||||
startCountdown()
|
||||
getCodeApi(username, captchaId, '2', parentInvitationCode)
|
||||
.then((res: any) => {
|
||||
// 业务失败(限流/验证码失效)响应拦截器已弹过错误提示,这里只释放倒计时
|
||||
if (res?.code !== 0 && res?.code !== 200) {
|
||||
resetCountdown()
|
||||
return
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
captchaCode.value = captchaId
|
||||
ElMessage.success('验证码已发送')
|
||||
})
|
||||
.catch(() => resetCountdown())
|
||||
},
|
||||
validFail: (_res: unknown, _config: unknown, tac: any) => {
|
||||
ElMessage.error('滑块验证失败,请重试')
|
||||
|
||||
@@ -10,7 +10,7 @@ import { RegisterUserType } from '@/api/login/types'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import { completeLogin } from '../completeLogin'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { registerApi, getCodeApi } from '@/api/login'
|
||||
import { registerApi, getCodeApi, precheckPhoneApi } from '@/api/login'
|
||||
import { PATH_URL } from '@/axios/service'
|
||||
|
||||
declare global {
|
||||
@@ -38,12 +38,38 @@ const { required } = useValidator()
|
||||
const getCodeTime = ref(60)
|
||||
const getCodeLoading = ref(false)
|
||||
let tacInstance: any = null
|
||||
let codeTimer: ReturnType<typeof setInterval> | undefined
|
||||
|
||||
// 点下按钮就开始倒计时:短信网关往返通常 1~3 秒,等接口返回再倒计时会像卡死
|
||||
const startCountdown = () => {
|
||||
if (codeTimer) clearInterval(codeTimer)
|
||||
getCodeTime.value = 60
|
||||
getCodeLoading.value = true
|
||||
codeTimer = setInterval(() => {
|
||||
getCodeTime.value--
|
||||
if (getCodeTime.value <= 0) {
|
||||
clearInterval(codeTimer)
|
||||
codeTimer = undefined
|
||||
getCodeTime.value = 60
|
||||
getCodeLoading.value = false
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 发送失败(限流/验证码失效/发送异常):解禁按钮,让用户能立刻重试
|
||||
const resetCountdown = () => {
|
||||
if (codeTimer) clearInterval(codeTimer)
|
||||
codeTimer = undefined
|
||||
getCodeTime.value = 60
|
||||
getCodeLoading.value = false
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (tacInstance) {
|
||||
tacInstance.destroyWindow()
|
||||
tacInstance = null
|
||||
}
|
||||
if (codeTimer) clearInterval(codeTimer)
|
||||
})
|
||||
|
||||
const getCode = async () => {
|
||||
@@ -52,6 +78,12 @@ const getCode = async () => {
|
||||
ElMessage.error('手机号不能为空')
|
||||
return
|
||||
}
|
||||
// 先验账号再弹滑块,与登录页同一份规则(注册页无账号时靠招商邀请码放行);接口失败/被限流时放行走原流程
|
||||
const phoneCheck = await precheckPhoneApi(
|
||||
formData.username,
|
||||
(formData as any).parentInvitationCode
|
||||
).catch(() => null)
|
||||
if (!phoneCheck) return
|
||||
|
||||
// 判断TAC是否加载
|
||||
if (typeof window.TAC === 'undefined' || typeof window.CaptchaConfig === 'undefined') {
|
||||
@@ -71,23 +103,18 @@ const getCode = async () => {
|
||||
tac.destroyWindow()
|
||||
tacInstance = null
|
||||
const captchaId = window._captchaId
|
||||
// 滑块验证成功,发送短信验证码
|
||||
// 滑块验证成功,立刻进入倒计时,再等短信接口返回
|
||||
startCountdown()
|
||||
getCodeApi(formData.username, captchaId)
|
||||
.then(() => {
|
||||
.then((res: any) => {
|
||||
// 业务失败(限流/验证码失效)响应拦截器已弹过错误提示,这里只释放倒计时
|
||||
if (res?.code !== 0 && res?.code !== 200) {
|
||||
resetCountdown()
|
||||
return
|
||||
}
|
||||
ElMessage.success('获取验证码成功')
|
||||
getCodeLoading.value = true
|
||||
const timer = setInterval(() => {
|
||||
getCodeTime.value--
|
||||
if (getCodeTime.value <= 0) {
|
||||
clearInterval(timer)
|
||||
getCodeTime.value = 60
|
||||
getCodeLoading.value = false
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage.error('获取验证码失败')
|
||||
})
|
||||
.catch(() => resetCountdown())
|
||||
},
|
||||
validFail: (res: any, c: any, tac: any) => {
|
||||
ElMessage.error('滑块验证失败,请重试')
|
||||
|
||||
@@ -255,12 +255,15 @@
|
||||
<ElTableColumn prop="id" label="ID" width="60" />
|
||||
<ElTableColumn prop="templateName" label="模板名称" min-width="150" />
|
||||
<ElTableColumn prop="ornamentCount" label="饰品数" width="80" />
|
||||
<ElTableColumn prop="createBy" label="创建人" width="100" />
|
||||
<ElTableColumn prop="createBy" label="创建人" width="100">
|
||||
<template #default="{ row }">{{ row.createBy || '其他主播' }}</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn prop="createTime" label="创建时间" width="170" />
|
||||
<ElTableColumn label="操作" width="140">
|
||||
<template #default="{ row }">
|
||||
<ElButton type="primary" link size="small" @click="handleLoadTemplate(row)">加载</ElButton>
|
||||
<ElButton type="danger" link size="small" @click="handleDeleteTemplate(row.id)">删除</ElButton>
|
||||
<!-- 后端只允许创建者本人或超管删除;共享模板 createBy 会被置空,这里不给别人显示删除按钮 -->
|
||||
<ElButton v-if="row.createBy" type="danger" link size="small" @click="handleDeleteTemplate(row.id)">删除</ElButton>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
</ElTable>
|
||||
|
||||
@@ -29,12 +29,6 @@
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional> <!-- 表示依赖不会传递 -->
|
||||
</dependency>
|
||||
<!-- spring-doc -->
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Mysql驱动包 -->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
|
||||
@@ -4,8 +4,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -33,7 +31,6 @@ import com.ruoyi.system.service.ISysDictTypeService;
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Api(tags = "管理端 字段值管理")
|
||||
@RestController
|
||||
@RequestMapping("/system/dict/data")
|
||||
public class SysDictDataController extends BaseController
|
||||
@@ -44,7 +41,6 @@ public class SysDictDataController extends BaseController
|
||||
@Autowired
|
||||
private ISysDictTypeService dictTypeService;
|
||||
|
||||
@ApiOperation("获取字典值")
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysDictData dictData)
|
||||
@@ -91,7 +87,6 @@ public class SysDictDataController extends BaseController
|
||||
/**
|
||||
* 新增字典类型
|
||||
*/
|
||||
@ApiOperation("新增字典值")
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:add')")
|
||||
@Log(title = "字典数据", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
@@ -104,7 +99,6 @@ public class SysDictDataController extends BaseController
|
||||
/**
|
||||
* 修改保存字典类型
|
||||
*/
|
||||
@ApiOperation("修改字典值")
|
||||
@PreAuthorize("@ss.hasPermi('system:dict:edit')")
|
||||
@Log(title = "字典数据", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.ruoyi.web.controller.system;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -24,7 +23,6 @@ import com.ruoyi.system.service.ISysMenuService;
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Api(tags = "管理端认证api")
|
||||
@RestController
|
||||
public class SysLoginController
|
||||
{
|
||||
|
||||
@@ -11,11 +11,10 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* swagger 用户测试方法
|
||||
* 用户测试方法(若依自带示例,未对外使用)
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
//@Api(tags = "用户信息管理")
|
||||
@RestController
|
||||
@RequestMapping("/test/user")
|
||||
public class TestController extends BaseController
|
||||
@@ -26,7 +25,6 @@ public class TestController extends BaseController
|
||||
users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
|
||||
}
|
||||
|
||||
// @ApiOperation("获取用户列表")
|
||||
@GetMapping("/list")
|
||||
public R<List<UserEntity>> userList()
|
||||
{
|
||||
@@ -34,8 +32,6 @@ public class TestController extends BaseController
|
||||
return R.ok(userList);
|
||||
}
|
||||
|
||||
// @ApiOperation("获取用户详细")
|
||||
// @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
|
||||
@GetMapping("/{userId}")
|
||||
public R<UserEntity> getUser(@PathVariable Integer userId)
|
||||
{
|
||||
@@ -49,13 +45,6 @@ public class TestController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
// @ApiOperation("新增用户")
|
||||
// @ApiImplicitParams({
|
||||
// @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class),
|
||||
// @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class),
|
||||
// @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class),
|
||||
// @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class)
|
||||
// })
|
||||
@PostMapping("/save")
|
||||
public R<String> save(UserEntity user)
|
||||
{
|
||||
@@ -67,7 +56,6 @@ public class TestController extends BaseController
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// @ApiOperation("更新用户")
|
||||
@PutMapping("/update")
|
||||
public R<String> update(@RequestBody UserEntity user)
|
||||
{
|
||||
@@ -84,8 +72,6 @@ public class TestController extends BaseController
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// @ApiOperation("删除用户信息")
|
||||
// @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
|
||||
@DeleteMapping("/{userId}")
|
||||
public R<String> delete(@PathVariable Integer userId)
|
||||
{
|
||||
@@ -101,19 +87,14 @@ public class TestController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
//@ApiModel(value = "UserEntity", description = "用户实体")
|
||||
class UserEntity
|
||||
{
|
||||
// @ApiModelProperty("用户ID")
|
||||
private Integer userId;
|
||||
|
||||
// @ApiModelProperty("用户名称")
|
||||
private String username;
|
||||
|
||||
// @ApiModelProperty("用户密码")
|
||||
private String password;
|
||||
|
||||
// @ApiModelProperty("用户手机")
|
||||
private String mobile;
|
||||
|
||||
public UserEntity()
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
package com.ruoyi.web.core.config;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.models.auth.In;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiKey;
|
||||
import springfox.documentation.service.AuthorizationScope;
|
||||
import springfox.documentation.service.SecurityReference;
|
||||
import springfox.documentation.service.SecurityScheme;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class SwaggerConfig {
|
||||
|
||||
/**
|
||||
* 后台接口分组
|
||||
*/
|
||||
// @Bean
|
||||
public Docket adminDocket() {
|
||||
return new Docket(DocumentationType.OAS_30)
|
||||
.select()
|
||||
// 扫描注解
|
||||
.apis(RequestHandlerSelectors.basePackage("com.ruoyi.admin.controller"))
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
// 扫描所有.apis(RequestHandlerSelectors.any())
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.groupName("admin")
|
||||
// 设置安全模式,访问token
|
||||
.securitySchemes(securitySchemes())
|
||||
.securityContexts(securityContexts());
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户业务接口分组
|
||||
*/
|
||||
@Bean
|
||||
public Docket userDocket() {
|
||||
return new Docket(DocumentationType.OAS_30)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com.ruoyi.user.controller"))
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.groupName("user")
|
||||
.securitySchemes(securitySchemes())
|
||||
.securityContexts(securityContexts());
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方业务接口分组
|
||||
*/
|
||||
@Bean
|
||||
public Docket thirdPartyDocket() {
|
||||
return new Docket(DocumentationType.OAS_30)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com.ruoyi.thirdparty"))
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.groupName("thirdParty")
|
||||
.securitySchemes(securitySchemes())
|
||||
.securityContexts(securityContexts());
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩法业务接口分组
|
||||
*/
|
||||
@Bean
|
||||
public Docket playingMethodDocket() {
|
||||
return new Docket(DocumentationType.OAS_30)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com.ruoyi.playingmethod.controller"))
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.groupName("playingMethod")
|
||||
.securitySchemes(securitySchemes())
|
||||
.securityContexts(securityContexts());
|
||||
}
|
||||
|
||||
/**
|
||||
* 糖果玩法业务接口分组
|
||||
*/
|
||||
@Bean
|
||||
public Docket gameSugarMethodDocket() {
|
||||
return new Docket(DocumentationType.OAS_30)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com.ruoyi.game.sugar.controller"))
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.groupName("gameSugarMethod")
|
||||
.securitySchemes(securitySchemes())
|
||||
.securityContexts(securityContexts());
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务业务接口分组
|
||||
*/
|
||||
@Bean
|
||||
public Docket taskDocket() {
|
||||
return new Docket(DocumentationType.OAS_30)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com.ruoyi.task.controller"))
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.groupName("task")
|
||||
.securitySchemes(securitySchemes())
|
||||
.securityContexts(securityContexts());
|
||||
}
|
||||
|
||||
/**
|
||||
* 推广后台接口分组
|
||||
*/
|
||||
@Bean
|
||||
public Docket promoDocket() {
|
||||
return new Docket(DocumentationType.OAS_30)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com.ruoyi.promo.controller"))
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.groupName("promo")
|
||||
.securitySchemes(securitySchemes())
|
||||
.securityContexts(securityContexts());
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全模式,这里指定token通过Authorization请求头传递
|
||||
*/
|
||||
private List<SecurityScheme> securitySchemes() {
|
||||
List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
|
||||
apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
|
||||
return apiKeyList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全上下文
|
||||
*/
|
||||
private List<SecurityContext> securityContexts() {
|
||||
List<SecurityContext> securityContexts = new ArrayList<>();
|
||||
securityContexts.add(SecurityContext.builder()
|
||||
.securityReferences(defaultAuth())
|
||||
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
|
||||
.build());
|
||||
return securityContexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认的安全引用
|
||||
*/
|
||||
private List<SecurityReference> defaultAuth() {
|
||||
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
|
||||
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
|
||||
authorizationScopes[0] = authorizationScope;
|
||||
List<SecurityReference> securityReferences = new ArrayList<>();
|
||||
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
|
||||
return securityReferences;
|
||||
}
|
||||
}
|
||||
@@ -70,12 +70,12 @@ spring:
|
||||
enabled: true
|
||||
statViewServlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
# 白名单:只允许本机访问(原来留空 = 任意 IP 都能打开控制台)
|
||||
allow: 127.0.0.1
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: ruoyi
|
||||
login-password: 123456
|
||||
# 控制台管理用户名和密码(河南单独一套,勿用常州/默认值)
|
||||
login-username: druidhn
|
||||
login-password: Hn@Druid#7t4Wq9
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
|
||||
@@ -69,13 +69,15 @@ spring:
|
||||
webStatFilter:
|
||||
enabled: true
|
||||
statViewServlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
# 生产关闭 Druid 控制台:/druid/** 是匿名放行的,开着等于把全部 SQL 语句、URI 统计、连接信息挂到公网
|
||||
# 需要临时排障时改成 true,并保持 allow 白名单 + 非默认口令,用完立刻关回
|
||||
enabled: false
|
||||
# 白名单:只允许本机访问(原来留空 = 任意 IP)
|
||||
allow: 127.0.0.1
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: ruoyi
|
||||
login-password: 123456
|
||||
# 控制台管理用户名和密码(河南单独一套,临时开启时使用,勿改回默认值)
|
||||
login-username: druidhn
|
||||
login-password: Hn@Druid#7t4Wq9
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.ruoyi.framework.config;
|
||||
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.domain.entity.UserData;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* 三端 token 隔离规则验证(不启动 Spring,直接测 SecurityConfig 里的三个判定方法):
|
||||
* <ul>
|
||||
* <li>后台面 /admin|/system|/monitor|/tool|/test → 只认后台 sys_user 账号签发的 token</li>
|
||||
* <li>推广面 /promo/** → 只认推广后台签发的 token(loginScope = promo)</li>
|
||||
* <li>玩家面 /api/** → 只认玩家端签发的 token(loginScope = player)</li>
|
||||
* </ul>
|
||||
* 关键点:主播(01)/招商(04)/卡商(05) 是同一张 tt_user 表、两端都能登录,LoginUser 长得一模一样,
|
||||
* 只有登录端标记能区分,所以「主播的玩家端 token」不能进推广接口,「主播的推广 token」也不能进玩家接口。
|
||||
*/
|
||||
public class SecurityRulesTest {
|
||||
|
||||
private final SecurityConfig config = new SecurityConfig();
|
||||
|
||||
/** 后台账号登录(sys_user) */
|
||||
private static LoginUser adminLogin() {
|
||||
LoginUser loginUser = new LoginUser();
|
||||
loginUser.setUser(new SysUser());
|
||||
loginUser.setLoginScope(LoginUser.SCOPE_ADMIN);
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
/** 推广后台登录(超管 99 / 主播 01 / 招商 04 / 卡商 05) */
|
||||
private static LoginUser promoLogin(String userType) {
|
||||
LoginUser loginUser = new LoginUser();
|
||||
loginUser.setUserData(UserData.builder().userType(userType).build());
|
||||
loginUser.setLoginScope(LoginUser.SCOPE_PROMO);
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
/** 玩家端登录(通用用户 00 / 主播 01 / 招商 04 / 卡商 05) */
|
||||
private static LoginUser playerLogin(String userType) {
|
||||
LoginUser loginUser = new LoginUser();
|
||||
loginUser.setUserData(UserData.builder().userType(userType).build());
|
||||
loginUser.setLoginScope(LoginUser.SCOPE_PLAYER);
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
/** 本次改造前签发的老 token:没有登录端标记 */
|
||||
private static LoginUser legacyLogin(String userType) {
|
||||
LoginUser loginUser = new LoginUser();
|
||||
loginUser.setUserData(UserData.builder().userType(userType).build());
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
/** 已认证的令牌:与 JwtAuthenticationTokenFilter 一致,用三参构造(两参构造是"未认证"状态) */
|
||||
private static Supplier<Authentication> auth(LoginUser principal) {
|
||||
return principal == null ? () -> null
|
||||
: () -> new UsernamePasswordAuthenticationToken(principal, null, Collections.emptyList());
|
||||
}
|
||||
|
||||
/** 未认证的令牌:两参构造,isAuthenticated() 为 false */
|
||||
private static Supplier<Authentication> unauthenticated(LoginUser principal) {
|
||||
return () -> new UsernamePasswordAuthenticationToken(principal, null);
|
||||
}
|
||||
|
||||
private boolean adminAllowed(LoginUser principal) {
|
||||
return config.checkAdminUser(auth(principal), null).isGranted();
|
||||
}
|
||||
|
||||
private boolean promoAllowed(LoginUser principal) {
|
||||
return config.checkPromoUser(auth(principal), null).isGranted();
|
||||
}
|
||||
|
||||
private boolean playerAllowed(LoginUser principal) {
|
||||
return config.checkPlayerUser(auth(principal), null).isGranted();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void adminEndOnlyAcceptsBackendAccount() {
|
||||
assertTrue(adminAllowed(adminLogin()), "后台账号应能访问后台接口");
|
||||
assertFalse(adminAllowed(promoLogin("99")), "推广超管 token 不能访问后台接口");
|
||||
assertFalse(adminAllowed(promoLogin("01")), "推广 token 不能访问后台接口");
|
||||
assertFalse(adminAllowed(playerLogin("00")), "玩家 token 不能访问后台接口");
|
||||
assertFalse(adminAllowed(playerLogin("01")), "主播的玩家端 token 不能访问后台接口");
|
||||
assertFalse(adminAllowed(null), "未登录不能访问后台接口");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void promoEndOnlyAcceptsPromoToken() {
|
||||
for (String userType : new String[]{"99", "04", "01", "05"}) {
|
||||
assertTrue(promoAllowed(promoLogin(userType)), "推广后台 token(" + userType + ")应能访问推广接口");
|
||||
}
|
||||
assertFalse(promoAllowed(playerLogin("01")), "主播的玩家端 token 不能访问推广接口");
|
||||
assertFalse(promoAllowed(playerLogin("00")), "玩家 token 不能访问推广接口");
|
||||
assertFalse(promoAllowed(adminLogin()), "后台 token 不能访问推广接口");
|
||||
assertFalse(promoAllowed(legacyLogin("01")), "本次改造前的老 token 没有端标记,必须重新登录");
|
||||
assertFalse(promoAllowed(null), "未登录不能访问推广接口");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playerEndOnlyAcceptsPlayerToken() {
|
||||
for (String userType : new String[]{"00", "01", "04", "05"}) {
|
||||
assertTrue(playerAllowed(playerLogin(userType)), "玩家端 token(" + userType + ")应能访问 /api/**");
|
||||
}
|
||||
assertFalse(playerAllowed(promoLogin("01")), "主播的推广 token 不能访问 /api/**");
|
||||
assertFalse(playerAllowed(promoLogin("99")), "推广超管 token 不能访问 /api/**");
|
||||
assertFalse(playerAllowed(adminLogin()), "后台 token 不能访问 /api/**");
|
||||
assertFalse(playerAllowed(legacyLogin("00")), "本次改造前的老 token 没有端标记,必须重新登录");
|
||||
assertFalse(playerAllowed(null), "未登录不能访问 /api/**");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unauthenticatedTokenIsDeniedEverywhere() {
|
||||
Supplier<Authentication> notAuthenticated = unauthenticated(adminLogin());
|
||||
assertFalse(config.checkAdminUser(notAuthenticated, null).isGranted());
|
||||
assertFalse(config.checkPromoUser(notAuthenticated, null).isGranted());
|
||||
assertFalse(config.checkPlayerUser(notAuthenticated, null).isGranted());
|
||||
}
|
||||
}
|
||||
@@ -192,13 +192,6 @@
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Swagger3依赖 -->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-boot-starter</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -22,6 +22,15 @@ public class LoginUser implements UserDetails
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 登录端:游戏管理后台(sys_user 账号) */
|
||||
public static final String SCOPE_ADMIN = "admin";
|
||||
|
||||
/** 登录端:推广后台(promo_admin 超管 / 主播 01 / 招商 04 / 卡商 05) */
|
||||
public static final String SCOPE_PROMO = "promo";
|
||||
|
||||
/** 登录端:玩家端(H5 / App,api_ 前缀登录) */
|
||||
public static final String SCOPE_PLAYER = "player";
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@@ -79,6 +88,13 @@ public class LoginUser implements UserDetails
|
||||
|
||||
private UserData userData;
|
||||
|
||||
/**
|
||||
* 登录端标记(admin / promo / player):同一个 tt_user 既能登录玩家端也能登录推广后台,
|
||||
* 两端签发的 token 必须互不通用,鉴权时按这个标记区分(见 SecurityConfig 的三条规则)。
|
||||
* 签发时在 ApiUserDetailsServiceImpl 按账号前缀写入,随会话缓存在 Redis 里。
|
||||
*/
|
||||
private String loginScope;
|
||||
|
||||
public LoginUser(Long userId, UserData userData) {
|
||||
this.userId = userId;
|
||||
this.userData = userData;
|
||||
|
||||
@@ -30,7 +30,9 @@ public class MimeTypeUtils
|
||||
// 图片
|
||||
"bmp", "gif", "jpg", "jpeg", "png",
|
||||
// word excel powerpoint
|
||||
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
|
||||
// 2026-09-23 去掉 html/htm:上传目录 /profile/** 是匿名可访问的静态目录,
|
||||
// 放行 html/htm 等于允许任意登录用户往自己域名下丢页面(.html 被当静态资源打开就是 XSS/钓鱼面)
|
||||
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt",
|
||||
// 压缩文件
|
||||
"rar", "zip", "gz", "bz2",
|
||||
// 视频格式
|
||||
|
||||
@@ -5,14 +5,12 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
@@ -54,11 +52,6 @@ public class ResourcesConfig implements WebMvcConfigurer
|
||||
|
||||
registry.addResourceHandler("/upload/**")
|
||||
.addResourceLocations("file:" + RuoYiConfig.getProfile() + "/upload/");
|
||||
|
||||
/** swagger配置 */
|
||||
registry.addResourceHandler("/swagger-ui/**")
|
||||
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
|
||||
.setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,6 +36,7 @@ import java.util.function.Supplier;
|
||||
@EnableWebSecurity
|
||||
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
|
||||
public class SecurityConfig {
|
||||
|
||||
@Qualifier("apiUserDetailsServiceImpl")
|
||||
@Autowired
|
||||
private UserDetailsService apiUserDetailsService;
|
||||
@@ -101,13 +102,21 @@ public class SecurityConfig {
|
||||
// 静态资源
|
||||
.requestMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html",
|
||||
"/**/*.css", "/**/*.js", "/profile/**", "/uploads/**", "/upload/**").permitAll()
|
||||
// Swagger & Druid
|
||||
.requestMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
|
||||
// Druid 监控台:生产已在 application-pro.yml 关闭 statViewServlet(enabled=false)
|
||||
// 并限制 allow=127.0.0.1 + 非默认口令;这里保留放行是为了本地开发能打开控制台
|
||||
.requestMatchers("/druid/**").permitAll()
|
||||
// WebSocket
|
||||
.requestMatchers("/api/websocket/skins").permitAll()
|
||||
.requestMatchers("/ws/**").permitAll()
|
||||
// 后台接口:只认「后台 sys_user 账号」的 token(详见 checkAdminUser)
|
||||
.requestMatchers("/admin/**").access(this::checkAdminUser)
|
||||
// 后台接口(游戏管理后台 + 框架自带系统管理/监控/代码生成/测试接口):
|
||||
// 只认「后台 sys_user 账号」的 token,推广 / 玩家 token 一律 403(详见 checkAdminUser)
|
||||
// /common/** 是文件上传下载(只有后台 ruoyi-ui 在用),不放进三端前缀里会对所有端开放
|
||||
.requestMatchers("/admin/**", "/system/**", "/monitor/**", "/tool/**", "/test/**", "/common/**")
|
||||
.access(this::checkAdminUser)
|
||||
// 推广接口:只认推广身份的 token,玩家(00)与后台账号一律 403(详见 checkPromoUser)
|
||||
.requestMatchers("/promo/**").access(this::checkPromoUser)
|
||||
// 玩家接口:只认玩家端身份的 token,推广超管与后台账号一律 403(详见 checkPlayerUser)
|
||||
.requestMatchers("/api/**").access(this::checkPlayerUser)
|
||||
// 其他所有请求都需要认证
|
||||
.anyRequest().authenticated();
|
||||
})
|
||||
@@ -138,8 +147,8 @@ public class SecurityConfig {
|
||||
* → LoginUser.userData 是 UserData,LoginUser.user 为 null → 拒绝(403)。
|
||||
* 这样即使某个后台 Controller 忘了标 @PreAuthorize,也不会被玩家 token 调用。
|
||||
*/
|
||||
private AuthorizationDecision checkAdminUser(Supplier<? extends Authentication> authentication,
|
||||
RequestAuthorizationContext context) {
|
||||
AuthorizationDecision checkAdminUser(Supplier<? extends Authentication> authentication,
|
||||
RequestAuthorizationContext context) {
|
||||
Authentication auth = authentication.get();
|
||||
if (auth == null || !auth.isAuthenticated()) {
|
||||
return new AuthorizationDecision(false);
|
||||
@@ -150,6 +159,48 @@ public class SecurityConfig {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* /promo/** 的访问判定:只允许「推广后台签发」的 token(loginScope = promo)。
|
||||
*
|
||||
* 同一个 tt_user(主播 01 / 招商 04 / 卡商 05)既能登录玩家端也能登录推广后台,
|
||||
* 两端拿到的 LoginUser(userId + userData)完全一样,光看 userType 区分不了,
|
||||
* 所以这里必须按登录端标记卡:玩家端签发的 token 即使账号是主播,也进不来推广接口。
|
||||
*/
|
||||
AuthorizationDecision checkPromoUser(Supplier<? extends Authentication> authentication,
|
||||
RequestAuthorizationContext context) {
|
||||
LoginUser loginUser = loginUserOf(authentication);
|
||||
if (loginUser == null || loginUser.getUserData() == null) {
|
||||
return new AuthorizationDecision(false);
|
||||
}
|
||||
return new AuthorizationDecision(LoginUser.SCOPE_PROMO.equals(loginUser.getLoginScope()));
|
||||
}
|
||||
|
||||
/**
|
||||
* /api/** 的访问判定:只允许「玩家端签发」的 token(loginScope = player)。
|
||||
*
|
||||
* 推广后台 token(哪怕底层账号就是 tt_user)一律拒绝;后台账号(sys_user)没有 userData,也进不来。
|
||||
*/
|
||||
AuthorizationDecision checkPlayerUser(Supplier<? extends Authentication> authentication,
|
||||
RequestAuthorizationContext context) {
|
||||
LoginUser loginUser = loginUserOf(authentication);
|
||||
if (loginUser == null || loginUser.getUserData() == null) {
|
||||
return new AuthorizationDecision(false);
|
||||
}
|
||||
return new AuthorizationDecision(LoginUser.SCOPE_PLAYER.equals(loginUser.getLoginScope()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出已认证的 LoginUser,其余情况(匿名 / 未认证 / 非本框架主体)返回 null
|
||||
*/
|
||||
private LoginUser loginUserOf(Supplier<? extends Authentication> authentication) {
|
||||
Authentication auth = authentication.get();
|
||||
if (auth == null || !auth.isAuthenticated()) {
|
||||
return null;
|
||||
}
|
||||
return auth.getPrincipal() instanceof LoginUser loginUser ? loginUser : null;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public BCryptPasswordEncoder bCryptPasswordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
|
||||
+3
-1
@@ -61,6 +61,8 @@ public class UserDetailsServiceImpl implements UserDetailsService
|
||||
|
||||
public UserDetails createLoginUser(SysUser user)
|
||||
{
|
||||
return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
|
||||
LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
|
||||
loginUser.setLoginScope(LoginUser.SCOPE_ADMIN);
|
||||
return loginUser;
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -45,6 +45,11 @@ public class WsTokenService {
|
||||
if (loginUser == null) {
|
||||
return null;
|
||||
}
|
||||
// 只认玩家端 token:推广/后台 token 即使 userId 撞上某个 tt_user 的 id 也不能连玩家 WS
|
||||
// (与 SecurityConfig.checkPlayerUser 口径一致;本次改造前签发的老 token 无端标记,同样要重新登录)
|
||||
if (!LoginUser.SCOPE_PLAYER.equals(loginUser.getLoginScope())) {
|
||||
return null;
|
||||
}
|
||||
return loginUser.getUserId().equals(expectedUserId) ? uuid : null;
|
||||
} catch (Exception e) {
|
||||
log.warn("WS Token 校验异常, userId={}", expectedUserId, e);
|
||||
|
||||
@@ -246,11 +246,11 @@
|
||||
v-model="item.value"
|
||||
maxlength="11"
|
||||
clearable
|
||||
placeholder="留空则自动生成随机手机号"
|
||||
placeholder="请输入 11 位手机号(必填)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div style="font-size:12px;color:#7a664e;padding-left:90px;">
|
||||
<i class="el-icon-info"></i> 手机号选填:填写后作为登录账号,留空则系统随机生成
|
||||
<i class="el-icon-info"></i> 手机号必填:该号即推广后台登录账号,登录要用它接收短信验证码
|
||||
</div>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
@@ -292,11 +292,11 @@
|
||||
v-model="item.value"
|
||||
maxlength="11"
|
||||
clearable
|
||||
placeholder="留空则自动生成随机手机号"
|
||||
placeholder="请输入 11 位手机号(必填)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div style="font-size:12px;color:#7a664e;padding-left:90px;">
|
||||
<i class="el-icon-info"></i> 手机号选填:填写后作为登录账号,留空则系统随机生成
|
||||
<i class="el-icon-info"></i> 手机号必填:该号即推广后台登录账号,登录要用它接收短信验证码
|
||||
</div>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
@@ -399,9 +399,7 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="用户类型:" prop="userType">
|
||||
<span v-if="form.userType === '00'">系统用户</span>
|
||||
<span v-if="form.userType === '01'">主播</span>
|
||||
<span v-if="form.userType === '02'">普通用户</span>
|
||||
<span v-for="dict in dict.type.user_type" v-if="dict.value === form.userType" :key="dict.value">{{ dict.label }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户状态:">
|
||||
<span v-if="form.status === '0'">正常</span>
|
||||
@@ -484,7 +482,7 @@ export default {
|
||||
addNewUser: false,
|
||||
addRobot: false,
|
||||
addCardMerchant: false,
|
||||
// 招商账号-自定义手机号输入列表(每项 { value },留空则后端随机生成)
|
||||
// 招商账号-手机号输入列表(每项 { value },必填,作为推广后台登录账号)
|
||||
businessPhones: [{ value: "" }],
|
||||
// 卡商账号-自定义手机号输入列表
|
||||
cardPhones: [{ value: "" }],
|
||||
@@ -675,24 +673,26 @@ export default {
|
||||
onCardNumberChange(val) {
|
||||
this.cardPhones = this.buildPhoneInputs(val, this.cardPhones);
|
||||
},
|
||||
/* 校验并提取自定义手机号:合法返回数组(留空占位为""),非法返回 null */
|
||||
/* 校验并提取手机号:全部必填,合法返回数组,非法返回 null */
|
||||
extractCustomPhones(phones) {
|
||||
const result = [];
|
||||
const seen = new Set();
|
||||
const reg = /^1[3-9]\d{9}$/;
|
||||
for (let i = 0; i < phones.length; i++) {
|
||||
const v = (phones[i].value || "").trim();
|
||||
if (v) {
|
||||
if (!reg.test(v)) {
|
||||
this.$modal.msgError(`第 ${i + 1} 个手机号格式不正确,请输入 11 位有效手机号`);
|
||||
return null;
|
||||
}
|
||||
if (seen.has(v)) {
|
||||
this.$modal.msgError(`第 ${i + 1} 个手机号重复:${v}`);
|
||||
return null;
|
||||
}
|
||||
seen.add(v);
|
||||
if (!v) {
|
||||
this.$modal.msgError(`请填写第 ${i + 1} 个手机号`);
|
||||
return null;
|
||||
}
|
||||
if (!reg.test(v)) {
|
||||
this.$modal.msgError(`第 ${i + 1} 个手机号格式不正确,请输入 11 位有效手机号`);
|
||||
return null;
|
||||
}
|
||||
if (seen.has(v)) {
|
||||
this.$modal.msgError(`第 ${i + 1} 个手机号重复:${v}`);
|
||||
return null;
|
||||
}
|
||||
seen.add(v);
|
||||
result.push(v);
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<i-frame :src="url" />
|
||||
</template>
|
||||
<script>
|
||||
import iFrame from "@/components/iFrame/index";
|
||||
|
||||
export default {
|
||||
name: "Swagger",
|
||||
components: { iFrame },
|
||||
data() {
|
||||
return {
|
||||
// url: process.env.VUE_APP_BASE_API + "/swagger-ui/index.html"
|
||||
url: process.env.VUE_APP_BASE_API + "/doc.html"
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.ruoyi.domain.dto.packSack;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -12,7 +11,6 @@ import java.util.List;
|
||||
@Data
|
||||
public class PackSackCondition {
|
||||
|
||||
@ApiModelProperty("背包类型(1我的库存 2提货背包 3福利箱子)")
|
||||
private Integer packType;
|
||||
|
||||
private List<Integer> uidList;
|
||||
@@ -27,9 +25,7 @@ public class PackSackCondition {
|
||||
|
||||
private String endTime;
|
||||
|
||||
@ApiModelProperty("价格排序方向(1升序 2降序,null不排序)")
|
||||
private Integer priceSort;
|
||||
|
||||
@ApiModelProperty("时间排序方向(1升序 2降序,null不排序)")
|
||||
private Integer timeSort;
|
||||
}
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
package com.ruoyi.domain.dto.share;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 分享记录列表查询参数
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("分享记录列表查询参数")
|
||||
public class ShareRecordQueryDTO {
|
||||
|
||||
/** 可选;按被邀请人用户ID过滤 */
|
||||
@ApiModelProperty("下级用户ID(可选)")
|
||||
private Long subUserId;
|
||||
|
||||
/** 页码(由前端传入) */
|
||||
@ApiModelProperty(value = "页码", required = true, example = "1")
|
||||
private Integer pageNum;
|
||||
|
||||
/** 每页大小(由前端传入) */
|
||||
@ApiModelProperty(value = "每页大小", required = true, example = "10")
|
||||
private Integer pageSize;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.ruoyi.domain.other;
|
||||
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
@@ -9,28 +8,20 @@ import java.math.BigDecimal;
|
||||
@Data
|
||||
public class ApiShoppingBody {
|
||||
|
||||
@ApiParam("商品名称")
|
||||
private String name;
|
||||
|
||||
@ApiParam("类型(0全部饰品 1匕首 2手枪 3步枪 4微型冲锋枪 5重型武器 6手套 7印花 8其它)")
|
||||
private String type;
|
||||
|
||||
@ApiParam("品质(1普通 2StatTrak™ 3纪念品 4★ 5★ StatTrak™ 6闪耀 7金色 8全息 9闪亮)")
|
||||
private String quality;
|
||||
|
||||
@ApiParam("稀有度")
|
||||
private String rarity;
|
||||
|
||||
@ApiParam("外观(1崭新出厂 2略有磨损 3久经沙场 4残损不堪 5战痕累累 6无涂装)")
|
||||
private String exterior;
|
||||
|
||||
@ApiParam("最高价格")
|
||||
private BigDecimal maxPrice;
|
||||
|
||||
@ApiParam("最低价格")
|
||||
private BigDecimal minPrice = BigDecimal.ZERO;
|
||||
|
||||
@ApiParam("1价格升序 2价格降序 3更新时间升序 4更新时间降序")
|
||||
private Integer sortBy;
|
||||
|
||||
@Min(value = 1, message = "每页长度最小为1")
|
||||
@@ -39,7 +30,6 @@ public class ApiShoppingBody {
|
||||
@Min(value = 1, message = "页码最小为1")
|
||||
private Integer pageNum;
|
||||
|
||||
@ApiParam("是否可兑换")
|
||||
private Boolean isExchange;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.ruoyi.domain.other;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.Max;
|
||||
@@ -12,15 +11,12 @@ import java.util.Map;
|
||||
@Data
|
||||
public class CreateFightBody {
|
||||
|
||||
@ApiModelProperty("模式(0欧皇 1非酋)")
|
||||
@NotBlank(message = "模式不能为空")
|
||||
private String model;
|
||||
|
||||
@ApiModelProperty("玩家人数")
|
||||
@Max(value = 12, message = "最大值12")
|
||||
private Integer playerNumber;
|
||||
|
||||
@ApiModelProperty("组队模式(0或空=个人对战 1=2v2组队,座位0/1为一队、座位2/3为二队)")
|
||||
private Integer teamMode;
|
||||
|
||||
// 所有宝箱
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.ruoyi.domain.other;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
|
||||
@@ -21,12 +20,9 @@ public class CreateOrderParam {
|
||||
@Min(value = 1, message = "最小值1")
|
||||
private Integer goodsNum;
|
||||
|
||||
@ApiModelProperty("对接qs支付新增:支付方式(alipay/wxpay)")
|
||||
private String payType;
|
||||
|
||||
@ApiModelProperty("1:原有支付,2:图片支付")
|
||||
private Integer payWay = 1;
|
||||
|
||||
@ApiModelProperty("百度推广bdvid")
|
||||
private String bdVid;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
package com.ruoyi.domain.other;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FightBoutData {
|
||||
|
||||
@ApiModelProperty("对战ID")
|
||||
private Integer fightId;
|
||||
|
||||
@ApiModelProperty("对战回合号")
|
||||
private Integer boutNum;
|
||||
|
||||
@ApiModelProperty("过期时间")
|
||||
private Integer expirationTime;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,6 @@ public class PromoWebConfig implements WebMvcConfigurer {
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(promoMaintenanceInterceptor)
|
||||
.addPathPatterns("/promo/**")
|
||||
.excludePathPatterns("/promo/login", "/promo/smsLogin", "/promo/register");
|
||||
.excludePathPatterns("/promo/smsLogin", "/promo/register");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@ import com.ruoyi.domain.entity.sys.PromoAdmin;
|
||||
import com.ruoyi.domain.entity.sys.TtUser;
|
||||
import com.ruoyi.promo.domain.entity.PromoCardKey;
|
||||
import com.ruoyi.promo.mapper.PromoCardKeyMapper;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -32,7 +30,6 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 超级管理员专属管理接口
|
||||
*/
|
||||
@Api(tags = "超管管理")
|
||||
@RestController
|
||||
@RequestMapping("/promo/adminManage")
|
||||
public class PromoAdminManageController extends BaseController {
|
||||
@@ -63,7 +60,6 @@ public class PromoAdminManageController extends BaseController {
|
||||
/**
|
||||
* 招商管理:查看所有招商及其下属主播汇总数据
|
||||
*/
|
||||
@ApiOperation("招商管理列表")
|
||||
@GetMapping("/businessList")
|
||||
public R<List<Map<String, Object>>> getBusinessList() {
|
||||
if (!isSuperAdmin()) {
|
||||
@@ -207,7 +203,6 @@ public class PromoAdminManageController extends BaseController {
|
||||
/**
|
||||
* 主播管理:查看所有主播及其下属用户汇总数据
|
||||
*/
|
||||
@ApiOperation("主播管理列表")
|
||||
@GetMapping("/anchorList")
|
||||
public R<List<Map<String, Object>>> getAnchorList() {
|
||||
if (!isSuperAdmin()) {
|
||||
@@ -305,7 +300,6 @@ public class PromoAdminManageController extends BaseController {
|
||||
/**
|
||||
* 卡商管理:查看所有卡商及其卡密记录
|
||||
*/
|
||||
@ApiOperation("卡商管理列表")
|
||||
@GetMapping("/cardMerchantList")
|
||||
public R<List<Map<String, Object>>> getCardMerchantList() {
|
||||
if (!isSuperAdmin()) {
|
||||
@@ -420,7 +414,6 @@ public class PromoAdminManageController extends BaseController {
|
||||
|
||||
// ==================== 推广后台管理员账号管理(仅超管) ====================
|
||||
|
||||
@ApiOperation("管理员列表")
|
||||
@GetMapping("/adminList")
|
||||
public R<List<PromoAdmin>> adminList() {
|
||||
if (!isSuperAdmin()) {
|
||||
@@ -432,7 +425,6 @@ public class PromoAdminManageController extends BaseController {
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@ApiOperation("新增/修改管理员")
|
||||
@PostMapping("/saveAdmin")
|
||||
public R<Void> saveAdmin(@RequestBody PromoAdmin body) {
|
||||
if (!isSuperAdmin()) {
|
||||
@@ -511,7 +503,6 @@ public class PromoAdminManageController extends BaseController {
|
||||
.count() > 0;
|
||||
}
|
||||
|
||||
@ApiOperation("删除管理员")
|
||||
@PostMapping("/deleteAdmin/{id}")
|
||||
public R<Void> deleteAdmin(@PathVariable("id") Integer id) {
|
||||
if (!isSuperAdmin()) {
|
||||
|
||||
@@ -10,8 +10,6 @@ import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.promo.model.PromoCaptchaCheckRequest;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -26,7 +24,6 @@ import java.util.concurrent.TimeUnit;
|
||||
* POST /promo/captcha/gen - 生成验证码
|
||||
* POST /promo/captcha/check - 校验验证码
|
||||
*/
|
||||
@Api(tags = "推广后台滑块验证码")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/promo/captcha")
|
||||
@@ -44,7 +41,6 @@ public class PromoCaptchaController extends BaseController {
|
||||
/**
|
||||
* 生成滑块验证码
|
||||
*/
|
||||
@ApiOperation("生成滑块验证码")
|
||||
@Anonymous
|
||||
@PostMapping("/gen")
|
||||
public R<Object> genCaptcha() {
|
||||
@@ -74,7 +70,6 @@ public class PromoCaptchaController extends BaseController {
|
||||
* 校验滑块验证码
|
||||
* 通过后在 Redis 写入 promo:captcha:verified:{phoneNumber} = captchaId,有效期 5 分钟
|
||||
*/
|
||||
@ApiOperation("校验滑块验证码")
|
||||
@Anonymous
|
||||
@PostMapping("/check")
|
||||
public R<Object> checkCaptcha(@RequestBody PromoCaptchaCheckRequest request) {
|
||||
|
||||
@@ -10,8 +10,6 @@ import com.ruoyi.promo.domain.entity.PromoCardKey;
|
||||
import com.ruoyi.promo.service.PromoCardKeyService;
|
||||
import com.ruoyi.promo.service.PromoLoginService;
|
||||
import com.ruoyi.domain.entity.TtRechargeProd;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -20,7 +18,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Api(tags = "卡商卡密管理")
|
||||
@RestController
|
||||
@RequestMapping("/promo/cardKey")
|
||||
public class PromoCardKeyController extends BaseController {
|
||||
@@ -37,7 +34,6 @@ public class PromoCardKeyController extends BaseController {
|
||||
/**
|
||||
* 获取卡商信息(名称、余额)
|
||||
*/
|
||||
@ApiOperation("获取卡商信息")
|
||||
@GetMapping("/merchantInfo")
|
||||
public R<Map<String, Object>> getMerchantInfo() {
|
||||
var loginUser = getLoginUser();
|
||||
@@ -56,7 +52,6 @@ public class PromoCardKeyController extends BaseController {
|
||||
/**
|
||||
* 获取充值列表(金额选项)
|
||||
*/
|
||||
@ApiOperation("获取充值金额列表")
|
||||
@GetMapping("/rechargeList")
|
||||
public R<List<TtRechargeProd>> getRechargeList() {
|
||||
List<TtRechargeProd> list = promoLoginService.queryList();
|
||||
@@ -66,7 +61,6 @@ public class PromoCardKeyController extends BaseController {
|
||||
/**
|
||||
* 生成卡密
|
||||
*/
|
||||
@ApiOperation("生成卡密")
|
||||
@PostMapping("/generate")
|
||||
public R<List<String>> generateCardKeys(@RequestBody Map<String, Object> request) {
|
||||
var loginUser = getLoginUser();
|
||||
@@ -112,7 +106,6 @@ public class PromoCardKeyController extends BaseController {
|
||||
/**
|
||||
* 销毁未使用卡密(软删除并按面值退回卡商余额;已使用的不可销毁)
|
||||
*/
|
||||
@ApiOperation("销毁卡密")
|
||||
@PostMapping("/destroy")
|
||||
public R<String> destroyCardKey(@RequestBody Map<String, Object> request) {
|
||||
var loginUser = getLoginUser();
|
||||
@@ -140,7 +133,6 @@ public class PromoCardKeyController extends BaseController {
|
||||
/**
|
||||
* 获取卡密列表
|
||||
*/
|
||||
@ApiOperation("获取卡密列表")
|
||||
@GetMapping("/list")
|
||||
public R<IPage<PromoCardKey>> getCardKeyList(
|
||||
@RequestParam(required = false) String usedByName,
|
||||
|
||||
@@ -9,8 +9,6 @@ import com.ruoyi.domain.common.constant.UserType;
|
||||
import com.ruoyi.promo.domain.entity.PromoCdkey;
|
||||
import com.ruoyi.promo.domain.entity.PromoCdkeyRedeem;
|
||||
import com.ruoyi.promo.service.PromoCdkeyService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -23,7 +21,6 @@ import java.util.concurrent.TimeUnit;
|
||||
/**
|
||||
* 推广CDKEY管理
|
||||
*/
|
||||
@Api(tags = "推广CDKEY管理")
|
||||
@RestController
|
||||
@RequestMapping("/promo/cdkey")
|
||||
public class PromoCdkeyController extends BaseController {
|
||||
@@ -37,7 +34,6 @@ public class PromoCdkeyController extends BaseController {
|
||||
/**
|
||||
* 生成CDKEY(仅主播账号可操作)
|
||||
*/
|
||||
@ApiOperation("生成CDKEY")
|
||||
@PostMapping("/generate")
|
||||
public R<List<String>> generate(@RequestBody Map<String, Object> form) {
|
||||
var loginUser = getLoginUser();
|
||||
@@ -70,7 +66,6 @@ public class PromoCdkeyController extends BaseController {
|
||||
/**
|
||||
* 获取创建CDKEY记录列表
|
||||
*/
|
||||
@ApiOperation("获取创建CDKEY记录列表")
|
||||
@GetMapping("/createList")
|
||||
public R<List<PromoCdkey>> createList(
|
||||
@RequestParam(required = false) String startDate,
|
||||
@@ -91,7 +86,6 @@ public class PromoCdkeyController extends BaseController {
|
||||
/**
|
||||
* 获取兑换CDKEY记录列表
|
||||
*/
|
||||
@ApiOperation("获取兑换CDKEY记录列表")
|
||||
@GetMapping("/redeemList")
|
||||
public R<List<PromoCdkeyRedeem>> redeemList(
|
||||
@RequestParam(required = false) String startDate,
|
||||
@@ -113,7 +107,6 @@ public class PromoCdkeyController extends BaseController {
|
||||
/**
|
||||
* 创建CDKEY日报
|
||||
*/
|
||||
@ApiOperation("创建CDKEY日报")
|
||||
@GetMapping("/createDaily")
|
||||
public R<List<Map<String, Object>>> createDaily(
|
||||
@RequestParam(required = false) String startDate,
|
||||
@@ -133,7 +126,6 @@ public class PromoCdkeyController extends BaseController {
|
||||
/**
|
||||
* 兑换CDKEY日报
|
||||
*/
|
||||
@ApiOperation("兑换CDKEY日报")
|
||||
@GetMapping("/redeemDaily")
|
||||
public R<List<Map<String, Object>>> redeemDaily(
|
||||
@RequestParam(required = false) String startDate,
|
||||
|
||||
@@ -20,15 +20,12 @@ import com.ruoyi.admin.config.RedisConstants;
|
||||
import com.ruoyi.admin.mapper.PromoAdminMapper;
|
||||
import com.ruoyi.admin.mapper.TtUserMapper;
|
||||
import com.ruoyi.common.redis.config.RedisLock;
|
||||
import com.ruoyi.domain.other.ApiLoginBody;
|
||||
import com.ruoyi.domain.other.ApiVerificationCodeLoginBody;
|
||||
import com.ruoyi.promo.contract.request.RegisterRequest;
|
||||
import com.ruoyi.promo.contract.request.UpdateInvitationCodeRequest;
|
||||
import com.ruoyi.promo.contract.response.GetShareDomainResponse;
|
||||
import com.ruoyi.promo.service.PromoLoginService;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -40,7 +37,6 @@ import java.util.Map;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Api(tags = "推广后台用户认证")
|
||||
@RestController
|
||||
@RequestMapping("/promo")
|
||||
public class PromoLoginController extends BaseController {
|
||||
@@ -63,7 +59,6 @@ public class PromoLoginController extends BaseController {
|
||||
@Autowired
|
||||
private RedisLock redisLock;
|
||||
|
||||
@ApiOperation("获取推广后台用户信息")
|
||||
@PostMapping("/getInfo")
|
||||
public R<Map<String, Object>> getPromoInfo() {
|
||||
var loginUser = getLoginUser();
|
||||
@@ -134,7 +129,6 @@ public class PromoLoginController extends BaseController {
|
||||
return R.ok(info);
|
||||
}
|
||||
|
||||
@ApiOperation("修改个人资料(昵称/手机号/邮箱)")
|
||||
@PostMapping("/updateProfile")
|
||||
public R<Void> updateProfile(@RequestBody Map<String, String> body) {
|
||||
var loginUser = getLoginUser();
|
||||
@@ -186,7 +180,6 @@ public class PromoLoginController extends BaseController {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@ApiOperation("修改头像(超管,前端裁剪后的 base64)")
|
||||
@PostMapping("/updateAvatar")
|
||||
public R<Void> updateAvatar(@RequestBody Map<String, String> body) {
|
||||
var loginUser = getLoginUser();
|
||||
@@ -216,7 +209,6 @@ public class PromoLoginController extends BaseController {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@ApiOperation("修改登录密码")
|
||||
@PostMapping("/updatePassword")
|
||||
public R<Void> updatePassword(@RequestBody Map<String, String> body) {
|
||||
var loginUser = getLoginUser();
|
||||
@@ -263,21 +255,6 @@ public class PromoLoginController extends BaseController {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@ApiOperation("推广后台用户登录")
|
||||
@Anonymous
|
||||
@PostMapping("/login")
|
||||
public AjaxResult login(@RequestBody ApiLoginBody apiLoginBody) {
|
||||
if ("1".equals(configService.selectConfigByKey("promoMaintenance"))) {
|
||||
return AjaxResult.error("系统维护中,请稍后再试");
|
||||
}
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
String token = promoLoginService.login(apiLoginBody.getUsername(), apiLoginBody.getPassword());
|
||||
ajax.put(Constants.TOKEN, token);
|
||||
ajax.put("user", null);
|
||||
return ajax;
|
||||
}
|
||||
|
||||
@ApiOperation("推广后台短信验证码登录")
|
||||
@Anonymous
|
||||
@PostMapping("/smsLogin")
|
||||
public AjaxResult smsLogin(@RequestBody ApiVerificationCodeLoginBody body) {
|
||||
@@ -294,7 +271,6 @@ public class PromoLoginController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("推广后台用户注册")
|
||||
@Anonymous
|
||||
@PostMapping("/register")
|
||||
public AjaxResult register(@RequestBody RegisterRequest request) {
|
||||
@@ -311,27 +287,23 @@ public class PromoLoginController extends BaseController {
|
||||
return ajax;
|
||||
}
|
||||
|
||||
@ApiOperation("推广后台用户修改推广码")
|
||||
@PostMapping("/updateInvitationCode")
|
||||
public R updateInvitationCode(@RequestBody @Validated UpdateInvitationCodeRequest request) {
|
||||
return promoLoginService.updateInvitationCode(request);
|
||||
}
|
||||
|
||||
@ApiOperation("获取主播/招商推广域名")
|
||||
@GetMapping("/getsharedomain")
|
||||
public R<GetShareDomainResponse> getShareDomain() {
|
||||
return promoLoginService.getShareDomain();
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("获取充值卡列表")
|
||||
@GetMapping("/card/list")
|
||||
public PageDataInfo<TtRechargeProd> cardList() {
|
||||
List<TtRechargeProd> list = promoLoginService.queryList();
|
||||
return getPageData(list);
|
||||
}
|
||||
|
||||
@ApiOperation("生成充值卡")
|
||||
@PostMapping("/generateCard/{rechargeListId}/{num}")
|
||||
@UpdateUserCache
|
||||
public R<List<String>> generateCard(@PathVariable("rechargeListId") Integer rechargeListId,
|
||||
|
||||
@@ -5,14 +5,11 @@ import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.domain.common.constant.UserType;
|
||||
import com.ruoyi.promo.domain.entity.PromoMenuConfig;
|
||||
import com.ruoyi.promo.service.PromoMenuService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Api(tags = "推广后台菜单权限管理")
|
||||
@RestController
|
||||
@RequestMapping("/promo/menu")
|
||||
public class PromoMenuController extends BaseController {
|
||||
@@ -23,7 +20,6 @@ public class PromoMenuController extends BaseController {
|
||||
/**
|
||||
* 获取当前登录用户的菜单权限(根据用户类型)
|
||||
*/
|
||||
@ApiOperation("获取当前用户菜单权限")
|
||||
@GetMapping("/getMenus")
|
||||
public R<List<String>> getMenus() {
|
||||
var loginUser = getLoginUser();
|
||||
@@ -38,7 +34,6 @@ public class PromoMenuController extends BaseController {
|
||||
/**
|
||||
* 获取所有可分配的菜单配置(从数据库读取,前端权限页用)
|
||||
*/
|
||||
@ApiOperation("获取所有可分配菜单")
|
||||
@GetMapping("/allMenuConfigs")
|
||||
public R<List<PromoMenuConfig>> getAllMenuConfigs() {
|
||||
var loginUser = getLoginUser();
|
||||
@@ -55,7 +50,6 @@ public class PromoMenuController extends BaseController {
|
||||
/**
|
||||
* 超管:获取某角色类型的菜单配置
|
||||
*/
|
||||
@ApiOperation("获取角色菜单配置(超管用)")
|
||||
@GetMapping("/getRoleMenus/{roleType}")
|
||||
public R<List<String>> getRoleMenus(@PathVariable("roleType") String roleType) {
|
||||
var loginUser = getLoginUser();
|
||||
@@ -72,7 +66,6 @@ public class PromoMenuController extends BaseController {
|
||||
/**
|
||||
* 超管:保存某角色类型的菜单权限
|
||||
*/
|
||||
@ApiOperation("保存角色菜单权限(超管用)")
|
||||
@PostMapping("/saveRoleMenus")
|
||||
public R<Void> saveRoleMenus(@RequestBody Map<String, Object> request) {
|
||||
var loginUser = getLoginUser();
|
||||
|
||||
@@ -13,13 +13,12 @@ import com.ruoyi.domain.entity.TtBoxRecords;
|
||||
import com.ruoyi.domain.entity.TtOrnament;
|
||||
import com.ruoyi.domain.entity.roll.*;
|
||||
import com.ruoyi.domain.entity.sys.TtUser;
|
||||
import com.ruoyi.domain.common.constant.UserType;
|
||||
import com.ruoyi.domain.common.constant.TtAccountRecordSource;
|
||||
import com.ruoyi.domain.common.constant.TtboxRecordSource;
|
||||
import com.ruoyi.admin.service.TtUserService;
|
||||
import com.ruoyi.admin.mapper.TtUserMapper;
|
||||
import com.ruoyi.promo.mapper.*;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -31,7 +30,6 @@ import java.util.*;
|
||||
/**
|
||||
* 推广 ROLL 房管理
|
||||
*/
|
||||
@Api(tags = "推广 ROLL 房管理")
|
||||
@RestController
|
||||
@RequestMapping("/promo/roll")
|
||||
@Slf4j
|
||||
@@ -70,11 +68,24 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 获取奖池列表(下拉选择用)
|
||||
*/
|
||||
@ApiOperation("获取奖池列表")
|
||||
@GetMapping("/jackpotList")
|
||||
public R<List<TtRollJackpot>> jackpotList(
|
||||
@RequestParam(value = "jackpotName", required = false) String jackpotName) {
|
||||
// 归属校验:只返回自己 Roll 房关联的奖池(此前无过滤,任何推广账号都能看到别人的全部奖池)
|
||||
List<Integer> myJackpotIds = new ArrayList<>();
|
||||
for (TtRoll roll : new LambdaQueryChainWrapper<>(promoRollMapper)
|
||||
.eq(TtRoll::getUserId, getUserId().intValue())
|
||||
.isNotNull(TtRoll::getJackpotId)
|
||||
.list()) {
|
||||
if (!myJackpotIds.contains(roll.getJackpotId())) {
|
||||
myJackpotIds.add(roll.getJackpotId());
|
||||
}
|
||||
}
|
||||
if (myJackpotIds.isEmpty()) {
|
||||
return R.ok(new ArrayList<>());
|
||||
}
|
||||
LambdaQueryWrapper<TtRollJackpot> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.in(TtRollJackpot::getJackpotId, myJackpotIds);
|
||||
if (StringUtils.isNotEmpty(jackpotName)) {
|
||||
wrapper.like(TtRollJackpot::getJackpotName, jackpotName);
|
||||
}
|
||||
@@ -85,7 +96,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 搜索可用饰品(用于添加到奖池)
|
||||
*/
|
||||
@ApiOperation("搜索可用饰品")
|
||||
@GetMapping("/ornaments")
|
||||
public R<List<TtOrnament>> searchOrnaments(
|
||||
@RequestParam(required = false) String name,
|
||||
@@ -105,7 +115,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 按价格区间搜索饰品(用于模板选择,价格升序)
|
||||
*/
|
||||
@ApiOperation("按价格区间搜索饰品(分页)")
|
||||
@GetMapping("/ornamentsByPrice")
|
||||
public R<Map<String, Object>> searchOrnamentsByPrice(
|
||||
@RequestParam(required = false) BigDecimal minPrice,
|
||||
@@ -142,7 +151,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 获取固定金币饰品列表(唯一Hash名以 jinbi- 开头,按面值升序)
|
||||
*/
|
||||
@ApiOperation("获取固定金币饰品列表")
|
||||
@GetMapping("/coinOrnaments")
|
||||
public R<List<TtOrnament>> coinOrnaments() {
|
||||
LambdaQueryWrapper<TtOrnament> wrapper = Wrappers.lambdaQuery();
|
||||
@@ -154,9 +162,12 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 获取奖池饰品列表
|
||||
*/
|
||||
@ApiOperation("获取奖池饰品列表")
|
||||
@GetMapping("/jackpotOrnaments/{jackpotId}")
|
||||
public R<List<TtRollJackpotOrnaments>> jackpotOrnaments(@PathVariable("jackpotId") Integer jackpotId) {
|
||||
R<String> ownerCheck = checkJackpotOwner(jackpotId);
|
||||
if (ownerCheck != null) {
|
||||
return R.fail(ownerCheck.getMsg());
|
||||
}
|
||||
List<TtRollJackpotOrnaments> list = new LambdaQueryChainWrapper<>(promoJackpotOrnamentsMapper)
|
||||
.eq(TtRollJackpotOrnaments::getJackpotId, jackpotId)
|
||||
.list();
|
||||
@@ -166,7 +177,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 向奖池添加饰品
|
||||
*/
|
||||
@ApiOperation("向奖池添加饰品")
|
||||
@PostMapping("/addOrnaments")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<String> addOrnaments(@RequestBody Map<String, Object> body) {
|
||||
@@ -231,7 +241,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 从奖池移除饰品
|
||||
*/
|
||||
@ApiOperation("从奖池移除饰品")
|
||||
@DeleteMapping("/removeOrnament/{id}")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<String> removeOrnament(@PathVariable("id") Integer id) {
|
||||
@@ -266,7 +275,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 更新奖池饰品数量
|
||||
*/
|
||||
@ApiOperation("更新奖池饰品数量")
|
||||
@PutMapping("/updateOrnamentNum")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<String> updateOrnamentNum(@RequestBody Map<String, Object> body) {
|
||||
@@ -410,7 +418,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* Roll房列表
|
||||
*/
|
||||
@ApiOperation("Roll房列表")
|
||||
@GetMapping("/list")
|
||||
public R<List<TtRoll>> list(
|
||||
@RequestParam(required = false) Integer id,
|
||||
@@ -433,9 +440,13 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* Roll房详情
|
||||
*/
|
||||
@ApiOperation("Roll房详情")
|
||||
@GetMapping("/{rollId}")
|
||||
public R<TtRoll> getInfo(@PathVariable("rollId") Integer rollId) {
|
||||
// 归属校验:只能看自己的 Roll 房(此前传任意 id 都能看到别人房间配置)
|
||||
R<String> ownerCheck = checkRollOwner(rollId);
|
||||
if (ownerCheck != null) {
|
||||
return R.fail(ownerCheck.getMsg());
|
||||
}
|
||||
TtRoll roll = promoRollMapper.selectById(rollId);
|
||||
if (roll == null) return R.fail("Roll房不存在");
|
||||
return R.ok(roll);
|
||||
@@ -444,7 +455,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 新增Roll房
|
||||
*/
|
||||
@ApiOperation("新增Roll房")
|
||||
@PostMapping
|
||||
@RepeatSubmit(interval = 3000, message = "Roll房创建中,请勿重复提交")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@@ -601,7 +611,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 修改Roll房
|
||||
*/
|
||||
@ApiOperation("修改Roll房")
|
||||
@PutMapping
|
||||
public R<String> edit(@RequestBody TtRoll ttRoll) {
|
||||
if (ttRoll.getId() == null) return R.fail("Roll房ID不能为空");
|
||||
@@ -639,7 +648,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 删除 Roll 房
|
||||
*/
|
||||
@ApiOperation("删除 Roll 房")
|
||||
@DeleteMapping("/{rollId}")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<String> remove(@PathVariable("rollId") Integer rollId) {
|
||||
@@ -688,7 +696,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 指定奖池饰品获奖用户
|
||||
*/
|
||||
@ApiOperation("指定奖池饰品获奖用户")
|
||||
@PutMapping("/designateOrnamentUser")
|
||||
public R<String> designateOrnamentUser(@RequestBody Map<String, Object> body) {
|
||||
Integer id = body.get("id") != null ? ((Number) body.get("id")).intValue() : null;
|
||||
@@ -773,7 +780,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* Roll房用户列表
|
||||
*/
|
||||
@ApiOperation("Roll 房用户列表")
|
||||
@GetMapping("/users/{rollId}")
|
||||
public R<List<TtRollUser>> users(@PathVariable("rollId") Integer rollId) {
|
||||
R<String> ownerCheck = checkRollOwner(rollId);
|
||||
@@ -793,7 +799,6 @@ public class PromoRollController extends BaseController {
|
||||
* Roll房中奖名单(参与用户中了什么饰品)
|
||||
* 数据口径:tt_box_records 中 source=roll房(3) 且 rollId 匹配的记录,为开奖后实际发放的饰品
|
||||
*/
|
||||
@ApiOperation("Roll 房中奖名单")
|
||||
@GetMapping("/winners/{rollId}")
|
||||
public R<List<Map<String, Object>>> winners(@PathVariable("rollId") Integer rollId) {
|
||||
R<String> ownerCheck = checkRollOwner(rollId);
|
||||
@@ -859,36 +864,77 @@ public class PromoRollController extends BaseController {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验奖池归属:奖池必须关联当前登录用户自己的 Roll 房
|
||||
* (读接口用,不要求"未开奖"——已开奖的房间本人仍然要看自己的奖池)
|
||||
*/
|
||||
private R<String> checkJackpotOwner(Integer jackpotId) {
|
||||
TtRoll roll = findRollByJackpot(jackpotId);
|
||||
if (roll == null) return R.fail("奖池未关联Roll房");
|
||||
if (roll.getUserId() == null || !roll.getUserId().equals(getUserId().intValue())) {
|
||||
return R.fail("无权查看他人奖池");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 奖项模板归属校验:只有创建者本人或推广超管可以改/删
|
||||
*/
|
||||
private R<String> checkTemplateOwner(TtRollPrizeTemplate tpl) {
|
||||
if (tpl == null) return R.fail("模板不存在");
|
||||
if (isSuperAdmin() || isTemplateCreator(tpl)) return null;
|
||||
return R.fail("无权操作他人奖项模板");
|
||||
}
|
||||
|
||||
/** 模板是共享库(建房间时可选用任意模板),但 createBy 是创建人手机号,非本人/超管一律置空 */
|
||||
private void hideTemplateCreatorIfNotMine(List<TtRollPrizeTemplate> list) {
|
||||
for (TtRollPrizeTemplate tpl : list) {
|
||||
hideTemplateCreatorIfNotMine(tpl);
|
||||
}
|
||||
}
|
||||
|
||||
private void hideTemplateCreatorIfNotMine(TtRollPrizeTemplate tpl) {
|
||||
if (tpl == null || isSuperAdmin() || isTemplateCreator(tpl)) return;
|
||||
tpl.setCreateBy(null);
|
||||
}
|
||||
|
||||
private boolean isTemplateCreator(TtRollPrizeTemplate tpl) {
|
||||
var loginUser = getLoginUser();
|
||||
String currentUserName = (loginUser != null && loginUser.getUserData() != null)
|
||||
? loginUser.getUserData().getUserName() : null;
|
||||
return currentUserName != null && currentUserName.equals(tpl.getCreateBy());
|
||||
}
|
||||
|
||||
private boolean isSuperAdmin() {
|
||||
var loginUser = getLoginUser();
|
||||
return loginUser != null && loginUser.getUserData() != null
|
||||
&& UserType.SUPER_ADMIN.getCode().equals(loginUser.getUserData().getUserType());
|
||||
}
|
||||
|
||||
// ==================== 奖项模板管理 ====================
|
||||
|
||||
/**
|
||||
* 获取奖项模板列表
|
||||
*/
|
||||
@ApiOperation("获取奖项模板列表")
|
||||
@GetMapping("/prizeTemplates")
|
||||
public R<List<TtRollPrizeTemplate>> prizeTemplateList() {
|
||||
List<TtRollPrizeTemplate> list = new LambdaQueryChainWrapper<>(promoRollPrizeTemplateMapper)
|
||||
.orderByDesc(TtRollPrizeTemplate::getCreateTime)
|
||||
.list();
|
||||
// 补充每个模板的饰品数量
|
||||
for (TtRollPrizeTemplate tpl : list) {
|
||||
int count = new LambdaQueryChainWrapper<>(promoRollPrizeTemplateDetailMapper)
|
||||
.eq(TtRollPrizeTemplateDetail::getTemplateId, tpl.getId())
|
||||
.count().intValue();
|
||||
// 用 description 字段临时存数量(不加新字段)
|
||||
tpl.setCreateBy(tpl.getCreateBy());
|
||||
}
|
||||
// 模板是共享库(创建房间时可以选择任意模板),但 createBy 存的是 tt_user.user_name(手机号),
|
||||
// 只有本人和超管能看到,其他人置空,避免泄露他人手机号
|
||||
hideTemplateCreatorIfNotMine(list);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取奖项模板详情(含饰品列表)
|
||||
*/
|
||||
@ApiOperation("获取奖项模板详情")
|
||||
@GetMapping("/prizeTemplate/{templateId}")
|
||||
public R<Map<String, Object>> prizeTemplateDetail(@PathVariable("templateId") Integer templateId) {
|
||||
TtRollPrizeTemplate tpl = promoRollPrizeTemplateMapper.selectById(templateId);
|
||||
if (tpl == null) return R.fail("模板不存在");
|
||||
hideTemplateCreatorIfNotMine(tpl);
|
||||
List<TtRollPrizeTemplateDetail> details = new LambdaQueryChainWrapper<>(promoRollPrizeTemplateDetailMapper)
|
||||
.eq(TtRollPrizeTemplateDetail::getTemplateId, templateId)
|
||||
.orderByDesc(TtRollPrizeTemplateDetail::getPrice)
|
||||
@@ -902,7 +948,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 创建奖项模板
|
||||
*/
|
||||
@ApiOperation("创建奖项模板")
|
||||
@PostMapping("/prizeTemplate")
|
||||
public R<TtRollPrizeTemplate> createPrizeTemplate(@RequestBody Map<String, Object> body) {
|
||||
String templateName = body.get("templateName") != null ? body.get("templateName").toString() : null;
|
||||
@@ -933,7 +978,6 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 修改奖项模板
|
||||
*/
|
||||
@ApiOperation("修改奖项模板")
|
||||
@PutMapping("/prizeTemplate")
|
||||
public R<String> updatePrizeTemplate(@RequestBody Map<String, Object> body) {
|
||||
Integer id = body.get("id") != null ? ((Number) body.get("id")).intValue() : null;
|
||||
@@ -941,6 +985,9 @@ public class PromoRollController extends BaseController {
|
||||
|
||||
TtRollPrizeTemplate existing = promoRollPrizeTemplateMapper.selectById(id);
|
||||
if (existing == null) return R.fail("模板不存在");
|
||||
// 归属校验:只有创建者本人或推广超管能改别人的奖项模板
|
||||
R<String> ownerCheck = checkTemplateOwner(existing);
|
||||
if (ownerCheck != null) return ownerCheck;
|
||||
|
||||
// 校验模板总价值不低于200金币
|
||||
BigDecimal total = calcTemplateTotal(body);
|
||||
@@ -967,9 +1014,13 @@ public class PromoRollController extends BaseController {
|
||||
/**
|
||||
* 删除奖项模板
|
||||
*/
|
||||
@ApiOperation("删除奖项模板")
|
||||
@DeleteMapping("/prizeTemplate/{templateId}")
|
||||
public R<String> deletePrizeTemplate(@PathVariable("templateId") Integer templateId) {
|
||||
TtRollPrizeTemplate existing = promoRollPrizeTemplateMapper.selectById(templateId);
|
||||
if (existing == null) return R.fail("模板不存在");
|
||||
// 归属校验:只有创建者本人或推广超管能删别人的奖项模板
|
||||
R<String> ownerCheck = checkTemplateOwner(existing);
|
||||
if (ownerCheck != null) return ownerCheck;
|
||||
promoRollPrizeTemplateMapper.deleteById(templateId);
|
||||
new LambdaUpdateChainWrapper<>(promoRollPrizeTemplateDetailMapper)
|
||||
.eq(TtRollPrizeTemplateDetail::getTemplateId, templateId)
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
package com.ruoyi.promo.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||
import com.ruoyi.admin.mapper.PromoAdminMapper;
|
||||
import com.ruoyi.admin.service.TtUserService;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.domain.common.constant.UserType;
|
||||
import com.ruoyi.domain.entity.sys.TtUser;
|
||||
import com.ruoyi.promo.model.PromoPhoneRequest;
|
||||
import com.ruoyi.promo.service.PromoAccountService;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
import com.ruoyi.thirdparty.common.model.ApiSmsBody;
|
||||
import com.ruoyi.thirdparty.common.service.ApiSmsService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -22,39 +17,72 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 推广后台短信验证码控制器
|
||||
* POST /promo/sms/getVerifyCode - 获取短信验证码(需要滑块验证)
|
||||
* POST /promo/sms/precheck - 点「获取验证码」时的账号前置校验(不弹滑块)
|
||||
* POST /promo/sms/getVerifyCode - 获取短信验证码(需要滑块验证,此处再兜底校验一次账号)
|
||||
*/
|
||||
@Api(tags = "推广后台短信")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/promo/sms")
|
||||
public class PromoSmsController extends BaseController {
|
||||
|
||||
/** 前置校验节流:同一手机号 10 分钟最多 10 次,避免被拿来批量探测哪些手机号有推广后台账号 */
|
||||
private static final int PRECHECK_MAX_COUNT = 10;
|
||||
private static final int PRECHECK_MINUTES = 10;
|
||||
|
||||
private final ISysConfigService sysConfigService;
|
||||
private final ApiSmsService apiSmsService;
|
||||
private final PromoAdminMapper promoAdminMapper;
|
||||
private final PromoAccountService promoAccountService;
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
@Autowired
|
||||
private TtUserService userService;
|
||||
|
||||
public PromoSmsController(ISysConfigService sysConfigService,
|
||||
ApiSmsService apiSmsService,
|
||||
PromoAdminMapper promoAdminMapper) {
|
||||
PromoAccountService promoAccountService) {
|
||||
this.sysConfigService = sysConfigService;
|
||||
this.apiSmsService = apiSmsService;
|
||||
this.promoAdminMapper = promoAdminMapper;
|
||||
this.promoAccountService = promoAccountService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取验证码前的账号校验:没权限的号直接在这儿被拦住,不用先拖一次滑块再被拒
|
||||
*/
|
||||
@Anonymous
|
||||
@PostMapping("/precheck")
|
||||
public R<Object> precheck(@RequestBody PromoPhoneRequest request) {
|
||||
String websiteMaintenance = sysConfigService.selectConfigByKey("websiteMaintenance");
|
||||
if ("1".equals(websiteMaintenance)) {
|
||||
return R.fail("网站维护中......");
|
||||
}
|
||||
|
||||
String phoneNumber = request.getPhoneNumber();
|
||||
if (StringUtils.isEmpty(phoneNumber)) {
|
||||
return R.fail("手机号不能为空");
|
||||
}
|
||||
String throttleKey = "promo:sms:precheck:" + phoneNumber;
|
||||
Long count = redisCache.redisTemplate.opsForValue().increment(throttleKey);
|
||||
if (count != null && count == 1L) {
|
||||
redisCache.expire(throttleKey, PRECHECK_MINUTES, TimeUnit.MINUTES);
|
||||
}
|
||||
if (count != null && count > PRECHECK_MAX_COUNT) {
|
||||
return R.fail("操作过于频繁,请" + PRECHECK_MINUTES + "分钟后再试");
|
||||
}
|
||||
|
||||
String denyReason = promoAccountService.checkLoginPermission(phoneNumber, request.getParentInvitationCode());
|
||||
if (denyReason != null) {
|
||||
return R.fail(denyReason);
|
||||
}
|
||||
return R.ok("校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取短信验证码(推广后台版本)
|
||||
* 需要先完成/promo/captcha/check 滑块验证
|
||||
*/
|
||||
@ApiOperation("获取短信验证码")
|
||||
@Anonymous
|
||||
@PostMapping("/getVerifyCode")
|
||||
public R<Object> getVerifyCode(@RequestBody ApiSmsBody smsBody) {
|
||||
@@ -69,23 +97,10 @@ public class PromoSmsController extends BaseController {
|
||||
return R.fail("验证码类型错误");
|
||||
}
|
||||
if ("2".equals(smsBody.getType())) {
|
||||
TtUser user = new LambdaQueryChainWrapper<>(userService.getBaseMapper())
|
||||
.eq(TtUser::getPhoneNumber, phoneNumber)
|
||||
.eq(TtUser::getDelFlag, "0")
|
||||
.eq(TtUser::getStatus, "0")
|
||||
.one();
|
||||
boolean hasPromoRole = user != null
|
||||
&& (UserType.ANCHOR.getCode().equals(user.getUserType())
|
||||
|| UserType.BUSINESS_USER.getCode().equals(user.getUserType())
|
||||
|| UserType.CARD_MERCHANT.getCode().equals(user.getUserType()));
|
||||
// 超级管理员账号(promo_admin.username / phone_number)也可以是手机号,同样允许短信登录
|
||||
boolean isSuperAdmin = !hasPromoRole && promoAdminMapper.findByAccount(phoneNumber) != null;
|
||||
// 手机号没注册过:带有效招商邀请码时允许发码(登录即自动注册为主播)
|
||||
boolean canAutoRegister = !hasPromoRole && !isSuperAdmin
|
||||
&& StringUtils.isNotEmpty(smsBody.getParentInvitationCode())
|
||||
&& findBusinessByInvitationCode(smsBody.getParentInvitationCode()) != null;
|
||||
if (!hasPromoRole && !isSuperAdmin && !canAutoRegister) {
|
||||
return R.fail("该手机号无推广后台登录权限");
|
||||
// 兜底:前置校验可以被绕过(直接打接口),真正发短信前必须再验一次
|
||||
String denyReason = promoAccountService.checkLoginPermission(phoneNumber, smsBody.getParentInvitationCode());
|
||||
if (denyReason != null) {
|
||||
return R.fail(denyReason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +115,8 @@ public class PromoSmsController extends BaseController {
|
||||
if (StringUtils.isEmpty(storedCaptchaId) || !storedCaptchaId.equals(captchaId)) {
|
||||
return R.fail("滑块验证已过期或无效,请重新验证");
|
||||
}
|
||||
// 一次性消费:同一个 captchaId 在 5 分钟有效期内只能换一条短信,否则可重放刷短信
|
||||
redisCache.deleteObject(verifiedKey);
|
||||
|
||||
String msg = apiSmsService.getVerifyCode(smsBody);
|
||||
if (StringUtils.isNotEmpty(msg)) {
|
||||
@@ -113,19 +130,4 @@ public class PromoSmsController extends BaseController {
|
||||
log.info("[推广后台短信发送成功] phone={}", phoneNumber);
|
||||
return R.ok("获取验证码成功,请注意短信通知!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 按邀请码找招商账号(必须是 04 招商)
|
||||
*/
|
||||
private TtUser findBusinessByInvitationCode(String invitationCode) {
|
||||
TtUser parent = new LambdaQueryChainWrapper<>(userService.getBaseMapper())
|
||||
.eq(TtUser::getInvitationCode, invitationCode.trim().toUpperCase())
|
||||
.eq(TtUser::getDelFlag, "0")
|
||||
.eq(TtUser::getStatus, "0")
|
||||
.one();
|
||||
if (parent == null || !UserType.BUSINESS_USER.getCode().equals(parent.getUserType())) {
|
||||
return null;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ import com.ruoyi.promo.domain.param.AnchorDayTurnoverParam;
|
||||
import com.ruoyi.promo.domain.vo.AnchorDayTurnoverVO;
|
||||
import com.ruoyi.promo.mapper.PromoTurnoverMapper;
|
||||
import com.ruoyi.promo.service.PromoTurnoverService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -46,7 +44,6 @@ import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Api(tags = "推广流水")
|
||||
@RestController
|
||||
@RequestMapping("/promo/turnover")
|
||||
public class PromoTurnoverController extends BaseController {
|
||||
@@ -66,28 +63,24 @@ public class PromoTurnoverController extends BaseController {
|
||||
@Autowired
|
||||
private TtUserBlendErcashMapper ttUserBlendErcashMapper;
|
||||
|
||||
@ApiOperation("获取实时数据")
|
||||
@GetMapping("/getRealTimeData")
|
||||
public AjaxResult getRealTimeData() {
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return promoTurnoverService.getRealTimeData(userId.intValue());
|
||||
}
|
||||
|
||||
@ApiOperation("获取首页游戏返利看板数据")
|
||||
@GetMapping("/getGameCommissionData")
|
||||
public AjaxResult getGameCommissionData() {
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return promoTurnoverService.getGameCommissionData(userId.intValue());
|
||||
}
|
||||
|
||||
@ApiOperation("获取近10天推广数据")
|
||||
@GetMapping("getLast10DaysPromotionData")
|
||||
public AjaxResult getLast10DaysPromotionData() {
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return promoTurnoverService.getLast10DaysPromotionData(userId.intValue());
|
||||
}
|
||||
|
||||
@ApiOperation("获取主播推广数据")
|
||||
@GetMapping("/getAnchorPromotionData")
|
||||
public TableDataInfo getAnchorPromotionData(AnchorDayTurnoverParam param) {
|
||||
if (param.getPageNum() == null || param.getPageNum() <= 0) {
|
||||
@@ -176,7 +169,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
return pageDataInfo;
|
||||
}
|
||||
|
||||
@ApiOperation("获取下级历史数据")
|
||||
@GetMapping("/getSubBranches")
|
||||
public AjaxResult getSubBranches(GetSubBranchesRequest request) {
|
||||
Long userId = getUserId();
|
||||
@@ -185,22 +177,28 @@ public class PromoTurnoverController extends BaseController {
|
||||
return AjaxResult.success(response);
|
||||
}
|
||||
|
||||
@ApiOperation("获取日流水记录")
|
||||
@GetMapping("/getPurchaseByUserId/{userId}")
|
||||
public TableDataInfo getPurchaseByUserId(GetPurchaseByUserIdRequest request) {
|
||||
return promoTurnoverService.getPurchaseByUserId(request);
|
||||
}
|
||||
|
||||
@ApiOperation("获取佣金比例")
|
||||
@GetMapping("/getCommissionRateByUserId/{userId}")
|
||||
public AjaxResult getCommissionRateByUserId(@PathVariable("userId") Integer userId) {
|
||||
// 归属校验:只能查自己或自己直属下级的返佣比例(此前传任意 userId 都能查到别人的比例)
|
||||
Long currentUserId = getUserId();
|
||||
if (!userId.equals(currentUserId.intValue())) {
|
||||
TtUser targetUser = userMapper.selectById(userId);
|
||||
if (targetUser == null || targetUser.getParentId() == null
|
||||
|| !targetUser.getParentId().equals(currentUserId.intValue())) {
|
||||
return AjaxResult.error("无权查看该用户的佣金比例");
|
||||
}
|
||||
}
|
||||
BigDecimal commissionRate = promoTurnoverService.getCommissionRateByUserId(userId);
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("commissionRate", commissionRate);
|
||||
return AjaxResult.success(map);
|
||||
}
|
||||
|
||||
@ApiOperation("获取佣金比例")
|
||||
@PutMapping("/updateCommissionRate")
|
||||
public AjaxResult updateCommissionRate(@RequestBody TtUser ttUser) {
|
||||
Integer userId = ttUser.getUserId();
|
||||
@@ -229,7 +227,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
return row >= 1 ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
|
||||
}
|
||||
|
||||
@ApiOperation("获取佣金列表")
|
||||
@GetMapping("/getCommissionList")
|
||||
public AjaxResult getCommissionList() {
|
||||
Long userId = getUserId();
|
||||
@@ -237,7 +234,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
return AjaxResult.success(commissionList);
|
||||
}
|
||||
|
||||
@ApiOperation("我的下级列表")
|
||||
@GetMapping("/mySubordinates")
|
||||
public AjaxResult mySubordinates(@RequestParam(required = false) String account) {
|
||||
Long userId = getUserId();
|
||||
@@ -266,7 +262,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
@ApiOperation("解除下级关系")
|
||||
@PostMapping("/removeSubordinate")
|
||||
public AjaxResult removeSubordinate(@RequestParam("subUserId") Integer subUserId) {
|
||||
Long currentUserId = getUserId();
|
||||
@@ -288,7 +283,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
return success ? AjaxResult.success("解除成功") : AjaxResult.error("解除失败");
|
||||
}
|
||||
|
||||
@ApiOperation("获取已结算佣金总额")
|
||||
@GetMapping("/settledTotalCommission")
|
||||
public AjaxResult settledTotalCommission(@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate) {
|
||||
@@ -317,7 +311,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
@ApiOperation("下级流水记录")
|
||||
@GetMapping("/flowRecord")
|
||||
public AjaxResult flowRecord(@RequestParam(required = false) Integer userId,
|
||||
@RequestParam(required = false) String startDate,
|
||||
@@ -538,7 +531,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("招商每日佣金(默认本周,支持 startDate/endDate 自定义范围)")
|
||||
@GetMapping("/weeklyDailyCommission")
|
||||
public AjaxResult weeklyDailyCommission(@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate) {
|
||||
@@ -822,7 +814,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
return dateObj.toString();
|
||||
}
|
||||
|
||||
@ApiOperation("获取主播推广奖励列表")
|
||||
@GetMapping("/queryPromoteWelfare")
|
||||
public AjaxResult queryPromoteWelfare(QueryPromoteWelfareRequest request) {
|
||||
Long userId = getUserId();
|
||||
@@ -830,7 +821,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
return AjaxResult.success(response);
|
||||
}
|
||||
|
||||
@ApiOperation("佣金明细记录")
|
||||
@GetMapping("/commissionDetail")
|
||||
public AjaxResult commissionDetail(
|
||||
@RequestParam(required = false) String date,
|
||||
@@ -896,7 +886,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
@ApiOperation("佣金日报")
|
||||
@GetMapping("/commissionDaily")
|
||||
public AjaxResult commissionDaily(
|
||||
@RequestParam(required = false) String date,
|
||||
@@ -945,7 +934,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
@ApiOperation("佣金汇总")
|
||||
@GetMapping("/commissionSummary")
|
||||
public AjaxResult commissionSummary(
|
||||
@RequestParam(required = false) String startDate,
|
||||
@@ -1010,7 +998,6 @@ public class PromoTurnoverController extends BaseController {
|
||||
return userIds;
|
||||
}
|
||||
|
||||
@ApiOperation("下级充值报表")
|
||||
@GetMapping("/subordinateRecharge")
|
||||
public AjaxResult subordinateRecharge(
|
||||
@RequestParam(required = false) String month,
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.ruoyi.promo.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 手机号入参(取验证码前置校验用)
|
||||
*/
|
||||
@Data
|
||||
public class PromoPhoneRequest {
|
||||
|
||||
private String phoneNumber;
|
||||
|
||||
private String parentInvitationCode;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.ruoyi.promo.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||
import com.ruoyi.admin.mapper.PromoAdminMapper;
|
||||
import com.ruoyi.admin.service.TtUserService;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.domain.common.constant.UserType;
|
||||
import com.ruoyi.domain.entity.sys.TtUser;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 推广后台登录账号校验。
|
||||
* 点「获取验证码」时先跑一遍(不弹滑块),发短信时再跑一遍兜底,两处必须是同一份规则。
|
||||
*/
|
||||
@Service
|
||||
public class PromoAccountService {
|
||||
|
||||
private final TtUserService userService;
|
||||
private final PromoAdminMapper promoAdminMapper;
|
||||
|
||||
public PromoAccountService(TtUserService userService, PromoAdminMapper promoAdminMapper) {
|
||||
this.userService = userService;
|
||||
this.promoAdminMapper = promoAdminMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null 表示有权登录;否则是给用户看的拒绝原因
|
||||
*/
|
||||
public String checkLoginPermission(String phoneNumber, String parentInvitationCode) {
|
||||
TtUser user = new LambdaQueryChainWrapper<>(userService.getBaseMapper())
|
||||
.eq(TtUser::getPhoneNumber, phoneNumber)
|
||||
.eq(TtUser::getDelFlag, "0")
|
||||
.eq(TtUser::getStatus, "0")
|
||||
.one();
|
||||
boolean hasPromoRole = user != null
|
||||
&& (UserType.ANCHOR.getCode().equals(user.getUserType())
|
||||
|| UserType.BUSINESS_USER.getCode().equals(user.getUserType())
|
||||
|| UserType.CARD_MERCHANT.getCode().equals(user.getUserType()));
|
||||
if (hasPromoRole) {
|
||||
return null;
|
||||
}
|
||||
// 超级管理员账号(promo_admin.username / phone_number)也可以是手机号,同样允许短信登录
|
||||
if (promoAdminMapper.findByAccount(phoneNumber) != null) {
|
||||
return null;
|
||||
}
|
||||
// 手机号从未注册过 + 有效招商邀请码:允许发码,登录时自动注册为主播(01)。
|
||||
// 手机号已被占用(普通用户02 / 机器人 / 白号 / 已停用已删除的老号)时不能走自动注册:
|
||||
// 自动注册会因手机号已存在而跳过,最后只在建 token 时报「用户不存在」,得在这里拦住。
|
||||
boolean canAutoRegister = !phoneRegistered(phoneNumber)
|
||||
&& StringUtils.isNotEmpty(parentInvitationCode)
|
||||
&& findBusinessByInvitationCode(parentInvitationCode) != null;
|
||||
if (canAutoRegister) {
|
||||
return null;
|
||||
}
|
||||
// 统一提示「无权限」:能走到这里的要么是本来就没推广后台权限的号(含已注册的普通用户),
|
||||
// 要么是邀请码没填/填错。不区分「已注册」,避免把某个手机号的注册状态暴露出去。
|
||||
return "该手机号无推广后台登录权限";
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号在 tt_user 中是否已存在(含停用/软删除)。
|
||||
* 必须与 PromoLoginServiceImpl.autoRegisterAnchorIfNeeded 的存在性口径一致,
|
||||
* 否则两处判断不一致时会出现「发得出验证码但登录报用户不存在」。
|
||||
*/
|
||||
private boolean phoneRegistered(String phoneNumber) {
|
||||
return new LambdaQueryChainWrapper<>(userService.getBaseMapper())
|
||||
.eq(TtUser::getPhoneNumber, phoneNumber)
|
||||
.count() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按邀请码找招商账号(必须是 04 招商)
|
||||
*/
|
||||
private TtUser findBusinessByInvitationCode(String invitationCode) {
|
||||
TtUser parent = new LambdaQueryChainWrapper<>(userService.getBaseMapper())
|
||||
.eq(TtUser::getInvitationCode, invitationCode.trim().toUpperCase())
|
||||
.eq(TtUser::getDelFlag, "0")
|
||||
.eq(TtUser::getStatus, "0")
|
||||
.one();
|
||||
if (parent == null || !UserType.BUSINESS_USER.getCode().equals(parent.getUserType())) {
|
||||
return null;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,8 @@ import java.util.List;
|
||||
|
||||
public interface PromoLoginService {
|
||||
|
||||
String login(String username, String password);
|
||||
|
||||
/**
|
||||
* 推广后台短信验证码登录;手机号未注册时,带上级邀请码则自动注册为主播
|
||||
* 推广后台登录(仅手机号 + 4 位短信验证码);手机号未注册时,带上级邀请码则自动注册为主播
|
||||
*/
|
||||
String smsLogin(String phoneNumber, String code, String parentInvitationCode);
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.ruoyi.common.utils.uuid.UUID;
|
||||
import com.ruoyi.domain.common.constant.TtAccountRecordSource;
|
||||
import com.ruoyi.domain.common.constant.UserType;
|
||||
import com.ruoyi.domain.entity.TtRechargeProd;
|
||||
import com.ruoyi.domain.entity.sys.PromoAdmin;
|
||||
import com.ruoyi.domain.entity.sys.TtUser;
|
||||
import com.ruoyi.domain.other.TtRedPacket;
|
||||
import com.ruoyi.domain.other.TtUserAvatar;
|
||||
@@ -35,6 +34,7 @@ import com.ruoyi.framework.web.service.TokenService;
|
||||
import com.ruoyi.promo.contract.request.RegisterRequest;
|
||||
import com.ruoyi.promo.contract.request.UpdateInvitationCodeRequest;
|
||||
import com.ruoyi.promo.contract.response.GetShareDomainResponse;
|
||||
import com.ruoyi.promo.service.PromoAccountService;
|
||||
import com.ruoyi.promo.service.PromoLoginService;
|
||||
import com.ruoyi.system.domain.SysConfig;
|
||||
import com.ruoyi.system.mapper.SysConfigMapper;
|
||||
@@ -53,6 +53,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -83,6 +84,9 @@ public class PromoLoginServiceImpl implements PromoLoginService {
|
||||
@Autowired
|
||||
private ApiSmsService apiSmsService;
|
||||
|
||||
@Autowired
|
||||
private PromoAccountService promoAccountService;
|
||||
|
||||
@Autowired
|
||||
private UserIdGenerator userIdGenerator;
|
||||
|
||||
@@ -104,110 +108,76 @@ public class PromoLoginServiceImpl implements PromoLoginService {
|
||||
/** 推广码已修改标记 Redis Key 前缀 */
|
||||
private static final String INVITATION_CODE_MODIFIED_KEY = "promo:invitation_code_modified:";
|
||||
|
||||
/** 登录失败计数:账号维度 / IP 维度,窗口内失败满 10 次锁定 10 分钟 */
|
||||
private static final String LOGIN_FAIL_ACCOUNT_KEY = "promo:login_fail:account:";
|
||||
private static final String LOGIN_FAIL_IP_KEY = "promo:login_fail:ip:";
|
||||
private static final int LOGIN_FAIL_MAX = 10;
|
||||
private static final int LOGIN_FAIL_LOCK_MINUTES = 10;
|
||||
|
||||
|
||||
/**
|
||||
* 推广后台账号密码登录(短信未接入前统一走这里):
|
||||
* ① 超管 → promo_admin(username 或 phone_number)
|
||||
* ② 招商(04)/主播(01)/卡商(05) → tt_user(账号为手机号)
|
||||
*/
|
||||
@Override
|
||||
public String login(String username, String password) {
|
||||
sysLoginService.loginPreCheck(username, password);
|
||||
String account = username.trim();
|
||||
|
||||
// ① 超级管理员
|
||||
PromoAdmin promoAdmin = promoAdminMapper.findByAccount(account);
|
||||
if (promoAdmin != null) {
|
||||
if (!SecurityUtils.matchesPassword(password, promoAdmin.getPassword())) {
|
||||
throw new IllegalArgumentException("账号或密码错误");
|
||||
}
|
||||
// 走 promo_ 前缀,确保拿到的是超管身份(promo_admin 表)
|
||||
LoginUser loginUser = sysLoginService.createLoginUser("promo_" + promoAdmin.getUsername(), password);
|
||||
return tokenService.createToken(loginUser);
|
||||
}
|
||||
|
||||
// ② 招商/主播/卡商
|
||||
TtUser user = new LambdaQueryChainWrapper<>(userService.getBaseMapper())
|
||||
.and(w -> w.eq(TtUser::getPhoneNumber, account).or().eq(TtUser::getUserName, account))
|
||||
.one();
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("账号或密码错误");
|
||||
}
|
||||
if (!UserType.ANCHOR.getCode().equals(user.getUserType())
|
||||
&& !UserType.BUSINESS_USER.getCode().equals(user.getUserType())
|
||||
&& !UserType.CARD_MERCHANT.getCode().equals(user.getUserType())) {
|
||||
throw new IllegalArgumentException("该账号无推广后台登录权限");
|
||||
}
|
||||
if (!SecurityUtils.matchesPassword(password, user.getPassword())) {
|
||||
throw new IllegalArgumentException("账号或密码错误");
|
||||
}
|
||||
return createUserToken(user.getPhoneNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
* 这个框既能填 4 位短信验证码,也能直接填密码:
|
||||
* ① 非 4 位数字 → 按密码处理(超管 promo_admin / 招商·主播·卡商 tt_user)
|
||||
* ② 4 位数字 → 按短信验证码处理
|
||||
* 推广后台登录:只认「手机号 + 4 位短信验证码」。
|
||||
* 账号密码登录已下线(/promo/login 一并删除),避免用密码绕过短信校验被撞库。
|
||||
*/
|
||||
@Override
|
||||
public String smsLogin(String phoneNumber, String code, String parentInvitationCode) {
|
||||
String account = StringUtils.trim(phoneNumber);
|
||||
String value = StringUtils.trim(code);
|
||||
|
||||
PromoAdmin promoAdmin = StringUtils.isNotEmpty(account) ? promoAdminMapper.findByAccount(account) : null;
|
||||
TtUser ttUser = StringUtils.isNotEmpty(account) ? findUserByAccount(account) : null;
|
||||
boolean hasPromoRole = ttUser != null
|
||||
&& !"1".equals(ttUser.getDelFlag())
|
||||
&& !"1".equals(ttUser.getStatus())
|
||||
&& (UserType.ANCHOR.getCode().equals(ttUser.getUserType())
|
||||
|| UserType.BUSINESS_USER.getCode().equals(ttUser.getUserType())
|
||||
|| UserType.CARD_MERCHANT.getCode().equals(ttUser.getUserType()));
|
||||
if (promoAdmin == null && ttUser == null && !Validator.isMobile(account)) {
|
||||
throw new IllegalArgumentException("手机号格式错误,请检查手机号是否输入正确!");
|
||||
}
|
||||
boolean isCode = NumberUtil.isNumber(value) && value.length() == 4;
|
||||
|
||||
// ① 密码登录
|
||||
if (!isCode && StringUtils.isNotEmpty(value)) {
|
||||
if (promoAdmin != null && StringUtils.isNotEmpty(promoAdmin.getPassword())
|
||||
&& SecurityUtils.matchesPassword(value, promoAdmin.getPassword())) {
|
||||
// 走 promo_ 前缀,确保拿到的是超管身份
|
||||
LoginUser loginUser = sysLoginService.createLoginUser("promo_" + promoAdmin.getUsername(), value);
|
||||
return tokenService.createToken(loginUser);
|
||||
checkLoginNotLocked(account);
|
||||
try {
|
||||
// 非 4 位数字一律按验证码错误处理,不再兼容「填密码」
|
||||
if (!NumberUtil.isNumber(value) || value.length() != 4) {
|
||||
throw new IllegalArgumentException("验证码错误");
|
||||
}
|
||||
if (hasPromoRole && StringUtils.isNotEmpty(ttUser.getPassword())
|
||||
&& SecurityUtils.matchesPassword(value, ttUser.getPassword())) {
|
||||
return createUserToken(ttUser.getPhoneNumber());
|
||||
String validateCaptcha = apiSmsService.validateCaptcha(value, "ApiLogin_" + account);
|
||||
if (!"success".equals(validateCaptcha)) {
|
||||
throw new IllegalArgumentException(validateCaptcha);
|
||||
}
|
||||
if (promoAdmin != null || hasPromoRole) {
|
||||
throw new IllegalArgumentException("密码错误");
|
||||
// 发码时校验过一次,这里再兜一次:App 登录短信与推广后台共用同一个验证码 key
|
||||
// (ApiLogin_<手机号>),普通用户拿 App 的码来打本接口时,没有这一步就会走到
|
||||
// 建 token 才报「用户不存在」。两处必须是同一份口径。
|
||||
String denyReason = promoAccountService.checkLoginPermission(account, parentInvitationCode);
|
||||
if (denyReason != null) {
|
||||
throw new IllegalArgumentException(denyReason);
|
||||
}
|
||||
if (ttUser != null) {
|
||||
throw new IllegalArgumentException("该账号无推广后台登录权限");
|
||||
}
|
||||
throw new IllegalArgumentException("验证码错误");
|
||||
// 手机号没注册过:带上级邀请码则自动注册为主播(口径与 App 的 verificationCodeLoginOrRegister 一致)
|
||||
autoRegisterAnchorIfNeeded(account, parentInvitationCode);
|
||||
String token = createUserToken(account);
|
||||
clearLoginFail(account);
|
||||
return token;
|
||||
} catch (IllegalArgumentException e) {
|
||||
recordLoginFail(account);
|
||||
throw e;
|
||||
}
|
||||
|
||||
// ② 短信验证码
|
||||
if (!isCode) {
|
||||
throw new IllegalArgumentException("验证码错误");
|
||||
}
|
||||
String validateCaptcha = apiSmsService.validateCaptcha(value, "ApiLogin_" + account);
|
||||
if (!"success".equals(validateCaptcha)) {
|
||||
throw new IllegalArgumentException(validateCaptcha);
|
||||
}
|
||||
// 手机号没注册过:带上级邀请码则自动注册为主播(口径与 App 的 verificationCodeLoginOrRegister 一致)
|
||||
autoRegisterAnchorIfNeeded(account, parentInvitationCode);
|
||||
return createUserToken(account);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按手机号或用户名查 tt_user
|
||||
* 登录失败计数(账号 + IP 双维度):窗口内失败达到阈值直接拒绝,避免无限撞验证码/刷账号
|
||||
*/
|
||||
private TtUser findUserByAccount(String account) {
|
||||
return new LambdaQueryChainWrapper<>(userService.getBaseMapper())
|
||||
.and(w -> w.eq(TtUser::getPhoneNumber, account).or().eq(TtUser::getUserName, account))
|
||||
.one();
|
||||
private void checkLoginNotLocked(String account) {
|
||||
if (loginFailCount(LOGIN_FAIL_ACCOUNT_KEY + account) >= LOGIN_FAIL_MAX
|
||||
|| loginFailCount(LOGIN_FAIL_IP_KEY + IpUtils.getIpAddr()) >= LOGIN_FAIL_MAX) {
|
||||
throw new IllegalArgumentException("失败次数过多,请 " + LOGIN_FAIL_LOCK_MINUTES + " 分钟后再试");
|
||||
}
|
||||
}
|
||||
|
||||
private void recordLoginFail(String account) {
|
||||
bumpLoginFail(LOGIN_FAIL_ACCOUNT_KEY + account);
|
||||
bumpLoginFail(LOGIN_FAIL_IP_KEY + IpUtils.getIpAddr());
|
||||
}
|
||||
|
||||
private void bumpLoginFail(String key) {
|
||||
redisCache.setCacheObject(key, loginFailCount(key) + 1, LOGIN_FAIL_LOCK_MINUTES, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
/** 登录成功只清账号维度;IP 维度留给它自然过期,避免同一 IP 靠一次成功把失败记录洗掉 */
|
||||
private void clearLoginFail(String account) {
|
||||
redisCache.deleteObject(LOGIN_FAIL_ACCOUNT_KEY + account);
|
||||
}
|
||||
|
||||
private int loginFailCount(String key) {
|
||||
Integer count = redisCache.getCacheObject(key);
|
||||
return count == null ? 0 : count;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
-7
@@ -32,8 +32,6 @@ import com.ruoyi.game.mahjong.mapper.MahjongRoundMapper;
|
||||
import com.ruoyi.game.mahjong.repository.MahjongCycleRepository;
|
||||
import com.ruoyi.game.mahjong.repository.MahjongRewardPoolCacheRepository;
|
||||
import com.ruoyi.game.mahjong.service.MahjongDistributionService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -49,7 +47,6 @@ import java.util.stream.Collectors;
|
||||
* 与玫瑰女郎逐行同构,差异:只有 normal 一个模式、桶 16 档、封顶 500x、game_type = MAHJONG。
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "麻将胡了后台")
|
||||
@RestController
|
||||
@RequestMapping("/admin/mahjong")
|
||||
public class MahjongAdminController extends BaseController {
|
||||
@@ -71,7 +68,6 @@ public class MahjongAdminController extends BaseController {
|
||||
|
||||
// ==================== 箱子配置 ====================
|
||||
|
||||
@ApiOperation("箱子列表(含各身份目标/实时 RTP 与一轮总回合)")
|
||||
@GetMapping("/box/list")
|
||||
public R boxList(@RequestParam(defaultValue = "1") int pageNum,
|
||||
@RequestParam(defaultValue = "10") int pageSize,
|
||||
@@ -154,7 +150,6 @@ public class MahjongAdminController extends BaseController {
|
||||
}
|
||||
|
||||
/** 某箱某身份的桶分布:含 convergeCount(收敛账本) + fixedRounds/convergeRounds(按该身份分布反推) */
|
||||
@ApiOperation("某箱某身份的倍率桶分布")
|
||||
@GetMapping("/box/buckets/{boxId}")
|
||||
public R boxBuckets(@PathVariable Long boxId,
|
||||
@RequestParam(required = false, defaultValue = "common") String audience) {
|
||||
@@ -174,7 +169,6 @@ public class MahjongAdminController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "箱子配置", action = "保存", businessType = BusinessType.UPDATE)
|
||||
@ApiOperation("保存某箱某身份的倍率桶分布(items 为固定池回合,反推回写总回合)")
|
||||
@PostMapping("/box/buckets/save")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R boxBucketsSave(@RequestBody Map<String, Object> params) {
|
||||
@@ -189,7 +183,6 @@ public class MahjongAdminController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "箱子配置", action = "重算分布", businessType = BusinessType.UPDATE)
|
||||
@ApiOperation("按目标 RTP 重算某箱某身份分布")
|
||||
@PostMapping("/box/buckets/calc")
|
||||
public R calcDistribution(@RequestBody Map<String, Object> params) {
|
||||
Long boxId = asLong(params.get("boxId"));
|
||||
|
||||
-7
@@ -19,8 +19,6 @@ import com.ruoyi.game.mahjong.mapper.MahjongPrizeOrnamentMapper;
|
||||
import com.ruoyi.game.mahjong.mapper.MahjongRecordMapper;
|
||||
import com.ruoyi.game.mahjong.service.MahjongGameService;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -30,7 +28,6 @@ import java.util.stream.Collectors;
|
||||
|
||||
/** 客户端接口:Base = {host}/api/mahjong,全部 POST + JSON + token 鉴权(对齐设计方案 §7) */
|
||||
@Slf4j
|
||||
@Api(tags = "麻将胡了游戏")
|
||||
@RestController
|
||||
@RequestMapping("/api/mahjong")
|
||||
public class MahjongClientController extends BaseController {
|
||||
@@ -44,7 +41,6 @@ public class MahjongClientController extends BaseController {
|
||||
/** 进行中的局不展示:结算时 settle_source=start,播完末帧才改 finish;超过单局缓存 TTL(30分钟) 视为已结束兜底 */
|
||||
private static final long IN_PROGRESS_MS = 30 * 60 * 1000L;
|
||||
|
||||
@ApiOperation("获取箱子列表")
|
||||
@PostMapping("/boxes")
|
||||
public R boxes() {
|
||||
List<MahjongBox> list = boxMapper.selectList(new LambdaQueryWrapper<MahjongBox>()
|
||||
@@ -65,7 +61,6 @@ public class MahjongClientController extends BaseController {
|
||||
return R.ok(Map.of("list", boxes));
|
||||
}
|
||||
|
||||
@ApiOperation("执行旋转(新游戏或继续游戏)")
|
||||
@PostMapping("/dospin")
|
||||
public R dospin(@RequestBody SpinRequest req) {
|
||||
Long userId = getUserId();
|
||||
@@ -91,7 +86,6 @@ public class MahjongClientController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("查询游戏记录(分页;scope: 0全服/1我的,默认1我的;只含已播完的局)")
|
||||
@PostMapping("/records")
|
||||
public R records(@RequestBody(required = false) RecordPageRequest req) {
|
||||
Long userId = getUserId();
|
||||
@@ -169,7 +163,6 @@ public class MahjongClientController extends BaseController {
|
||||
return exterior == null || exterior.isEmpty() ? name : name + " (" + exterior + ")";
|
||||
}
|
||||
|
||||
@ApiOperation("查询是否有进行中的游戏(断线重连)")
|
||||
@PostMapping("/hasActive")
|
||||
public R hasActive() {
|
||||
Long userId = getUserId();
|
||||
|
||||
-15
@@ -15,8 +15,6 @@ import com.ruoyi.game.wheel.constants.WheelPoolType;
|
||||
import com.ruoyi.game.wheel.service.AdminWheelService;
|
||||
import com.ruoyi.game.wheel.vo.WheelBetRecordVO;
|
||||
import com.ruoyi.game.wheel.vo.WheelPoolAdjustmentVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -27,7 +25,6 @@ import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Api(tags = "疯狂转盘")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/wheel")
|
||||
@@ -57,20 +54,17 @@ public class AdminWheelController extends BaseController {
|
||||
@Autowired
|
||||
private GameWheelPoolAdjustmentMapper poolAdjustmentMapper;
|
||||
|
||||
@ApiOperation("获取疯狂转盘游戏配置")
|
||||
@GetMapping("/gameconfig")
|
||||
public AjaxResult getGameConfig() {
|
||||
return adminWheelService.getGameConfig();
|
||||
}
|
||||
|
||||
@Log(title = "游戏配置", action = "保存", businessType = BusinessType.UPDATE)
|
||||
@ApiOperation("更新疯狂转盘游戏配置")
|
||||
@PostMapping("/gameconfig")
|
||||
public AjaxResult updateGameConfig(@RequestBody String body) {
|
||||
return adminWheelService.updateGameConfig(body);
|
||||
}
|
||||
|
||||
@ApiOperation("回合记录列表")
|
||||
@GetMapping("/round/list")
|
||||
public TableDataInfo roundList(
|
||||
@RequestParam(required = false) String date,
|
||||
@@ -88,7 +82,6 @@ public class AdminWheelController extends BaseController {
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@ApiOperation("投注记录列表")
|
||||
@GetMapping("/bet/list")
|
||||
public TableDataInfo betList(
|
||||
@RequestParam(required = false) Long roundId,
|
||||
@@ -101,7 +94,6 @@ public class AdminWheelController extends BaseController {
|
||||
|
||||
// ======================== 奖励矩阵 CRUD ========================
|
||||
|
||||
@ApiOperation("奖励矩阵列表")
|
||||
@GetMapping("/matrix/list")
|
||||
public AjaxResult matrixList(
|
||||
@RequestParam(required = false) Integer betAmount,
|
||||
@@ -120,7 +112,6 @@ public class AdminWheelController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "奖励矩阵", action = "保存", businessType = BusinessType.UPDATE)
|
||||
@ApiOperation("保存奖励矩阵行")
|
||||
@PostMapping("/matrix/save")
|
||||
public AjaxResult matrixSave(@RequestBody GameWheelRewardMatrix matrix) {
|
||||
GameWheelRewardMatrix exist = matrix.getId() == null ? null : rewardMatrixMapper.selectById(matrix.getId());
|
||||
@@ -145,7 +136,6 @@ public class AdminWheelController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "奖励矩阵", action = "删除", businessType = BusinessType.DELETE)
|
||||
@ApiOperation("删除奖励矩阵行(软删:置 status=0)")
|
||||
@DeleteMapping("/matrix/delete/{id}")
|
||||
public AjaxResult matrixDelete(@PathVariable Long id) {
|
||||
rewardMatrixMapper.update(null, new LambdaUpdateWrapper<GameWheelRewardMatrix>()
|
||||
@@ -156,7 +146,6 @@ public class AdminWheelController extends BaseController {
|
||||
|
||||
// ======================== 奖池统计 ========================
|
||||
|
||||
@ApiOperation("奖池统计")
|
||||
@GetMapping("/pool/stats")
|
||||
public AjaxResult poolStats() {
|
||||
return AjaxResult.success(adminWheelService.buildPoolStats());
|
||||
@@ -165,7 +154,6 @@ public class AdminWheelController extends BaseController {
|
||||
// ======================== 奖池调节 ========================
|
||||
|
||||
@Log(title = "游戏配置", action = "调整奖池", businessType = BusinessType.GRANT)
|
||||
@ApiOperation("奖池调整(注水/抽水)")
|
||||
@PostMapping("/pool/adjust")
|
||||
@RepeatSubmit(interval = 3000)
|
||||
public AjaxResult adjustPool(@RequestBody Map<String, Object> params) {
|
||||
@@ -173,7 +161,6 @@ public class AdminWheelController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "游戏配置", action = "重置奖池", businessType = BusinessType.CLEAN)
|
||||
@ApiOperation("重置奖池(累计统计与余额一起归零)")
|
||||
@PostMapping("/pool/reset")
|
||||
public AjaxResult resetPool(@RequestBody(required = false) Map<String, Object> params) {
|
||||
Map<String, Object> p = params == null ? Collections.emptyMap() : params;
|
||||
@@ -182,7 +169,6 @@ public class AdminWheelController extends BaseController {
|
||||
return adminWheelService.resetPool(poolType, reason, getUsername());
|
||||
}
|
||||
|
||||
@ApiOperation("奖池调整记录")
|
||||
@GetMapping("/pool/adjustLog")
|
||||
public TableDataInfo adjustLog(@RequestParam(required = false) String poolType) {
|
||||
startPage();
|
||||
@@ -211,7 +197,6 @@ public class AdminWheelController extends BaseController {
|
||||
return target;
|
||||
}
|
||||
|
||||
@ApiOperation("获取奖池余额(含人工调整)")
|
||||
@GetMapping("/pool/balance")
|
||||
public AjaxResult getPoolBalance(@RequestParam(required = false) String poolType) {
|
||||
if (StringUtils.isEmpty(poolType)) {
|
||||
|
||||
-8
@@ -18,8 +18,6 @@ import com.ruoyi.game.wheel.contract.api.response.GetRoundResultsResponse;
|
||||
import com.ruoyi.game.wheel.service.ApiWheelService;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
import com.ruoyi.user.service.ApiUserService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -29,7 +27,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import java.util.Map;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Api(tags = "疯狂转盘")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/wheel")
|
||||
@@ -55,7 +52,6 @@ public class ApiWheelController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("投注")
|
||||
@PostMapping("/dobet")
|
||||
// 这里**不加** @RepeatSubmit:一局允许同一组合重复下注(最多 50 注),连点两次 5 元 = 两注,
|
||||
// 是正常玩法而不是重复提交;加了会把第二次合法下注挡成"不允许重复提交"。
|
||||
@@ -82,7 +78,6 @@ public class ApiWheelController extends BaseController {
|
||||
return apiWheelService.doBet(request, userId);
|
||||
}
|
||||
|
||||
@ApiOperation("获取最新一期游戏状态")
|
||||
@PostMapping("/last_round_info")
|
||||
public R<GetRoundInfoResponse> getLastRoundInfo(@RequestBody GetLastRoundInfoRequest request) {
|
||||
R loginCheck = checkLogin();
|
||||
@@ -91,7 +86,6 @@ public class ApiWheelController extends BaseController {
|
||||
return apiWheelService.getLastRoundInfo(userId);
|
||||
}
|
||||
|
||||
@ApiOperation("获取玩家的游戏历史记录")
|
||||
@PostMapping("/history_bet_info")
|
||||
public R<GetRoundHistoryResponse> getHistoryBetInfo(@RequestBody GetHistoryBetRequest request) {
|
||||
R loginCheck = checkLogin();
|
||||
@@ -100,7 +94,6 @@ public class ApiWheelController extends BaseController {
|
||||
return apiWheelService.getHistoryBetInfo(request, userId);
|
||||
}
|
||||
|
||||
@ApiOperation("获取疯狂转盘游戏历史记录")
|
||||
@PostMapping("/round_history_bet_info")
|
||||
public R<GetRoundHistoryResponse> getRoundHistoryBetInfo(@RequestBody GetRoundHistoryRequest request) {
|
||||
R loginCheck = checkLogin();
|
||||
@@ -109,7 +102,6 @@ public class ApiWheelController extends BaseController {
|
||||
return apiWheelService.getRoundHistoryInfo(request);
|
||||
}
|
||||
|
||||
@ApiOperation("获取历史开奖结果(每一轮的开奖符号)")
|
||||
@PostMapping("/round_results")
|
||||
public R<GetRoundResultsResponse> getRoundResults(@RequestBody GetRoundResultsRequest request) {
|
||||
R loginCheck = checkLogin();
|
||||
|
||||
@@ -41,19 +41,6 @@
|
||||
<version>${ruoyi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Swagger3依赖 -->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-boot-starter</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
<!-- <exclusions>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>io.swagger</groupId>-->
|
||||
<!-- <artifactId>swagger-models</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- </exclusions>-->
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
-7
@@ -5,15 +5,12 @@ import com.ruoyi.reward.contract.admin.request.AdjustRewardPoolRequest;
|
||||
import com.ruoyi.reward.contract.admin.response.QueryGlobalRewardConfig;
|
||||
import com.ruoyi.reward.model.GloalRewardConfig;
|
||||
import com.ruoyi.reward.service.GlobalRewardPoolService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Api(tags = "全局奖池配置")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/globalrewardpool")
|
||||
@@ -21,7 +18,6 @@ public class AdminGlobalRewardPoolController {
|
||||
@Autowired
|
||||
private GlobalRewardPoolService globalRewardPoolService;
|
||||
|
||||
@ApiOperation("获取奖池配置和状态")
|
||||
@GetMapping("/config")
|
||||
public R<QueryGlobalRewardConfig> getGameConfig() {
|
||||
var config = globalRewardPoolService.getGameConfig();
|
||||
@@ -37,7 +33,6 @@ public class AdminGlobalRewardPoolController {
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
@ApiOperation("更新奖池配置")
|
||||
@PostMapping("/config")
|
||||
public R<Void> updateGameConfig(@RequestBody GloalRewardConfig params) {
|
||||
String msg = globalRewardPoolService.updateGameConfig(params);
|
||||
@@ -46,14 +41,12 @@ public class AdminGlobalRewardPoolController {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@ApiOperation("重置奖池缓存")
|
||||
@PostMapping("/reset")
|
||||
public R<?> resetRewardPool() {
|
||||
globalRewardPoolService.resetCache();
|
||||
return R.ok(null, "奖池缓存已清空");
|
||||
}
|
||||
|
||||
@ApiOperation("调整奖池(抽水/放水)")
|
||||
@PostMapping("/adjust")
|
||||
public R<?> adjustRewardPool(@RequestBody AdjustRewardPoolRequest req) {
|
||||
if (req.getAmount() == null || req.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
|
||||
|
||||
-4
@@ -14,7 +14,6 @@ import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.uuid.IdUtils;
|
||||
import com.ruoyi.domain.entity.TtBlankCardKey;
|
||||
import com.ruoyi.domain.entity.TtRechargeProd;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -40,7 +39,6 @@ public class AdminBlankCardKeyController extends BaseController {
|
||||
/**
|
||||
* 获取充值产品列表(金额选项)
|
||||
*/
|
||||
@ApiOperation("获取充值产品列表")
|
||||
@GetMapping("/rechargeList")
|
||||
public R<List<TtRechargeProd>> getRechargeList() {
|
||||
List<TtRechargeProd> list = rechargeProdMapper.selectList(
|
||||
@@ -52,7 +50,6 @@ public class AdminBlankCardKeyController extends BaseController {
|
||||
/**
|
||||
* 生成空白卡密(管理后台,不扣余额)
|
||||
*/
|
||||
@ApiOperation("生成空白卡密")
|
||||
@PostMapping("/generate")
|
||||
public R<List<String>> generate(@RequestBody java.util.Map<String, Object> request) {
|
||||
Integer rechargeListId = (Integer) request.get("rechargeListId");
|
||||
@@ -99,7 +96,6 @@ public class AdminBlankCardKeyController extends BaseController {
|
||||
/**
|
||||
* 获取空白卡密列表
|
||||
*/
|
||||
@ApiOperation("获取空白卡密列表")
|
||||
@GetMapping("/list")
|
||||
public R<List<TtBlankCardKey>> list(
|
||||
@RequestParam(required = false) String usedByName,
|
||||
|
||||
-7
@@ -9,8 +9,6 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.domain.entity.TtLossRebate;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -22,7 +20,6 @@ import java.util.List;
|
||||
* 数据由定时任务 lossRebateService.generateHalfMonthLossRebate() 每半月写入,
|
||||
* 本页只做「查看 + 对超过单期上限的用户人工发放CDK」。
|
||||
*/
|
||||
@Api(tags = "管理端 亏损返水")
|
||||
@RestController
|
||||
@RequestMapping("/admin/lossRebate")
|
||||
public class LossRebateController extends BaseController {
|
||||
@@ -33,7 +30,6 @@ public class LossRebateController extends BaseController {
|
||||
this.lossRebateService = lossRebateService;
|
||||
}
|
||||
|
||||
@ApiOperation("亏损返水结算明细列表")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TtLossRebate> list(@RequestParam(required = false) String period,
|
||||
@RequestParam(required = false) Integer userId,
|
||||
@@ -45,21 +41,18 @@ public class LossRebateController extends BaseController {
|
||||
|
||||
@Log(title = "亏损返水", action = "发放CDK", businessType = BusinessType.GRANT,
|
||||
entityClass = TtLossRebate.class, mapperClass = TtLossRebateMapper.class, idField = "id")
|
||||
@ApiOperation("人工发放CDK(超过单期上限/自动发放失败的记录)")
|
||||
@PostMapping("/grant")
|
||||
public R<String> grant(@RequestBody GrantRequest request) {
|
||||
if (request == null || request.getId() == null) return R.fail("缺少明细ID");
|
||||
return lossRebateService.grantManually(request.getId(), request.getAmount(), getUsername());
|
||||
}
|
||||
|
||||
@ApiOperation("读取单期返水上限")
|
||||
@GetMapping("/config")
|
||||
public AjaxResult getConfig() {
|
||||
return AjaxResult.success(lossRebateService.getMaxAmount());
|
||||
}
|
||||
|
||||
@Log(title = "亏损返水", action = "保存上限", businessType = BusinessType.UPDATE)
|
||||
@ApiOperation("保存单期返水上限(返水超过该金额不自动发放,转人工;0=不设上限)")
|
||||
@PostMapping("/config")
|
||||
public AjaxResult saveConfig(@RequestParam(required = false) BigDecimal maxAmount) {
|
||||
lossRebateService.saveMaxAmount(maxAmount);
|
||||
|
||||
-6
@@ -12,15 +12,12 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Api(tags = "管理端 商城管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/shopping")
|
||||
public class ShoppingController extends BaseController {
|
||||
@@ -34,7 +31,6 @@ public class ShoppingController extends BaseController {
|
||||
this.ornamentsService = ornamentsService;
|
||||
}
|
||||
|
||||
@ApiOperation("商品列表")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<ShoppingDataVO> list(ShoppingBody shoppingBody) {
|
||||
startPage();
|
||||
@@ -65,7 +61,6 @@ public class ShoppingController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "商城列表", action = "一键上架", businessType = BusinessType.UPDATE)
|
||||
@ApiOperation("一键上架所有商品")
|
||||
@PostMapping("/putAwayAll")
|
||||
public R<Boolean> putAwayAll() {
|
||||
LambdaUpdateWrapper<TtOrnament> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
@@ -82,7 +77,6 @@ public class ShoppingController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "商城列表", action = "一键下架", businessType = BusinessType.UPDATE)
|
||||
@ApiOperation("一键下架所有商品")
|
||||
@PostMapping("/soldOutAll")
|
||||
public R<Boolean> soldOutAll() {
|
||||
LambdaUpdateWrapper<TtOrnament> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
|
||||
-12
@@ -20,8 +20,6 @@ import com.ruoyi.domain.other.TtBoxBody;
|
||||
import com.ruoyi.domain.vo.BoxPoolStatisticsVO;
|
||||
import com.ruoyi.domain.vo.TtBoxDataVO;
|
||||
import com.ruoyi.domain.vo.box.TtBoxUserVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
@@ -38,7 +36,6 @@ import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 宝箱管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/box")
|
||||
public class TtBoxController extends BaseController {
|
||||
@@ -57,7 +54,6 @@ public class TtBoxController extends BaseController {
|
||||
return success();
|
||||
}
|
||||
|
||||
@ApiOperation("获取宝箱列表")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TtBoxDataVO> list(TtBoxBody ttBoxBody) {
|
||||
startPage();
|
||||
@@ -80,14 +76,12 @@ public class TtBoxController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "宝箱列表", action = "修改", businessType = BusinessType.UPDATE)
|
||||
@ApiOperation("修改宝箱")
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody TtBoxDataVO ttBoxDataVO) {
|
||||
String msg = boxService.updateTtBoxById(ttBoxDataVO);
|
||||
return StringUtils.isEmpty(msg) ? AjaxResult.success() : AjaxResult.error(msg);
|
||||
}
|
||||
|
||||
@ApiOperation("清空当前奖池")
|
||||
@GetMapping("clearPrizePool/{boxId}")
|
||||
public R clearPrizePool(@PathVariable("boxId") Integer boxId) {
|
||||
|
||||
@@ -110,27 +104,23 @@ public class TtBoxController extends BaseController {
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@ApiOperation("宝箱统计(按奖池/开箱人类型拆分)")
|
||||
@GetMapping("/statisticsBoxData/{boxId}")
|
||||
public R<List<BoxPoolStatisticsVO>> statisticsBoxData(@PathVariable Integer boxId, @RequestParam(required = false) Date date) {
|
||||
List<BoxPoolStatisticsVO> poolStatistics = boxService.statisticsBoxData(boxId, date);
|
||||
return R.ok(poolStatistics);
|
||||
}
|
||||
|
||||
@ApiOperation("添加宝箱三级爆率玩家范围")
|
||||
@PostMapping("/createTtBoxThirdExplosiveUsers")
|
||||
public AjaxResult createTtBoxThirdExplosiveUsers(@RequestBody TtBoxUserVO ttBoxUserVO) {
|
||||
String msg = boxService.createTtBoxThirdExplosiveUsers(ttBoxUserVO);
|
||||
return StringUtils.isEmpty(msg) ? AjaxResult.success() : AjaxResult.error(msg);
|
||||
}
|
||||
|
||||
@ApiOperation("查询宝箱三级爆率玩家范围")
|
||||
@GetMapping("/queryTtBoxThirdExplosiveUsers/{boxId}")
|
||||
public AjaxResult queryBoxUsers(@PathVariable Integer boxId) {
|
||||
return boxService.queryTtBoxThirdExplosiveUsers(boxId);
|
||||
}
|
||||
|
||||
@ApiOperation("删除宝箱三级爆率玩家范围")
|
||||
@PostMapping("/deleteTtBoxThirdExplosiveUsers")
|
||||
public AjaxResult deleteTtBoxThirdExplosiveUsers(@RequestBody TtBoxUserVO ttBoxUserVO) {
|
||||
return boxService.deleteTtBoxThirdExplosiveUsers(ttBoxUserVO);
|
||||
@@ -143,13 +133,11 @@ public class TtBoxController extends BaseController {
|
||||
util.exportExcel(response, list.getRows(), "宝箱列表");
|
||||
}
|
||||
|
||||
@ApiOperation("查询开箱临时爆率队列")
|
||||
@GetMapping("/mockresult/list")
|
||||
public R<List<BoxMockCache.MockItem>> getBoxMockResult(@RequestParam("uid") Integer uid) {
|
||||
return R.ok(boxMockService.getMockResultList(uid));
|
||||
}
|
||||
|
||||
@ApiOperation("设置开箱临时爆率队列")
|
||||
@PostMapping("/mockresult/list")
|
||||
public R<List<BoxMockCache.MockItem>> updateBoxMockResult(@RequestBody BoxMockRequest request) {
|
||||
return R.ok(boxMockService.updateMockResultList(request));
|
||||
|
||||
-6
@@ -12,8 +12,6 @@ import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@@ -26,7 +24,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Api(tags = "管理端 宝箱物品")
|
||||
@RestController
|
||||
@RequestMapping("/admin/boxOrnaments")
|
||||
public class TtBoxOrnamentsController extends BaseController {
|
||||
@@ -37,7 +34,6 @@ public class TtBoxOrnamentsController extends BaseController {
|
||||
this.boxOrnamentsService = boxOrnamentsService;
|
||||
}
|
||||
|
||||
@ApiOperation("宝箱物品详情")
|
||||
@GetMapping("/list/{boxId}")
|
||||
public PageDataInfo<TtBoxOrnamentsDataVO> list(@PathVariable("boxId") Integer boxId) {
|
||||
// 在分页之前算总数(避免PageHelper干扰百分比计算)
|
||||
@@ -48,7 +44,6 @@ public class TtBoxOrnamentsController extends BaseController {
|
||||
return getPageData(list);
|
||||
}
|
||||
|
||||
@ApiOperation("宝箱统计数据")
|
||||
@GetMapping("/globalData/{boxId}")
|
||||
public R globalData(@PathVariable("boxId") Integer boxId) {
|
||||
return boxOrnamentsService.globalData(boxId);
|
||||
@@ -123,7 +118,6 @@ public class TtBoxOrnamentsController extends BaseController {
|
||||
}
|
||||
@Log(title = "宝箱列表", action = "批量填货", businessType = BusinessType.INSERT)
|
||||
// 宝箱填货
|
||||
@ApiOperation("宝箱填货")
|
||||
@PostMapping("/batchAdd")
|
||||
public AjaxResult batchAdd(@RequestBody batchAddParam param) {
|
||||
return boxOrnamentsService.batchAdd(param);
|
||||
|
||||
-5
@@ -20,7 +20,6 @@ import com.ruoyi.domain.common.constant.UserType;
|
||||
import com.ruoyi.domain.entity.TtUserBlendErcash;
|
||||
import com.ruoyi.domain.entity.sys.TtUser;
|
||||
import com.ruoyi.domain.vo.user.TtUserVo;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -48,7 +47,6 @@ public class TtCardMerchantController extends BaseController {
|
||||
@Autowired
|
||||
private RedisLock redisLock;
|
||||
|
||||
@ApiOperation("获取卡商列表")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TtUserVo> cardMerchantList(
|
||||
@RequestParam(required = false) Integer userId,
|
||||
@@ -86,7 +84,6 @@ public class TtCardMerchantController extends BaseController {
|
||||
|
||||
@Log(title = "卡商充值", action = "确认充值", businessType = BusinessType.GRANT,
|
||||
entityClass = TtUser.class, mapperClass = TtUserMapper.class, idField = "userId")
|
||||
@ApiOperation("卡商充值(管理员给卡商增加余额)")
|
||||
@PostMapping("/recharge")
|
||||
public AjaxResult cardMerchantRecharge(@RequestBody Map<String, Object> params) {
|
||||
Integer userId = (Integer) params.get("userId");
|
||||
@@ -154,7 +151,6 @@ public class TtCardMerchantController extends BaseController {
|
||||
|
||||
@Log(title = "卡商充值", action = "确认修改", businessType = BusinessType.UPDATE,
|
||||
entityClass = TtUser.class, mapperClass = TtUserMapper.class, idField = "userId")
|
||||
@ApiOperation("修改卡商余额(直接设为指定值,按差额写审计流水)")
|
||||
@PostMapping("/updateBalance")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AjaxResult cardMerchantUpdateBalance(@RequestBody Map<String, Object> params) {
|
||||
@@ -234,7 +230,6 @@ public class TtCardMerchantController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("卡商充值记录")
|
||||
@GetMapping("/rechargeLog")
|
||||
public PageDataInfo<TtUserBlendErcash> cardMerchantRechargeLog(@RequestParam(required = false) Integer userId) {
|
||||
LambdaQueryChainWrapper<TtUserBlendErcash> wrapper = new LambdaQueryChainWrapper<>(blendErcashMapper);
|
||||
|
||||
-7
@@ -11,13 +11,10 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 发货管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/deliverGoods")
|
||||
public class TtDeliveryRecordController extends BaseController {
|
||||
@@ -28,7 +25,6 @@ public class TtDeliveryRecordController extends BaseController {
|
||||
this.deliveryRecordService = deliveryRecordService;
|
||||
}
|
||||
|
||||
@ApiOperation("发货申请列表")
|
||||
@GetMapping("/getDeliveryApplyList")
|
||||
public PageDataInfo<DeliveryApplyVO> getDeliveryApplyList(TtDeliveryApplyBody deliveryApplyBody) {
|
||||
startPage();
|
||||
@@ -36,7 +32,6 @@ public class TtDeliveryRecordController extends BaseController {
|
||||
return getPageData(list);
|
||||
}
|
||||
|
||||
@ApiOperation("退回发货申请")
|
||||
@PostMapping("/deliveryFail")
|
||||
public R<Boolean> deliveryFail(@RequestParam("deliveryRecordId") Integer deliveryRecordId, @RequestParam("message") String message) {
|
||||
String msg = deliveryRecordService.deliveryFail(deliveryRecordId, message);
|
||||
@@ -44,14 +39,12 @@ public class TtDeliveryRecordController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "发货记录", action = "确认发货", businessType = BusinessType.GRANT)
|
||||
@ApiOperation("审核通过发货申请")
|
||||
@PostMapping("/deliveryApprove")
|
||||
public R<Boolean> deliveryApprove(@RequestParam("deliveryRecordId") Integer deliveryRecordId) {
|
||||
String msg = deliveryRecordService.deliveryApprove(deliveryRecordId);
|
||||
return StringUtils.isEmpty(msg) ? R.ok(true, "操作成功!") : R.fail(false, msg);
|
||||
}
|
||||
|
||||
@ApiOperation("发货记录申请")
|
||||
@GetMapping("/getDeliveryRecordList")
|
||||
public PageDataInfo<TtDeliveryRecordDataVO> getDeliveryRecordList(TtDeliveryRecordBody deliveryRecordBody) {
|
||||
startPage();
|
||||
|
||||
-9
@@ -13,13 +13,10 @@ import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.domain.entity.roll.TtOfficialRollConfig;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 官方周期Roll配置")
|
||||
@RestController
|
||||
@RequestMapping("/admin/officialRollConfig")
|
||||
public class TtOfficialRollConfigController extends BaseController {
|
||||
@@ -30,7 +27,6 @@ public class TtOfficialRollConfigController extends BaseController {
|
||||
this.configService = configService;
|
||||
}
|
||||
|
||||
@ApiOperation("配置列表")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TtOfficialRollConfig> list(
|
||||
@RequestParam(value = "configName", required = false) String configName,
|
||||
@@ -46,7 +42,6 @@ public class TtOfficialRollConfigController extends BaseController {
|
||||
return getPageData(configList);
|
||||
}
|
||||
|
||||
@ApiOperation("配置详情")
|
||||
@GetMapping("/{id}")
|
||||
public R<TtOfficialRollConfig> getInfo(@PathVariable("id") Integer id) {
|
||||
return R.ok(configService.getById(id));
|
||||
@@ -54,7 +49,6 @@ public class TtOfficialRollConfigController extends BaseController {
|
||||
|
||||
@Log(title = "官方周期Roll配置", action = "新增", businessType = BusinessType.INSERT,
|
||||
entityClass = TtOfficialRollConfig.class, mapperClass = TtOfficialRollConfigMapper.class)
|
||||
@ApiOperation("新增配置")
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody TtOfficialRollConfig config) {
|
||||
config.setCreateBy(getUsername());
|
||||
@@ -64,7 +58,6 @@ public class TtOfficialRollConfigController extends BaseController {
|
||||
|
||||
@Log(title = "官方周期Roll配置", action = "修改", businessType = BusinessType.UPDATE,
|
||||
entityClass = TtOfficialRollConfig.class, mapperClass = TtOfficialRollConfigMapper.class)
|
||||
@ApiOperation("编辑配置")
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody TtOfficialRollConfig config) {
|
||||
config.setUpdateBy(getUsername());
|
||||
@@ -73,13 +66,11 @@ public class TtOfficialRollConfigController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "官方周期Roll配置", action = "删除", businessType = BusinessType.DELETE)
|
||||
@ApiOperation("删除配置")
|
||||
@DeleteMapping("/{id}")
|
||||
public AjaxResult remove(@PathVariable("id") Integer id) {
|
||||
return configService.removeById(id) ? AjaxResult.success() : AjaxResult.error("删除失败");
|
||||
}
|
||||
|
||||
@ApiOperation("启用/停用配置")
|
||||
@PutMapping("/changeStatus")
|
||||
public AjaxResult changeStatus(@RequestBody TtOfficialRollConfig config) {
|
||||
if (config.getId() == null) return AjaxResult.error("配置ID不能为空");
|
||||
|
||||
-4
@@ -6,14 +6,11 @@ import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.domain.dto.sys.OrderQueryCondition;
|
||||
import com.ruoyi.domain.entity.TtOrder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 订单管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/order")
|
||||
public class TtOrderController extends BaseController {
|
||||
@@ -24,7 +21,6 @@ public class TtOrderController extends BaseController {
|
||||
this.ttOrderService = ttOrderService;
|
||||
}
|
||||
|
||||
@ApiOperation("网站支付订单查询")
|
||||
@PostMapping("/list")
|
||||
public R list(@RequestBody @Validated OrderQueryCondition condition) {
|
||||
return ttOrderService.adminList(condition);
|
||||
|
||||
-8
@@ -15,8 +15,6 @@ import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.domain.other.TtOrnamentsPrice;
|
||||
import com.ruoyi.domain.vo.TtOrnamentVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -24,7 +22,6 @@ import org.springframework.web.bind.annotation.*;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 饰品管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/ornaments")
|
||||
public class TtOrnamentsController extends BaseController {
|
||||
@@ -36,7 +33,6 @@ public class TtOrnamentsController extends BaseController {
|
||||
private TtOrnamentService ttOrnamentService;
|
||||
|
||||
// 饰品列表多条件筛选
|
||||
@ApiOperation("饰品列表多条件筛选")
|
||||
@GetMapping("/list")
|
||||
public R list(TtOrnamentsBody param) {
|
||||
Page<TtOrnamentVO> ttOrnamentVOPage = ttOrnamentService.listByParam(param);
|
||||
@@ -59,7 +55,6 @@ public class TtOrnamentsController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "饰品列表", action = "发放饰品", businessType = BusinessType.GRANT)
|
||||
@ApiOperation("饰品发放")
|
||||
@PostMapping("/grantOrnaments/{userId}/{ornamentsId}/{num}")
|
||||
public AjaxResult grantOrnaments(@PathVariable("userId") Integer userId,
|
||||
@PathVariable("ornamentsId") Long ornamentsId,
|
||||
@@ -75,7 +70,6 @@ public class TtOrnamentsController extends BaseController {
|
||||
|
||||
@Log(title = "饰品列表", action = "新增饰品", businessType = BusinessType.INSERT,
|
||||
entityClass = TtOrnament.class, mapperClass = TtOrnamentMapper.class)
|
||||
@ApiOperation("新增饰品")
|
||||
@PostMapping("/addTtOrnament")
|
||||
public AjaxResult add(@RequestBody TtOrnament ttOrnament) {
|
||||
if (ttOrnament.getId() == null) {
|
||||
@@ -86,14 +80,12 @@ public class TtOrnamentsController extends BaseController {
|
||||
|
||||
@Log(title = "饰品列表", action = "编辑", businessType = BusinessType.UPDATE,
|
||||
entityClass = TtOrnament.class, mapperClass = TtOrnamentMapper.class)
|
||||
@ApiOperation("修改饰品")
|
||||
@PostMapping("/editTtOrnament")
|
||||
public AjaxResult edit(@RequestBody TtOrnament ttOrnament) {
|
||||
return toAjax(ornamentsService.updateById(ttOrnament));
|
||||
}
|
||||
|
||||
@Log(title = "饰品列表", action = "删除", businessType = BusinessType.DELETE)
|
||||
@ApiOperation("删除饰品(支持批量)")
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult delete(@PathVariable("ids") List<Long> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
|
||||
-4
@@ -10,13 +10,10 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 饰品等级信息")
|
||||
@RestController
|
||||
@RequestMapping("/admin/ornamentsLevel")
|
||||
public class TtOrnamentsLevelController extends BaseController {
|
||||
@@ -27,7 +24,6 @@ public class TtOrnamentsLevelController extends BaseController {
|
||||
this.ornamentsLevelService = ornamentsLevelService;
|
||||
}
|
||||
|
||||
@ApiOperation("获取所有饰品等级背景")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TtOrnamentsLevel> list() {
|
||||
startPage();
|
||||
|
||||
-3
@@ -8,7 +8,6 @@ import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.domain.param.promotion.AnchorDailyTurnoverParam;
|
||||
import com.ruoyi.domain.param.promotion.AnchorRechargeParam;
|
||||
import com.ruoyi.domain.vo.promotion.AnchorDailyTurnoverVo;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -22,7 +21,6 @@ public class TtPromoTurnoverController extends BaseController {
|
||||
@Autowired
|
||||
private TtPromoTurnoverService ttPromoTurnoverService;
|
||||
|
||||
@ApiOperation("获取主播推广数据")
|
||||
@GetMapping("/getAnchorPromotionData")
|
||||
public PageDataInfo<AnchorDailyTurnoverVo> getAnchorPromotionData(AnchorDailyTurnoverParam param) {
|
||||
List<AnchorDailyTurnoverVo> list = ttPromoTurnoverService.getAnchorDailyTurnover(param);
|
||||
@@ -38,7 +36,6 @@ public class TtPromoTurnoverController extends BaseController {
|
||||
return pageDataInfo;
|
||||
}
|
||||
|
||||
@ApiOperation("主播充值")
|
||||
@PostMapping("/recharge")
|
||||
public AjaxResult recharge(@RequestBody AnchorRechargeParam param) {
|
||||
return ttPromoTurnoverService.recharge(param);
|
||||
|
||||
-4
@@ -13,14 +13,11 @@ import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 红包")
|
||||
@RestController
|
||||
@RequestMapping("/admin/redPacket")
|
||||
public class TtRedPacketController extends BaseController {
|
||||
@@ -45,7 +42,6 @@ public class TtRedPacketController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "CDK口令", action = "新增", businessType = BusinessType.INSERT)
|
||||
@ApiOperation("生成红包")
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody TtRedPacketDataVO ttRedPacketDataVO) {
|
||||
List<String> passwordList = redPacketService.insertRedPacket(ttRedPacketDataVO);
|
||||
|
||||
-18
@@ -24,8 +24,6 @@ import com.ruoyi.domain.entity.roll.TtRollUser;
|
||||
import com.ruoyi.domain.entity.sys.TtUser;
|
||||
import com.ruoyi.domain.vo.TtRollPrizeDataVO;
|
||||
import com.ruoyi.domain.vo.roll.RollJackpotOrnamentsByPageVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.Data;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -35,7 +33,6 @@ import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Api(tags = "管理端 roll房")
|
||||
@RestController
|
||||
@RequestMapping("/admin/roll")
|
||||
public class TtRollController extends BaseController {
|
||||
@@ -77,7 +74,6 @@ public class TtRollController extends BaseController {
|
||||
@Log(title = "Roll房列表", action = "新增", businessType = BusinessType.INSERT,
|
||||
entityClass = TtRoll.class, mapperClass = TtRollMapper.class)
|
||||
// 创建roll房
|
||||
@ApiOperation("创建roll房")
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody TtRoll ttRoll) {
|
||||
|
||||
@@ -88,7 +84,6 @@ public class TtRollController extends BaseController {
|
||||
}
|
||||
|
||||
// roll房拉人
|
||||
@ApiOperation("roll房拉人")
|
||||
@PostMapping("/inviteRollUser")
|
||||
public R inviteRollUser(@RequestBody InviteRollUser InviteRollUser) {
|
||||
|
||||
@@ -97,7 +92,6 @@ public class TtRollController extends BaseController {
|
||||
}
|
||||
|
||||
// 获取roll房成员信息
|
||||
@ApiOperation("获取roll房成员信息")
|
||||
@GetMapping("getRollUsers/{rollId}")
|
||||
public AjaxResult getRollUsers(@PathVariable("rollId") Integer rollId) {
|
||||
return rollService.getRollUsers(rollId);
|
||||
@@ -106,7 +100,6 @@ public class TtRollController extends BaseController {
|
||||
|
||||
@Log(title = "Roll房列表", action = "修改", businessType = BusinessType.UPDATE,
|
||||
entityClass = TtRoll.class, mapperClass = TtRollMapper.class)
|
||||
@ApiOperation("编辑roll房")
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody TtRoll ttRoll) {
|
||||
|
||||
@@ -117,14 +110,12 @@ public class TtRollController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "Roll房列表", action = "删除", businessType = BusinessType.DELETE)
|
||||
@ApiOperation("删除roll房")
|
||||
@DeleteMapping("/remove/{rollId}")
|
||||
public AjaxResult remove(@PathVariable Long rollId) {
|
||||
return rollService.removeRollById(rollId, getUsername());
|
||||
}
|
||||
|
||||
|
||||
// @ApiOperation("roll房奖品列表")
|
||||
// @PostMapping("/getRollPrizeList")
|
||||
// public R<List<TtRollPrizeDataVO>> getRollPrizeList(@RequestBody RollPrizesCondition condition) {
|
||||
//
|
||||
@@ -133,7 +124,6 @@ public class TtRollController extends BaseController {
|
||||
// return R.ok(list);
|
||||
//
|
||||
// }
|
||||
@ApiOperation("roll房奖品列表")
|
||||
@GetMapping("/getRollPrizeList/{rollId}")
|
||||
public R<List<TtRollPrizeDataVO>> getRollPrizeList(@PathVariable("rollId") Integer rollId) {
|
||||
|
||||
@@ -143,40 +133,34 @@ public class TtRollController extends BaseController {
|
||||
|
||||
}
|
||||
|
||||
@ApiOperation("获取 roll房奖池详情")
|
||||
@PostMapping("/getRollPrizePool")
|
||||
public R<RollJackpotOrnamentsByPageVO> getRollPrizePool(@RequestBody @Validated GetRollPrizePool param) {
|
||||
return rollService.getRollPrizePool(param);
|
||||
}
|
||||
|
||||
@ApiOperation("roll房的指定获奖人名单")
|
||||
@GetMapping("/rollWinners/{rollId}")
|
||||
public R rollWinners(@PathVariable Integer rollId) {
|
||||
return rollUserService.rollWinners(rollId);
|
||||
}
|
||||
|
||||
@ApiOperation("roll房实际中奖记录(开奖后参与用户中了什么饰品)")
|
||||
@GetMapping("/winningRecords/{rollId}")
|
||||
public R<List<Map<String, Object>>> winningRecords(@PathVariable("rollId") Integer rollId) {
|
||||
return rollService.winningRecords(rollId);
|
||||
}
|
||||
|
||||
@Log(title = "装备列表", action = "指定获奖者", businessType = BusinessType.INSERT)
|
||||
@ApiOperation("指定roll房winner")
|
||||
@PostMapping("/namedWinner")
|
||||
public AjaxResult namedWinner(@RequestBody @Validated TtRollPrizeDataVO param) {
|
||||
return rollService.namedWinner(param);
|
||||
}
|
||||
|
||||
@Log(title = "装备列表", action = "取消奖品", businessType = BusinessType.DELETE)
|
||||
@ApiOperation("取消指定roll房奖品")
|
||||
@DeleteMapping("/cancelNamedWinner")
|
||||
public R cancelNamedWinner(@RequestBody List<Integer> rollUserPrizeIds) {
|
||||
return rollService.cancelNamedWinner(rollUserPrizeIds);
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("获取ROLL房用户")
|
||||
@GetMapping("/getRollUser/{rollId}")
|
||||
public AjaxResult getRollUser(@PathVariable("rollId") Integer rollId) {
|
||||
List<TtUser> rollUserList = rollService.getRollUser(rollId);
|
||||
@@ -184,13 +168,11 @@ public class TtRollController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "房间用户", action = "加入机器人", businessType = BusinessType.INSERT)
|
||||
@ApiOperation("加入机器人")
|
||||
@PostMapping("/addRobot")
|
||||
public AjaxResult addRobot(@RequestBody AddRobotBody addRobotBody) {
|
||||
return rollService.addRobot(addRobotBody);
|
||||
}
|
||||
@Log(title = "房间用户", action = "加入用户", businessType = BusinessType.INSERT)
|
||||
@ApiOperation("强制加入普通用户")
|
||||
@PostMapping("/addUser")
|
||||
public AjaxResult addUser(@RequestBody AddUserBody addUserBody) {
|
||||
return rollService.addUser(addUserBody);
|
||||
|
||||
-5
@@ -13,14 +13,11 @@ import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 roll奖池")
|
||||
@RestController
|
||||
@RequestMapping("/admin/rollJackpot")
|
||||
public class TtRollJackpotController extends BaseController {
|
||||
@@ -31,7 +28,6 @@ public class TtRollJackpotController extends BaseController {
|
||||
this.rollJackpotService = rollJackpotService;
|
||||
}
|
||||
|
||||
@ApiOperation("奖池列表")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TtRollJackpot> list(@RequestParam(value = "jackpotName", required = false) String jackpotName) {
|
||||
startPage();
|
||||
@@ -51,7 +47,6 @@ public class TtRollJackpotController extends BaseController {
|
||||
|
||||
@Log(title = "奖池列表", action = "新增", businessType = BusinessType.INSERT,
|
||||
entityClass = TtRollJackpot.class, mapperClass = TtRollJackpotMapper.class)
|
||||
@ApiOperation("添加奖池")
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody TtRollJackpot ttRollJackpot) {
|
||||
ttRollJackpot.setCreateBy(getUsername());
|
||||
|
||||
-6
@@ -16,14 +16,11 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 roll奖池物品管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/rollJackpotOrnaments")
|
||||
public class TtRollJackpotOrnamentsController extends BaseController {
|
||||
@@ -37,7 +34,6 @@ public class TtRollJackpotOrnamentsController extends BaseController {
|
||||
this.rollJackpotOrnamentsService = rollJackpotOrnamentsService;
|
||||
}
|
||||
|
||||
@ApiOperation("物品列表")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TtRollJackpotOrnamentsDataVO> list(TtRollJackpotOrnamentsBody rollJackpotOrnamentsBody) {
|
||||
startPage();
|
||||
@@ -61,7 +57,6 @@ public class TtRollJackpotOrnamentsController extends BaseController {
|
||||
|
||||
@Log(title = "奖池列表", action = "修改", businessType = BusinessType.UPDATE,
|
||||
entityClass = TtRollJackpotOrnaments.class, mapperClass = TtRollJackpotOrnamentsMapper.class)
|
||||
@ApiOperation("修改奖池道具")
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody TtRollJackpotOrnaments rollJOEdit) {
|
||||
String msg = rollJackpotOrnamentsService.updateRollJackpotOrnamentsById(rollJOEdit);
|
||||
@@ -82,7 +77,6 @@ public class TtRollJackpotOrnamentsController extends BaseController {
|
||||
return toAjax(ok);
|
||||
}
|
||||
|
||||
@ApiOperation("奖池批量填货")
|
||||
@PostMapping("/batchAdd/{rollJackpotId}/{OrnamentsIds}")
|
||||
public AjaxResult batchAdd(@PathVariable Integer rollJackpotId, @PathVariable Long[] OrnamentsIds) {
|
||||
String msg = rollJackpotOrnamentsService.batchAdd(rollJackpotId, Arrays.asList(OrnamentsIds));
|
||||
|
||||
-9
@@ -11,14 +11,11 @@ import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.domain.other.TransferApplyBody;
|
||||
import com.ruoyi.domain.vo.transfer.TransferApplyBatchVO;
|
||||
import com.ruoyi.domain.vo.transfer.TransferApplyVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Api(tags = "管理端 转赠申请管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/transferApply")
|
||||
public class TtTransferApplyController extends BaseController {
|
||||
@@ -32,7 +29,6 @@ public class TtTransferApplyController extends BaseController {
|
||||
this.redisLock = redisLock;
|
||||
}
|
||||
|
||||
@ApiOperation("转赠申请列表(按饰品逐条)")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TransferApplyVO> list(TransferApplyBody body) {
|
||||
startPage();
|
||||
@@ -40,7 +36,6 @@ public class TtTransferApplyController extends BaseController {
|
||||
return getPageData(list);
|
||||
}
|
||||
|
||||
@ApiOperation("转赠申请批次列表(按批次聚合,含饰品明细)")
|
||||
@GetMapping("/batchList")
|
||||
public PageDataInfo<TransferApplyBatchVO> batchList(TransferApplyBody body) {
|
||||
startPage();
|
||||
@@ -48,7 +43,6 @@ public class TtTransferApplyController extends BaseController {
|
||||
return getPageData(list);
|
||||
}
|
||||
|
||||
@ApiOperation("审核通过(单条,兼容旧接口)")
|
||||
@Log(title = "转赠申请", action = "同意", businessType = BusinessType.GRANT)
|
||||
@PostMapping("/approve")
|
||||
public R<Boolean> approve(@RequestParam("id") Integer id) {
|
||||
@@ -64,7 +58,6 @@ public class TtTransferApplyController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("审核驳回(单条,兼容旧接口)")
|
||||
@Log(title = "转赠申请", action = "驳回", businessType = BusinessType.GRANT)
|
||||
@PostMapping("/reject")
|
||||
public R<Boolean> reject(@RequestParam("id") Integer id,
|
||||
@@ -81,7 +74,6 @@ public class TtTransferApplyController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("批次审核通过(整个批次一起通过)")
|
||||
@Log(title = "转赠申请", action = "确定同意", businessType = BusinessType.GRANT)
|
||||
@PostMapping("/approveBatch")
|
||||
public R<Boolean> approveBatch(@RequestParam("batchId") String batchId) {
|
||||
@@ -97,7 +89,6 @@ public class TtTransferApplyController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("批次审核驳回(整个批次一起驳回)")
|
||||
@Log(title = "转赠申请", action = "驳回", businessType = BusinessType.GRANT)
|
||||
@PostMapping("/rejectBatch")
|
||||
public R<Boolean> rejectBatch(@RequestParam("batchId") String batchId,
|
||||
|
||||
-6
@@ -9,9 +9,6 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -25,7 +22,6 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Api(tags = "管理端 失败物品奖励")
|
||||
@RestController
|
||||
@RequestMapping("/admin/upgradeFailOrnaments")
|
||||
public class TtUpgradeFailOrnamentsController extends BaseController {
|
||||
@@ -43,7 +39,6 @@ public class TtUpgradeFailOrnamentsController extends BaseController {
|
||||
@NotNull(message = "参与升级物品id不能为空")
|
||||
private Integer upgradeOrnamentId;
|
||||
}
|
||||
@ApiOperation("失败奖励列表")
|
||||
@PostMapping("/list")
|
||||
public PageDataInfo<TtUpgradeFailOrnamentsDataVO> list(@RequestBody listParam param) {
|
||||
startPage();
|
||||
@@ -67,7 +62,6 @@ public class TtUpgradeFailOrnamentsController extends BaseController {
|
||||
private Boolean useAllFlag;
|
||||
}
|
||||
@Log(title = "失败奖励", action = "新增", businessType = BusinessType.INSERT)
|
||||
@ApiOperation("批量添加失败奖励")
|
||||
@PostMapping("/batchAdd")
|
||||
public AjaxResult batchAdd(@RequestBody @Validated BatchAddParam param) {
|
||||
return upgradeFailOrnamentsService.batchAdd(param);
|
||||
|
||||
-5
@@ -14,8 +14,6 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -24,7 +22,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Api(tags = "管理端 幸运升级")
|
||||
@RestController
|
||||
@RequestMapping("/admin/upgradeOrnaments")
|
||||
public class TtUpgradeOrnamentsController extends BaseController {
|
||||
@@ -38,7 +35,6 @@ public class TtUpgradeOrnamentsController extends BaseController {
|
||||
this.upgradeOrnamentsService = upgradeOrnamentsService;
|
||||
}
|
||||
|
||||
@ApiOperation("获取参与幸运升级的物品")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TtUpgradeOrnamentsDataVO> list(TtUpgradeOrnamentsBody ttUpgradeOrnamentsBody){
|
||||
startPage();
|
||||
@@ -53,7 +49,6 @@ public class TtUpgradeOrnamentsController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "饰品列表", action = "新增", businessType = BusinessType.INSERT)
|
||||
@ApiOperation("批量填货")
|
||||
@PostMapping("/batchAdd/{ornamentsIds}")
|
||||
public AjaxResult batchAdd(@PathVariable Long[] ornamentsIds) {
|
||||
String msg = upgradeOrnamentsService.batchAdd(Arrays.asList(ornamentsIds));
|
||||
|
||||
-4
@@ -10,14 +10,11 @@ import com.ruoyi.domain.other.TtUpgradeRecordBody;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.domain.vo.upgrade.UpgradeRecordVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 幸运升级日志")
|
||||
@RestController
|
||||
@RequestMapping("/admin/upgradeRecord")
|
||||
public class TtUpgradeRecordController extends BaseController {
|
||||
@@ -28,7 +25,6 @@ public class TtUpgradeRecordController extends BaseController {
|
||||
this.upgradeRecordService = upgradeRecordService;
|
||||
}
|
||||
|
||||
@ApiOperation("幸运升级日志")
|
||||
@PostMapping("/list")
|
||||
public R<Page<UpgradeRecordVO>> list(@RequestBody @Validated UpgradeCondition param){
|
||||
return upgradeRecordService.adminGetLog(param);
|
||||
|
||||
-9
@@ -6,8 +6,6 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.domain.other.UpgradeWatermarkSettingBody;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -21,7 +19,6 @@ import java.util.Map;
|
||||
* 后台只配一个「目标水位(%)」:水位高于它 → 随机数中心下移(放水);低于它 → 上移(收紧),
|
||||
* 长期自动收敛回目标值。随机数的取值范围仍由每个饰品自己的区间限定。
|
||||
*/
|
||||
@Api(tags = "幸运升级·奖池水位")
|
||||
@RestController
|
||||
@RequestMapping("/admin/upgradeWatermark")
|
||||
public class TtUpgradeWatermarkController extends BaseController {
|
||||
@@ -29,13 +26,11 @@ public class TtUpgradeWatermarkController extends BaseController {
|
||||
@Autowired
|
||||
private UpgradeWatermarkService watermarkService;
|
||||
|
||||
@ApiOperation("当前水位快照 + 目标水位策略 + 按目标水位推算的随机数中心")
|
||||
@GetMapping("/info")
|
||||
public R<Map<String, Object>> info() {
|
||||
return R.ok(watermarkService.info());
|
||||
}
|
||||
|
||||
@ApiOperation("保存目标水位策略(目标水位 + 灵敏度)")
|
||||
@Log(title = "幸运升级水位策略", action = "保存", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/setting")
|
||||
public R<Map<String, Object>> saveSetting(@RequestBody UpgradeWatermarkSettingBody body) {
|
||||
@@ -46,7 +41,6 @@ public class TtUpgradeWatermarkController extends BaseController {
|
||||
return R.ok(watermarkService.info());
|
||||
}
|
||||
|
||||
@ApiOperation("注水/抽水(type 1注水 2抽水;调整原因必填)")
|
||||
@Log(title = "幸运升级水位", action = "注水/抽水", businessType = BusinessType.GRANT)
|
||||
@PostMapping("/adjust")
|
||||
public R<Map<String, Object>> adjust(@RequestBody Map<String, Object> body) {
|
||||
@@ -60,7 +54,6 @@ public class TtUpgradeWatermarkController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("重置人工调整(插入抵消日志,SUM(delta) 归零,历史保留)")
|
||||
@Log(title = "幸运升级水位", action = "重置调整", businessType = BusinessType.CLEAN)
|
||||
@PostMapping("/adjustReset")
|
||||
public R<Map<String, Object>> adjustReset(@RequestBody(required = false) Map<String, Object> body) {
|
||||
@@ -72,14 +65,12 @@ public class TtUpgradeWatermarkController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("调整历史(分页)")
|
||||
@GetMapping("/adjustLog")
|
||||
public R<Map<String, Object>> adjustLog(@RequestParam(defaultValue = "1") int page,
|
||||
@RequestParam(defaultValue = "10") int size) {
|
||||
return R.ok(watermarkService.pageLog(page, size));
|
||||
}
|
||||
|
||||
@ApiOperation("按历史记录全量重算累计下注/返奖(纠正 Redis 计数漂移)")
|
||||
@Log(title = "幸运升级水位", action = "重算累计量", businessType = BusinessType.CLEAN)
|
||||
@PostMapping("/recalc")
|
||||
public R<Map<String, Object>> recalc() {
|
||||
|
||||
-5
@@ -9,8 +9,6 @@ import com.ruoyi.system.config.ArchiveDaysConfig;
|
||||
import com.ruoyi.domain.other.TtUserAmountRecordsBody;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -22,7 +20,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Api(tags = "管理端 金币账户")
|
||||
@RestController
|
||||
@RequestMapping("/admin/userAmountRecords")
|
||||
public class TtUserAmountRecordsController extends BaseController {
|
||||
@@ -38,7 +35,6 @@ public class TtUserAmountRecordsController extends BaseController {
|
||||
this.userAmountRecordsService = userAmountRecordsService;
|
||||
}
|
||||
|
||||
@ApiOperation("获取列表")
|
||||
@PostMapping("/list")
|
||||
public R list(@RequestBody @Validated TtUserAmountRecordsBody ttUserAmountRecordsBody) {
|
||||
return userAmountRecordsService.queryList(ttUserAmountRecordsBody);
|
||||
@@ -55,7 +51,6 @@ public class TtUserAmountRecordsController extends BaseController {
|
||||
* - userId 排序 → 快速模式(先分页用户再聚合当页数据,Java内存排序)
|
||||
* - 聚合字段排序 → 全局排序模式(先聚合所有用户→SQL排序→分页),确保全局排序正确
|
||||
*/
|
||||
@ApiOperation("用户流水统计")
|
||||
@GetMapping("/userTurnover")
|
||||
public R userTurnover(
|
||||
@RequestParam(required = false) Integer userId,
|
||||
|
||||
-5
@@ -5,8 +5,6 @@ import com.ruoyi.admin.service.TtUserBlendErcashService;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.domain.dto.userRecord.BlendErcashCondition;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -15,7 +13,6 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Api(tags = "管理端 收支明细")
|
||||
@RestController
|
||||
@RequestMapping("/admin/blendErcash")
|
||||
@Slf4j
|
||||
@@ -24,13 +21,11 @@ public class TtUserBlendErcashController extends BaseController {
|
||||
@Autowired
|
||||
private TtUserBlendErcashService ttUserBlendErcashService;
|
||||
|
||||
@ApiOperation("收支明细")
|
||||
@PostMapping("/list")
|
||||
public R list(@RequestBody @Validated BlendErcashCondition condition) {
|
||||
return ttUserBlendErcashService.byCondition(condition);
|
||||
}
|
||||
|
||||
@ApiOperation("收支明细-仅归档表")
|
||||
@PostMapping("/archive/list")
|
||||
public R archiveList(@RequestBody @Validated BlendErcashCondition condition) {
|
||||
return ttUserBlendErcashService.byConditionArchive(condition);
|
||||
|
||||
-10
@@ -27,7 +27,6 @@ import com.ruoyi.domain.other.TtUserBody;
|
||||
import com.ruoyi.domain.other.TtUserPackSackBody;
|
||||
import com.ruoyi.domain.vo.TtUserPackSackDataVO;
|
||||
import com.ruoyi.domain.vo.user.TtUserVo;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -89,14 +88,12 @@ public class TtUserController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "用户列表", action = "生成招商账号", businessType = BusinessType.INSERT)
|
||||
@ApiOperation("生成招商账号")
|
||||
@PostMapping("/generateAccount")
|
||||
public void generateAccount(HttpServletResponse response, @RequestBody GenerateAccountBody body) {
|
||||
List<TtUser> userList = userService.getAccountList(body.getNum(), body.getCustomPhoneNumbers());
|
||||
userService.generateAccount(response, userList);
|
||||
}
|
||||
|
||||
@ApiOperation("生成账号")
|
||||
@GetMapping("/generateAccountByPhoneNum")
|
||||
public R generateAccountByPhoneNum(HttpServletResponse response, @RequestParam("phoneNum") String phoneNum,
|
||||
@RequestParam("password") String password) {
|
||||
@@ -105,7 +102,6 @@ public class TtUserController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "用户列表", action = "生成机器人", businessType = BusinessType.INSERT)
|
||||
@ApiOperation("生成机器人")
|
||||
@PostMapping("/generateRobot/{num}")
|
||||
public void generateRobot(HttpServletResponse response, @PathVariable("num") Integer num) {
|
||||
List<TtUser> userList = userService.getRobotList(num);
|
||||
@@ -113,7 +109,6 @@ public class TtUserController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "用户列表", action = "生成白号", businessType = BusinessType.INSERT)
|
||||
@ApiOperation("生成白号")
|
||||
@PostMapping("/generateBlankAccount")
|
||||
public void generateBlankAccount(HttpServletResponse response, @RequestBody GenerateAccountBody body) {
|
||||
List<TtUser> userList = userService.getBlankAccountList(body.getNum(), body.getCustomPhoneNumbers());
|
||||
@@ -121,7 +116,6 @@ public class TtUserController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "用户列表", action = "生成卡商账号", businessType = BusinessType.INSERT)
|
||||
@ApiOperation("生成卡商账号")
|
||||
@PostMapping("/generateCardMerchant")
|
||||
public void generateCardMerchant(HttpServletResponse response, @RequestBody GenerateAccountBody body) {
|
||||
List<TtUser> userList = userService.getCardMerchantList(body.getNum(), body.getCustomPhoneNumbers());
|
||||
@@ -130,7 +124,6 @@ public class TtUserController extends BaseController {
|
||||
|
||||
@Log(title = "用户列表", action = "修改", businessType = BusinessType.UPDATE,
|
||||
entityClass = TtUser.class, mapperClass = TtUserMapper.class)
|
||||
@ApiOperation("修改用户信息")
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody TtUser ttUser) {
|
||||
ttUser.setUpdateBy(getUsername());
|
||||
@@ -146,7 +139,6 @@ public class TtUserController extends BaseController {
|
||||
|
||||
@Log(title = "用户列表", action = "修改邀请码", businessType = BusinessType.UPDATE,
|
||||
entityClass = TtUser.class, mapperClass = TtUserMapper.class)
|
||||
@ApiOperation("修改邀请码")
|
||||
@PostMapping("/editInvitationCode")
|
||||
public AjaxResult editInvitationCode(@RequestBody TtUser ttUser) {
|
||||
ttUser.setUpdateBy(getUsername());
|
||||
@@ -225,7 +217,6 @@ public class TtUserController extends BaseController {
|
||||
|
||||
@Log(title = "用户列表", action = "重置余额积分", businessType = BusinessType.CLEAN,
|
||||
entityClass = TtUser.class, mapperClass = TtUserMapper.class, idField = "userId")
|
||||
@ApiOperation("重置用户余额和积分")
|
||||
@PostMapping("/resetBalance/{userId}")
|
||||
public AjaxResult resetUserBalance(@PathVariable("userId") Integer userId){
|
||||
TtUser ttUser = new TtUser();
|
||||
@@ -239,7 +230,6 @@ public class TtUserController extends BaseController {
|
||||
}
|
||||
|
||||
@Log(title = "用户列表", action = "真删除", businessType = BusinessType.FORCE)
|
||||
@ApiOperation("真删除用户(数据库删除,不可恢复)")
|
||||
@DeleteMapping("/forceDelete/{userId}")
|
||||
public AjaxResult forceDelete(@PathVariable("userId") Integer userId) {
|
||||
// 0. 先清登录态:物理删除后 tt_user 查不到该用户,若不清 Redis Token,
|
||||
|
||||
-10
@@ -18,8 +18,6 @@ import com.ruoyi.domain.entity.TtOrnament;
|
||||
import com.ruoyi.domain.entity.lottery.TtTurnoverLottery;
|
||||
import com.ruoyi.domain.entity.lottery.TtTurnoverLotteryPrize;
|
||||
import com.ruoyi.domain.entity.lottery.TtTurnoverLotteryRecord;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -31,7 +29,6 @@ import java.util.concurrent.TimeUnit;
|
||||
/**
|
||||
* 后台管理 - 流水抽奖配置
|
||||
*/
|
||||
@Api(tags = "后台流水抽奖管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/turnoverLottery")
|
||||
public class TurnoverLotteryAdminController extends BaseController {
|
||||
@@ -57,7 +54,6 @@ public class TurnoverLotteryAdminController extends BaseController {
|
||||
/**
|
||||
* 获取抽奖活动列表
|
||||
*/
|
||||
@ApiOperation("获取抽奖活动列表")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TtTurnoverLottery> list(
|
||||
@RequestParam(required = false) String lotteryName,
|
||||
@@ -92,7 +88,6 @@ public class TurnoverLotteryAdminController extends BaseController {
|
||||
/**
|
||||
* 保存抽奖奖品配置
|
||||
*/
|
||||
@ApiOperation("保存抽奖奖品")
|
||||
@PostMapping("/save/{lotteryId}")
|
||||
public R<String> savePrizes(
|
||||
@PathVariable("lotteryId") Long lotteryId,
|
||||
@@ -112,7 +107,6 @@ public class TurnoverLotteryAdminController extends BaseController {
|
||||
/**
|
||||
* 更新抽奖活动状态
|
||||
*/
|
||||
@ApiOperation("更新抽奖状态")
|
||||
@PostMapping("/toggleStatus")
|
||||
public R<String> toggleStatus(@RequestBody Map<String, Object> body) {
|
||||
Long lotteryId = body.get("lotteryId") != null ? ((Number) body.get("lotteryId")).longValue() : null;
|
||||
@@ -139,7 +133,6 @@ public class TurnoverLotteryAdminController extends BaseController {
|
||||
/**
|
||||
* 创建新的抽奖活动
|
||||
*/
|
||||
@ApiOperation("创建抽奖活动")
|
||||
@PostMapping("/create")
|
||||
public R<TtTurnoverLottery> create(@RequestBody Map<String, Object> body) {
|
||||
String lotteryName = body.get("lotteryName") != null ? body.get("lotteryName").toString() : null;
|
||||
@@ -170,7 +163,6 @@ public class TurnoverLotteryAdminController extends BaseController {
|
||||
/**
|
||||
* 删除抽奖活动
|
||||
*/
|
||||
@ApiOperation("删除抽奖活动")
|
||||
@DeleteMapping("/delete/{lotteryId}")
|
||||
public R<String> delete(@PathVariable("lotteryId") Long lotteryId) {
|
||||
lotteryMapper.deleteById(lotteryId);
|
||||
@@ -180,7 +172,6 @@ public class TurnoverLotteryAdminController extends BaseController {
|
||||
/**
|
||||
* 搜索饰品 (用于奖品配置时调用)
|
||||
*/
|
||||
@ApiOperation("搜索饰品")
|
||||
@GetMapping("/searchOrnaments")
|
||||
public R<List<TtOrnament>> searchOrnaments(
|
||||
@RequestParam(value = "name", required = false) String name,
|
||||
@@ -205,7 +196,6 @@ public class TurnoverLotteryAdminController extends BaseController {
|
||||
/**
|
||||
* 更新抽奖活动基础信息
|
||||
*/
|
||||
@ApiOperation("更新抽奖活动")
|
||||
@PostMapping("/update")
|
||||
public R<String> update(@RequestBody Map<String, Object> body) {
|
||||
Long lotteryId = body.get("lotteryId") != null ? ((Number) body.get("lotteryId")).longValue() : null;
|
||||
|
||||
-8
@@ -18,8 +18,6 @@ import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.domain.entity.lottery.TtTurnoverLottery;
|
||||
import com.ruoyi.domain.entity.lottery.TtTurnoverLotteryPrize;
|
||||
import com.ruoyi.domain.other.TtOrnamentsLevel;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -33,7 +31,6 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 流水抽奖奖品管理 (仿宝箱饰品管理 boxOrnaments)
|
||||
*/
|
||||
@Api(tags = "流水抽奖奖品管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/turnoverLotteryPrize")
|
||||
public class TurnoverLotteryPrizeController extends BaseController {
|
||||
@@ -56,7 +53,6 @@ public class TurnoverLotteryPrizeController extends BaseController {
|
||||
/**
|
||||
* 获取奖品列表 (分页,含爆率百分比计算)
|
||||
*/
|
||||
@ApiOperation("奖品列表")
|
||||
@GetMapping("/list/{lotteryId}")
|
||||
public PageDataInfo<TtTurnoverLotteryPrize> list(@PathVariable("lotteryId") Long lotteryId) {
|
||||
// 先算总数(避免 PageHelper 干扰百分比计算)
|
||||
@@ -108,7 +104,6 @@ public class TurnoverLotteryPrizeController extends BaseController {
|
||||
/**
|
||||
* 获取单个奖品详情
|
||||
*/
|
||||
@ApiOperation("奖品详情")
|
||||
@GetMapping("/{id}")
|
||||
public R<TtTurnoverLotteryPrize> getInfo(@PathVariable("id") Long id) {
|
||||
return R.ok(prizeMapper.selectById(id));
|
||||
@@ -118,7 +113,6 @@ public class TurnoverLotteryPrizeController extends BaseController {
|
||||
/**
|
||||
* 新增奖品
|
||||
*/
|
||||
@ApiOperation("新增奖品")
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody TtTurnoverLotteryPrize prize) {
|
||||
if (prize == null || prize.getLotteryId() == null) {
|
||||
@@ -165,7 +159,6 @@ public class TurnoverLotteryPrizeController extends BaseController {
|
||||
/**
|
||||
* 修改奖品
|
||||
*/
|
||||
@ApiOperation("修改奖品")
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody TtTurnoverLotteryPrize prize) {
|
||||
Long lotteryId = prize.getLotteryId();
|
||||
@@ -211,7 +204,6 @@ public class TurnoverLotteryPrizeController extends BaseController {
|
||||
/**
|
||||
* 删除奖品
|
||||
*/
|
||||
@ApiOperation("删除奖品")
|
||||
@DeleteMapping("/{lotteryId}/{ids}")
|
||||
public AjaxResult remove(@PathVariable Long lotteryId, @PathVariable Long[] ids) {
|
||||
String lockKey = RedisConstants.TURNOVER_LOTTERY_DRAW_BOX_LOCK + lotteryId;
|
||||
|
||||
-5
@@ -9,8 +9,6 @@ import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.domain.entity.lottery.TtTurnoverLotteryRecord;
|
||||
import com.ruoyi.domain.entity.lottery.TtTurnoverLottery;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -19,7 +17,6 @@ import java.util.List;
|
||||
/**
|
||||
* 后台管理 - 抽奖记录查询
|
||||
*/
|
||||
@Api(tags = "后台抽奖记录管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/turnoverLotteryRecord")
|
||||
public class TurnoverLotteryRecordController extends BaseController {
|
||||
@@ -33,7 +30,6 @@ public class TurnoverLotteryRecordController extends BaseController {
|
||||
/**
|
||||
* 查询抽奖记录列表
|
||||
*/
|
||||
@ApiOperation("查询抽奖记录")
|
||||
@GetMapping("/list")
|
||||
public PageDataInfo<TtTurnoverLotteryRecord> list(
|
||||
@RequestParam(value = "userId", required = false) Long userId,
|
||||
@@ -58,7 +54,6 @@ public class TurnoverLotteryRecordController extends BaseController {
|
||||
/**
|
||||
* 获取所有抽奖活动(用于下拉选择)
|
||||
*/
|
||||
@ApiOperation("获取抽奖活动选项")
|
||||
@GetMapping("/lotteryOptions")
|
||||
public R<List<TtTurnoverLottery>> lotteryOptions() {
|
||||
LambdaQueryWrapper<TtTurnoverLottery> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
-7
@@ -6,8 +6,6 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.redis.config.RedisLock;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -18,7 +16,6 @@ import java.util.concurrent.TimeUnit;
|
||||
/**
|
||||
* 用户端 - 流水抽奖
|
||||
*/
|
||||
@Api(tags = "用户流水抽奖")
|
||||
@RestController
|
||||
@RequestMapping("/api/turnoverLottery")
|
||||
public class TurnoverLotteryUserController extends BaseController {
|
||||
@@ -32,7 +29,6 @@ public class TurnoverLotteryUserController extends BaseController {
|
||||
/**
|
||||
* 获取用户今日流水统计和可参与的抽奖宝箱
|
||||
*/
|
||||
@ApiOperation("获取抽奖信息")
|
||||
@PostMapping("/myStats")
|
||||
public R<Map<String, Object>> getMyStats() {
|
||||
Integer userId = getUserId().intValue();
|
||||
@@ -42,7 +38,6 @@ public class TurnoverLotteryUserController extends BaseController {
|
||||
/**
|
||||
* 执行抽奖
|
||||
*/
|
||||
@ApiOperation("执行抽奖")
|
||||
@PostMapping("/draw")
|
||||
public R<Map<String, Object>> draw(@RequestBody Map<String, Object> params) {
|
||||
Integer userId = getUserId().intValue();
|
||||
@@ -82,7 +77,6 @@ public class TurnoverLotteryUserController extends BaseController {
|
||||
/**
|
||||
* 查询我的抽奖记录(分页)
|
||||
*/
|
||||
@ApiOperation("我的抽奖记录")
|
||||
@PostMapping("/myRecords")
|
||||
public R<Map<String, Object>> myRecords(@RequestBody(required = false) Map<String, Object> params) {
|
||||
Integer userId = getUserId().intValue();
|
||||
@@ -109,7 +103,6 @@ public class TurnoverLotteryUserController extends BaseController {
|
||||
/**
|
||||
* 查询全服中奖记录(分页,已排除白号/机器人/封禁/已删除用户)
|
||||
*/
|
||||
@ApiOperation("全服中奖记录")
|
||||
@PostMapping("/globalRecords")
|
||||
public R<Map<String, Object>> globalRecords(@RequestBody(required = false) Map<String, Object> params) {
|
||||
Long lotteryId = null;
|
||||
|
||||
-5
@@ -13,15 +13,12 @@ import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.domain.vo.upgrade.SimpleOrnamentVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "管理端 道具管理")
|
||||
@RestController
|
||||
@RequestMapping("/admin/websiteProperty")
|
||||
@Slf4j
|
||||
@@ -36,7 +33,6 @@ public class WebsitePropertyController extends BaseController {
|
||||
this.ornamentsService = ornamentsService;
|
||||
}
|
||||
|
||||
// @ApiOperation("获取道具列表")
|
||||
// @GetMapping("/list")
|
||||
// public PageDataInfo<WebsitePropertyDataVO> list() {
|
||||
// startPage();
|
||||
@@ -44,7 +40,6 @@ public class WebsitePropertyController extends BaseController {
|
||||
// return getPageData(Arrays.asList());
|
||||
// }
|
||||
|
||||
@ApiOperation("获取道具列表")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(OrnamentCondition condition) {
|
||||
startPage();
|
||||
|
||||
@@ -7,7 +7,6 @@ import com.ruoyi.domain.entity.TtOrnament;
|
||||
import com.ruoyi.domain.entity.TtOrnamentsYY;
|
||||
import com.ruoyi.domain.vo.WebsitePropertyDataVO;
|
||||
import com.ruoyi.domain.vo.upgrade.SimpleOrnamentVO;
|
||||
import io.swagger.models.auth.In;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
+15
-7
@@ -78,7 +78,7 @@ public class ApiUserDetailsServiceImpl implements UserDetailsService {
|
||||
} else {
|
||||
userData.setParentInvitationCode(ParentUser.getInvitationCode());
|
||||
}
|
||||
return createLoginUser(userData);
|
||||
return createLoginUser(userData, LoginUser.SCOPE_PLAYER);
|
||||
} else if (username.startsWith("promo_user_")) {
|
||||
String phoneNumber = username.substring(11);
|
||||
TtUser user = new LambdaQueryChainWrapper<>(ttUserService.getBaseMapper())
|
||||
@@ -93,7 +93,7 @@ public class ApiUserDetailsServiceImpl implements UserDetailsService {
|
||||
if (hasPromoRole) {
|
||||
UserData userData = UserData.builder().build();
|
||||
BeanUtils.copyBeanProp(userData, user);
|
||||
return createLoginUser(userData);
|
||||
return createLoginUser(userData, LoginUser.SCOPE_PROMO);
|
||||
}
|
||||
// 超级管理员账号(promo_admin.username / phone_number)也可以是手机号
|
||||
PromoAdmin promoAdmin = promoAdminMapper.findByAccount(phoneNumber);
|
||||
@@ -105,7 +105,7 @@ public class ApiUserDetailsServiceImpl implements UserDetailsService {
|
||||
.userType(UserType.SUPER_ADMIN.getCode())
|
||||
.password(promoAdmin.getPassword())
|
||||
.build();
|
||||
return createLoginUser(userData);
|
||||
return createLoginUser(userData, LoginUser.SCOPE_PROMO);
|
||||
}
|
||||
// 以下报错语义与原逻辑保持一致
|
||||
if (StringUtils.isNull(user)) {
|
||||
@@ -137,7 +137,7 @@ public class ApiUserDetailsServiceImpl implements UserDetailsService {
|
||||
.userType(UserType.SUPER_ADMIN.getCode())
|
||||
.password(promoAdmin.getPassword())
|
||||
.build();
|
||||
return createLoginUser(userData);
|
||||
return createLoginUser(userData, LoginUser.SCOPE_PROMO);
|
||||
} else {
|
||||
SysUser user = userService.selectUserByUserName(username);
|
||||
if (StringUtils.isNull(user)) {
|
||||
@@ -157,11 +157,19 @@ public class ApiUserDetailsServiceImpl implements UserDetailsService {
|
||||
}
|
||||
}
|
||||
|
||||
private UserDetails createLoginUser(UserData userData) {
|
||||
return new LoginUser(userData.getUserId().longValue(), userData);
|
||||
/**
|
||||
* 玩家 / 推广端登录:账号前缀决定登录端标记,token 只能用于对应端的接口
|
||||
*/
|
||||
private UserDetails createLoginUser(UserData userData, String loginScope) {
|
||||
LoginUser loginUser = new LoginUser(userData.getUserId().longValue(), userData);
|
||||
loginUser.setLoginScope(loginScope);
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
/** 后台账号登录(sys_user) */
|
||||
private UserDetails createLoginUser(SysUser user) {
|
||||
return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
|
||||
LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
|
||||
loginUser.setLoginScope(LoginUser.SCOPE_ADMIN);
|
||||
return loginUser;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -12,7 +12,9 @@ public interface TtFightResultService extends IService<TtFightResult> {
|
||||
FightResultVO getFightResult(Integer fightId);
|
||||
|
||||
/**
|
||||
* 批量获取多个对战的详细结果(替代循环调用 getFightResult 的 N+1 问题)
|
||||
* 批量获取多个对战的结果(替代循环调用 getFightResult 的 N+1 问题)。
|
||||
* 只算卡片要展示的金额,开箱明细(fightResult/winnerPrize/endGamePrize)不组装,
|
||||
* 客户端点卡片进观战/回顾时自己请求 getFightResult 取权威明细。
|
||||
*
|
||||
* @param fightIds 对战ID列表
|
||||
* @return 按入参顺序返回的 FightResultVO 列表(跳过不存在的 fightId)
|
||||
|
||||
+2
-6
@@ -38,9 +38,7 @@ public interface TtUserService extends IService<TtUser> {
|
||||
|
||||
void generateAccount(HttpServletResponse response, List<TtUser> accountList);
|
||||
|
||||
List<TtUser> getAccountList(Integer num);
|
||||
|
||||
// 生成招商账号:支持按位置传入自定义手机号(为空的位置随机生成)
|
||||
// 生成招商账号:手机号必填(推广后台靠手机号收短信验证码登录,随机号收不到码)
|
||||
List<TtUser> getAccountList(Integer num, List<String> customPhoneNumbers);
|
||||
|
||||
TtUser getAccountList(String phoneNumber, String password);
|
||||
@@ -52,9 +50,7 @@ public interface TtUserService extends IService<TtUser> {
|
||||
// 生成白号:支持按位置传入自定义手机号(为空的位置随机生成)
|
||||
List<TtUser> getBlankAccountList(Integer num, List<String> customPhoneNumbers);
|
||||
|
||||
List<TtUser> getCardMerchantList(Integer num);
|
||||
|
||||
// 生成卡商账号:支持按位置传入自定义手机号(为空的位置随机生成)
|
||||
// 生成卡商账号:手机号必填(推广后台靠手机号收短信验证码登录,随机号收不到码)
|
||||
List<TtUser> getCardMerchantList(Integer num, List<String> customPhoneNumbers);
|
||||
|
||||
boolean checkUserNameUnique(TtUser user);
|
||||
|
||||
+78
-113
@@ -306,7 +306,7 @@ public class TtFightResultServiceImpl extends ServiceImpl<TtFightResultMapper, T
|
||||
Map<Integer, TtFight> fightMap = fights.stream()
|
||||
.collect(Collectors.toMap(TtFight::getId, f -> f, (a, b) -> a));
|
||||
|
||||
// 2. 批量查询所有座位玩家的 vipLevel
|
||||
// 2. 批量查询座位玩家 vipLevel + 房主实时昵称(一次查询覆盖两类用户)
|
||||
List<Integer> allPlayerIds = fights.stream()
|
||||
.filter(f -> f.getSeats() != null)
|
||||
.flatMap(f -> f.getSeats().stream())
|
||||
@@ -314,30 +314,42 @@ public class TtFightResultServiceImpl extends ServiceImpl<TtFightResultMapper, T
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
Map<Integer, Integer> vipMap = new HashMap<>();
|
||||
if (!allPlayerIds.isEmpty()) {
|
||||
List<Integer> allUserIds = new ArrayList<>(allPlayerIds);
|
||||
fights.stream().map(TtFight::getUserId).filter(Objects::nonNull).forEach(allUserIds::add);
|
||||
allUserIds = allUserIds.stream().distinct().collect(Collectors.toList());
|
||||
Map<Integer, TtUser> userMap = new HashMap<>();
|
||||
if (!allUserIds.isEmpty()) {
|
||||
List<TtUser> users = new LambdaQueryChainWrapper<>(ttUserMapper)
|
||||
.in(TtUser::getUserId, allPlayerIds)
|
||||
.select(TtUser::getUserId, TtUser::getVipLevel)
|
||||
.in(TtUser::getUserId, allUserIds)
|
||||
.select(TtUser::getUserId, TtUser::getVipLevel, TtUser::getNickName)
|
||||
.list();
|
||||
vipMap = users.stream()
|
||||
.collect(Collectors.toMap(TtUser::getUserId,
|
||||
u -> u.getVipLevel() != null && u.getVipLevel() > 0 ? u.getVipLevel() - 1 : 0, (a, b) -> a));
|
||||
userMap = users.stream().filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(TtUser::getUserId, u -> u, (a, b) -> a));
|
||||
}
|
||||
for (TtFight fight : fights) {
|
||||
if (fight.getSeats() != null) {
|
||||
for (FightSeat seat : fight.getSeats()) {
|
||||
if (seat.getPlayerId() != null) {
|
||||
seat.setVipLevel(vipMap.getOrDefault(seat.getPlayerId(), 0));
|
||||
TtUser user = userMap.get(seat.getPlayerId());
|
||||
Integer vipLevel = user != null ? user.getVipLevel() : null;
|
||||
seat.setVipLevel(vipLevel != null && vipLevel > 0 ? vipLevel - 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 用户存在时用实时昵称覆盖;用户被物理删除时保留入库的 ownerNickName
|
||||
TtUser owner = userMap.get(fight.getUserId());
|
||||
if (owner != null && owner.getNickName() != null) {
|
||||
fight.setOwnerNickName(owner.getNickName());
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 批量查询所有 TtBoxRecords(按 fight_id 分组,只取本场玩家的记录)
|
||||
// 3. 批量查询所有 TtBoxRecords(按 fight_id 分组,只取本场玩家的记录;只查算金额需要的列)
|
||||
LambdaQueryWrapper<TtBoxRecords> boxRecordsQuery = new LambdaQueryWrapper<>();
|
||||
boxRecordsQuery.in(TtBoxRecords::getFightId, fightIds)
|
||||
.in(TtBoxRecords::getUserId, allPlayerIds);
|
||||
.in(TtBoxRecords::getUserId, allPlayerIds)
|
||||
.select(TtBoxRecords::getFightId, TtBoxRecords::getUserId, TtBoxRecords::getHolderUserId,
|
||||
TtBoxRecords::getOrnamentId, TtBoxRecords::getOrnamentsPrice,
|
||||
TtBoxRecords::getFightRoundNumber, TtBoxRecords::getCreateTime);
|
||||
List<TtBoxRecords> allBoxRecords = boxRecordsService.list(boxRecordsQuery);
|
||||
|
||||
// 过滤旧数据:回合数不超过对战实际总回合数 + 时间过滤
|
||||
@@ -377,25 +389,7 @@ public class TtFightResultServiceImpl extends ServiceImpl<TtFightResultMapper, T
|
||||
.collect(Collectors.toMap(TtBox::getBoxId, b -> b.getBoxName() != null ? b.getBoxName() : "", (a, b) -> a));
|
||||
}
|
||||
|
||||
// 5. 批量查询所有饰品 exteriorName
|
||||
List<Long> allOrnamentIds = allBoxRecords.stream()
|
||||
.filter(r -> r.getOrnamentId() != null)
|
||||
.map(TtBoxRecords::getOrnamentId)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
Map<Long, String> exteriorNameMap = new HashMap<>();
|
||||
if (!allOrnamentIds.isEmpty()) {
|
||||
List<TtOrnament> ornaments = new LambdaQueryChainWrapper<>(ttOrnamentMapper)
|
||||
.in(TtOrnament::getId, allOrnamentIds)
|
||||
.select(TtOrnament::getId, TtOrnament::getExteriorName)
|
||||
.list();
|
||||
exteriorNameMap = ornaments.stream()
|
||||
.collect(Collectors.toMap(TtOrnament::getId,
|
||||
o -> normalizeExterior(o.getExteriorName()),
|
||||
(a, b) -> a));
|
||||
}
|
||||
|
||||
// 6. 逐个构建 FightResultVO
|
||||
// 5. 逐个构建结果(只算金额,不组装开箱明细列表)
|
||||
List<FightResultVO> result = new ArrayList<>();
|
||||
for (Integer fightId : fightIds) {
|
||||
TtFight fight = fightMap.get(fightId);
|
||||
@@ -420,46 +414,23 @@ public class TtFightResultServiceImpl extends ServiceImpl<TtFightResultMapper, T
|
||||
}
|
||||
}
|
||||
|
||||
// 构建 fightBoxVOList
|
||||
// 箱图只用 boxImg01(boxImg02 客户端零读取);价格/箱名回填到 boxData,客户端按 boxId 取用
|
||||
Map<String, FightBoxVO> boxData = fight.getBoxData();
|
||||
ArrayList<FightBoxVO> fightBoxVOList = new ArrayList<>();
|
||||
if (boxData != null) {
|
||||
final Map<Integer, BigDecimal> finalBoxPriceMap = boxPriceMap;
|
||||
final Map<Integer, String> finalBoxNameMap = batchBoxNameMap;
|
||||
boxData.keySet().stream()
|
||||
.sorted(Comparator.comparingInt(Integer::parseInt))
|
||||
.forEach(boxId -> {
|
||||
Object value = boxData.get(boxId);
|
||||
if (value instanceof LinkedHashMap) {
|
||||
Map<String, Object> map = (LinkedHashMap) value;
|
||||
FightBoxVO vo = new FightBoxVO(
|
||||
map.get("boxId") != null ? Integer.valueOf(map.get("boxId").toString()) : null,
|
||||
map.get("number") != null ? Integer.valueOf(map.get("number").toString()) : null,
|
||||
map.get("boxImg01") != null ? map.get("boxImg01").toString() : null,
|
||||
map.get("boxImg02") != null ? map.get("boxImg02").toString() : null);
|
||||
vo.setPrice(finalBoxPriceMap.getOrDefault(vo.getBoxId(), BigDecimal.ZERO));
|
||||
vo.setBoxName(finalBoxNameMap.getOrDefault(vo.getBoxId(), ""));
|
||||
fightBoxVOList.add(vo);
|
||||
} else {
|
||||
FightBoxVO vo = boxData.get(boxId);
|
||||
vo.setPrice(finalBoxPriceMap.getOrDefault(vo.getBoxId(), BigDecimal.ZERO));
|
||||
vo.setBoxName(finalBoxNameMap.getOrDefault(vo.getBoxId(), ""));
|
||||
fightBoxVOList.add(vo);
|
||||
}
|
||||
});
|
||||
for (Map.Entry<String, FightBoxVO> entry : boxData.entrySet()) {
|
||||
FightBoxVO box = resolveFightBoxVO(entry.getValue());
|
||||
if (box == null) {
|
||||
continue;
|
||||
}
|
||||
box.setPrice(boxPriceMap.getOrDefault(box.getBoxId(), BigDecimal.ZERO));
|
||||
box.setBoxName(batchBoxNameMap.getOrDefault(box.getBoxId(), ""));
|
||||
box.setBoxImg02(null);
|
||||
entry.setValue(box);
|
||||
}
|
||||
}
|
||||
|
||||
// 分离正常回合结果和赛后奖励
|
||||
List<TtBoxRecords> roundResults = fightBoxRecords.stream()
|
||||
.filter(r -> r.getFightRoundNumber() != null && r.getFightRoundNumber() > 0)
|
||||
.collect(Collectors.toList());
|
||||
List<TtBoxRecords> endGameRecords = fightBoxRecords.stream()
|
||||
.filter(r -> r.getFightRoundNumber() == null || r.getFightRoundNumber() <= 0)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 胜利方获得的回合饰品(排除赛后奖励)
|
||||
// 胜利方:DB winner_ids 为空时,从 Redis 对战状态快照兜底(单场处理,异常不影响批量流程)
|
||||
List<Integer> winnerIds = fight.getWinnerIds() != null ? fight.getWinnerIds() : new ArrayList<>();
|
||||
// 数据库 winner_ids 为空时,从 Redis 对战状态快照兜底(单个 fight 处理,异常不影响批量流程)
|
||||
if (winnerIds.isEmpty()) {
|
||||
try {
|
||||
FightState state = redisCache.getCacheObject("fight_state:" + fightId);
|
||||
@@ -471,63 +442,57 @@ public class TtFightResultServiceImpl extends ServiceImpl<TtFightResultMapper, T
|
||||
log.warn("对战{} 从Redis获取winnerIds兜底失败: {}", fightId, e.getMessage());
|
||||
}
|
||||
}
|
||||
final List<Integer> finalWinnerIds = winnerIds;
|
||||
List<TtBoxRecords> winnerPrize = roundResults.stream()
|
||||
.filter(r -> r.getHolderUserId() != null && finalWinnerIds.contains(r.getHolderUserId()))
|
||||
.filter(r -> r.getOrnamentId() != null)
|
||||
.collect(Collectors.toList());
|
||||
// 平分奖:赛后奖励中持有人为赢家的记录,计入赢家所得
|
||||
winnerPrize.addAll(endGameRecords.stream()
|
||||
.filter(r -> r.getHolderUserId() != null && finalWinnerIds.contains(r.getHolderUserId()))
|
||||
.filter(r -> r.getOrnamentId() != null)
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
// 失败方安慰奖
|
||||
List<TtBoxRecords> endGamePrize = endGameRecords.stream()
|
||||
.filter(r -> r.getHolderUserId() != null && !finalWinnerIds.contains(r.getHolderUserId()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 填充 exteriorName
|
||||
List<TtBoxRecords> allPrizeRecords = new ArrayList<>();
|
||||
allPrizeRecords.addAll(winnerPrize);
|
||||
allPrizeRecords.addAll(endGamePrize);
|
||||
final Map<Long, String> finalExteriorNameMap = exteriorNameMap;
|
||||
allPrizeRecords.forEach(r -> {
|
||||
if (r.getOrnamentId() != null) {
|
||||
r.setExteriorName(finalExteriorNameMap.getOrDefault(r.getOrnamentId(), "崭新出厂"));
|
||||
// 明细列表(fightResult/winnerPrize/endGamePrize)不组装,直接把口径累加成金额:
|
||||
// 赢家所得 = 持有人为赢家的全部记录(回合饰品 + 赛后平分奖),只算真实饰品(ornamentId 非空);
|
||||
// 失败方安慰奖 = 赛后记录(回合数<=0)中持有人非赢家的部分。
|
||||
BigDecimal winnerTotalPrice = BigDecimal.ZERO;
|
||||
BigDecimal loserTotalPrice = BigDecimal.ZERO;
|
||||
BigDecimal totalOrnamentsPrice = BigDecimal.ZERO;
|
||||
for (TtBoxRecords record : fightBoxRecords) {
|
||||
BigDecimal price = record.getOrnamentsPrice();
|
||||
if (price == null) {
|
||||
continue;
|
||||
}
|
||||
});
|
||||
totalOrnamentsPrice = totalOrnamentsPrice.add(price);
|
||||
Integer holderUserId = record.getHolderUserId();
|
||||
if (holderUserId == null) {
|
||||
continue;
|
||||
}
|
||||
if (winnerIds.contains(holderUserId)) {
|
||||
if (record.getOrnamentId() != null) {
|
||||
winnerTotalPrice = winnerTotalPrice.add(price);
|
||||
}
|
||||
} else if (record.getFightRoundNumber() == null || record.getFightRoundNumber() <= 0) {
|
||||
loserTotalPrice = loserTotalPrice.add(price);
|
||||
}
|
||||
}
|
||||
|
||||
// 获得的饰品按价格降序,空价格放最后
|
||||
roundResults.sort(ORNAMENT_PRICE_DESC);
|
||||
winnerPrize.sort(ORNAMENT_PRICE_DESC);
|
||||
endGamePrize.sort(ORNAMENT_PRICE_DESC);
|
||||
|
||||
// 计算金额
|
||||
BigDecimal winnerTotalPrice = winnerPrize.stream()
|
||||
.map(r -> r.getOrnamentsPrice() != null ? r.getOrnamentsPrice() : BigDecimal.ZERO)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal loserTotalPrice = endGamePrize.stream()
|
||||
.map(r -> r.getOrnamentsPrice() != null ? r.getOrnamentsPrice() : BigDecimal.ZERO)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal totalOrnamentsPrice = fightBoxRecords.stream()
|
||||
.filter(r -> r.getOrnamentsPrice() != null)
|
||||
.map(TtBoxRecords::getOrnamentsPrice)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
FightResultVO resultVO = FightResultVO.builder()
|
||||
result.add(FightResultVO.builder()
|
||||
.fight(fight)
|
||||
.winnerIds(winnerIds)
|
||||
.fightResult(roundResults)
|
||||
.winnerPrize(winnerPrize)
|
||||
.endGamePrize(endGamePrize)
|
||||
.winnerTotalPrice(winnerTotalPrice)
|
||||
.loserTotalPrice(loserTotalPrice)
|
||||
.totalOrnamentsPrice(totalOrnamentsPrice)
|
||||
.fightBoxVOList(fightBoxVOList)
|
||||
.build();
|
||||
result.add(resultVO);
|
||||
.build());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* boxData 反序列化后可能是 FightBoxVO,也可能是原始 Map(历史脏数据),统一取成 FightBoxVO。
|
||||
*/
|
||||
private FightBoxVO resolveFightBoxVO(Object value) {
|
||||
if (value == null) return null;
|
||||
if (value instanceof FightBoxVO) return (FightBoxVO) value;
|
||||
if (value instanceof LinkedHashMap) {
|
||||
Map<String, Object> map = (LinkedHashMap) value;
|
||||
return new FightBoxVO(
|
||||
map.get("boxId") != null ? Integer.valueOf(map.get("boxId").toString()) : null,
|
||||
map.get("number") != null ? Integer.valueOf(map.get("number").toString()) : null,
|
||||
map.get("boxImg01") != null ? map.get("boxImg01").toString() : null,
|
||||
map.get("boxImg02") != null ? map.get("boxImg02").toString() : null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+21
-15
@@ -473,11 +473,6 @@ public class TtUserServiceImpl extends ServiceImpl<TtUserMapper, TtUser> impleme
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TtUser> getAccountList(Integer num) {
|
||||
return getAccountList(num, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<TtUser> getAccountList(Integer num, List<String> customPhoneNumbers) {
|
||||
@@ -490,8 +485,8 @@ public class TtUserServiceImpl extends ServiceImpl<TtUserMapper, TtUser> impleme
|
||||
.list();
|
||||
List<TtUser> userList = new ArrayList<>();
|
||||
for (int i = 0; i < num; i++) {
|
||||
// 优先使用第 i 个自定义手机号,为空则随机生成
|
||||
String phoneNumber = getCustomPhoneOrRandom(customPhoneNumbers, i);
|
||||
// 招商账号必须逐个指定手机号,不随机生成
|
||||
String phoneNumber = getRequiredPhone(customPhoneNumbers, i, "招商账号");
|
||||
String nickName = RandomUtils.getRandomName(new Random().nextInt(2));
|
||||
String password = generateMixedPassword(10);
|
||||
String invitationCode = getInvitationCode();
|
||||
@@ -523,7 +518,7 @@ public class TtUserServiceImpl extends ServiceImpl<TtUserMapper, TtUser> impleme
|
||||
}
|
||||
|
||||
/**
|
||||
* 取第 index 个自定义手机号;为空或越界时返回随机生成的手机号
|
||||
* 取第 index 个自定义手机号;为空或越界时返回随机生成的手机号(仅白号使用)
|
||||
*/
|
||||
private String getCustomPhoneOrRandom(List<String> customPhoneNumbers, int index) {
|
||||
if (customPhoneNumbers != null && index < customPhoneNumbers.size()
|
||||
@@ -533,6 +528,22 @@ public class TtUserServiceImpl extends ServiceImpl<TtUserMapper, TtUser> impleme
|
||||
return getRandomPhoneNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取第 index 个手机号(必填)。招商/卡商账号是推广后台的登录账号,
|
||||
* 登录只认「手机号 + 短信验证码」,随机号收不到码就等于发一个登不进去的号,所以不兜底随机生成。
|
||||
*/
|
||||
private String getRequiredPhone(List<String> customPhoneNumbers, int index, String label) {
|
||||
String phone = customPhoneNumbers != null && index < customPhoneNumbers.size()
|
||||
? StringUtils.trim(customPhoneNumbers.get(index)) : null;
|
||||
if (StringUtils.isBlank(phone)) {
|
||||
throw new ServiceException("请填写第 " + (index + 1) + " 个" + label + "的手机号");
|
||||
}
|
||||
if (!phone.matches("^1[3-9]\\d{9}$")) {
|
||||
throw new ServiceException("第 " + (index + 1) + " 个手机号格式不正确,请输入 11 位有效手机号");
|
||||
}
|
||||
return phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验自定义手机号:批次内不可重复,且不可与库中已存在(用户名/手机号)冲突。
|
||||
* 忽略 del_flag,连软删除记录也拦截,避免直接 insert 触发唯一键冲突。
|
||||
@@ -722,11 +733,6 @@ public class TtUserServiceImpl extends ServiceImpl<TtUserMapper, TtUser> impleme
|
||||
return userList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TtUser> getCardMerchantList(Integer num) {
|
||||
return getCardMerchantList(num, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<TtUser> getCardMerchantList(Integer num, List<String> customPhoneNumbers) {
|
||||
@@ -739,8 +745,8 @@ public class TtUserServiceImpl extends ServiceImpl<TtUserMapper, TtUser> impleme
|
||||
.list();
|
||||
List<TtUser> userList = new ArrayList<>();
|
||||
for (int i = 0; i < num; i++) {
|
||||
// 优先使用第 i 个自定义手机号,为空则随机生成
|
||||
String phoneNumber = getCustomPhoneOrRandom(customPhoneNumbers, i);
|
||||
// 卡商账号必须逐个指定手机号,不随机生成
|
||||
String phoneNumber = getRequiredPhone(customPhoneNumbers, i, "卡商账号");
|
||||
String nickName = RandomUtils.getRandomName(new Random().nextInt(2));
|
||||
String password = generateMixedPassword(10);
|
||||
String invitationCode = getInvitationCode();
|
||||
|
||||
-7
@@ -1,7 +1,5 @@
|
||||
package com.ruoyi.playingmethod.contract.api.request;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@@ -18,25 +16,20 @@ import jakarta.validation.constraints.Min;
|
||||
* - boxId 为空:查询全部箱子的记录
|
||||
* - boxId 不为空:仅查询当前选中箱子的记录
|
||||
*/
|
||||
@ApiModel("经典开箱记录查询参数")
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Builder
|
||||
public class ClassicBoxRecordPageRequest {
|
||||
|
||||
@ApiModelProperty("页码,默认 1")
|
||||
@Min(value = 1, message = "页码最小 1")
|
||||
private Integer page = 1;
|
||||
|
||||
@ApiModelProperty("每页条数,默认 20")
|
||||
@Range(min = 1, max = 50, message = "每页条数 1-50")
|
||||
private Integer size = 20;
|
||||
|
||||
@ApiModelProperty("选中箱子 ID:为空则查询全部箱子的记录,不为空则仅查询该箱子")
|
||||
private Integer boxId;
|
||||
|
||||
@ApiModelProperty("排序方式:0-时间降序,1-时间升序,2-价格降序,默认 0")
|
||||
@Builder.Default
|
||||
private Integer orderByFie = 0;
|
||||
}
|
||||
|
||||
-3
@@ -1,6 +1,5 @@
|
||||
package com.ruoyi.playingmethod.contract.api.request;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -15,11 +14,9 @@ public class GetRollListParamRequest {
|
||||
private Integer rollId;
|
||||
|
||||
// 0官方 1主播
|
||||
@ApiModelProperty("0官方 1主播")
|
||||
private Integer rollType;
|
||||
|
||||
// 0全部 1可参与 2我的 3已结束
|
||||
@ApiModelProperty("0全部 1可参与 2我的 3已结束")
|
||||
private Integer rollStatus;
|
||||
|
||||
private Integer userId;
|
||||
|
||||
+6
-28
@@ -33,10 +33,6 @@ import com.ruoyi.playingmethod.contract.api.request.ClassicBoxRecordPageRequest;
|
||||
import com.ruoyi.playingmethod.service.ApiBindBoxService;
|
||||
import com.ruoyi.playingmethod.service.ApiBoxRecordsService;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -46,7 +42,6 @@ import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Api(tags = "玩转盲盒模式")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/bindbox")
|
||||
@@ -79,7 +74,6 @@ public class ApiBindBoxController extends BaseController {
|
||||
@Autowired
|
||||
private RedisLock redisLock;
|
||||
|
||||
@ApiOperation("获取宝箱信息")
|
||||
@Anonymous
|
||||
@PostMapping("/boxData")
|
||||
public R<TtBoxA> getBoxData(@RequestBody BoxIdRequest request) {
|
||||
@@ -95,17 +89,12 @@ public class ApiBindBoxController extends BaseController {
|
||||
return R.ok(boxData);
|
||||
}
|
||||
|
||||
@ApiOperation("获取补偿箱信息")
|
||||
@PostMapping("/getCompBoxData")
|
||||
// [停用-前端零调用] @PostMapping("/getCompBoxData")
|
||||
public AjaxResult getCompBoxData(@RequestBody BoxIdRequest request) {
|
||||
List<TtOrnamentsA> compBoxData = bindBoxService.getCompBoxData(request.getBoxId());
|
||||
return success(compBoxData);
|
||||
}
|
||||
|
||||
@ApiOperation("获取宝箱列表")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "boxType", value = "宝箱类型(1普通箱 2对战箱 3补偿箱 4九宫格)", dataType = "String", dataTypeClass = String.class)
|
||||
})
|
||||
@Anonymous
|
||||
@PostMapping("/getBoxList")
|
||||
public R<List<TtBoxVO>> getBoxList(@RequestBody(required=false) GetBoxListRequest request) {
|
||||
@@ -123,7 +112,6 @@ public class ApiBindBoxController extends BaseController {
|
||||
/**
|
||||
* 盲盒开箱模式开箱
|
||||
*/
|
||||
@ApiOperation("盲盒开箱")
|
||||
@UpdateUserCache
|
||||
@RateLimiter(time = 60, count = 30, limitType = LimitType.IP)
|
||||
@PostMapping("/openBox")
|
||||
@@ -182,8 +170,7 @@ public class ApiBindBoxController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("获取历史开箱信息")
|
||||
@PostMapping("/getBindBoxHistory")
|
||||
// [停用-前端零调用] @PostMapping("/getBindBoxHistory")
|
||||
public R getBindBoxHistory(@RequestBody @Validated queryCondition param) {
|
||||
if (param.getStatus().equals(1) || param.getStatus().equals(10)) {
|
||||
return R.fail("非法的状态参数。");
|
||||
@@ -193,7 +180,6 @@ public class ApiBindBoxController extends BaseController {
|
||||
return R.ok(ttBoxRecordsVOS);
|
||||
}
|
||||
|
||||
@ApiOperation("获取个人历史开箱记录")
|
||||
@PostMapping("/myBoxHistory")
|
||||
public R<List<TtBoxRecordsVO>> myBoxHistory(@RequestBody queryCondition param) {
|
||||
Long userId = getUserId();
|
||||
@@ -217,8 +203,7 @@ public class ApiBindBoxController extends BaseController {
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@ApiOperation("获取当前补偿值")
|
||||
@PostMapping("/getCompValue")
|
||||
// [停用-前端零调用] @PostMapping("/getCompValue")
|
||||
public AjaxResult getCompValue(@RequestBody BoxIdRequest request) {
|
||||
Long userId = getUserId();
|
||||
TtUser ttUser = userService.getById(userId);
|
||||
@@ -230,8 +215,7 @@ public class ApiBindBoxController extends BaseController {
|
||||
return success(bindBoxService.getCompValue(ttUser, ttBox));
|
||||
}
|
||||
|
||||
@ApiOperation("盲盒top")
|
||||
@PostMapping("/top")
|
||||
// [停用-前端零调用] @PostMapping("/top")
|
||||
public R<List<TtBoxRecordsVO>> topBlinkBox() {
|
||||
Long userId = getUserId();
|
||||
if (ObjectUtil.isNull(userId)) {
|
||||
@@ -253,8 +237,7 @@ public class ApiBindBoxController extends BaseController {
|
||||
return R.ok(ttBoxRecordsVOS);
|
||||
}
|
||||
|
||||
@ApiOperation("十佳掉落")
|
||||
@PostMapping("/tenTop")
|
||||
// [停用-前端零调用] @PostMapping("/tenTop")
|
||||
public R<List<TtBoxRecordsVO>> tenTop() {
|
||||
TenTopQuery param = new TenTopQuery();
|
||||
param.setSource(Collections.singletonList(TtboxRecordSource.BLIND_BOX.getCode()));
|
||||
@@ -266,7 +249,6 @@ public class ApiBindBoxController extends BaseController {
|
||||
return R.ok(ttBoxRecordsVOS);
|
||||
}
|
||||
|
||||
@ApiOperation("今日百佳")
|
||||
@PostMapping("/todayTopHundred")
|
||||
public R<List<TtBoxRecordsVO>> todayTopHundred() {
|
||||
List<Integer> status = Arrays.asList(
|
||||
@@ -283,8 +265,7 @@ public class ApiBindBoxController extends BaseController {
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@ApiOperation("历史百佳")
|
||||
@PostMapping("/historyTopHundred")
|
||||
// [停用-前端零调用] @PostMapping("/historyTopHundred")
|
||||
public R<List<TtBoxRecordsVO>> historyTopHundred() {
|
||||
List<Integer> status = Arrays.asList(
|
||||
TtboxRecordStatus.IN_PACKSACK_ON.getCode(),
|
||||
@@ -300,7 +281,6 @@ public class ApiBindBoxController extends BaseController {
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@ApiOperation("实时 - 所有人历史开箱按时间排序")
|
||||
@Anonymous
|
||||
@PostMapping("/realtime")
|
||||
public R<List<TtBoxRecordsVO>> realtime(@RequestBody @Validated BoxRecordPageRequest request) {
|
||||
@@ -324,7 +304,6 @@ public class ApiBindBoxController extends BaseController {
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@ApiOperation("欧皇 - 所有人开箱按最高价格排序")
|
||||
@Anonymous
|
||||
@PostMapping("/luckyKing")
|
||||
public R<List<TtBoxRecordsVO>> luckyKing(@RequestBody @Validated BoxRecordPageRequest request) {
|
||||
@@ -357,7 +336,6 @@ public class ApiBindBoxController extends BaseController {
|
||||
* - 全服全部箱子:不传参数 / 不登录 → 查看所有用户的所有箱子的开箱记录
|
||||
* - 全服当前箱子:不传 userId + 传 boxId / 不登录 → 查看指定箱子的全服记录
|
||||
*/
|
||||
@ApiOperation("经典开箱记录")
|
||||
@Anonymous
|
||||
@PostMapping("/classicRecords")
|
||||
public R<List<TtBoxRecordsVO>> classicRecords(@RequestBody @Validated ClassicBoxRecordPageRequest request) {
|
||||
|
||||
+1
-5
@@ -6,8 +6,6 @@ import com.ruoyi.common.utils.PageUtils;
|
||||
import com.ruoyi.domain.dto.boxRecords.queryCondition;
|
||||
import com.ruoyi.domain.vo.boxRecords.TtBoxRecordsVO;
|
||||
import com.ruoyi.playingmethod.service.ApiBoxRecordsService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -17,7 +15,6 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "出货记录")
|
||||
@RestController
|
||||
@RequestMapping("/api/boxRecords")
|
||||
public class ApiBoxRecordsController {
|
||||
@@ -25,8 +22,7 @@ public class ApiBoxRecordsController {
|
||||
@Autowired
|
||||
private ApiBoxRecordsService apiBoxRecordsService;
|
||||
|
||||
@ApiOperation("获取历史出货记录")
|
||||
@PostMapping("/historyByCondition")
|
||||
// [停用-前端零调用] @PostMapping("/historyByCondition")
|
||||
public R getBindBoxHistory(@RequestBody @Validated queryCondition param) {
|
||||
if (param.getStatus().contains(1) || param.getStatus().contains(10)) {
|
||||
return R.fail("非法的状态参数。");
|
||||
|
||||
+2
-7
@@ -8,13 +8,10 @@ import com.ruoyi.common.core.page.PageDataInfo;
|
||||
import com.ruoyi.playingmethod.service.ApiCompoundService;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
import com.ruoyi.domain.vo.UserPackSackDataVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "合成")
|
||||
@RestController
|
||||
@RequestMapping("/api/compound")
|
||||
public class ApiCompoundController extends BaseController {
|
||||
@@ -31,8 +28,7 @@ public class ApiCompoundController extends BaseController {
|
||||
this.compoundService = compoundService;
|
||||
}
|
||||
|
||||
@ApiOperation("合成")
|
||||
@PostMapping("/compound")
|
||||
// [停用-前端零调用] @PostMapping("/compound")
|
||||
public R<UserPackSackDataVO> compound(@RequestBody List<Long> packSackIds) {
|
||||
String websiteMaintenance = sysConfigService.selectConfigByKey("websiteMaintenance");
|
||||
if ("1".equals(websiteMaintenance)) {
|
||||
@@ -46,8 +42,7 @@ public class ApiCompoundController extends BaseController {
|
||||
return compoundService.compound(packSackIds, ttUser);
|
||||
}
|
||||
|
||||
@ApiOperation("获取用户合成记录")
|
||||
@PostMapping("/getUserCompoundRecord")
|
||||
// [停用-前端零调用] @PostMapping("/getUserCompoundRecord")
|
||||
public PageDataInfo<UserPackSackDataVO> getUserCompoundRecord() {
|
||||
startPage();
|
||||
List<UserPackSackDataVO> userCompoundRecord = compoundService.getUserCompoundRecord(getUserId().intValue());
|
||||
|
||||
+7
-22
@@ -19,10 +19,6 @@ import com.ruoyi.playingmethod.contract.api.request.BoxIdRequest;
|
||||
import com.ruoyi.playingmethod.contract.api.request.OpenBoxRequest;
|
||||
import com.ruoyi.playingmethod.mapper.ApiBindBoxMapper;
|
||||
import com.ruoyi.playingmethod.service.ApiExponentService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -34,7 +30,6 @@ import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
@Api(tags = "指数盲盒")
|
||||
@RestController
|
||||
@RequestMapping("/api/exponent")
|
||||
public class ApiExponentController extends BaseController {
|
||||
@@ -57,10 +52,9 @@ public class ApiExponentController extends BaseController {
|
||||
@Autowired
|
||||
private RedisLock redisLock;
|
||||
|
||||
@ApiOperation("加入指数盲盒")
|
||||
@Anonymous
|
||||
@UpdateUserCache
|
||||
@PostMapping("/join")
|
||||
// [停用-前端零调用] @PostMapping("/join")
|
||||
public R join(@RequestBody @Validated ExponentJoinParam param) {
|
||||
TtUser ttUser = ttUserService.getById(getUserId());
|
||||
if ("0".equals(ttUser.getIsRealCheck())) {
|
||||
@@ -95,53 +89,44 @@ public class ApiExponentController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("获取宝箱列表")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "boxType", value = "宝箱类型(1普通箱 2对战箱 3补偿箱 4九宫格 5指数盲盒)", dataType = "String", dataTypeClass = String.class)
|
||||
})
|
||||
@Anonymous
|
||||
@PostMapping("/box")
|
||||
// [停用-前端零调用] @PostMapping("/box")
|
||||
public R box(@RequestBody BoxIdRequest request) {
|
||||
TtUser ttUser = ttUserService.getById(getUserId());
|
||||
return apiExponentService.box(ttUser, request.getBoxId());
|
||||
}
|
||||
|
||||
@ApiOperation("最近十期结果")
|
||||
@Anonymous
|
||||
@PostMapping("/recenttenperiod")
|
||||
// [停用-前端零调用] @PostMapping("/recenttenperiod")
|
||||
public R recenttenperiod() {
|
||||
PageUtils.clearPage();
|
||||
return apiExponentService.recenttenperiod();
|
||||
}
|
||||
|
||||
@ApiOperation("结果信息")
|
||||
@Anonymous
|
||||
@PostMapping("/info")
|
||||
// [停用-前端零调用] @PostMapping("/info")
|
||||
public R info() {
|
||||
PageUtils.clearPage();
|
||||
TtUser ttUser = ttUserService.getById(getUserId());
|
||||
return apiExponentService.info(ttUser);
|
||||
}
|
||||
|
||||
@ApiOperation("指数记录")
|
||||
@Anonymous
|
||||
@PostMapping("/records")
|
||||
// [停用-前端零调用] @PostMapping("/records")
|
||||
public R records() {
|
||||
startPage();
|
||||
TtUser ttUser = ttUserService.getById(getUserId());
|
||||
return apiExponentService.records(ttUser);
|
||||
}
|
||||
|
||||
@ApiOperation("我的箱子")
|
||||
@Anonymous
|
||||
@PostMapping("/mybox")
|
||||
// [停用-前端零调用] @PostMapping("/mybox")
|
||||
public R mybox() {
|
||||
TtUser ttUser = ttUserService.getById(getUserId());
|
||||
return apiExponentService.mybox(ttUser);
|
||||
}
|
||||
@ApiOperation("盲盒开箱")
|
||||
@UpdateUserCache
|
||||
@PostMapping("/openBox")
|
||||
// [停用-前端零调用] @PostMapping("/openBox")
|
||||
public R openBox(@RequestBody OpenBoxRequest request) {
|
||||
TtUser ttUser = ttUserService.getById(getUserId());
|
||||
if ("0".equals(ttUser.getIsRealCheck())) {
|
||||
|
||||
+8
-39
@@ -34,16 +34,15 @@ import com.ruoyi.domain.other.TtBoxVO;
|
||||
import com.ruoyi.domain.vo.ApiFightListDataVO;
|
||||
import com.ruoyi.domain.vo.FightResultDataVO;
|
||||
import com.ruoyi.domain.vo.fight.FightBoxVO;
|
||||
import com.ruoyi.domain.vo.fight.FightResultVO;
|
||||
import com.ruoyi.domain.vo.upgrade.SimpleOrnamentVO;
|
||||
import com.ruoyi.playingmethod.model.vo.ApiFightCardVo;
|
||||
import com.ruoyi.playingmethod.model.vo.ApiFightRankingVO;
|
||||
import com.ruoyi.playingmethod.model.vo.ApiFightResultVo;
|
||||
import com.ruoyi.playingmethod.service.ApiBindBoxService;
|
||||
import com.ruoyi.playingmethod.service.ApiFightService;
|
||||
import com.ruoyi.playingmethod.contract.api.request.BoxIdRequest;
|
||||
import com.ruoyi.domain.other.TtBoxA;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
@@ -58,13 +57,11 @@ import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Api(tags = "对战模式")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/fight")
|
||||
public class ApiFightController extends BaseController {
|
||||
|
||||
private final TtFightResultService fightResultService;
|
||||
private final ISysConfigService sysConfigService;
|
||||
private final TtUserService userService;
|
||||
private final ApiFightService apiFightService;
|
||||
@@ -85,12 +82,10 @@ public class ApiFightController extends BaseController {
|
||||
@Autowired
|
||||
private TtUserMapper ttUserMapper;
|
||||
|
||||
public ApiFightController(TtFightResultService fightResultService,
|
||||
ISysConfigService sysConfigService,
|
||||
public ApiFightController(ISysConfigService sysConfigService,
|
||||
TtUserService userService,
|
||||
ApiFightService apiFightService,
|
||||
RedisCache redisCache) {
|
||||
this.fightResultService = fightResultService;
|
||||
this.sysConfigService = sysConfigService;
|
||||
this.userService = userService;
|
||||
this.apiFightService = apiFightService;
|
||||
@@ -117,7 +112,6 @@ public class ApiFightController extends BaseController {
|
||||
/**
|
||||
* Step1 创建对战房间
|
||||
*/
|
||||
@ApiOperation("创建对战房间")
|
||||
@UpdateUserCache
|
||||
@PostMapping("/createFight")
|
||||
public R createFight(@Validated @RequestBody CreateFightBody createFightParam) {
|
||||
@@ -157,7 +151,6 @@ public class ApiFightController extends BaseController {
|
||||
/**
|
||||
* 复刻对战房间:复制目标房间的宝箱配置、人数、组队模式等,创建一个新房间,当前用户成为房主
|
||||
*/
|
||||
@ApiOperation("复刻对战房间")
|
||||
@UpdateUserCache
|
||||
@PostMapping("/copyFight")
|
||||
public R copyFight(@RequestBody FightDetailParam param) {
|
||||
@@ -196,7 +189,6 @@ public class ApiFightController extends BaseController {
|
||||
/**
|
||||
* Step2 加入房间(占座),先行HTTP
|
||||
*/
|
||||
@ApiOperation("加入对战房间")
|
||||
@PostMapping("/joinFightRoom")
|
||||
public R joinFightRoom(@RequestBody FightDetailParam param) {
|
||||
Integer fightId = param.getFightId();
|
||||
@@ -234,8 +226,7 @@ public class ApiFightController extends BaseController {
|
||||
/**
|
||||
* 退出房间
|
||||
*/
|
||||
@ApiOperation("退出房间")
|
||||
@PostMapping("/fightRoomExit")
|
||||
// [停用-前端零调用] @PostMapping("/fightRoomExit")
|
||||
public R fightRoomExit(@RequestBody FightDetailParam param) {
|
||||
Integer fightId = param.getFightId();
|
||||
String websiteMaintenance = sysConfigService.selectConfigByKey("websiteMaintenance");
|
||||
@@ -255,7 +246,6 @@ public class ApiFightController extends BaseController {
|
||||
/**
|
||||
* Step3 玩家准备游戏
|
||||
*/
|
||||
@ApiOperation("玩家准备游戏")
|
||||
@UpdateUserCache
|
||||
@PostMapping("/seatrReady")
|
||||
public R seatrReady(@RequestBody FightDetailParam param) {
|
||||
@@ -281,7 +271,6 @@ public class ApiFightController extends BaseController {
|
||||
/**
|
||||
* Step4 开始游戏(前端满人自动开始)
|
||||
*/
|
||||
@ApiOperation("开始游戏")
|
||||
@PostMapping("/fightBegin")
|
||||
public R fightBegin(@RequestBody FightDetailParam param) {
|
||||
String websiteMaintenance = sysConfigService.selectConfigByKey("websiteMaintenance");
|
||||
@@ -305,7 +294,6 @@ public class ApiFightController extends BaseController {
|
||||
/**
|
||||
* 游戏结束标记
|
||||
*/
|
||||
@ApiOperation("游戏结束标记")
|
||||
@PostMapping("/fightEnd")
|
||||
public R fightEnd(@RequestBody FightDetailParam param) {
|
||||
Integer fightId = param.getFightId();
|
||||
@@ -323,7 +311,6 @@ public class ApiFightController extends BaseController {
|
||||
/**
|
||||
* 抽奖机测试
|
||||
*/
|
||||
// @ApiOperation("抽奖机测试")
|
||||
// @GetMapping("LotteryMachineTest")
|
||||
public R LotteryMachineTest() {
|
||||
R checkLogin = checkLogin();
|
||||
@@ -337,7 +324,6 @@ public class ApiFightController extends BaseController {
|
||||
return R.ok(ornamentId);
|
||||
}
|
||||
|
||||
@ApiOperation("我参与的历史对战记录")
|
||||
@PostMapping("/fightOnMyOwn")
|
||||
public R fightOnMyOwn(@RequestBody FightOnMyOwnParam param) {
|
||||
Long userId = getUserId();
|
||||
@@ -345,7 +331,7 @@ public class ApiFightController extends BaseController {
|
||||
|
||||
param.setPlayerId(userId.intValue());
|
||||
|
||||
List<ApiFightListDataVO> list = apiFightService.getFightList(param);
|
||||
List<ApiFightCardVo> list = apiFightService.getFightList(param);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@@ -353,7 +339,6 @@ public class ApiFightController extends BaseController {
|
||||
* 快速加入对战房间 - 在本阵营(model 0=欧皇 1=非酋)内返回等待中且有空座位、
|
||||
* 总价不超过用户余额的最高价房间 id(不落座,需登录)
|
||||
*/
|
||||
@ApiOperation("快速加入对战房间")
|
||||
@UpdateUserCache
|
||||
@PostMapping("/quickJoinFightRoom")
|
||||
public R<Long> quickJoinFightRoom(@RequestBody QuickJoinFightParam param) {
|
||||
@@ -365,26 +350,22 @@ public class ApiFightController extends BaseController {
|
||||
return apiFightService.quickJoinFightRoom(userId, param != null ? param.getModel() : null);
|
||||
}
|
||||
|
||||
@ApiOperation("全服历史对战记录")
|
||||
@PostMapping("/fightOnAll")
|
||||
public R fightOnAll(@RequestBody FightOnMyOwnParam param) {
|
||||
List<ApiFightListDataVO> list = apiFightService.getFightList(param);
|
||||
List<ApiFightCardVo> list = apiFightService.getFightList(param);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@ApiOperation("历史对战详情")
|
||||
@PostMapping("/fightDetail")
|
||||
public R fightDetail(@RequestBody FightDetailParam param) {
|
||||
return apiFightService.fightDetail(param);
|
||||
}
|
||||
|
||||
@ApiOperation("获取指定记录更早的历史对战")
|
||||
@PostMapping("/earlierHistory")
|
||||
public R earlierHistory(@RequestBody FightDetailParam param) {
|
||||
return apiFightService.earlierHistory(param);
|
||||
}
|
||||
|
||||
@ApiOperation("获取对战宝箱详情")
|
||||
@PostMapping("/simpleBoxDetail")
|
||||
public PageDataInfo<SimpleOrnamentVO> simpleBoxDetail(@RequestBody Map<String, Integer> param) {
|
||||
startPage();
|
||||
@@ -393,7 +374,6 @@ public class ApiFightController extends BaseController {
|
||||
return getPageData(list);
|
||||
}
|
||||
|
||||
@ApiOperation("获取对战宝箱")
|
||||
@PostMapping("/getFightBoxList")
|
||||
@Anonymous
|
||||
public R<List<TtBoxVO>> getFightBoxList(@RequestBody(required = false) Map<String, Integer> param) {
|
||||
@@ -403,7 +383,6 @@ public class ApiFightController extends BaseController {
|
||||
return R.ok(boxData);
|
||||
}
|
||||
|
||||
@ApiOperation("获取对战列表")
|
||||
@Anonymous
|
||||
@PostMapping("/getFightList")
|
||||
public PageDataInfo<ApiFightListDataVO> getFightList(@RequestBody(required = false) Map<String, Object> param) {
|
||||
@@ -415,7 +394,6 @@ public class ApiFightController extends BaseController {
|
||||
return getPageData(list);
|
||||
}
|
||||
|
||||
@ApiOperation("获取对战大厅房间列表(HTTP)")
|
||||
@Anonymous
|
||||
@PostMapping("/hall")
|
||||
public R<Map<String, Object>> fightHall(@RequestBody(required = false) Map<String, Object> param) {
|
||||
@@ -509,28 +487,24 @@ public class ApiFightController extends BaseController {
|
||||
return R.ok(result, "所有对战房间");
|
||||
}
|
||||
|
||||
@ApiOperation("获取对战数据")
|
||||
@PostMapping("/getFightData")
|
||||
public R<ApiFightListDataVO> getFightData(@RequestBody FightDetailParam param) {
|
||||
ApiFightListDataVO apiFightListDataVO = apiFightService.getFightList(null, null, null, param.getFightId()).get(0);
|
||||
return R.ok(apiFightListDataVO);
|
||||
}
|
||||
|
||||
// @ApiOperation("获取对战结果")
|
||||
// @GetMapping("/getFightResult/{fightId}")
|
||||
// public R<FightResultDataVO> getFightResult(@PathVariable("fightId") Integer fightId) {
|
||||
// FightResultDataVO fightResultDataVO = fightResultService.getFightResult(fightId);
|
||||
// return R.ok(fightResultDataVO);
|
||||
// }
|
||||
|
||||
@ApiOperation("获取对战结果")
|
||||
@PostMapping("/getFightResult")
|
||||
public R<FightResultVO> getFightResult(@RequestBody FightDetailParam param) {
|
||||
FightResultVO fightResultVO = fightResultService.getFightResult(param.getFightId());
|
||||
public R<ApiFightResultVo> getFightResult(@RequestBody FightDetailParam param) {
|
||||
ApiFightResultVo fightResultVO = apiFightService.getFightResultForClient(param.getFightId());
|
||||
return R.ok(fightResultVO);
|
||||
}
|
||||
|
||||
@ApiOperation("存储对战回合数据")
|
||||
@PostMapping("/saveFightBoutData")
|
||||
public R<Boolean> saveFightBoutData(@RequestBody FightBoutData fightBoutData) {
|
||||
R checkLogin = checkLogin();
|
||||
@@ -540,7 +514,6 @@ public class ApiFightController extends BaseController {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@ApiOperation("获取对战回合数")
|
||||
@PostMapping("/getFightBoutNum")
|
||||
public R<Integer> getFightBoutNum(@RequestBody FightDetailParam param) {
|
||||
Integer fightId = param.getFightId();
|
||||
@@ -580,7 +553,6 @@ public class ApiFightController extends BaseController {
|
||||
return R.ok(fightResultDataVO);
|
||||
}
|
||||
|
||||
@ApiOperation("获取对战排行榜")
|
||||
@Anonymous
|
||||
@PostMapping("/fightRanking")
|
||||
public AjaxResult getFightRanking() {
|
||||
@@ -605,14 +577,12 @@ public class ApiFightController extends BaseController {
|
||||
return AjaxResult.success(map);
|
||||
}
|
||||
|
||||
@ApiOperation("十佳对战, 1:最大金额,2:最大增长,3:最大倍数")
|
||||
@Anonymous
|
||||
@PostMapping("/tenTopFight")
|
||||
public AjaxResult tenTopFight(@RequestBody BaiJiaFightParam param) {
|
||||
return AjaxResult.success(apiFightService.tenTopFight(param.getMaxType(), param.getModel(), param.getMinPrice(), param.getMaxPrice(), param.getKeyword()));
|
||||
}
|
||||
|
||||
@ApiOperation("邀请机器人加入对战房间")
|
||||
@PostMapping({"/joinFightRoomForRobot"})
|
||||
public R joinFightRoomForRobot(@RequestBody FightDetailParam param) {
|
||||
R checkLogin = checkLogin();
|
||||
@@ -653,7 +623,6 @@ public class ApiFightController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("对战宝箱详情")
|
||||
@Anonymous
|
||||
@PostMapping("/boxData")
|
||||
public R<TtBoxA> getFightBoxData(@RequestBody BoxIdRequest request) {
|
||||
|
||||
+1
-5
@@ -18,8 +18,6 @@ import com.ruoyi.domain.vo.fight.FightBoxVO;
|
||||
import com.ruoyi.domain.vo.fight.FightResultVO;
|
||||
import com.ruoyi.playingmethod.contract.api.request.FightRoomInfoRequest;
|
||||
import com.ruoyi.playingmethod.service.ApiFightService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -39,7 +37,6 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 对战房间 HTTP 接口(原 WsFightRoom WebSocket 接口的 HTTP 替代)
|
||||
*/
|
||||
@Api(tags = "对战房间HTTP接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/fight/room")
|
||||
@@ -60,8 +57,7 @@ public class ApiFightRoomController extends BaseController {
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
@ApiOperation("获取对战房间信息/结果")
|
||||
@PostMapping("/info")
|
||||
// [停用-前端零调用] @PostMapping("/info")
|
||||
public R<Object> info(@RequestBody FightRoomInfoRequest request) {
|
||||
Long userId = getUserId();
|
||||
Integer fightId = request.getFightId();
|
||||
|
||||
+3
-13
@@ -21,8 +21,6 @@ import com.ruoyi.playingmethod.service.ApiLuckyUpgradeService;
|
||||
import com.ruoyi.playingmethod.service.ApiUpgradeRecordService;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
import com.ruoyi.user.service.ApiUserPackSackService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -32,7 +30,6 @@ import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "幸运升级模式")
|
||||
@RestController
|
||||
@RequestMapping("/api/luckyUpgrade")
|
||||
public class ApiLuckyUpgradeController extends BaseController {
|
||||
@@ -66,7 +63,6 @@ public class ApiLuckyUpgradeController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("获取可升级的饰品列表")
|
||||
@Anonymous
|
||||
@PostMapping("/getOrnamentsList")
|
||||
public R<List<ApiLuckyOrnamentsDataVO>> getOrnamentsList(@RequestBody ApiLuckyUpgradeBody apiLuckyUpgradeBody){
|
||||
@@ -89,7 +85,6 @@ public class ApiLuckyUpgradeController extends BaseController {
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@ApiOperation("幸运升级")
|
||||
@UpdateUserCache
|
||||
@PostMapping("/upgrade")
|
||||
public R upgrade(@RequestBody @Validated UpgradeBodyA upgradeParam){
|
||||
@@ -109,14 +104,12 @@ public class ApiLuckyUpgradeController extends BaseController {
|
||||
return apiLuckyUpgradeService.upgrade(ttUser, upgradeParam);
|
||||
}
|
||||
|
||||
@ApiOperation("获取幸运升级历史记录")
|
||||
@PostMapping("/getUpgradeRecord")
|
||||
// [停用-前端零调用] @PostMapping("/getUpgradeRecord")
|
||||
public R getUpgradeRecord(@RequestBody @Validated UpgradeCondition param){
|
||||
return upgradeRecordService.historyDetail(param);
|
||||
}
|
||||
|
||||
@ApiOperation("获取幸运升级十佳记录")
|
||||
@PostMapping("/tenTopUpgradeRecord")
|
||||
// [停用-前端零调用] @PostMapping("/tenTopUpgradeRecord")
|
||||
public R tenTopUpgradeRecord(@RequestBody(required = false) TenTopUpgradeRequest request){
|
||||
Boolean isVictory = (request == null) ? null : request.getIsVictory();
|
||||
R result = upgradeRecordService.tenTopDetail(isVictory);
|
||||
@@ -134,8 +127,7 @@ public class ApiLuckyUpgradeController extends BaseController {
|
||||
return result;
|
||||
}
|
||||
|
||||
@ApiOperation("获取个人幸运升级历史记录列表")
|
||||
@PostMapping("/myHistoryRecord")
|
||||
// [停用-前端零调用] @PostMapping("/myHistoryRecord")
|
||||
public R myHistoryRecord(@RequestBody(required = false) @Validated MyUpgradeRecordRequest request){
|
||||
R check = checkLogin();
|
||||
if (!check.getCode().equals(200)) {
|
||||
@@ -148,7 +140,6 @@ public class ApiLuckyUpgradeController extends BaseController {
|
||||
return upgradeRecordService.myHistoryRecord(userId, request);
|
||||
}
|
||||
|
||||
@ApiOperation("获取当前饰品最近100条拉取记录(含用户头像、概率、饰品全名、磨损度、品质图、图片、价格)")
|
||||
@PostMapping("/recentPulls")
|
||||
public R<List<ApiLuckyUpgradeRecentPullVO>> recentPulls(@RequestBody @Validated UpgradeCondition param) {
|
||||
if (param.getUpgradeRecordId() == null) {
|
||||
@@ -158,7 +149,6 @@ public class ApiLuckyUpgradeController extends BaseController {
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@ApiOperation("幸运升级记录分页(scope: 0全服/1我的;itemScope: 0全部饰品/1当前饰品;均需登录)")
|
||||
@PostMapping("/recordPage")
|
||||
public R recordPage(@RequestBody @Validated UpgradeRecordPageRequest req) {
|
||||
// 记录页无论全服/我的均需登录
|
||||
|
||||
-8
@@ -15,8 +15,6 @@ import com.ruoyi.playingmethod.contract.api.request.GetRedPackRequest;
|
||||
import com.ruoyi.playingmethod.service.ApiRedPackService;
|
||||
import com.ruoyi.thirdparty.wechat.domain.PtLoginUser;
|
||||
import com.ruoyi.thirdparty.wechat.service.ApiTokenService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -29,7 +27,6 @@ import java.util.List;
|
||||
@Deprecated
|
||||
@RestController
|
||||
@RequestMapping("/api/redPackData")
|
||||
@Api(tags = "红包")
|
||||
public class ApiRedPackContoller extends BaseController {
|
||||
|
||||
@Autowired
|
||||
@@ -42,7 +39,6 @@ public class ApiRedPackContoller extends BaseController {
|
||||
// @PostMapping("/getRedPackList")
|
||||
@UserPermission
|
||||
@NoRepeatSubmit
|
||||
@ApiOperation(value = "获取红包列表")
|
||||
public TableDataInfo getRedPackList(HttpServletRequest request, @RequestBody GetRedPackListRequest getRedPackListRequest) {
|
||||
PtLoginUser user = tokenService.getLoginUser(request);
|
||||
|
||||
@@ -57,7 +53,6 @@ public class ApiRedPackContoller extends BaseController {
|
||||
// @PostMapping("/getRedPack")
|
||||
@UserPermission
|
||||
@NoRepeatSubmit
|
||||
@ApiOperation(value = "领取红包")
|
||||
public AjaxResult getRedPack(@RequestBody GetRedPackRequest request) {
|
||||
Long userId = getUserId();
|
||||
return redPackService.getRedPack(userId, request.getRedPackId());
|
||||
@@ -67,7 +62,6 @@ public class ApiRedPackContoller extends BaseController {
|
||||
// @PostMapping("/getRedPackByKey")
|
||||
@UserPermission
|
||||
@NoRepeatSubmit
|
||||
@ApiOperation(value = "根据红包口令兑换红包")
|
||||
public AjaxResult getRedPackByKey(@RequestBody GetRedPackByKeyRequest request) {
|
||||
LoginUser loginUser = getLoginUser();
|
||||
if (request.getRedPackKey() == null || "".equals(request.getRedPackKey())) {
|
||||
@@ -80,7 +74,6 @@ public class ApiRedPackContoller extends BaseController {
|
||||
// @PostMapping("/getActivityDataHis")
|
||||
@UserPermission
|
||||
@NoRepeatSubmit
|
||||
@ApiOperation(value = "查询参与的红包活动记录")
|
||||
public TableDataInfo getBoxDataHis(HttpServletRequest request) {
|
||||
PtLoginUser user = tokenService.getLoginUser(request);
|
||||
startPage();
|
||||
@@ -93,7 +86,6 @@ public class ApiRedPackContoller extends BaseController {
|
||||
// @PostMapping("/getRedPackDataDetail")
|
||||
@UserPermission
|
||||
@NoRepeatSubmit
|
||||
@ApiOperation(value = "查询历史记录")
|
||||
public AjaxResult getRedPackDataDetail(HttpServletRequest request, @RequestBody GetRedPackDetailRequest getRedPackDetailRequest) {
|
||||
PtLoginUser user = tokenService.getLoginUser(request);
|
||||
return redPackService.getRedPackDataDetail(user, getRedPackDetailRequest.getRecordId());
|
||||
|
||||
+1
-5
@@ -7,8 +7,6 @@ import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.framework.web.service.TokenService;
|
||||
import com.ruoyi.playingmethod.model.body.SynthesizeRequest;
|
||||
import com.ruoyi.playingmethod.service.IApiReplacementRecordService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@@ -26,15 +24,13 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/replacementRecord")
|
||||
@Api(tags = "汰换记录")
|
||||
public class ApiReplacementRecordController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private IApiReplacementRecordService ttReplacementRecordService;
|
||||
|
||||
@PostMapping("/synthesizeItems")
|
||||
// [停用-前端零调用] @PostMapping("/synthesizeItems")
|
||||
@UserPermission
|
||||
@ApiOperation("汰换饰品")
|
||||
public AjaxResult synthesizeItems(@RequestBody SynthesizeRequest synthesizeRequest) {
|
||||
LoginUser loginUser = getLoginUser();
|
||||
return ttReplacementRecordService.synthesizeItems(loginUser, synthesizeRequest.getBoIds());
|
||||
|
||||
+2
-14
@@ -24,9 +24,6 @@ import com.ruoyi.playingmethod.service.ApiRollService;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
import com.ruoyi.domain.vo.RollDetailsDataVO;
|
||||
import com.ruoyi.domain.vo.RollListDataVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -42,7 +39,6 @@ import jakarta.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "ROLL房模式")
|
||||
@RestController
|
||||
@RequestMapping("/api/roll")
|
||||
public class ApiRollController extends BaseController {
|
||||
@@ -69,7 +65,6 @@ public class ApiRollController extends BaseController {
|
||||
private String rollPassword;
|
||||
}
|
||||
|
||||
@ApiOperation("加入 ROLL 房")
|
||||
@RepeatSubmit(message = "操作过于频繁,请稍后重试!")
|
||||
@PostMapping("/joinRoll")
|
||||
public R joinRoll(@RequestBody @Validated JoinRollParam param) {
|
||||
@@ -91,7 +86,6 @@ public class ApiRollController extends BaseController {
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("获取ROLL房列表")
|
||||
@Anonymous
|
||||
@PostMapping("/getRollList")
|
||||
public TableDataInfo getRollList(@RequestBody GetRollListParamRequest param) {
|
||||
@@ -119,33 +113,28 @@ public class ApiRollController extends BaseController {
|
||||
return getPageData(list);
|
||||
}
|
||||
|
||||
@ApiOperation("获取ROLL房详情")
|
||||
@PostMapping("/getRollDetails")
|
||||
public R<RollDetailsDataVO> getRollDetails(@RequestBody RollIdRequest request) {
|
||||
Long userId = getUserId();
|
||||
return apiRollService.getRollDetails(request.getRollId(), userId);
|
||||
}
|
||||
|
||||
@ApiOperation("获取ROLL房参与人员详情")
|
||||
@PostMapping("/getRollPlayers")
|
||||
public R<List<RollUserVO>> getRollPlayers(@RequestBody @Validated GetRollPlayersParam param) {
|
||||
return apiRollService.getRollPlayers(param);
|
||||
}
|
||||
|
||||
@ApiOperation("获取ROLL房奖池详情")
|
||||
@PostMapping("/getRollPrizePool")
|
||||
public R<List<RollJackpotOrnamentsVO>> getRollPrizePool(@RequestBody @Validated GetRollPrizePool param) {
|
||||
return apiRollService.getRollPrizePool(param);
|
||||
}
|
||||
|
||||
@ApiOperation("获取ROLL开奖详情")
|
||||
@PostMapping("/getRollOpenPrize")
|
||||
public R<List<TtBoxRecordsVO>> getRollOpenPrize(@RequestBody @Validated GetRollOpenPrizeParam param) {
|
||||
return apiRollService.getRollOpenPrize(param);
|
||||
}
|
||||
|
||||
@ApiOperation("开奖测试,正式环境删除")
|
||||
@PostMapping("/endRoll")
|
||||
// [停用-前端零调用] @PostMapping("/endRoll")
|
||||
public R endRoll(@RequestBody RollIdRequest request){
|
||||
// TODO: 移除或添加管理员权限校验
|
||||
return apiRollService.endROLL(request.getRollId());
|
||||
@@ -176,8 +165,7 @@ public class ApiRollController extends BaseController {
|
||||
return "1";
|
||||
}
|
||||
|
||||
@ApiOperation("roll房间号搜索")
|
||||
@PostMapping("/searchRollId")
|
||||
// [停用-前端零调用] @PostMapping("/searchRollId")
|
||||
public TableDataInfo searchRoll(@RequestBody RollIdRequest request){
|
||||
GetRollListParamRequest param = new GetRollListParamRequest();
|
||||
param.setRollId(request.getRollId());
|
||||
|
||||
-2
@@ -4,7 +4,6 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.playingmethod.entity.TtAttendanceRecord;
|
||||
import com.ruoyi.playingmethod.service.IApiAttendanceRecordService;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -12,7 +11,6 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "签到记录")
|
||||
@RestController
|
||||
@RequestMapping("/api/attendanceRecord")
|
||||
public class ApiTtAttendanceRecordController extends BaseController {
|
||||
|
||||
+1
-6
@@ -5,14 +5,11 @@ import com.ruoyi.admin.service.TtUserAvatarService;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.domain.other.TtUserAvatar;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Api(tags = "用户头像")
|
||||
@RestController
|
||||
@RequestMapping("/api/userAvatar")
|
||||
public class ApiUserAvatarController extends BaseController {
|
||||
@@ -23,8 +20,7 @@ public class ApiUserAvatarController extends BaseController {
|
||||
this.userAvatarService = userAvatarService;
|
||||
}
|
||||
|
||||
@ApiOperation("用户头像列表")
|
||||
@PostMapping("/list")
|
||||
// [停用-前端零调用] @PostMapping("/list")
|
||||
public R<List<TtUserAvatar>> list() {
|
||||
LambdaQueryWrapper<TtUserAvatar> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(TtUserAvatar::getStatus, "0")
|
||||
@@ -33,7 +29,6 @@ public class ApiUserAvatarController extends BaseController {
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@ApiOperation("获取头像图片资源路径列表")
|
||||
@PostMapping("/images")
|
||||
public R<List<String>> getAvatarImages() {
|
||||
LambdaQueryWrapper<TtUserAvatar> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
+4
-14
@@ -15,16 +15,12 @@ import com.ruoyi.playingmethod.contract.api.request.OpenWelfareBoxRequest;
|
||||
import com.ruoyi.playingmethod.model.ApiWelfare;
|
||||
import com.ruoyi.playingmethod.service.ApiWelfareService;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Api(tags = "福利")
|
||||
@RestController
|
||||
@RequestMapping("/api/welfare")
|
||||
public class ApiWelfareController extends BaseController {
|
||||
@@ -41,10 +37,7 @@ public class ApiWelfareController extends BaseController {
|
||||
@Autowired
|
||||
private TtUserService userService;
|
||||
|
||||
@ApiOperation("获取福利列表")
|
||||
@ApiResponse(code = 200, message = "eligible【是否具备领取条件(0否 1是)】" +
|
||||
"<br>claimStatus【领取状态(0未领取 1已领取)】")
|
||||
@PostMapping("/getWelfareList")
|
||||
// [停用-前端零调用] @PostMapping("/getWelfareList")
|
||||
public TableDataInfo getWelfareList() {
|
||||
startPage();
|
||||
Long userId = getUserId();
|
||||
@@ -52,8 +45,7 @@ public class ApiWelfareController extends BaseController {
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@ApiOperation("领取福利")
|
||||
@PostMapping("/claimWelfare")
|
||||
// [停用-前端零调用] @PostMapping("/claimWelfare")
|
||||
public AjaxResult claimWelfare(@RequestBody ClaimWelfareRequest request) {
|
||||
Long userId = getUserId();
|
||||
// 检查福利是否存在
|
||||
@@ -82,8 +74,7 @@ public class ApiWelfareController extends BaseController {
|
||||
return AjaxResult.success(openBoxVO);
|
||||
}
|
||||
|
||||
@ApiOperation("每日领取福利箱子")
|
||||
@PostMapping("/claimDailyBox")
|
||||
// [停用-前端零调用] @PostMapping("/claimDailyBox")
|
||||
public R<?> claimDailyBox() {
|
||||
Long userId = getUserId();
|
||||
try {
|
||||
@@ -94,8 +85,7 @@ public class ApiWelfareController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("批量开启福利箱子(1-15个)")
|
||||
@PostMapping("/openBoxes")
|
||||
// [停用-前端零调用] @PostMapping("/openBoxes")
|
||||
public R<?> openBoxes(@RequestBody @Validated OpenWelfareBoxRequest request) {
|
||||
Long userId = getUserId();
|
||||
String bindBoxMaintenance = sysConfigService.selectConfigByKey("bindBoxMaintenance");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user