diff --git a/src/main/java/com/tailbet/controller/OpsController.java b/src/main/java/com/tailbet/controller/OpsController.java index 216c72b..8c1b84d 100644 --- a/src/main/java/com/tailbet/controller/OpsController.java +++ b/src/main/java/com/tailbet/controller/OpsController.java @@ -25,6 +25,9 @@ public class OpsController { */ @PostMapping("/points/add") public R addPoints(@RequestBody PointsDTO dto) { + if (!UserContext.isOps()) { + return R.fail("无权限:仅运营可操作"); + } Long operatorId = UserContext.getUserId(); pointsService.addPoints(dto.getUserId(), dto.getAmount(), IPointsService.TYPE_OPS_ADD, null, operatorId, dto.getRemark()); @@ -36,17 +39,17 @@ public class OpsController { * 减积分 */ @PostMapping("/points/sub") - public R subPoints(@RequestBody PointsDTO dto) { - Long operatorId = UserContext.getUserId(); - boolean success = pointsService.subPoints(dto.getUserId(), dto.getAmount(), - IPointsService.TYPE_OPS_SUB, null, operatorId, dto.getRemark()); - if (success) { - return R.ok(); + public R subPoints(@RequestBody PointsDTO dto) { + if (!UserContext.isOps()) { + return R.fail("无权限:仅运营可操作"); } - return R.fail("余额不足或用户不存在"); - + Long operatorId = UserContext.getUserId(); + pointsService.subPoints(dto.getUserId(), dto.getAmount(), + IPointsService.TYPE_OPS_SUB, null, operatorId, dto.getRemark()); + return R.ok(); } + /** * 拉入群 */ diff --git a/src/main/java/com/tailbet/controller/UserController.java b/src/main/java/com/tailbet/controller/UserController.java index 80edfc0..4b4e981 100644 --- a/src/main/java/com/tailbet/controller/UserController.java +++ b/src/main/java/com/tailbet/controller/UserController.java @@ -7,7 +7,9 @@ import com.tailbet.model.vo.LoginUserVo; import com.tailbet.model.vo.LoginVo; import com.tailbet.model.vo.R; import com.tailbet.model.vo.UserContext; +import com.tailbet.openim.OpenIMClient; import com.tailbet.service.IUserService; +import com.tailbet.util.JwtUtil; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -20,6 +22,8 @@ import org.springframework.web.bind.annotation.*; public class UserController { private final IUserService userService; + private final JwtUtil jwtUtil; + private final OpenIMClient openIMClient; /** * 注册 @@ -36,9 +40,13 @@ public class UserController { */ @PostMapping("/login") public R login(@RequestBody LoginDTO dto) { - String token = userService.login(dto.getUsername(), dto.getPassword()); + Long userId = userService.login(dto.getUsername(), dto.getPassword()); + String token = jwtUtil.generateToken(userId, dto.getUsername()); + String openIMToken = openIMClient.getUserToken(String.valueOf(userId)); + LoginVo vo = new LoginVo(); vo.setToken(token); + vo.setOpenIMToken(openIMToken); return R.ok("登录成功", vo); } diff --git a/src/main/java/com/tailbet/model/vo/LoginVo.java b/src/main/java/com/tailbet/model/vo/LoginVo.java index 54879b1..f87ef75 100644 --- a/src/main/java/com/tailbet/model/vo/LoginVo.java +++ b/src/main/java/com/tailbet/model/vo/LoginVo.java @@ -11,4 +11,9 @@ public class LoginVo { * token */ private String token; + + /** + * OpenIM Token + */ + private String openIMToken; } \ No newline at end of file diff --git a/src/main/java/com/tailbet/openim/OpenIMClient.java b/src/main/java/com/tailbet/openim/OpenIMClient.java index 516a30c..41716fe 100644 --- a/src/main/java/com/tailbet/openim/OpenIMClient.java +++ b/src/main/java/com/tailbet/openim/OpenIMClient.java @@ -1,5 +1,7 @@ package com.tailbet.openim; +import cn.hutool.json.JSON; +import cn.hutool.json.JSONUtil; import com.tailbet.config.OpenIMConfig; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -149,4 +151,34 @@ public class OpenIMClient { return false; } } + + /** + * 获取用户Token + */ + public String getUserToken(String userId) { + String url = config.getApiUrl() + "/auth/user_token"; + + Map body = new HashMap<>(); + body.put("userID", userId); + body.put("expireTimeSeconds", 604800); // 7天有效期 + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set("token", config.getAdminToken()); + headers.set("operationID", userId + System.currentTimeMillis()); + + HttpEntity> request = new HttpEntity<>(body, headers); + + try { + ResponseEntity response = restTemplate.postForEntity(url, request, Map.class); + log.info("getUserToken:{}", JSONUtil.toJsonStr(response.getBody())); + if (response.getBody() != null && response.getBody().get("data") != null) { + Map data = (Map) response.getBody().get("data"); + return (String) data.get("token"); + } + } catch (Exception e) { + log.error("获取OpenIM用户Token失败: userId={}, error={}", userId, e.getMessage()); + } + return null; + } } diff --git a/src/main/java/com/tailbet/service/IPointsService.java b/src/main/java/com/tailbet/service/IPointsService.java index 7bf9480..eaea4ec 100644 --- a/src/main/java/com/tailbet/service/IPointsService.java +++ b/src/main/java/com/tailbet/service/IPointsService.java @@ -24,7 +24,7 @@ public interface IPointsService { /** * 扣除积分 */ - boolean subPoints(Long userId, Long amount, String type, String bizNo, Long operatorId, String remark); + void subPoints(Long userId, Long amount, String type, String bizNo, Long operatorId, String remark); /** * 获取用户积分 diff --git a/src/main/java/com/tailbet/service/IUserService.java b/src/main/java/com/tailbet/service/IUserService.java index eb91518..ff6ea30 100644 --- a/src/main/java/com/tailbet/service/IUserService.java +++ b/src/main/java/com/tailbet/service/IUserService.java @@ -22,7 +22,7 @@ public interface IUserService extends IService { /** * 用户登录 */ - String login(String username, String password); + Long login(String username, String password); /** * 获取当前登录用户 diff --git a/src/main/java/com/tailbet/service/impl/BetServiceImpl.java b/src/main/java/com/tailbet/service/impl/BetServiceImpl.java index b4645fd..6fbaebf 100644 --- a/src/main/java/com/tailbet/service/impl/BetServiceImpl.java +++ b/src/main/java/com/tailbet/service/impl/BetServiceImpl.java @@ -95,11 +95,9 @@ public class BetServiceImpl implements IBetService { BigDecimal odds = getOdds(playType); // 扣减积分 - boolean success = pointsService.subPoints(userId, betAmount.longValue(), + pointsService.subPoints(userId, betAmount.longValue(), IPointsService.TYPE_BET, null, null, "游戏下注"); - if (!success) { - throw new RuntimeException("余额不足"); - } + // 创建注单 BetOrder bet = new BetOrder(); diff --git a/src/main/java/com/tailbet/service/impl/PointsServiceImpl.java b/src/main/java/com/tailbet/service/impl/PointsServiceImpl.java index a7d1bb9..8ba6ad2 100644 --- a/src/main/java/com/tailbet/service/impl/PointsServiceImpl.java +++ b/src/main/java/com/tailbet/service/impl/PointsServiceImpl.java @@ -62,13 +62,13 @@ public class PointsServiceImpl implements IPointsService { */ @Override @Transactional - public boolean subPoints(Long userId, Long amount, String type, String bizNo, Long operatorId, String remark) { + public void subPoints(Long userId, Long amount, String type, String bizNo, Long operatorId, String remark) { User user = userMapper.selectById(userId); if (user == null) { throw new RuntimeException("用户不存在"); } if (user.getPoints() < amount) { - return false; + throw new RuntimeException("余额不足"); } Long before = user.getPoints(); @@ -76,7 +76,7 @@ public class PointsServiceImpl implements IPointsService { // 原子扣除积分(SQL层保证余额充足才扣) int rows = userMapper.subPoints(userId, amount); if (rows == 0) { - return false; + throw new RuntimeException("积分扣除失败"); } Long after = before - amount; @@ -93,7 +93,6 @@ public class PointsServiceImpl implements IPointsService { flow.setRemark(remark); pointsFlowMapper.insert(flow); - return true; } /** diff --git a/src/main/java/com/tailbet/service/impl/RedPacketServiceImpl.java b/src/main/java/com/tailbet/service/impl/RedPacketServiceImpl.java index b78c83d..47b2045 100644 --- a/src/main/java/com/tailbet/service/impl/RedPacketServiceImpl.java +++ b/src/main/java/com/tailbet/service/impl/RedPacketServiceImpl.java @@ -61,11 +61,9 @@ public class RedPacketServiceImpl implements IRedPacketService { } // 扣积分 - boolean success = pointsService.subPoints(userId, totalAmount.longValue(), + pointsService.subPoints(userId, totalAmount.longValue(), IPointsService.TYPE_RP_SEND, null, null, "发送红包"); - if (!success) { - throw new RuntimeException("余额不足"); - } + // 创建红包 RedPacket rp = new RedPacket(); @@ -275,7 +273,8 @@ public class RedPacketServiceImpl implements IRedPacketService { try { List amounts = objectMapper.readValue(rp.getShareAmounts(), - new TypeReference>() {}); + new TypeReference>() { + }); if (amounts.isEmpty()) { return calculateReceiveAmount(rp); } diff --git a/src/main/java/com/tailbet/service/impl/UserServiceImpl.java b/src/main/java/com/tailbet/service/impl/UserServiceImpl.java index eebcbdd..a2381ca 100644 --- a/src/main/java/com/tailbet/service/impl/UserServiceImpl.java +++ b/src/main/java/com/tailbet/service/impl/UserServiceImpl.java @@ -75,7 +75,7 @@ public class UserServiceImpl extends ServiceImpl implements IU * 用户登录 */ @Override - public String login(String username, String password) { + public Long login(String username, String password) { User user = getByUsername(username); if (user == null) { throw new RuntimeException("用户不存在"); @@ -86,7 +86,7 @@ public class UserServiceImpl extends ServiceImpl implements IU if (!passwordUtil.matches(password, user.getPassword())) { throw new RuntimeException("密码错误"); } - return jwtUtil.generateToken(user.getId(), user.getUsername()); + return user.getId(); }