前端增加消息中心,优化班级管理功能

main
yuan 2 months ago
parent 52d2592278
commit dcb121523f

@ -1,14 +1,16 @@
package com.ruoyi.web.controller.system;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.*;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.vo.SysUserVo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.test.domain.DO.StudentClassDO;
import com.ruoyi.test.domain.StudentClass;
import com.ruoyi.test.seriver.IStudentClassService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
@ -66,29 +68,50 @@ public class SysRoleController extends BaseController
@Autowired
private RedisCache redisCache;
@Autowired
private IStudentClassService iStudentClassService;
@GetMapping("selectUserByStudentKey")
public R<List<StudentClassDO>> selectUserByStudentKey(){
List<SysUser> list = roleService.selectUserByRoleKey("student");
List<StudentClassDO> list1 = new ArrayList<>();
for(SysUser sysUser : list){
StudentClassDO studentClassDO = new StudentClassDO();
studentClassDO.setId(sysUser.getUserId());
studentClassDO.setName(sysUser.getUserName());
StudentClass studentClass = iStudentClassService.selectById(sysUser.getUserId());
if(studentClass!=null){
studentClassDO.setGrade(studentClass.getGrade());
studentClassDO.setClass1(studentClass.getClass1());
}
list1.add(studentClassDO);
}
return R.ok(list1);
}
@GetMapping("selectUserByRoleKey")
public List<SysUserVo> selectUserByRoleKey(String roleKey){
List<SysUser> list = roleService.selectUserByRoleKey(roleKey);
List<SysUserVo> l = new ArrayList<>();
Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
List<Long> ids = new ArrayList<>();
Map<Long,String> map = new HashMap<>();
for(String key:keys){
LoginUser user = redisCache.getCacheObject(key);
if(user.getUserId()!=null){
ids.add(user.getUserId());
if(user!=null){
map.put(user.getUserId(),user.getToken());
}
}
for(SysUser user:list){
SysUserVo sysUserVo = new SysUserVo();
BeanUtils.copyProperties(user,sysUserVo);
if(ids.contains(user.getUserId())){
if(map.containsKey(user.getUserId())){
sysUserVo.setTokenId(map.get(user.getUserId()));
sysUserVo.setOnline(1);
}else{
sysUserVo.setOnline(0);
}
l.add(sysUserVo);
}
System.out.println("======="+l);
return l;
}

@ -0,0 +1,76 @@
package com.ruoyi.web.controller.test.gl;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.test.domain.Class1;
import com.ruoyi.test.domain.DO.StudentClassDO;
import com.ruoyi.test.domain.DO.StudentClassList;
import com.ruoyi.test.domain.DO.StudentDO;
import com.ruoyi.test.seriver.IClass1Service;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
@Api(tags = "管理端班级管理")
@RestController
@RequestMapping("/gl/classManage")
public class ClassManageController {
@Autowired
private IClass1Service class1Service;
@ApiOperation("班级查询")
@GetMapping("selectClass")
public R<List<Class1>> selectClass(String name, String grade)
{
return R.ok(class1Service.selectClass1(name,grade));
}
@ApiOperation("班级学生查询")
@GetMapping("studentListByGradeAndClass1")
public R<List<StudentDO>> studentListByGradeAndClass1(String grade, String Class1)
{
return R.ok(class1Service.studentListByGradeAndClass1(grade,Class1));
}
@ApiOperation("新建班级")
@PostMapping("addClass1")
public R<Integer> addClass1(@RequestBody Class1 class1)
{
return R.ok(class1Service.addclass1(class1.getName(),class1.getGrade(),class1.getClass1(),class1.getCommand()));
}
@ApiOperation("加入班级")
@PostMapping("insertClassByStudentList")
public R<Integer> insertClassByStudentList(@RequestBody StudentClassList list)
{
for(StudentClassDO studentClassDO : list.getStudentList()){
if(studentClassDO.getGrade()!=null && studentClassDO.getClass1()!=null){
class1Service.deleteClass(studentClassDO.getId(),studentClassDO.getGrade(),studentClassDO.getClass1());
}
}
List<Long> studentList1 = list.getStudentList().stream()
.map(StudentClassDO::getId)
.collect(Collectors.toList());
return R.ok(class1Service.insertClassByStudentList(studentList1,list.getGrade(),list.getClass1()));
}
@ApiOperation("删除学生")
@DeleteMapping("deleteStudent")
public R<Integer> deleteStudent(@RequestParam Long id, @RequestParam String grade, @RequestParam String Class1)
{
return R.ok(class1Service.deleteClass(id,grade,Class1));
}
@ApiOperation("修改班级信息")
@PostMapping("updateClass")
public R<Integer> updateClass(@RequestBody Class1 class1)
{
return R.ok(class1Service.updateClass1(class1));
}
}

@ -0,0 +1,52 @@
package com.ruoyi.web.controller.test.gl;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.test.domain.DO.MessageDO;
import com.ruoyi.test.domain.DO.MessageDO1;
import com.ruoyi.test.seriver.IMessageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Api(tags = "管理端消息管理")
@RestController
@RequestMapping("/gl/message")
public class MessageController {
@Autowired
private IMessageService iMessageService;
@Autowired
private ISysRoleService roleService;
@ApiOperation("消息列表")
@GetMapping("selectMessage")
public R<List<MessageDO>> selectMessage(){
return R.ok(iMessageService.selectMessage());
}
@ApiOperation("删除消息")
@DeleteMapping("deleteMessage")
public R<Integer> deleteMessage(Long id){
return R.ok(iMessageService.deleteMessage(id));
}
@ApiOperation("获取用户")
@GetMapping("getUserList")
public R<List<SysUser>> getUserList(){
List<SysUser> list = roleService.selectUserByRoleKey("student");
list.addAll(roleService.selectUserByRoleKey("teacher"));
return R.ok(list);
}
@ApiOperation("添加消息")
@PostMapping("addMessage")
public R<Integer> addMessage(@RequestBody MessageDO1 messageDO1){
return R.ok(iMessageService.addMessage(messageDO1));
}
}

@ -1,155 +0,0 @@
package com.ruoyi.web.controller.test.gl;//package com.ruoyi.web.controller.test.gl;
//
//import com.baomidou.mybatisplus.core.metadata.IPage;
//import com.ruoyi.common.core.domain.R;
//import com.ruoyi.common.core.domain.entity.SysUser;
//import com.ruoyi.common.utils.SecurityUtils;
//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.List;
//
//@Api(tags = "管理端用户管理")
//@RestController
//@RequestMapping("/gl/users")
//public class UserController {
// @Autowired
// private IUserService iUserService;
//
// /*
// 获取学生列表
// */
// @ApiOperation("学生列表")
// @GetMapping("student")
// public R<IPage<User>> selectList(int pagenum){
// return R.ok(iUserService.selectStudentList(pagenum));
// }
// /*获取学生用户名查询查询记录
// *@param name 用户名
// */
// @ApiOperation("学生用户名查询")
// @GetMapping("/seleteStudentName")
// public R<IPage<User>> selectStudent(int pagenum,String name){
// return R.ok(iUserService.selectStudent(pagenum,name));
// }
//
// /*增加学生用户信息
// *@param name 用户名
// */
// @ApiOperation("学生添加用户")
// @PostMapping("/insertStudent")
// public R<String> inserStudent(@RequestBody UserVo userVo){
// User user = new User();
// user.setAge(userVo.getAge());
// user.setBirthday(userVo.getBirthday());
// user.setGrade(userVo.getGrade());
// user.setSex(userVo.getSex());
// user.setName(userVo.getName());
// user.setTname(userVo.getTname());
// user.setTelephone(userVo.getTelephone());
// user.setRoleKey("2");
// user.setState(0L);
// SysUser sysUser = SecurityUtils.getLoginUser().getUser();
// Long zhid = sysUser.getUserId();
// user.setZhId(zhid);
// List<User> list = iUserService.selectStudentByZhid(zhid);
// if(list.size()==0){
// if(iUserService.insertUser(user)!=0){
// return R.ok("添加成功!");
// }else{
// return R.fail("添加失败!");
// }
// }
// return R.fail("该账号已绑定用户了!");
// }
//
//
//
// @ApiOperation("教师列表")
// @GetMapping("/teacher")
// public R<IPage<User>> selectTeacher(int pagenum){
// return R.ok(iUserService.selectTeacherList(pagenum));
// }
// /*获取教师用户名查询查询记录
// *@param name 用户名
// */
// @ApiOperation("教师用户名查询")
// @GetMapping("/seleteTeacherName")
// public R<IPage<User>> selectTeacher(int pagenum,String name){
// return R.ok(iUserService.selectTeacher(pagenum,name));
// }
// /*增加教师用户信息
// *@param name 用户名
// */
// @ApiOperation("老师添加用户")
// @PostMapping("/insertTeacher")
// public R<String> insertTeacher(@RequestBody UserVo userVo){
// User user = new User();
// user.setAge(userVo.getAge());
// user.setBirthday(userVo.getBirthday());
// user.setGrade(userVo.getGrade());
// user.setSex(userVo.getSex());
// user.setName(userVo.getName());
// user.setTname(userVo.getTname());
// user.setTelephone(userVo.getTelephone());
// user.setRoleKey("3");
// user.setState(0L);
// SysUser sysUser = SecurityUtils.getLoginUser().getUser();
// Long zhid = sysUser.getUserId();
// user.setZhId(zhid);
// List<User> list = iUserService.selectStudentByZhid(zhid);
// if(list.size()==0){
// if(iUserService.insertUser(user)!=0){
// return R.ok("添加成功!");
// }else{
// return R.fail("添加失败!");
// }
// }
// return R.fail("该账号已绑定用户了!");
// }
//
// @ApiOperation("管理员列表")
// @GetMapping("/Gl")
// public R<IPage<User>> selectGl(int pagenum){
// return R.ok(iUserService.selectGlList(pagenum));
// }
// /*获取管理员用户名查询查询记录
// *@param name 用户名
// */
// @ApiOperation("管理员用户名查询")
// @GetMapping("/seleteGlName")
// public R<IPage<User>> selectGl(int pagenum,String name){
// return R.ok(iUserService.selectGl(pagenum,name));
// }
// /*增加管理员用户信息
// *@param name 用户名
// */
// @ApiOperation("管理员添加用户")
// @PostMapping("/insertGl")
// public R<String> insertGl(@RequestBody UserVo userVo){
// User user = new User();
// user.setAge(userVo.getAge());
// user.setBirthday(userVo.getBirthday());
// user.setGrade(userVo.getGrade());
// user.setSex(userVo.getSex());
// user.setName(userVo.getName());
// user.setTname(userVo.getTname());
// user.setTelephone(userVo.getTelephone());
// user.setRoleKey("4");
// user.setState(0L);
// SysUser sysUser = SecurityUtils.getLoginUser().getUser();
// Long zhid = sysUser.getUserId();
// user.setZhId(zhid);
// List<User> list = iUserService.selectStudentByZhid(zhid);
// if(list.size()==0){
// if(iUserService.insertUser(user)!=0){
// return R.ok("添加成功!");
// }else{
// return R.fail("添加失败!");
// }
// }
// return R.fail("该账号已绑定用户了!");
// }
//}

@ -76,16 +76,16 @@ public class TeacherClassController {
}
//创建后默认加入创建账号的班级中
@ApiOperation("班级创建")
@GetMapping("addclass1")
public R<String> addclass1(String name,String grade,String Class1){
if(iClass1Service.addclass1(name,grade,Class1)!=0){
SysUser sysUser = SecurityUtils.getLoginUser().getUser();
Long id = sysUser.getUserId();
iTeacherManageClassService.addclass1(id,grade,Class1);
return R.ok("创建成功!");
}
return R.fail("创建失败!");
}
// @ApiOperation("班级创建")
// @GetMapping("addclass1")
// public R<String> addclass1(String name,String grade,String Class1){
// if(iClass1Service.addclass1(name,grade,Class1)!=0){
// SysUser sysUser = SecurityUtils.getLoginUser().getUser();
// Long id = sysUser.getUserId();
// iTeacherManageClassService.addclass1(id,grade,Class1);
// return R.ok("创建成功!");
// }
// return R.fail("创建失败!");
// }
}

@ -42,4 +42,6 @@ public class SysUserVo
//是否在线
private Integer online;
private String tokenId;
}

