前端优化退出登录功能,新增管理端用户中心

main
yuan 2 months ago
parent 1f23ba4798
commit 52d2592278

@ -1,9 +1,15 @@
package com.ruoyi.web.controller.system;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
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.vo.SysUserVo;
import com.ruoyi.common.core.redis.RedisCache;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@ -57,6 +63,35 @@ public class SysRoleController extends BaseController
@Autowired
private ISysDeptService deptService;
@Autowired
private RedisCache redisCache;
@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<>();
for(String key:keys){
LoginUser user = redisCache.getCacheObject(key);
if(user.getUserId()!=null){
ids.add(user.getUserId());
}
}
for(SysUser user:list){
SysUserVo sysUserVo = new SysUserVo();
BeanUtils.copyProperties(user,sysUserVo);
if(ids.contains(user.getUserId())){
sysUserVo.setOnline(1);
}else{
sysUserVo.setOnline(0);
}
l.add(sysUserVo);
}
System.out.println("======="+l);
return l;
}
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/list")
public TableDataInfo list(SysRole role)

@ -115,7 +115,6 @@ public class SysUserController extends BaseController
ajax.put("postIds", postService.selectPostListByUserId(userId));
ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
}
System.out.println("================"+ajax);
return ajax;
}

@ -3,21 +3,18 @@ package com.ruoyi.web.controller.test;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.gson.Gson;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.test.domain.DO.ExamCreateDO;
import com.ruoyi.test.domain.DO.ExamDO;
import com.ruoyi.test.domain.DO.OptionDO;
import com.ruoyi.test.domain.DO.SingleChoiceDO;
import com.ruoyi.test.domain.ExamCreate;
import com.ruoyi.test.domain.ExamPaper;
import com.ruoyi.test.domain.Questionbank;
import com.ruoyi.test.domain.Vo.ExamCreateVo;
import com.ruoyi.test.domain.Vo.QuestionbankVo;
import com.ruoyi.test.domain.Vo.QuestionbankVo1;
import com.ruoyi.test.domain.Vo.QuestionbankVo2;
import com.ruoyi.test.seriver.*;
import com.ruoyi.test.seriver.IExamCreateService;
import com.ruoyi.test.seriver.IExamDOService;
import com.ruoyi.test.seriver.IExamPaperService;
import com.ruoyi.test.seriver.IQuestionbankService;
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.*;

@ -5,12 +5,13 @@ import com.google.gson.Gson;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.test.domain.*;
import com.ruoyi.test.domain.Answer;
import com.ruoyi.test.domain.DO.AnswerDO;
import com.ruoyi.test.domain.DO.AnswerSheetDO;
import com.ruoyi.test.domain.DO.QuestionAnswerDO;
import com.ruoyi.test.domain.Markedtest;
import com.ruoyi.test.domain.Questionbank;
import com.ruoyi.test.domain.Vo.AnswerVo;
import com.ruoyi.test.domain.Vo.QuestionanswerVo;
import com.ruoyi.test.seriver.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -18,7 +19,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@Api(tags = "管理端答卷管理")
@RestController

@ -6,7 +6,6 @@ import com.ruoyi.test.domain.DO.PaperCreateDO;
import com.ruoyi.test.domain.DO.QuestionbankDO;
import com.ruoyi.test.domain.DO.QuestionbankDO1;
import com.ruoyi.test.domain.ExamPaper;
import com.ruoyi.test.domain.Questionbank;
import com.ruoyi.test.seriver.IExamCreateService;
import com.ruoyi.test.seriver.IExamPaperService;
import com.ruoyi.test.seriver.IQuestionbankService;

@ -8,7 +8,6 @@ import com.ruoyi.test.seriver.IKnowledgeTreeService;
import com.ruoyi.test.seriver.ISubjectKnowledgeDOService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@ -10,8 +10,6 @@ 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/subject")

