package com.supervision.controller; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.net.NetUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObjectIter; import cn.hutool.json.JSONUtil; import com.supervision.constant.UserTokenConstant; import com.supervision.exception.BusinessException; import com.supervision.model.User; import com.supervision.pojo.vo.LoginReqVO; import com.supervision.pojo.vo.LoginResVO; import com.supervision.pojo.vo.UserInfoReqVo; import com.supervision.pojo.vo.UserInfoResVo; import com.supervision.service.UserManageService; import com.supervision.service.UserService; import com.supervision.websocket.dto.UserWebSocketDTO; import com.supervision.websocket.UserResourceCheck; import com.supervision.util.TokenUtil; import com.supervision.util.UserUtil; import com.supervision.websocket.dto.WebSocketLoginDTO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.apache.xmlbeans.impl.common.IOUtil; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ScanOptions; import org.springframework.web.bind.annotation.*; import java.io.IOException; import java.time.LocalDateTime; import java.util.Map; import java.util.Optional; @Api(tags = "用户管理") @RestController @RequestMapping("user") @RequiredArgsConstructor public class UserController { private final UserService userService; private final RedisTemplate redisTemplate; private final UserManageService userManageService; private final UserResourceCheck userResourceCheck; @Value("${ws.nginx-ip:}") private String wsIp; @Value("${ws.nginx-port:}") private String wsPort; @Value("${spring.profiles.active}") private String active; @Value("${server.port}") private String port; @ApiOperation("登录") @PostMapping("login") public LoginResVO login(@RequestBody LoginReqVO reqVO) { if (!StrUtil.isAllNotBlank(reqVO.getUserAccount(), reqVO.getPassword())) { throw new BusinessException("用户名不能为空"); } Optional user = userService.lambdaQuery().eq(User::getAccount, reqVO.getUserAccount()).last("limit 1").oneOpt(); if (!user.isPresent() || !user.get().getPassword().equals(reqVO.getPassword())) { throw new BusinessException("用户名或密码有误!"); } // 更新用户最近的登录时间 user.get().setRecentLoginTime(LocalDateTime.now()); userService.updateById(user.get()); String token = TokenUtil.creatToken(JSONUtil.toJsonStr(user.get())); LoginResVO loginResVO = BeanUtil.toBean(user.get(), LoginResVO.class); loginResVO.setToken(token); return loginResVO; } @ApiOperation("踢用户下线") @GetMapping("kickUser") public void kickUser(String uuid, String userId) throws IOException { if (StrUtil.isNotBlank(uuid)) { redisTemplate.convertAndSend(UserTokenConstant.KICK_CHANNEL, JSONUtil.toJsonStr(new UserWebSocketDTO(uuid))); } else { ScanOptions options = ScanOptions.scanOptions() .match("*" + userId + "*") // 可选:使用模式匹配指定要匹配的键 .count(10) // 可选:指定每次迭代返回的元素数量 .build(); Cursor> cursor = null; try { cursor = redisTemplate.opsForHash().scan(UserTokenConstant.USER_WEBSOCKET_CACHE, options); while (cursor.hasNext()) { Map.Entry entry = cursor.next(); Object value = entry.getValue(); WebSocketLoginDTO bean = JSONUtil.toBean(String.valueOf(value), WebSocketLoginDTO.class); if (userId.equals(bean.getUserId())) { redisTemplate.convertAndSend(UserTokenConstant.KICK_CHANNEL, JSONUtil.toJsonStr(new UserWebSocketDTO(bean.getUserId()))); } } } catch (Exception e) { if (ObjectUtil.isNotNull(cursor)) { cursor.close(); } } } } @ApiOperation("查看资源是否有剩余") @GetMapping("resourceIsFree") public boolean resourceIsFree() { return userResourceCheck.achieveDiagnoseResource(); } @ApiOperation("修改用户信息") @PutMapping("updateUserInfo") public boolean updateUserInfo(@RequestBody UserInfoReqVo userInfo) { return userManageService.updateUserInfo(userInfo); } @ApiOperation("查看账号信息") @GetMapping("getUserAccountInfo") public UserInfoResVo getUserAccountInfo() { User user = UserUtil.getUser(); return userManageService.getUserAccountInfo(user.getId()); } @ApiOperation("获取本机IP地址,用来给websocket使用") @GetMapping("queryWebSocketUrl") public String queryWebSocketUrl() { // 如果是本地开发环境,则获取本机IP地址 if ("local".equals(active)) { String template = "ws://{}:{}/virtual-patient/"; String localhostStr = NetUtil.getLocalhostStr(); return StrUtil.format(template, localhostStr, port); } else { String template = "wss://{}:{}/virtual-patient-websocket/"; if (StrUtil.isNotBlank(wsIp) && StrUtil.isNotBlank(wsPort)) { return StrUtil.format(template, wsIp, wsPort); } } throw new BusinessException("未获取到ws的nginx地址,请确认配置文件是否配置"); } @ApiOperation("获取当前在线的用户") @GetMapping("queryCurrentOnlineUser") public Map queryCurrentOnlineUser() { return redisTemplate.opsForHash().entries(UserTokenConstant.USER_WEBSOCKET_CACHE); } }