@ -7,7 +7,7 @@ import lombok.Data;
@TableName("class1")
public class Class1 {
private long id;
private Long id;
private String name;
private String grade;

@ -0,0 +1,16 @@
package com.ruoyi.test.domain.DO;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class MessageDO {
private Long id;
private String teacherName;
private String studentName;
private String source;
private String createtime;
}

@ -0,0 +1,12 @@
package com.ruoyi.test.domain.DO;
import lombok.Data;
@Data
public class StudentClassDO {
private Long id;
private String name;
private String grade;
private String class1;
}

@ -0,0 +1,14 @@
package com.ruoyi.test.domain.DO;
import lombok.Data;
import java.util.List;
@Data
public class StudentClassList {
private List<StudentClassDO> studentList;
private String grade;
private String class1;
}

@ -0,0 +1,17 @@
package com.ruoyi.test.domain.DO;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
@Data
public class StudentDO {
private Long id;
private String name;
public StudentDO(Long id, String name) {
this.id = id;
this.name = name;
}
}

@ -2,16 +2,24 @@ package com.ruoyi.test.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.test.domain.Class1;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import java.util.List;
@Mapper
public interface Class1Mapper extends BaseMapper<Class1> {
@Update("update class1 set num = #{num} where id= #{id} ")
int updateClass(@Param("id") Long id,@Param("num") Integer num);
int addclass1(@Param("name") String name ,@Param("grade") String grade,@Param("Class1") String Class1);
int addclass1(@Param("name") String name ,@Param("grade") String grade,@Param("Class1") String Class1, @Param("command") String command);
@Delete("delete from student_class where studentid = #{id} and grade = #{grade} and Class1 = #{Class1}")
int deleteStudentClass(@Param("id") Long id,@Param("grade") String grade,@Param("Class1") String Class1);
@Update("UPDATE class1 SET name = #{class1.name}, grade = #{class1.grade}, Class1 = #{class1.class1}, command = #{class1.command} WHERE id = #{class1.id}")
int updateClass1(@Param("class1") Class1 class1);
}

@ -2,6 +2,7 @@ package com.ruoyi.test.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.test.domain.Message;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -11,4 +12,7 @@ public interface MessageMapper extends BaseMapper<Message> {
int addMessage(@Param("message") Message message);
int updateMessage(@Param("id") Long id);
@Delete("delete from message where id=#{id}")
int deleteMessage(@Param("id") Long id);
}

@ -6,10 +6,14 @@ import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface StudentClassMapper extends BaseMapper<StudentClass> {
@Delete("delete from student_class where studentid = #{id}")
int deleteStudentClass(@Param("id") Long id);
int insertClassByStudentList(@Param("studentid") Long studentid,@Param("grade") String grade, @Param("Class1")String Class1);
}

@ -1,6 +1,8 @@
package com.ruoyi.test.seriver;
import com.ruoyi.test.domain.Class1;
import com.ruoyi.test.domain.DO.StudentDO;
import io.swagger.models.auth.In;
import java.util.List;
@ -12,6 +14,15 @@ public interface IClass1Service {
int updateClass(Long id,Integer num);
int addclass1(String name,String grade,String Class1);
int addclass1(String name,String grade,String Class1,String command);
List<Class1> selectClass1(String name,String grade);
List<StudentDO> studentListByGradeAndClass1(String grade, String Class1);
Integer deleteClass(Long id,String grade,String Class1);
Integer insertClassByStudentList(List<Long> studentList1, String grade, String Class1);
int updateClass1(Class1 class1);
}

@ -1,5 +1,7 @@
package com.ruoyi.test.seriver;
import com.ruoyi.test.domain.DO.MessageDO;
import com.ruoyi.test.domain.DO.MessageDO1;
import com.ruoyi.test.domain.Message;
import com.ruoyi.test.domain.Vo.MessageVo;
@ -12,4 +14,10 @@ public interface IMessageService {
List<Message> selectById(Long id);
Integer updateMessage(Long id);
List<MessageDO> selectMessage();
int deleteMessage(Long id);
int addMessage(MessageDO1 messageDO1);
}

@ -2,13 +2,22 @@ package com.ruoyi.test.seriver.Impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import com.ruoyi.test.domain.Class1;
import com.ruoyi.test.domain.DO.StudentDO;
import com.ruoyi.test.domain.StudentClass;
import com.ruoyi.test.mapper.Class1Mapper;
import com.ruoyi.test.mapper.StudentClassMapper;
import com.ruoyi.test.seriver.IClass1Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class Class1ServiceImpl extends ServiceImpl<Class1Mapper, Class1> implements IClass1Service {
@ -16,6 +25,12 @@ public class Class1ServiceImpl extends ServiceImpl<Class1Mapper, Class1> impleme
@Autowired
private Class1Mapper class1Mapper;
@Autowired
private StudentClassMapper studentClassMapper;
@Autowired
private ISysUserService iSysUserService;
@Override
public Class1 classList(String grade, String Class) {
LambdaQueryWrapper<Class1> queryWrapper = new LambdaQueryWrapper<>();
@ -37,7 +52,56 @@ public class Class1ServiceImpl extends ServiceImpl<Class1Mapper, Class1> impleme
}
@Override
public int addclass1(String name, String grade, String Class1) {
return class1Mapper.addclass1(name,grade,Class1);
public int addclass1(String name, String grade, String Class1, String command) {
return class1Mapper.addclass1(name,grade,Class1,command);
}
@Override
public List<Class1> selectClass1(String name, String grade) {
System.out.println("name:"+name+" grade:"+grade);
LambdaQueryWrapper<Class1> queryWrapper = new LambdaQueryWrapper<>();
if (grade != null) {
queryWrapper.eq(Class1::getGrade, grade);
}
if (name != null) {
queryWrapper.like(Class1::getName, name);
}
System.out.println("========="+class1Mapper.selectList(queryWrapper));
return class1Mapper.selectList(queryWrapper);
}
@Override
public List<StudentDO> studentListByGradeAndClass1(String grade, String Class1) {
LambdaQueryWrapper<StudentClass> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StudentClass::getGrade,grade)
.eq(StudentClass::getClass1,Class1);
List<Long> list = studentClassMapper.selectList(queryWrapper)
.stream()
.map(StudentClass::getStudentid)
.collect(Collectors.toList());
List<StudentDO> studentDOList = new ArrayList<>();
for (Long aLong : list){
SysUser sysUser = iSysUserService.selectUserById(aLong);
studentDOList.add(new StudentDO(sysUser.getUserId(),sysUser.getUserName()));
}
return studentDOList;
}
@Override
public Integer deleteClass(Long id, String grade, String Class1) {
return class1Mapper.deleteStudentClass(id,grade,Class1);
}
@Override
public Integer insertClassByStudentList(List<Long> studentList1, String grade, String Class1) {
for(Long aLong : studentList1){
studentClassMapper.insertClassByStudentList(aLong,grade,Class1);
}
return 1;
}
@Override
public int updateClass1(Class1 class1) {
return class1Mapper.updateClass1(class1);
}
}

@ -2,7 +2,10 @@ package com.ruoyi.test.seriver.Impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.test.domain.DO.MessageDO;
import com.ruoyi.test.domain.DO.MessageDO1;
import com.ruoyi.test.domain.Message;
import com.ruoyi.test.domain.Vo.MessageVo;
import com.ruoyi.test.mapper.MessageMapper;
@ -11,6 +14,10 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Service
@ -47,5 +54,45 @@ public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> impl
return messageMapper.updateMessage(id);
}
@Override
public List<MessageDO> selectMessage() {
LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();
List<Message> list = messageMapper.selectList(queryWrapper);
List<MessageDO> list1 = new ArrayList<>();
for(Message message : list){
MessageDO messageDO = new MessageDO();
BeanUtils.copyProperties(message,messageDO);
LocalDateTime createtime = message.getCreatetime();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = createtime.format(formatter);
messageDO.setCreatetime(formattedDateTime);
Long teacherId = message.getTeacherId();
SysUser sysUser = iSysUserService.selectUserById(teacherId);
messageDO.setTeacherName(sysUser.getUserName());
Long studentId = message.getStudentId();
SysUser sysUser1 = iSysUserService.selectUserById(studentId);
messageDO.setStudentName(sysUser1.getUserName());
list1.add(messageDO);
}
return list1;
}
@Override
public int deleteMessage(Long id) {
return messageMapper.deleteMessage(id);
}
@Override
public int addMessage(MessageDO1 messageDO1) {
for(Long studentId : messageDO1.getList()){
Message message = new Message();
message.setStudentId(studentId);
message.setTeacherId(messageDO1.getId());
message.setSource(messageDO1.getSource());
messageMapper.addMessage(message);
}
return 1;
}
}