@ -7,15 +7,11 @@ import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.test.domain.Task;
import com.ruoyi.test.domain.Vo.TaskVo;
import com.ruoyi.test.seriver.ITaskService;
import com.ruoyi.web.controller.tool.testTool.ResultVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Api(tags = "管理端任务管理")
@RestController
@RequestMapping("/gl/tesk")
@ -25,12 +21,12 @@ public class TaskController {
private ITaskService iTaskService;
@ApiOperation("任务列表")
@GetMapping("selectList")
public ResultVo<IPage<Task>> selectList(int pagenum,int pagesize){
// return R.ok(iTaskService.selectList(pagenum,pagesize));
return ResultVo.ok(iTaskService.selectList(pagenum,pagesize));
}
// @ApiOperation("任务列表")
// @GetMapping("selectList")
// public ResultVo<IPage<Task>> selectList(int pagenum,int pagesize){
//// return R.ok(iTaskService.selectList(pagenum,pagesize));
// return ResultVo.ok(iTaskService.selectList(pagenum,pagesize));
// }
// @ApiOperation("根据年级获取任务列表")
// @GetMapping("selectListByGrade")

@ -1,4 +1,4 @@
//package com.ruoyi.web.controller.test.gl;
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;

@ -7,7 +7,6 @@ import com.ruoyi.test.domain.Vo.VideoVo;
import com.ruoyi.test.seriver.IVideoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@ -14,7 +14,6 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@ -1,12 +1,13 @@
package com.ruoyi.web.controller.test.student;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.test.domain.*;
import com.ruoyi.test.domain.ClassExamPaper;
import com.ruoyi.test.domain.DO.ExamPaperDO1;
import com.ruoyi.test.domain.ExamPaper;
import com.ruoyi.test.domain.Questionbank;
import com.ruoyi.test.domain.StudentClass;
import com.ruoyi.test.seriver.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@ -5,9 +5,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.test.domain.*;
import com.ruoyi.test.domain.Answer;
import com.ruoyi.test.domain.DO.CorrectionDO;
import com.ruoyi.test.domain.DO.QuestionbankDO1;
import com.ruoyi.test.domain.ExamPaper;
import com.ruoyi.test.domain.Markedtest;
import com.ruoyi.test.domain.Questionbank;
import com.ruoyi.test.seriver.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@ -1,7 +1,6 @@
package com.ruoyi.web.controller.test.student;
import com.google.gson.Gson;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
@ -13,10 +12,8 @@ import com.ruoyi.test.domain.DO.QuestionAnswerDO;
import com.ruoyi.test.domain.DO.UserDO;
import com.ruoyi.test.domain.Vo.AnswerVo;
import com.ruoyi.test.seriver.*;
import com.ruoyi.web.controller.system.SysUserController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@ -2,7 +2,6 @@ package com.ruoyi.web.controller.test.student;
import com.ruoyi.test.seriver.IClassExamPaperService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@ -6,7 +6,6 @@ import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.test.domain.*;
import com.ruoyi.test.domain.DO.ClassExamPaperDO;
import com.ruoyi.test.domain.DO.ExamPaperDO;
import com.ruoyi.test.seriver.*;
import io.swagger.annotations.Api;

@ -6,7 +6,6 @@ import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.test.domain.Class1;
import com.ruoyi.test.domain.DO.StudentListDO;
import com.ruoyi.test.domain.TeacherManageClass;
import com.ruoyi.test.seriver.IClass1Service;
import com.ruoyi.test.seriver.IStudentClassService;
@ -14,7 +13,9 @@ import com.ruoyi.test.seriver.ITeacherManageClassService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;

@ -10,7 +10,6 @@ import com.ruoyi.test.domain.ClassExamPaper;
import com.ruoyi.test.domain.DO.*;
import com.ruoyi.test.domain.ExamPaper;
import com.ruoyi.test.domain.TeacherManageClass;
import com.ruoyi.test.domain.Vo.ExamPaperVo;
import com.ruoyi.test.domain.Vo.QuestionbankVo1;
import com.ruoyi.test.seriver.*;
import io.swagger.annotations.Api;

@ -8,8 +8,8 @@ import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.test.domain.DO.StudentListDO;
import com.ruoyi.test.domain.StudentClass;
import com.ruoyi.test.domain.TeacherManageClass;
import com.ruoyi.test.seriver.IStudentClassService;
import com.ruoyi.test.seriver.IClassExamPaperService;
import com.ruoyi.test.seriver.IStudentClassService;
import com.ruoyi.test.seriver.ITeacherManageClassService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@ -47,6 +47,10 @@ user:
# Spring配置
spring:
component-scan:
base-packages:
- com.ruoyi.test # 手写代码路径
- com.ruoyi.kaoshi # 生成代码路径
# 资源信息
messages:
# 国际化资源文件路径

@ -138,6 +138,11 @@
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

@ -0,0 +1,45 @@
package com.ruoyi.common.core.domain.vo;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
@Data
public class SysUserVo
{
/** 用户ID */
@Excel(name = "用户序号", type = Excel.Type.EXPORT, cellType = Excel.ColumnType.NUMERIC, prompt = "用户编号")
private Long userId;
/** 部门ID */
@Excel(name = "部门编号", type = Excel.Type.IMPORT)
private Long deptId;
/** 用户账号 */
@Excel(name = "登录名称")
private String userName;
/** 用户昵称 */
@Excel(name = "用户名称")
private String nickName;
/** 用户邮箱 */
@Excel(name = "用户邮箱")
private String email;
/** 手机号码 */
@Excel(name = "手机号码", cellType = Excel.ColumnType.TEXT)
private String phonenumber;
/** 用户性别 */
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String sex;
/** 用户头像 */
private String avatar;
/** 密码 */
private String password;
//是否在线
private Integer online;
}

@ -40,6 +40,7 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
throws IOException, ServletException
{
LoginUser loginUser = tokenService.getLoginUser(request);
System.out.println("=========="+loginUser);
if (StringUtils.isNotNull(loginUser))
{
String userName = loginUser.getUsername();

@ -12,6 +12,13 @@ import com.ruoyi.common.core.domain.entity.SysRole;
*/
public interface SysRoleMapper
{
/**
* key
*
* @param roleKey key
* @return
*/
public SysRole selectRoleByRoleKey(String roleKey);
/**
*
*

@ -1,6 +1,8 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.common.core.domain.entity.SysUser;
@ -9,8 +11,9 @@ import com.ruoyi.common.core.domain.entity.SysUser;
*
* @author ruoyi
*/
public interface SysUserMapper
public interface SysUserMapper extends BaseMapper<SysUser>
{
List<SysUser> selectUsersByIds(@Param("ids") List<Long> userRoleIds);
/**
*
*

@ -1,6 +1,8 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.system.domain.SysUserRole;
@ -9,7 +11,7 @@ import com.ruoyi.system.domain.SysUserRole;
*
* @author ruoyi
*/
public interface SysUserRoleMapper
public interface SysUserRoleMapper extends BaseMapper<SysUserRole>
{
/**
* ID

@ -3,6 +3,7 @@ package com.ruoyi.system.service;
import java.util.List;
import java.util.Set;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.domain.SysUserRole;
/**
@ -12,6 +13,14 @@ import com.ruoyi.system.domain.SysUserRole;
*/
public interface ISysRoleService
{
/**
* key
*
* @param roleKey key
* @return
*/
public List<SysUser> selectUserByRoleKey(String roleKey);
/**
*
*

@ -1,10 +1,10 @@
package com.ruoyi.system.service.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.system.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -19,10 +19,6 @@ import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.SysRoleDept;
import com.ruoyi.system.domain.SysRoleMenu;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.mapper.SysRoleDeptMapper;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysRoleMenuMapper;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import com.ruoyi.system.service.ISysRoleService;
/**
@ -45,6 +41,27 @@ public class SysRoleServiceImpl implements ISysRoleService
@Autowired
private SysRoleDeptMapper roleDeptMapper;
@Autowired
private SysUserMapper userMapper;
/**
* key
*
* @param roleKey key
* @return
*/
@Override
public List<SysUser> selectUserByRoleKey(String roleKey) {
SysRole sysRole = roleMapper.selectRoleByRoleKey(roleKey);
LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysUserRole::getRoleId, sysRole.getRoleId());
List<Long> userRoleIds = userRoleMapper.selectList(queryWrapper)
.stream()
.map(SysUserRole::getUserId)
.collect(Collectors.toList());
return userMapper.selectUsersByIds(userRoleIds);
}
/**
*
*

@ -21,6 +21,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="remark" column="remark" />
</resultMap>
<select id="selectRoleByRoleKey" parameterType="String" resultMap="SysRoleResult">
<include refid="selectRoleVo"/>
where r.role_key = #{roleKey}
</select>
<sql id="selectRoleVo">
select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly,
r.status, r.del_flag, r.create_time, r.remark

@ -47,6 +47,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="status" column="role_status" />
</resultMap>
<select id="selectUsersByIds" parameterType="list" resultType="SysUser">
SELECT *
FROM sys_user
WHERE user_id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<sql id="selectUserVo">
select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.studentnumber,
d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,

@ -11,7 +11,6 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
@Service

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询消息管理列表
export function listMessage(query) {
return request({
url: '/kaoshi/message/list',
method: 'get',
params: query
})
}
// 查询消息管理详细
export function getMessage(id) {
return request({
url: '/kaoshi/message/' + id,
method: 'get'
})
}
// 新增消息管理
export function addMessage(data) {
return request({
url: '/kaoshi/message',
method: 'post',
data: data
})
}
// 修改消息管理
export function updateMessage(data) {
return request({
url: '/kaoshi/message',
method: 'put',
data: data
})
}
// 删除消息管理
export function delMessage(id) {
return request({
url: '/kaoshi/message/' + id,
method: 'delete'
})
}

@ -0,0 +1,308 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="教师id" prop="teacherId">
<el-input
v-model="queryParams.teacherId"
placeholder="请输入教师id"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="学生id" prop="studentId">
<el-input
v-model="queryParams.studentId"
placeholder="请输入学生id"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="消息" prop="source">
<el-input
v-model="queryParams.source"
placeholder="请输入消息"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否查看" prop="tf">
<el-input
v-model="queryParams.tf"
placeholder="请输入是否查看"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="创建时间" prop="createtime">
<el-date-picker clearable
v-model="queryParams.createtime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择创建时间">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['kaoshi:message:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['kaoshi:message:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['kaoshi:message:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['kaoshi:message:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="messageList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="id" align="center" prop="id" />
<el-table-column label="教师id" align="center" prop="teacherId" />
<el-table-column label="学生id" align="center" prop="studentId" />
<el-table-column label="消息" align="center" prop="source" />
<el-table-column label="是否查看" align="center" prop="tf" />
<el-table-column label="创建时间" align="center" prop="createtime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createtime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['kaoshi:message:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['kaoshi:message:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改消息管理对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="教师id" prop="teacherId">
<el-input v-model="form.teacherId" placeholder="请输入教师id" />
</el-form-item>
<el-form-item label="学生id" prop="studentId">
<el-input v-model="form.studentId" placeholder="请输入学生id" />
</el-form-item>
<el-form-item label="消息" prop="source">
<el-input v-model="form.source" placeholder="请输入消息" />
</el-form-item>
<el-form-item label="是否查看" prop="tf">
<el-input v-model="form.tf" placeholder="请输入是否查看" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listMessage, getMessage, delMessage, addMessage, updateMessage } from "@/api/kaoshi/message";
export default {
name: "Message",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
messageList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
teacherId: null,
studentId: null,
source: null,
tf: null,
createtime: null
},
//
form: {},
//
rules: {
teacherId: [
{ required: true, message: "教师id不能为空", trigger: "blur" }
],
studentId: [
{ required: true, message: "学生id不能为空", trigger: "blur" }
],
}
};
},
created() {
this.getList();
},
methods: {
/** 查询消息管理列表 */
getList() {
this.loading = true;
listMessage(this.queryParams).then(response => {
this.messageList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
teacherId: null,
studentId: null,
source: null,
tf: null,
createtime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加消息管理";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getMessage(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改消息管理";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateMessage(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addMessage(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除消息管理编号为"' + ids + '"的数据项?').then(function() {
return delMessage(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('kaoshi/message/export', {
...this.queryParams
}, `message_${new Date().getTime()}.xlsx`)
}
}
};
</script>

@ -83,6 +83,7 @@ export default {
'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;
@ -97,8 +98,13 @@ export default {
path: '/teacher/homePage',
query: { userId: userId }
});
// window.location.href = 'http://localhost:8081/teacher/correct';
}else{
}else if(res.data.roles[0] === 'gl'){
this.$router.push({
path: '/gl/userCenter',
query: {userId: userId}
});
}
else{
alert('该角色无权限');
this.refreshCaptcha();
}

@ -45,9 +45,27 @@ export default {
this.sss();
},
methods: {
logout() {
this.$store.dispatch("logout"); // Vuex
this.$router.push("/login"); //
async logout() {
try{
//
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.post("http://localhost:8080/logout", {}, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
})
console.log(response);
await this.$store.dispatch("clearToken", this.userId); // Vuex
this.$message.success("退出成功!");
await this.$router.push("/login"); //
}catch (error){
this.$message.error("接口异常!");
}
},
async sss(){
try {

@ -10,6 +10,8 @@
</template>
<script>
import axios from "axios";
export default {
name: "Header",
props: {
@ -17,11 +19,32 @@ export default {
collapse: Boolean,
},
methods: {
logout() {
async logout() {
try{
//
this.$store.dispatch("logout"); // Vuex
this.$router.push("/login"); //
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.post("http://localhost:8080/logout", {}, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
})
console.log(response);
await this.$store.dispatch("clearToken", this.userId); // Vuex
this.$message.success("退出成功!");
await this.$router.push("/login"); //
}catch (error){
this.$message.error("接口异常!");
}
},
},
created() {
// userId
this.userId = this.$route.query.userId;
}
}
</script>

@ -0,0 +1,49 @@
<template>
<el-menu :default-openeds="['1', '3']" style="min-height: 100%; overflow-x: hidden"
background-color="rgb(48,65,86)"
text-color="#fff"
active-text-color="#ffd04b"
:collapse-transition="false"
:collapse="isCollapse"
router
>
<div style="height: 60px;line-height: 60px;text-align: center">
<img src="../../assets/logo.png" alt="" style="width: 20px;position: relative;top: 5px;margin-right: 5px">
<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>
</template>
<script>
export default {
name: "Aside",
data() {
return {
hasStudentMenu: false, // false submenu
userId: '', // userId
};
},
props: {
isCollapse: Boolean,
logoTextShow: Boolean
},
created() {
// userId
this.userId = this.$route.query.userId;
}
}
</script>
<style scoped lang="scss">
</style>

@ -0,0 +1,90 @@
<template>
<div class="header-container">
<div class="left-section">
<span :class="collapseBtnClass" class="collapse-icon" @click="collapse"></span>
</div>
<div class="logout-container">
<span class="logout-btn" @click="logout">退</span>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "Header",
props: {
collapseBtnClass: String,
collapse: Boolean,
},
methods: {
async logout() {
try{
//
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
return;
}
const response = await axios.post("http://localhost:8080/logout", {}, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
})
console.log(response);
await this.$store.dispatch("clearToken", this.userId); // Vuex
this.$message.success("退出成功!");
await this.$router.push("/login"); //
}catch (error){
this.$message.error("接口异常!");
}
},
},
created() {
// userId
this.userId = this.$route.query.userId;
}
}
</script>
<style scoped lang="scss">
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 14px;
line-height: 50px;
padding: 0 20px;
border-bottom: 1px solid #ddd;
}
.left-section {
flex: 1;
}
.collapse-icon {
cursor: pointer;
font-size: 20px;
}
.logout-container {
display: flex;
align-items: center;
}
.logout-btn {
cursor: pointer;
font-size: 16px;
color: #409EFF;
padding: 5px 10px;
border-radius: 4px;
transition: background-color 0.3s ease, color 0.3s ease;
}
.logout-btn:hover {
background-color: #409EFF;
color: #fff;
}
</style>

@ -8,6 +8,12 @@ import store from '../store'; // 引入 Vuex store
Vue.use(VueRouter);
const routes = [
{
path:'/gl/userCenter',
name:'UserCenter',
component: () => import(/* webpackChunkName: "about" */ '../views/gl/UserCenter.vue'),
meta: { requiresAuth: true }
},
{
path:'/teacher/questions',
name:'Questions',

@ -0,0 +1,192 @@
<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;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
<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>
<!-- 刷新按钮 -->
<el-button @click="refreshData" size="small" type="primary" style="background-color: #409EFF; border-color: #409EFF;margin-right: 10px">
刷新
</el-button>
</div>
<!-- 表格 -->
<el-table :data="userList" border style="width: 100%; margin-top: 20px; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);">
<el-table-column prop="userId" label="ID" width="80" />
<el-table-column prop="userName" label="用户名" />
<el-table-column prop="nickName" label="昵称" />
<el-table-column prop="online" label="是否在线" width="300">
<template #default="scope">
<el-tag :type="scope.row.online === 1 ? 'success' : 'warning'">
{{ scope.row.online === 1 ? '在线' : '离线' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<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>
</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-form-item>
<el-form-item label="Name">
<span>{{ selectedUser.name }}</span>
</el-form-item>
<el-form-item label="Email">
<span>{{ selectedUser.email }}</span>
</el-form-item>
<el-form-item label="Role">
<span>{{ selectedUser.role }}</span>
</el-form-item>
</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";
export default {
name: "UserCenter",
components: { Aside, Header },
data() {
return {
collapseBtnClass: "el-icon-s-fold",
isCollapse: false,
sideWidth: 200,
logoTextShow: true,
activeTab: "teacher", // "teacher"
userList: [], //
dialogVisible: false, //
selectedUser: {}, //
//
currentPage: 1,
pageSize: 10,
total: 0, //
};
},
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 fetchUserList() {
try {
// Token
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push("/login");
return false;
}
const response = await axios.get("http://localhost:8080/system/role/selectUserByRoleKey", {
params: {
roleKey: this.activeTab,
},
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
this.userList = response.data;
console.log(response);
} catch (error) {
console.error("接口获取失败:", error);
this.$message.error("接口请求异常");
}
},
viewDetails(user) {
this.selectedUser = user; //
this.dialogVisible = true; //
},
//
refreshData() {
this.fetchUserList(); //
},
},
mounted() {
this.fetchUserList(); //
},
created() {
this.userId = this.$route.query.userId; // ID
},
};
</script>
<style scoped lang="scss">
.el-table {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.el-header {
background-color: #ffffff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.el-button {
font-weight: 500;
}
.el-dialog {
border-radius: 8px;
}
.el-tabs {
background-color: #fff;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
}
.el-aside {
box-shadow: 2px 0 6px rgba(0, 21, 41, 0.1);
}
.el-tag {
border-radius: 12px;
}
.el-table-column {
text-align: center;
}
.el-form-item span {
color: #555;
}
</style>
Loading…
Cancel
Save