前台用户 重构
This commit is contained in:
parent
1596e6fc33
commit
ac7864f34b
@ -0,0 +1,194 @@
|
|||||||
|
package org.jeecg.modules.aiol.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
|
import org.jeecg.common.system.util.JwtUtil;
|
||||||
|
import org.jeecg.common.system.vo.DictModel;
|
||||||
|
import org.jeecg.common.util.PasswordUtil;
|
||||||
|
import org.jeecg.common.util.RedisUtil;
|
||||||
|
import org.jeecg.config.shiro.IgnoreAuth;
|
||||||
|
import org.jeecg.modules.aiol.dto.TeacherInfo;
|
||||||
|
import org.jeecg.modules.aiol.dto.UserInfoResponse;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolUserInfo;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolUserInfoMapper;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolUserInfoService;
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
import org.jeecg.modules.system.service.ISysUserService;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Tag(name = "前台用户")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/aiol/aiolUser")
|
||||||
|
@Slf4j
|
||||||
|
public class AiolUserController {
|
||||||
|
@Autowired
|
||||||
|
private ISysUserService sysUserService;
|
||||||
|
@Autowired
|
||||||
|
private RedisUtil redisUtil;
|
||||||
|
@Autowired
|
||||||
|
private IAiolUserInfoService userBizService;
|
||||||
|
@Autowired
|
||||||
|
private AiolUserInfoMapper userInfoMapper;
|
||||||
|
@Autowired
|
||||||
|
private ISysBaseAPI sysBaseApi;
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
@Operation(summary = "用户登录")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<JSONObject> login(@RequestBody Map<String, String> user, HttpServletRequest request) {
|
||||||
|
Result<JSONObject> result = new Result<JSONObject>();
|
||||||
|
String username = user.get("username");
|
||||||
|
String password = user.get("password");
|
||||||
|
if (isLoginFailOvertimes(username)) {
|
||||||
|
return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// step.2 校验用户是否存在且有效
|
||||||
|
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysUser::getUsername, username);
|
||||||
|
SysUser sysUser = sysUserService.getOne(queryWrapper);
|
||||||
|
Result<?> checkResult = sysUserService.checkUserIsEffective(sysUser);
|
||||||
|
if (!checkResult.isSuccess()) {
|
||||||
|
return result.error500(checkResult.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// step.3 校验用户名或密码是否正确
|
||||||
|
String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
|
||||||
|
String syspassword = sysUser.getPassword();
|
||||||
|
if (!syspassword.equals(userpassword)) {
|
||||||
|
addLoginFailOvertimes(username);
|
||||||
|
result.error500("用户名或密码错误");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// step.4 登录成功获取用户信息
|
||||||
|
JSONObject obj = new JSONObject(new LinkedHashMap<>());
|
||||||
|
// 1.生成token
|
||||||
|
String token = JwtUtil.sign(username, syspassword);
|
||||||
|
// 设置token缓存有效时间
|
||||||
|
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||||
|
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
|
||||||
|
obj.put("token", token);
|
||||||
|
|
||||||
|
// TODO 查询用户信息
|
||||||
|
|
||||||
|
result.setResult(obj);
|
||||||
|
result.success("登录成功");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录失败超出次数5 返回true
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isLoginFailOvertimes(String username) {
|
||||||
|
String key = CommonConstant.LOGIN_FAIL + username;
|
||||||
|
Object failTime = redisUtil.get(key);
|
||||||
|
if (failTime != null) {
|
||||||
|
Integer val = Integer.parseInt(failTime.toString());
|
||||||
|
if (val > 5) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录登录失败次数
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
*/
|
||||||
|
private void addLoginFailOvertimes(String username) {
|
||||||
|
String key = CommonConstant.LOGIN_FAIL + username;
|
||||||
|
Object failTime = redisUtil.get(key);
|
||||||
|
Integer val = 0;
|
||||||
|
if (failTime != null) {
|
||||||
|
val = Integer.parseInt(failTime.toString());
|
||||||
|
}
|
||||||
|
// 10分钟,一分钟为60s
|
||||||
|
redisUtil.set(key, ++val, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/all_teachers")
|
||||||
|
@Operation(summary = "查询师资力量", description = "categoryId为all则查询全部")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<TeacherInfo>> queryAllTeachers(@RequestParam("categoryId") String categoryId) {
|
||||||
|
List<TeacherInfo> list = userBizService.queryAllTeachers(categoryId);
|
||||||
|
return Result.OK(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/info")
|
||||||
|
@Operation(summary = "查询用户信息", description = "通过JWT token获取当前用户的详细信息,包括基本信息、角色和扩展信息")
|
||||||
|
public Result<UserInfoResponse> queryUserInfo(HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
// 1. 从JWT中获取用户名
|
||||||
|
String username = JwtUtil.getUserNameByToken(request);
|
||||||
|
if (username == null || username.trim().isEmpty()) {
|
||||||
|
return Result.error(401, "用户未登录或token无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据用户名查询系统用户信息
|
||||||
|
SysUser sysUser = sysUserService.getUserByName(username);
|
||||||
|
if (sysUser == null) {
|
||||||
|
return Result.error(404, "用户不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 查询用户角色
|
||||||
|
List<String> roles = sysUserService.getUserRolesSet(username).stream()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 4. 根据用户ID查询user_info表信息
|
||||||
|
AiolUserInfo userInfo = userInfoMapper.selectOne(
|
||||||
|
new QueryWrapper<AiolUserInfo>().eq("user_id", sysUser.getId()));
|
||||||
|
|
||||||
|
// 5. 构建返回结果
|
||||||
|
UserInfoResponse response = new UserInfoResponse();
|
||||||
|
|
||||||
|
// 基本用户信息
|
||||||
|
UserInfoResponse.BaseInfo baseInfo = new UserInfoResponse.BaseInfo();
|
||||||
|
BeanUtils.copyProperties(sysUser, baseInfo);
|
||||||
|
response.setBaseInfo(baseInfo);
|
||||||
|
response.setRoles(roles);
|
||||||
|
|
||||||
|
// 扩展用户信息
|
||||||
|
if (userInfo != null) {
|
||||||
|
UserInfoResponse.ExtendedInfo extendedInfo = new UserInfoResponse.ExtendedInfo();
|
||||||
|
BeanUtils.copyProperties(userInfo, extendedInfo);
|
||||||
|
response.setExtendedInfo(extendedInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.OK(response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询用户信息失败:" + e.getMessage(), e);
|
||||||
|
return Result.error(500, "查询用户信息失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/schools")
|
||||||
|
@Operation(summary = "查询学校列表")
|
||||||
|
@IgnoreAuth
|
||||||
|
public Result<List<String>> querySchools() {
|
||||||
|
List<DictModel> list = sysBaseApi.getDictItems("school_list");
|
||||||
|
List<String> schools = list.stream()
|
||||||
|
.map(d -> d.getLabel())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return Result.OK(schools);
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,11 @@
|
|||||||
package org.jeecg.modules.aiol.service;
|
package org.jeecg.modules.aiol.service;
|
||||||
|
|
||||||
|
import org.jeecg.modules.aiol.dto.TeacherInfo;
|
||||||
import org.jeecg.modules.aiol.entity.AiolUserInfo;
|
import org.jeecg.modules.aiol.entity.AiolUserInfo;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 用户信息
|
* @Description: 用户信息
|
||||||
* @Author: jeecg-boot
|
* @Author: jeecg-boot
|
||||||
@ -10,5 +13,9 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||||||
* @Version: V1.0
|
* @Version: V1.0
|
||||||
*/
|
*/
|
||||||
public interface IAiolUserInfoService extends IService<AiolUserInfo> {
|
public interface IAiolUserInfoService extends IService<AiolUserInfo> {
|
||||||
|
/**
|
||||||
|
* 师资力量
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<TeacherInfo> queryAllTeachers(String categoryId);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,30 @@
|
|||||||
package org.jeecg.modules.aiol.service.impl;
|
package org.jeecg.modules.aiol.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import org.jeecg.modules.aiol.constant.EntityLinkConst;
|
||||||
|
import org.jeecg.modules.aiol.dto.TeacherInfo;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourse;
|
||||||
|
import org.jeecg.modules.aiol.entity.AiolCourseTeacher;
|
||||||
import org.jeecg.modules.aiol.entity.AiolUserInfo;
|
import org.jeecg.modules.aiol.entity.AiolUserInfo;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolCourseMapper;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolCourseTeacherMapper;
|
||||||
|
import org.jeecg.modules.aiol.mapper.AiolEntityLinkMapper;
|
||||||
import org.jeecg.modules.aiol.mapper.AiolUserInfoMapper;
|
import org.jeecg.modules.aiol.mapper.AiolUserInfoMapper;
|
||||||
|
import org.jeecg.modules.aiol.service.IAiolEntityLinkService;
|
||||||
import org.jeecg.modules.aiol.service.IAiolUserInfoService;
|
import org.jeecg.modules.aiol.service.IAiolUserInfoService;
|
||||||
|
import org.jeecg.modules.system.entity.SysUser;
|
||||||
|
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 用户信息
|
* @Description: 用户信息
|
||||||
* @Author: jeecg-boot
|
* @Author: jeecg-boot
|
||||||
@ -15,5 +33,62 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class AiolUserInfoServiceImpl extends ServiceImpl<AiolUserInfoMapper, AiolUserInfo> implements IAiolUserInfoService {
|
public class AiolUserInfoServiceImpl extends ServiceImpl<AiolUserInfoMapper, AiolUserInfo> implements IAiolUserInfoService {
|
||||||
|
@Autowired
|
||||||
|
private AiolCourseMapper courseMapper;
|
||||||
|
@Autowired
|
||||||
|
private AiolEntityLinkMapper entityLinkMapper;
|
||||||
|
@Autowired
|
||||||
|
private IAiolEntityLinkService entityLinkBizService;
|
||||||
|
@Autowired
|
||||||
|
private AiolCourseTeacherMapper courseTeacherMapper;
|
||||||
|
@Autowired
|
||||||
|
private AiolUserInfoMapper userInfoMapper;
|
||||||
|
@Autowired
|
||||||
|
private SysUserMapper sysUserMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TeacherInfo> queryAllTeachers(String categoryId) {
|
||||||
|
// categoryId为all则查询全部
|
||||||
|
// TODO 存入redis缓存
|
||||||
|
|
||||||
|
// 1 根据课程分类,查询该分类下的课程; all 则查询全部课程
|
||||||
|
// 2 遍历课程,根据课程id查询该课程的授课教师
|
||||||
|
// 3 将授课教师信息封装成TeacherInfo对象
|
||||||
|
// 4 返回授课教师列表(去重)
|
||||||
|
|
||||||
|
// 1 根据课程分类,查询该分类下的课程
|
||||||
|
List<String> courseIds;
|
||||||
|
if ("all".equals(categoryId)) {
|
||||||
|
// 查询全部课程
|
||||||
|
List<AiolCourse> courseList = courseMapper.selectList(null);
|
||||||
|
courseIds = courseList.stream().map(AiolCourse::getId).collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
courseIds = entityLinkBizService.listTargetIds(EntityLinkConst.SourceType.COURSE_CATEGORY, categoryId, EntityLinkConst.TargetType.COURSE);
|
||||||
|
}
|
||||||
|
Set<String> teacherIds = new HashSet<>();
|
||||||
|
List<TeacherInfo> result = new ArrayList<>();
|
||||||
|
for (String courseId : courseIds) {
|
||||||
|
// 2 根据课程id查询该课程的授课教师
|
||||||
|
List<AiolCourseTeacher> courseTeachers = courseTeacherMapper.selectList(new LambdaQueryWrapper<AiolCourseTeacher>().eq(AiolCourseTeacher::getCourseId, courseId));
|
||||||
|
// 3 将授课教师信息封装成TeacherInfo对象
|
||||||
|
for (AiolCourseTeacher courseTeacher : courseTeachers) {
|
||||||
|
// 4 将授课教师信息封装成TeacherInfo对象,去重
|
||||||
|
AiolUserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<AiolUserInfo>().eq(AiolUserInfo::getUserId, courseTeacher.getTeacherId()));
|
||||||
|
SysUser sysUser = sysUserMapper.selectById(courseTeacher.getTeacherId());
|
||||||
|
TeacherInfo teacherInfo = new TeacherInfo();
|
||||||
|
teacherInfo.setId(courseTeacher.getTeacherId());
|
||||||
|
teacherInfo.setName(sysUser.getRealname());
|
||||||
|
teacherInfo.setAvatar(sysUser.getAvatar());
|
||||||
|
teacherInfo.setTitle(userInfo.getTitle());
|
||||||
|
teacherInfo.setTag(userInfo.getTag());
|
||||||
|
teacherInfo.setSortOrder(userInfo.getSortOrder());
|
||||||
|
if (!teacherIds.contains(courseTeacher.getTeacherId())) {
|
||||||
|
result.add(teacherInfo);
|
||||||
|
teacherIds.add(courseTeacher.getTeacherId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user