@ -16,9 +16,6 @@ public class QuestionTypeServiceImpl extends ServiceImpl<QuestionTypeMapper, Que
@Override
public String getQuestiontype(Long id) {
System.out.println("--------------"+id);
LambdaQueryWrapper<QuestionType> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(QuestionType::getId,id);
return questionTypeMapper.selectOne(queryWrapper).getType();

@ -11,15 +11,18 @@
grade,
Class1,
num,
command,
createtime
)values (
#{name},
#{grade},
#{Class1},
0,
#{command},
Now()
)
</insert>
</mapper>

@ -4,4 +4,13 @@
<!--namespace命名空间要有唯一的值要求使用dao接口的权限定名称一个dao接口对应一个mappernamespace指明对应哪个dao接口-->
<mapper namespace="com.ruoyi.test.mapper.StudentClassMapper">
<!-- 所有的数据库操作都要写在mapper标签中可以使用特定的标签表示数据库中的特定操作 -->
<insert id="insertClassByStudentList" parameterType="map">
<![CDATA[
INSERT INTO student_class (studentid, grade, class1,addtime)
VALUES (#{studentid}, #{grade}, #{Class1}, now())
]]>
</insert>
</mapper>

@ -76,30 +76,28 @@ export default {
});
if (response.data.code === 200) {
const res = await axios.get('http://localhost:8080/getInfo',{
method: 'GET',
headers: {
'Authorization': response.data.token,
'Content-Type': 'application/json',
}});
console.log(res);
if(res.data.code==200){
const token = response.data.token;
const userId = res.data.user.userId;
this.$store.dispatch('setToken', { userId, token });
await this.$store.dispatch('setToken', {userId, token});
if(res.data.roles[0] === 'student'){
this.$router.push({
await this.$router.push({
path: '/user/profile',
query: { userId: userId }
query: {userId: userId}
});
}else if(res.data.roles[0] === 'teacher'){
this.$router.push({
await this.$router.push({
path: '/teacher/homePage',
query: { userId: userId }
query: {userId: userId}
});
}else if(res.data.roles[0] === 'gl'){
this.$router.push({
await this.$router.push({
path: '/gl/userCenter',
query: {userId: userId}
});

@ -20,7 +20,7 @@
</div>
<div class="logout-container">
<span class="logout-btn" @click="logout">退</span>
<span class="logout-btn" @click="logout()">退</span>
</div>
</div>
</template>
@ -42,6 +42,7 @@ export default {
},
created() {
this.userId = this.$route.query.userId;
console.log('userId:', this.userId);
this.sss();
},
methods: {
@ -59,7 +60,7 @@ export default {
'Content-Type': 'application/json',
},
})
console.log(response);
console.log("====="+this.userId);
await this.$store.dispatch("clearToken", this.userId); // Vuex
this.$message.success("退出成功!");
await this.$router.push("/login"); //

@ -4,7 +4,7 @@
<span :class="collapseBtnClass" class="collapse-icon" @click="collapse"></span>
</div>
<div class="logout-container">
<span class="logout-btn" @click="logout">退</span>
<span class="logout-btn" @click="logout()">退</span>
</div>
</div>
</template>

@ -12,15 +12,20 @@
<b style="color: white" v-show="logoTextShow">线</b>
</div>
<!-- 动态绑定 index使用模板字符串 -->
<el-menu-item :index="`/user/profile?userId=${userId}`">
<i class="el-icon-house"></i>
<span>主页</span>
</el-menu-item>
<el-menu-item :index="`/gl/userCenter?userId=${userId}`">
<i class="el-icon-user"></i>
<span>用户中心</span>
</el-menu-item>
<el-menu-item :index="`/gl/classManage?userId=${userId}`">
<i class="el-icon-monitor"></i>
<span>班级管理</span>
</el-menu-item>
<el-menu-item :index="`/gl/messageCenter?userId=${userId}`">
<i class="el-icon-message"></i>
<span>消息中心</span>
</el-menu-item>
</el-menu>
</template>

@ -4,7 +4,7 @@
<span :class="collapseBtnClass" class="collapse-icon" @click="collapse"></span>
</div>
<div class="logout-container">
<span class="logout-btn" @click="logout">退</span>
<span class="logout-btn" @click="logout()">退</span>
</div>
</div>
</template>

@ -8,6 +8,18 @@ import store from '../store'; // 引入 Vuex store
Vue.use(VueRouter);
const routes = [
{
path:'/gl/messageCenter',
name:'MessageCenter',
component: () => import(/* webpackChunkName: "about" */ '../views/gl/MessageCenter.vue'),
meta: { requiresAuth: true }
},
{
path:'/gl/classManage',
name:'ClassManage',
component: () => import(/* webpackChunkName: "about" */ '../views/gl/ClassManage.vue'),
meta: { requiresAuth: true }
},
{
path:'/gl/userCenter',
name:'UserCenter',
@ -95,15 +107,14 @@ const routes = [
path: '/login',
component: Login
},
{
path: '/',
redirect: '/login', // 默认重定向到 /login
},
{
path: '/register',
component: Register
},
{
path: '/homeView',
name: 'HomeView',
component: () => import(/* webpackChunkName: "about" */ '../views/HomeView.vue')
}
];
const router = new VueRouter({

@ -16,7 +16,12 @@ export default new Vuex.Store({
},
// 清除指定 userId 的 token
clearToken(state, userId) {
Vue.delete(state.tokens, userId); // 删除指定 userId 的 token
// 先删除指定的 token
console.log('clearToken', userId);
console.log('state.tokens', state.tokens);
const newTokens = { ...state.tokens }; // 创建 state.tokens 的副本
delete newTokens[userId]; // 删除副本中的指定 token
state.tokens = newTokens; // 更新 state.tokens 为新的副本
localStorage.setItem('tokens', JSON.stringify(state.tokens)); // 更新 localStorage
},
// 清除所有用户的 token
@ -25,6 +30,7 @@ export default new Vuex.Store({
localStorage.removeItem('tokens'); // 清除 localStorage 中的 tokens
},
},
actions: {
// 设置指定 userId 的 token
setToken({ commit }, { userId, token }) {

@ -100,9 +100,10 @@ export default {
async fetchSummaryData() {
try {
const token = this.$store.state.tokens[this.userId];
console.log('token:', token);
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push("/login");
await this.$router.push("/login");
return;
}
const response = await axios.get('http://localhost:8080/teacher/homepage/homepagesuju', {
@ -140,7 +141,7 @@ export default {
this.initCharts(); //
} catch (error) {
console.error('获取数据失败', error);
this.$message.error('获取数据失败');
}
},

@ -0,0 +1,507 @@
<template>
<el-container style="min-height: 100vh; background-color: #f5f7fa;">
<!-- 侧边栏 -->
<el-aside :width="sideWidth+'px'" style="background-color: #f1f3f5; box-shadow: 2px 0 6px rgba(0, 21, 41, 0.1); transition: all 0.3s;">
<Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow" />
</el-aside>
<el-container>
<!-- Header -->
<el-header style="border-bottom: 1px solid #e0e0e0; background-color: #fff;">
<Header :collapseBtnClass="collapseBtnClass" :collapse="collapse" />
</el-header>
<el-main style="padding: 20px; background-color: #fff; border-radius: 8px;">
<!-- 搜索框 -->
<el-row style="margin-bottom: 20px;" :gutter="20">
<el-col :span="8">
<el-input v-model="nameSearch" placeholder="搜索名字" clearable />
</el-col>
<el-col :span="8">
<el-input v-model="gradeSearch" placeholder="搜索年级" clearable />
</el-col>
<el-col :span="8">
<el-button type="primary" @click="fetchClasses"></el-button>
<el-button @click="resetSearch" type="primary" style="margin-left: 10px;">重置</el-button>
</el-col>
</el-row>
<!-- 班级管理 -->
<el-button type="primary" @click="openCreateClassDialog"></el-button>
<el-table :data="classes" style="width: 100%; margin-top: 20px;">
<el-table-column prop="name" label="班级名称" width="180"></el-table-column>
<el-table-column prop="grade" label="年级" width="100"></el-table-column>
<el-table-column prop="class1" label="班级" width="100"></el-table-column>
<el-table-column prop="command" label="备注" width="150"></el-table-column>
<el-table-column label="学生列表">
<template slot-scope="scope">
<el-button @click="viewStudents(scope.row)" type="success">查看学生</el-button>
</template>
</el-table-column>
<el-table-column label="操作" width="250">
<template slot-scope="scope">
<el-button @click="deleteClass(scope.row)" type="danger" size="small">删除班级</el-button>
<el-button @click="updateClass(scope.row)" type="primary" size="small" style="margin-left: 10px;">修改信息</el-button>
</template>
</el-table-column>
</el-table>
<!-- 查看学生弹窗 -->
<el-dialog :visible.sync="studentsDialogVisible" title="学生列表" width="500px">
<!-- 工具栏 -->
<div style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center;">
<el-input
v-model="studentSearch"
placeholder="搜索学生"
clearable
style="width: 70%;"
@input="handleSearch"
/>
<el-button type="primary" @click="openAddStudentDialog"></el-button>
</div>
<!-- 学生表格 -->
<el-table :data="filteredStudents" style="width: 100%;">
<el-table-column prop="id" label="学号" width="120"></el-table-column>
<el-table-column prop="name" label="学生姓名" width="180"></el-table-column>
<!-- 操作列 -->
<el-table-column label="操作" width="150">
<template slot-scope="scope">
<el-button @click="deleteStudent(scope.row)" type="danger" size="small" style="margin-right: 10px;">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<span slot="footer" class="dialog-footer">
<el-button @click="studentsDialogVisible = false">关闭</el-button>
</span>
</el-dialog>
<!-- 修改信息的弹窗 -->
<el-dialog
:visible.sync="updateDialogVisible"
title="修改班级信息"
width="50%">
<el-form :model="currentClass" ref="form" label-width="80px">
<el-form-item label="班级名称" prop="name">
<el-input v-model="currentClass.name" placeholder="请输入班级名称"></el-input>
</el-form-item>
<el-form-item label="年级" prop="grade">
<el-input v-model="currentClass.grade" placeholder="请输入年级"></el-input>
</el-form-item>
<el-form-item label="班级" prop="grade">
<el-input v-model="currentClass.class1" placeholder="请输入班级"></el-input>
</el-form-item>
<el-form-item label="备注" prop="grade">
<el-input v-model="currentClass.command" placeholder="请输入备注"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="updateDialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveClass"></el-button>
</div>
</el-dialog>
<!-- 新建班级弹窗 -->
<el-dialog :visible.sync="createClassDialogVisible" title="新建班级" width="400px">
<el-form :model="newClass" ref="createClassForm">
<el-form-item label="班级名称" prop="name" :rules="[{ required: true, message: '请输入班级名称', trigger: 'blur' }]">
<el-input v-model="newClass.name" placeholder="请输入班级名称"></el-input>
</el-form-item>
<el-form-item label="年级" prop="grade" :rules="[{ required: true, message: '请选择年级', trigger: 'change' }]">
<el-input v-model="newClass.grade" placeholder="请输入班级名称"></el-input>
</el-form-item>
<el-form-item label="班级" prop="class1" :rules="[{ required: true, message: '请选择班级', trigger: 'change' }]">
<el-input v-model="newClass.class1" placeholder="请输入班级名称"></el-input>
</el-form-item>
<el-form-item label="备注" prop="command" :rules="[{ message: '请选择班级', trigger: 'change' }]">
<el-input v-model="newClass.class1" placeholder="请输入班级名称"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="createClassDialogVisible = false">取消</el-button>
<el-button type="primary" @click="createClass"></el-button>
</span>
</el-dialog>
<!-- 添加学生弹窗 -->
<el-dialog :visible.sync="addStudentDialogVisible" title="批量添加学生" width="600px">
<!-- 学生列表 -->
<el-table
ref="table"
:data="availableStudents"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55"></el-table-column> <!-- -->
<el-table-column prop="name" label="学生名称"></el-table-column>
<el-table-column prop="grade" label="年级"></el-table-column>
<el-table-column prop="class1" label="班级"></el-table-column>
</el-table>
<!-- 底部按钮 -->
<span slot="footer" class="dialog-footer">
<el-button @click="addStudentDialogVisible = false">取消</el-button>
<el-button type="primary" @click="addStudents"></el-button>
</span>
</el-dialog>
</el-main>
</el-container>
</el-container>
</template>
<script>
import Header from "@/components/gl/Header.vue";
import Aside from "@/components/gl/Aside.vue";
import axios from "axios";
import { debounce } from 'lodash';
export default {
name: "ClassManage",
components: {Aside, Header},
data() {
return {
collapseBtnClass: "el-icon-s-fold",
isCollapse: false,
sideWidth: 200,
logoTextShow: true,
nameSearch: null, //
gradeSearch: null, //
classes: [], //
students: [], //
filteredStudents: [], //
studentSearch: "",//
newClass: [], //
searchQuery: '', //
availableStudents: [], //
selectedStudents: [{ id: 1, name: 'Student 1', grade: null, class1: null },], //
selectedClass: "", //
currentClass: [], //
createClassDialogVisible: false, //
addStudentsDialogVisible: false, //
studentsDialogVisible: false, //
addStudentDialogVisible: false, //
updateDialogVisible: false, //
}
},
methods: {
collapse() {
this.isCollapse = !this.isCollapse;
if (this.isCollapse) {
this.sideWidth = 64;
this.collapseBtnClass = "el-icon-s-unfold";
this.logoTextShow = false;
} else {
this.sideWidth = 200;
this.collapseBtnClass = "el-icon-s-fold";
this.logoTextShow = true;
}
},
//
async saveClass() {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.post("http://localhost:8080/gl/classManage/updateClass",
this.currentClass,
{
headers: {
Authorization: `Bearer ${token}`, // Bearer token
'Content-Type': 'application/json',
}
});
if (response.data.code === 200 && response.data.data > 0) {
this.$message.success("修改成功");
this.updateDialogVisible = false;
await this.fetchClasses();
} else {
this.$message.error("数据异常");
}
} catch (error) {
this.$message.error("接口异常!");
}
},
//
handleSelectionChange(val) {
this.selectedStudents = val; // `val`
},
//
handleSearch: debounce(function () {
if (this.studentSearch.trim()) {
this.filterStudents(); //
} else {
this.filteredStudents = this.students; //
}
}, 300), // 300ms
//
filterStudents() {
if (!this.students.length) return;
this.filteredStudents = this.students.filter(student => {
// id
return student.name.includes(this.studentSearch) ||
student.id.toString().includes(this.studentSearch); // id
});
},
//
async openAddStudentDialog(){
this.addStudentDialogVisible = true;
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.get("http://localhost:8080/system/role/selectUserByStudentKey", {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
if(response.data.code === 200){
this.availableStudents = response.data.data;
}else{
this.$message.error("数据异常");
}
}catch (error){
this.$message.error("接口异常!");
}
},
//
async deleteStudent(row) {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.delete("http://localhost:8080/gl/classManage/deleteStudent", {
params: {
id: row.id, // id
grade: this.selectedClass.grade, //
Class1: this.selectedClass.class1 //
},
headers: {
Authorization: `Bearer ${token}` // Bearer token
}
});
if (response.data.code === 200 && response.data.data > 0) {
this.$message.success("删除成功");
await this.viewStudents(this.selectedClass);
} else {
this.$message.error("数据异常");
}
} catch (error) {
this.$message.error("接口异常!");
}
},
//
openCreateClassDialog() {
this.createClassDialogVisible = true;
},
//
async createClass() {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.post("http://localhost:8080/gl/classManage/addClass1",
{
name: this.newClass.name,
grade: this.newClass.grade,
class1: this.newClass.class1,
command: this.newClass.command
},{
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
}
});
if(response.data.code === 200 && response.data.data > 0){
this.$message.success("班级添加成功!");
await this.fetchClasses();
this.createClassDialogVisible = false;
}else{
this.$message.error("班级添加失败!");
}
} catch (error) {
this.$message.error("接口异常!");
}
},
//
updateClass(row){
// currentClass
this.currentClass = { ...row };
//
this.updateDialogVisible = true;
},
//
deleteClass(classItem) {
this.$confirm('确定删除该班级吗?', '删除班级', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
const index = this.classes.indexOf(classItem);
if (index !== -1) {
this.classes.splice(index, 1);
this.$message.success('班级删除成功');
}
});
},
//
addStudents() {
// grade class1
const studentsWithFilledInfo = this.selectedStudents.filter(student => student.grade || student.class1);
// grade class1
if (studentsWithFilledInfo.length > 0) {
const studentNames = studentsWithFilledInfo.map(student => student.name).join(', ');
this.$confirm(
`学生 ${studentNames} 的年级或班级已经填写,是否继续添加新班级?\n\n 注:加入新班级会退出原来的班级,一个学生只能有一个班级。`,
'确认添加班级',
{
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
//
this.updateAllStudents();
}).catch(() => {
});
} else {
//
this.updateAllStudents();
}
},
async updateAllStudents() {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const requestData = JSON.parse(JSON.stringify({
studentList: this.selectedStudents,
grade: this.selectedClass.grade,
class1: this.selectedClass.class1
}));
const response = await axios.post("http://localhost:8080/gl/classManage/insertClassByStudentList",
requestData,
{
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
}
);
console.log(response);
if(response.data.code === 200 && response.data.data > 0){
this.$message.success("学生添加成功");
await this.viewStudents(this.selectedClass);
this.addStudentDialogVisible = false;
}else{
this.$message.error("学生添加失败");
}
} catch (error) {
this.$message.error("接口异常");
}
},
//
async viewStudents(classItem) {
this.studentsDialogVisible = true;
this.selectedClass = classItem;
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.get("http://localhost:8080/gl/classManage/studentListByGradeAndClass1", {
params: {
grade: classItem.grade,
Class1: classItem.class1
},
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
if(response.data.code === 200){
this.students = response.data.data;
this.filteredStudents = this.students;
}else{
this.$message.error("获取数据失败");
}
} catch (error) {
this.$message.error("接口异常");
}
},
//
async fetchClasses(){
try{
const token = this.$store.state.tokens[this.userId];
if(!token){
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.get("http://localhost:8080/gl/classManage/selectClass", {
params: {
name: this.nameSearch,
grade: this.gradeSearch
},
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
if(response.data.code === 200){
this.classes = response.data.data;
}else{
this.$message.error("获取班级列表失败");
}
}catch (error){
this.$message.error("接口异常");
}
},
resetSearch() {
//
this.nameSearch = null;
this.gradeSearch = null;
this.fetchClasses();
}
},
//
created() {
this.userId = this.$route.query.userId; // ID
this.fetchClasses();
},
}
</script>
<style scoped lang="scss">
.el-button {
font-weight: bold;
}
</style>

@ -0,0 +1,231 @@
<template>
<el-container style="min-height: 100vh; background-color: #f5f7fa;">
<!-- 侧边栏 -->
<el-aside :width="sideWidth+'px'" style="background-color: #f1f3f5; box-shadow: 2px 0 6px rgba(0, 21, 41, 0.1); transition: all 0.3s;">
<Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow" />
</el-aside>
<el-container>
<!-- Header -->
<el-header style="border-bottom: 1px solid #e0e0e0; background-color: #fff;">
<Header :collapseBtnClass="collapseBtnClass" :collapse="collapse" />
</el-header>
<el-main style="padding: 20px; background-color: #fff; border-radius: 8px;">
<!-- 消息管理界面 -->
<el-row style="margin-bottom: 20px;">
<el-col :span="24">
<el-button type="primary" @click="showAddMessageDialog"></el-button>
</el-col>
</el-row>
<el-table :data="messages" style="width: 100%" :key="messages.id">
<el-table-column label="id" prop="id" width="100"></el-table-column>
<el-table-column label="发布人" prop="teacherName" width="300"></el-table-column>
<el-table-column label="发布对象" prop="studentName" width="300"></el-table-column>
<el-table-column label="消息内容" prop="source" width="300"></el-table-column>
<el-table-column label="发布时间" prop="createtime" width="180"></el-table-column>
<el-table-column label="操作" width="180">
<template v-slot="scope">
<el-button size="small" @click="deleteMessage(scope.row.id)" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加消息对话框 -->
<el-dialog :visible.sync="addMessageDialogVisible" title="添加消息" width="500px" :style="{ maxHeight: '80vh' }">
<el-form :model="newMessage" label-width="80px" class="form-container">
<!-- 消息内容 -->
<el-form-item label="消息内容" prop="source" :rules="[{ required: true, message: '消息内容不能为空', trigger: 'blur' }]">
<el-input v-model="newMessage.source" type="textarea" placeholder="请输入消息内容" rows="4"></el-input>
</el-form-item>
<!-- 选择用户下拉框 -->
<el-form-item label="选择用户" prop="selectedUsers" :rules="[{ required: true, message: '请选择用户', trigger: 'change' }]">
<el-select v-model="newMessage.selectedUsers" multiple placeholder="请选择用户" style="width: 100%">
<el-option
v-for="user in userList"
:key="user.userId"
:label="user.userName"
:value="user.userId">
</el-option>
</el-select>
</el-form-item>
<div class="dialog-footer">
<el-button @click="addMessageDialogVisible = false" size="small">取消</el-button>
<el-button type="primary" @click="addMessage" size="small">确定</el-button>
</div>
</el-form>
</el-dialog>
</el-main>
</el-container>
</el-container>
</template>
<script>
import Header from "@/components/gl/Header.vue";
import Aside from "@/components/gl/Aside.vue";
import axios from "axios";
import source from "echarts/src/data/Source";
export default {
name: "MessageCenter",
components: { Aside, Header },
data() {
return {
collapseBtnClass: "el-icon-s-fold",
isCollapse: false,
sideWidth: 200,
logoTextShow: true,
messages: [],
newMessage: {
source: '',
selectedUsers: [], //
},
userList: [],
addMessageDialogVisible: false,
};
},
created() {
this.userId = this.$route.query.userId; // ID
this.fetchMessages();
this.fetchUserList();
},
methods: {
collapse() {
this.isCollapse = !this.isCollapse;
if (this.isCollapse) {
this.sideWidth = 64;
this.collapseBtnClass = "el-icon-s-unfold";
this.logoTextShow = false;
} else {
this.sideWidth = 200;
this.collapseBtnClass = "el-icon-s-fold";
this.logoTextShow = true;
}
},
async fetchMessages() {
try {
const token = this.$store.state.tokens[this.userId];
if(!token){
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.get('http://localhost:8080/gl/message/selectMessage', {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
if(response.data.code === 200 ) {
this.messages = response.data.data;
console.log(this.messages);
}else{
this.$message.error("数据异常");
}
} catch (error) {
this.$message.error("接口异常");
}
},
//
showAddMessageDialog() {
this.newMessage = { source: '', selectedUsers: [] }; //
this.addMessageDialogVisible = true;
},
//
async addMessage() {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const requestData = {
id: this.userId,
source: this.newMessage.source,
list: this.newMessage.selectedUsers, // ID
};
console.log(requestData);
const response = await axios.post('http://localhost:8080/gl/message/addMessage',
requestData,
{
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
if (response.data.code === 200 && response.data.data > 0) {
this.$message.success("添加成功");
await this.fetchMessages();
this.addMessageDialogVisible = false;
} else {
this.$message.error("数据异常");
}
} catch (error) {
this.$message.error("接口异常");
}
},
//
async deleteMessage(messageId) {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.delete('http://localhost:8080/gl/message/deleteMessage', {
params: { id: messageId },
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
if (response.data.code === 200 && response.data.data > 0){
this.$message.success("删除成功");
await this.fetchMessages();
} else {
this.$message.error("数据异常");
}
} catch (error) {
this.$message.error("接口异常");
}
},
async fetchUserList() {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.get('http://localhost:8080/gl/message/getUserList', {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
if (response.data.code ===200) {
this.userList = response.data.data;
}
}catch (error){
this.$message.error("接口异常");
}
},
},
};
</script>
<style scoped lang="scss">
.form-container {
padding: 20px;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
}
.el-form-item {
margin-bottom: 20px; /* Adjust spacing between form items */
}
</style>

@ -16,7 +16,6 @@
<el-tabs v-model="activeTab" @tab-click="fetchUserList" style="flex-grow: 1;">
<el-tab-pane label="老师" name="teacher"></el-tab-pane>
<el-tab-pane label="学生" name="student"></el-tab-pane>
<el-tab-pane label="无权限" name="null"></el-tab-pane>
</el-tabs>
<!-- 刷新按钮 -->
@ -37,33 +36,47 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<el-table-column label="操作" width="250">
<template #default="scope">
<div style="display: flex; align-items: center;">
<el-button @click="viewDetails(scope.row)" size="small" type="success" style="margin-right: 10px;">详细</el-button>
<el-button v-if="scope.row.online" @click="kickOutUser(scope.row)" size="small" type="danger">退</el-button>
<el-button @click="updateDetails(scope.row)" size="small" type="primary">修改</el-button>
<el-button v-if="scope.row.online" @click="confirmKickOut(scope.row)" size="small" type="danger">退</el-button>
</div>
</template>
</el-table-column>
</el-table>
<!-- User Details Dialog -->
<el-dialog :visible.sync="dialogVisible" title="User Details" width="500px" :style="{borderRadius: '8px'}">
<el-form :model="selectedUser" label-width="120px">
<el-form-item label="ID">
<span>{{ selectedUser.id }}</span>
<!-- 详情弹窗 -->
<el-dialog :visible.sync="dialogVisible" title="详细信息" width="500px" :style="{borderRadius: '10px', padding: '20px'}">
<el-form :model="selectedUser" label-width="120px" style="font-size: 14px; background-color: #f9f9f9; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">
<el-form-item label="用户id">
<span>{{ selectedUser.userId || '暂无数据' }}</span>
</el-form-item>
<el-form-item label="Name">
<span>{{ selectedUser.name }}</span>
<el-form-item label="用户名:">
<span>{{ selectedUser.userName || '暂无数据' }}</span>
</el-form-item>
<el-form-item label="昵称:">
<span>{{ selectedUser.nickName || '暂无数据' }}</span>
</el-form-item>
<el-form-item label="Email">
<span>{{ selectedUser.email }}</span>
<el-form-item label="性别:">
<span>{{ selectedUser.sex === null || selectedUser.sex === undefined ? '暂无数据' : (selectedUser.sex === 0 ? '女' : '男') }}</span>
</el-form-item>
<el-form-item label="Role">
<span>{{ selectedUser.role }}</span>
<el-form-item label="邮箱:">
<span>{{ selectedUser.email || '暂无数据' }}</span>
</el-form-item>
<el-form-item label="电话:">
<span>{{ selectedUser.phonenumber || '暂无数据' }}</span>
</el-form-item>
</el-form>
</el-dialog>
</el-main>
</el-container>
</el-container>
@ -73,6 +86,7 @@
import Header from "@/components/gl/Header.vue";
import Aside from "@/components/gl/Aside.vue";
import axios from "axios";
import { MessageBox } from 'element-ui'; // MessageBox
export default {
name: "UserCenter",
@ -112,7 +126,7 @@ export default {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push("/login");
await this.$router.push("/login");
return false;
}
const response = await axios.get("http://localhost:8080/system/role/selectUserByRoleKey", {
@ -125,7 +139,6 @@ export default {
},
});
this.userList = response.data;
console.log(response);
} catch (error) {
console.error("接口获取失败:", error);
this.$message.error("接口请求异常");
@ -139,6 +152,50 @@ export default {
refreshData() {
this.fetchUserList(); //
},
confirmKickOut(user) {
MessageBox.confirm(
`是否确定强退名称为 ${user.userName} 的账号?`, //
'警告', //
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning', //
}
).then(() => {
// 退
this.kickOutUser(user);
}).catch(() => {
//
console.log("用户取消了强退操作");
});
},
// 退
async kickOutUser(user) {
// 退
try{
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
await this.$router.push("/login");
return false;
}
const response = await axios.delete(`http://localhost:8080/monitor/online/${user.tokenId}`, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
if(response.data.code === 200){
this.$message.success("强退成功");
await this.fetchUserList();
}else{
this.$message.error("强退失败");
}
}catch (error){
this.$message.error("接口异常");
}
// API 退
},
},
mounted() {
this.fetchUserList(); //
@ -150,22 +207,85 @@ export default {
</script>
<style scoped lang="scss">
.el-table {
.el-dialog {
background-color: #ffffff; /* White background for the dialog */
border-radius: 12px; /* Round corners for dialog */
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); /* More prominent shadow */
padding: 20px;
}
.el-form {
background-color: #f9f9f9; /* Light gray background */
border-radius: 10px; /* Soft rounded corners */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* Light shadow effect */
padding: 25px;
font-size: 14px;
}
.el-form-item {
margin-bottom: 18px; /* Increased margin between form items */
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding: 10px;
background-color: #fff; /* White background for form items */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); /* Light shadow for each form item */
transition: all 0.3s ease;
}
.el-header {
background-color: #ffffff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
.el-form-item:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* Hover effect for form items */
}
.el-form-item span {
font-weight: 500;
color: #333; /* Darker text color for better readability */
display: block; /* Ensures text doesn't overflow */
}
.el-form-item label {
color: #888; /* Lighter color for form labels */
font-weight: bold;
font-size: 15px; /* Slightly larger font for labels */
margin-bottom: 10px; /* Space between label and value */
}
.el-dialog__header {
background-color: #409eff; /* Primary blue background for header */
color: white;
font-weight: bold;
font-size: 18px;
border-radius: 12px 12px 0 0; /* Rounded top corners */
padding: 20px 25px; /* Increased padding for header */
}
.el-dialog__body {
padding: 20px 25px;
}
.el-dialog__footer {
background-color: #f9f9f9;
border-radius: 0 0 12px 12px; /* Rounded bottom corners */
padding: 20px 25px;
text-align: right;
}
.el-button {
font-weight: 500;
transition: all 0.3s ease;
}
.el-dialog {
border-radius: 8px;
.el-button:hover {
background-color: #3080e7; /* Slightly darker blue on hover */
border-color: #3080e7;
}
.el-table {
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* Soft shadow for the table */
}
.el-header {
background-color: #ffffff;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); /* Light shadow for header */
}
.el-tabs {
@ -190,3 +310,4 @@ export default {
color: #555;
}
</style>

@ -261,7 +261,7 @@ export default {
.then(response => {
if (response.data.code==200) {
this.$message.success("密码更新成功,请重新登录");
this.$store.dispatch("logout"); // Vuex
this.$store.dispatch("clearToken",this.userId); // Vuex
this.$router.push("/login"); //
} else {
this.$message.error("密码更新失败");

Loading…
Cancel
Save