This commit is contained in:
tanyp 2023-04-14 16:16:35 +08:00
parent cd517c138c
commit a1a0ea03f5
31 changed files with 618 additions and 67 deletions

View File

@ -0,0 +1,16 @@
import request from '@/utils/request'
// 列表
export function page(params:any){
return new Promise((resolve, reject) => {
request({
url: '/tansci/syslog/loginLog',
method: 'get',
params: params
}).then((res:any) => {
resolve(res.data)
}).catch((e:any) => {
reject(e)
})
})
}

View File

@ -0,0 +1,28 @@
import request from '@/utils/request'
export function page(params:any){
return new Promise((resolve, reject) => {
request({
url: '/tansci/auth/onlineUser',
method: 'get',
params: params
}).then((res:any) => {
resolve(res.data)
}).catch((e:any) => {
reject(e)
})
})
}
export function kick(token:String){
return new Promise((resolve, reject) => {
request({
url: '/tansci/auth/kick/' + token,
method: 'get'
}).then((res:any) => {
resolve(res.data)
}).catch((e:any) => {
reject(e)
})
})
}

View File

@ -0,0 +1,16 @@
import request from '@/utils/request'
// 列表
export function page(params:any){
return new Promise((resolve, reject) => {
request({
url: '/tansci/syslog/operLog',
method: 'get',
params: params
}).then((res:any) => {
resolve(res.data)
}).catch((e:any) => {
reject(e)
})
})
}

View File

@ -1,5 +1,20 @@
import request from '@/utils/request'
// 列表树
export function tree(params:any){
return new Promise((resolve, reject) => {
request({
url: '/tansci/sysdict/tree',
method: 'get',
params: params
}).then((res:any) => {
resolve(res.data)
}).catch((e:any) => {
reject(e)
})
})
}
// 列表
export function list(params:any){
return new Promise((resolve, reject) => {

View File

@ -69,13 +69,9 @@
emit('onCurrentChange', e)
}
//
function onFind(arr:any,val:any){
if(!arr) return 'info';
let temp = arr.find(v=>{ return v.value == val});
if(temp) return temp.label;
return 'info';
return arr.find(v=>{ return v.value == val}).label;
}
</script>
<template>
@ -105,11 +101,15 @@
</el-icon>
</template>
</el-table-column>
<!-- 金额格式化 -->
<el-table-column v-else-if="item.type == 'price'"
<!-- el-statistic -->
<el-table-column v-else-if="item.type == 'statistic'"
:label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width">
<template #default="scope">
<span>{{common.toDecimal(scope.row[item.prop])}}</span>
<el-statistic :value="scope.row[item.prop]"
:precision="item.option.precision"
:formatter="item.option.formatter"
:prefix="item.option.prefix"
:suffix="item.option.suffix"/>
</template>
</el-table-column>
<!-- el-image -->
@ -167,13 +167,21 @@
:color="item.option.color"/>
</template>
</el-table-column>
<!-- 字典值 -->
<el-table-column v-else-if="item.type == 'dict'"
:label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width">
<template #default="scope">
<span>{{common.getDictLabel(item.dictType, scope.row[item.prop])}}</span>
</template>
</el-table-column>
<!-- 其他数据列 -->
<el-table-column v-else show-overflow-tooltip
:prop="item.alias==null?item.prop:item.alias"
:label="item.label"
:align="item.align != null ? item.align : 'center'"
:width="item.width"
:fixed="item.fixed">
:fixed="item.fixed"
:formatter="item.function">
</el-table-column>
</template>
<!-- 自定义插槽 -->

View File

@ -1,13 +1,14 @@
import { createRouter, createWebHistory } from "vue-router"
import { ElMessage } from 'element-plus'
import { getToken, removeToken, removeUser, setMenus } from "@/api/auth"
import common from '@/utils/common'
import { generateRoutes } from "./permission"
import common from './common'
import staticRouter from './staticRouter'
const router = createRouter({
history: createWebHistory(),
routes: [
...common
...staticRouter
]
})
@ -37,9 +38,10 @@ router.beforeEach(async (to:any, from:any, next) => {
router.addRoute(item)
})
let routers = common.concat(accessRoutes)
let routers = staticRouter.concat(accessRoutes)
setMenus([...routers])
})
await common.getDictData()
next({ ...to, replace: true })
} catch (error:any) {

View File

@ -56,8 +56,6 @@ export function generateRoutes(){
method: 'get'
}).then( (res:any) => {
const routers = filterRouter(res.data.result, 0)
console.log(routers)
resolve(routers)
})
})

View File

@ -1,5 +1,25 @@
import { list } from "@/api/system/dict"
const common:any = {}
// 数据字典
let dictList = []
common.getDictData = async function() {
await list({}).then((res:any) =>{
dictList = res.result
})
}
common.getDictGroup = (groupName:any) => {
return dictList.filter(item => item.groupName === groupName)
}
common.getDictLabel = (groupName:any, value:any) => {
let dicts = common.getDictGroup(groupName)
let dict = dicts.find((item:any) =>{
return item.dicValue == value
})
return dict ? dict.dicLabel : null;
}
// 生成UUID
common.uuid = () => {
function S4() {

View File

@ -0,0 +1,22 @@
<script setup lang="ts">
import { reactive, onMounted } from "vue"
const state = reactive({
shadow: 'always',
})
onMounted(()=>{
})
</script>
<template>
<el-card class="codegen-container" :shadow="state.shadow">
开发中
</el-card>
</template>
<style lang="scss" scoped>
.codegen-container{
}
</style>

View File

@ -0,0 +1,22 @@
<script setup lang="ts">
import { reactive, onMounted } from "vue"
const state = reactive({
shadow: 'always',
})
onMounted(()=>{
})
</script>
<template>
<el-card class="interface-container" :shadow="state.shadow">
开发中
</el-card>
</template>
<style lang="scss" scoped>
.interface-container{
}
</style>

View File

@ -0,0 +1,86 @@
<script setup lang="ts">
import { reactive, onMounted } from "vue"
import Table from '@/components/Table.vue'
import { page } from "@/api/monitor/loginLog"
const state = reactive({
loading: false,
page: {
current: 1,
size: 10,
total: 1,
},
operation:{
isShow: false,
width: '80'
},
tableTitle: [
{prop:'username',label:'登录账号'},
{prop:'type',label:'登录类型'},
{prop:'browser',label:'浏览器'},
{prop:'os',label:'操作系统'},
{prop:'address',label:'地理位置'},
{prop:'ip',label:'请求IP'},
{prop:'token',label:'Token'},
{prop:'failPassword',label:'登录密码'},
{prop:'message',label:'异常原因'},
{prop:'createTime',label:'创建时间'}
],
tableData:[],
})
onMounted(()=>{
loginLogPage()
})
function loginLogPage(){
state.loading = true;
page(state.page).then((res:any)=>{
if(res){
state.loading = false;
state.tableData = res.result.records;
state.page.current = res.result.current;
state.page.size = res.result.size;
state.page.total = res.result.total;
}
})
}
function onSizeChange(e){
state.page.size = e;
loginLogPage();
}
function onCurrentChange(e){
state.page.current = e;
loginLogPage();
}
function setCellColor(e, callback){
/**
* e.row表格那一行的数据
* e.column表格单元格那一列的信息
*/
if(e.row.type == '失败' && e.column.property === 'type'){
callback({color: 'var(--delete)', fontWeight: '700'});
} else if(e.row.type == '失败' && e.column.property === 'failPassword'){
callback({color: 'var(--delete)', fontWeight: '700'});
} else if(e.row.type == '成功' && e.column.property === 'type'){
callback({color: 'var(--add)', fontWeight: '700'});
} else {
callback({});
}
}
</script>
<template>
<el-card class="loginlog-container" shadow="always">
<Table :data="state.tableData" :column="state.tableTitle" :operation="state.operation" :page="state.page" :loading="state.loading"
@onSizeChange="onSizeChange" @onCurrentChange="onCurrentChange" @setCellColor="setCellColor">
</Table>
</el-card>
</template>
<style lang="scss" scoped>
.loginlog-container{
}
</style>

View File

@ -0,0 +1,105 @@
<script setup lang="ts">
import {onMounted, reactive, ref, unref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import type {FormInstance} from 'element-plus'
import Table from '@/components/Table.vue'
import {page,kick} from '@/api/monitor/onlineUser'
const searchForm = reactive({
username: null
})
const table = reactive({
loading: false,
page: {
current: 1,
size: 10,
total: 1,
},
operation:{
isShow: true,
width: '80'
},
tableTitle: [
{prop:'',label:'',fixed:'left'},
{prop:'username',label:'登录账号'},
{prop:'address',label:'地理位置'},
{prop:'ip',label:'请求IP'},
{prop:'browser',label:'浏览器'},
{prop:'os',label:'操作系统'},
{prop:'createTime',label:'登录时间'}
],
tableData:[],
})
onMounted(()=>{
onOnlineUserPage()
})
function onOnlineUserPage(){
table.loading = true;
page(Object.assign(table.page, searchForm)).then((res:any)=>{
if(res){
table.loading = false;
table.tableData = res.result.records;
table.page.current = res.result.current;
table.page.size = res.result.size;
table.page.total = res.result.total;
}
})
}
function onSizeChange(e){
table.page.size = e;
onOnlineUserPage();
}
function onCurrentChange(e){
table.page.current = e;
onOnlineUserPage();
}
function onRefresh(){
searchForm.username = null
onOnlineUserPage();
}
function onSearch(){
onOnlineUserPage();
}
function onKick(val:any){
ElMessageBox.confirm('确定将该用户踢下线吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
kick(val.column.row.token).then(res=>{
if(res){
ElMessage.success('操作成功!');
onOnlineUserPage();
}
})
}).catch(e=>{
console.log(e)
})
}
</script>
<template>
<el-card class="onlineuser-container" shadow="always">
<Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :page="table.page" :loading="table.loading"
@onSizeChange="onSizeChange" @onCurrentChange="onCurrentChange">
<template #search>
<div><el-input v-model="searchForm.username" placeholder="请输入登录名称"></el-input></div>
<div><el-button @click="onRefresh" icon="RefreshRight" circle></el-button></div>
<div><el-button @click="onSearch" type="primary" icon="Search">查询</el-button></div>
</template>
<template #column="scope">
<el-button @click="onKick(scope)" type='primary' text='primary' style="color:var(--edit); padding:0;">踢人</el-button>
</template>
</Table>
</el-card>
</template>
<style scoped lang="scss">
.onlineuser-container{
}
</style>

View File

@ -0,0 +1,140 @@
<script setup lang="ts">
import { reactive, onMounted } from "vue"
import Table from '@/components/Table.vue'
import { page } from "@/api/monitor/operLog"
const state = reactive({
loading: false,
page: {
current: 1,
size: 10,
total: 1,
},
operation:{
isShow: true,
width: '80'
},
tableTitle: [
{prop:'module',label:'功能模块'},
{prop:'message',label:'操作描述'},
{prop:'type',label:'操作类型',type:'tag',option:{size:'small',effect:'plain',typeList:[
{value: 'INSERT', label: 'success'},
{value: 'UPDATE', label: 'warning'},
{value: 'DELETE', label: 'danger'},
{value: 'SELECT', label: 'info'},
]}
},
{prop:'takeUpTime',label:'耗时(ms)'},
{prop:'status',label:'状态', type:'dict',dictType: 'oper_log_status'},
{prop:'method',label:'操作方法'},
{prop:'uri',label:'请求URI'},
{prop:'ip',label:'请求IP'},
{prop:'userName',label:'用户名称'},
{prop:'createTime',label:'创建时间'}
],
tableData:[],
detailVisible: false,
detail:{},
})
onMounted(()=>{
operLogPage()
})
function operLogPage(){
state.loading = true;
page(state.page).then((res:any)=>{
if(res){
state.loading = false;
state.tableData = res.result.records;
state.page.current = res.result.current;
state.page.size = res.result.size;
state.page.total = res.result.total;
}
})
}
function onSizeChange(e){
state.page.size = e;
operLogPage();
}
function onCurrentChange(e){
state.page.current = e;
operLogPage();
}
function onDetail(val:any){
state.detail = val.column.row;
state.detailVisible = true;
}
function setCellColor(e, callback){
/**
* e.row表格那一行的数据
* e.column表格单元格那一列的信息
*/
if(e.row.status == '失败' && e.column.property === 'status'){
callback({color: 'var(--delete)', fontWeight: '700'});
} else if(e.column.property === 'takeUpTime'){
callback({color: 'var(--delete)'});
} else {
callback({});
}
}
</script>
<template>
<el-card class="operlog-container" shadow="always">
<Table :data="state.tableData" :column="state.tableTitle" :operation="state.operation" :page="state.page" :loading="state.loading"
@onSizeChange="onSizeChange" @onCurrentChange="onCurrentChange" @setCellColor="setCellColor">
<template #column="scope">
<el-button @click="onDetail(scope)" type='primary' text='primary' style="color:var(--theme); padding:0;">详情</el-button>
</template>
</Table>
<el-dialog v-model="state.detailVisible" title="日志详情" :show-close="false" width="60%">
<el-descriptions :column="3" border>
<el-descriptions-item label-align="right" label="功能模块" :min-width="80">{{state.detail.module}}</el-descriptions-item>
<el-descriptions-item label-align="right" label="操作状态">
<el-tag v-if="state.detail.status == '1'" type="danger">异常</el-tag>
<el-tag v-else type="success">成功</el-tag>
</el-descriptions-item>
<el-descriptions-item label-align="right" label="耗时">
<span style="color:red;">{{state.detail.takeUpTime}} ms</span>
</el-descriptions-item>
<el-descriptions-item label-align="right" label="操作描述">{{state.detail.message}}</el-descriptions-item>
<el-descriptions-item label-align="right" label="操作类型">
<el-tag v-if="state.detail.type == 'SELECT'">{{state.detail.type}}</el-tag>
<el-tag v-else-if="state.detail.type == 'INSERT'" type="success">{{state.detail.type}}</el-tag>
<el-tag v-else-if="state.detail.type == 'UPDATE'" type="warning">{{state.detail.type}}</el-tag>
<el-tag v-else-if="state.detail.type == 'DELETE'" type="danger">{{state.detail.type}}</el-tag>
<el-tag v-else type="info">{{state.detail.type}}</el-tag>
</el-descriptions-item>
<el-descriptions-item label-align="right" label="操作用户">{{state.detail.userName}}</el-descriptions-item>
<el-descriptions-item label-align="right" label="请求URL">{{state.detail.uri}}</el-descriptions-item>
<el-descriptions-item label-align="right" label="请求IP">{{state.detail.ip}}</el-descriptions-item>
<el-descriptions-item label-align="right" label="创建时间">{{state.detail.createTime}}</el-descriptions-item>
<el-descriptions-item label-align="right" :span="3" label="操作方法">{{state.detail.method}}</el-descriptions-item>
<el-descriptions-item label-align="right" :span="3" label="请求参数">
<div class="detail-text scroll-div">{{state.detail.reqParam}}</div>
</el-descriptions-item>
<el-descriptions-item v-if="state.detail.status == '0'" label-align="right" :span="3" label="响应参数">
<div class="detail-text scroll-div">{{state.detail.resParam}}</div>
</el-descriptions-item>
<el-descriptions-item v-if="state.detail.status == '1'" label-align="right" :span="3" label="异常信息">
<div class="detail-text scroll-div">{{state.detail.unusual}}</div>
</el-descriptions-item>
</el-descriptions>
</el-dialog>
</el-card>
</template>
<style lang="scss" scoped>
.operlog-container{
.detail-text{
max-height: 400px;
overflow: auto;
}
.el-descriptions__label{
width: 80px;
}
}
</style>

View File

@ -2,8 +2,9 @@
import {onMounted, reactive, ref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import type {FormInstance} from 'element-plus'
import common from '@/utils/common'
import Table from '@/components/Table.vue'
import {list,save,update,del} from '@/api/system/dict'
import {tree,save,update,del} from '@/api/system/dict'
const table = reactive({
loading: false,
@ -14,7 +15,7 @@
tableTitle: [
{prop:'dicLabel',label:'字典标签',align:'left'},
{prop:'groupName',label:'分组名称'},
{prop:'type',label:'字典类型'},
{prop:'type',label:'字典类型',type:'dict',dictType:'business_type'},
{prop:'dicValue',label:'字典值'},
{prop:'sort',label:'排序'},
{prop:'createTime',label:'创建时间'},
@ -29,7 +30,7 @@
function onDictList(){
table.loading = true;
list({}).then((res:any)=>{
tree({}).then((res:any)=>{
if(res){
table.loading = false;
table.tableData = res.result;
@ -104,6 +105,7 @@
if(res){
ElMessage.success('删除成功!');
onDictList();
common.getDictData()
}
})
}).catch(e=>{
@ -120,6 +122,7 @@
if(res){
ElMessage.success("添加成功!");
onDictList()
common.getDictData()
}
})
} else {
@ -127,6 +130,7 @@
if(res){
ElMessage.success("更新成功!");
onDictList()
common.getDictData()
}
})
}

View File

@ -19,13 +19,13 @@
chineseName: '',
englishName: '',
sort: 0,
component: '',
component: null,
openMode: 0,
isDel: 0,
keepAlive: 0,
isShow: 0,
remarks: '',
permission: ''
permission: null
},
menuId: null,
iconVisible: false,
@ -88,13 +88,13 @@
chineseName: '',
englishName: '',
sort: 0,
component: '',
component: null,
openMode: 0,
isDel: 0,
keepAlive: 0,
isShow: 0,
remarks: '',
permission: ''
permission: null
}
} else if(val == 2) {
state.operate = 2;
@ -128,7 +128,7 @@
keepAlive: 0,
isShow: 0,
remarks: '',
permission: ''
permission: null
};
onMenuTree();
}
@ -173,7 +173,7 @@
chineseName: '',
englishName: '',
sort: 0,
component: '',
component: null,
openMode: 0,
isDel: 0,
keepAlive: 0,

View File

@ -24,14 +24,20 @@
{prop:'',label:'',fixed:'left'},
{prop:'username',label:'用户名称'},
{prop:'nickname',label:'用户昵称'},
{prop:'type',label:'用户类型'},
{prop:'type',label:'用户类型',type:'dict',dictType:'user_type'},
{prop:'avatar',label:'头像'},
{prop:'phone',label:'手机号'},
{prop:'gender',label:'性别'},
{prop:'gender',label:'性别',type:'dict',dictType:'user_gender'},
{prop:'birthday',label:'出生日期'},
{prop:'email',label:'邮箱'},
{prop:'address',label:'地址'},
{prop:'isLogin',label:'禁止登录'},
{prop:'isLogin',label:'是否禁用',type:'switch',
option:{
activeValue:0,activeColor:'#13ce66',activeText:'启用',
inactiveValue:1,inactiveColor:'#ff4949',inactiveText:'禁用',
inlinePrompt: false
}
},
{prop:'updateTime',label:'更新时间'},
{prop:'remarks',label:'描述'}
],
@ -71,6 +77,18 @@
onUserPage();
}
function onSwitchChange(row:any){
update({
id: row.id,
isLogin: row.isLogin
}).then(res=>{
if(res){
ElMessage.success('操作成功!');
onUserPage();
}
});
}
const formRef = ref<FormInstance>();
const form = reactive({
userVisible: false,
@ -201,7 +219,7 @@
<template>
<el-card class="user-container" shadow="always">
<Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :page="table.page" :loading="table.loading"
@onSizeChange="onSizeChange" @onCurrentChange="onCurrentChange">
@onSizeChange="onSizeChange" @onCurrentChange="onCurrentChange" @onSwitchChange="onSwitchChange">
<template #search>
<div><el-button type="primary" @click="onAddRole">添加</el-button></div>
<div><el-input v-model="searchForm.username" placeholder="请输入名称"></el-input></div>

View File

@ -15,6 +15,12 @@ public class Constants {
public final static Integer NOT_DEL_FALG = 0;
public final static Integer IS_DEL_FALG = 1;
/**
* 用户是否禁用0正常1禁用
*/
public final static Integer USER_IS_LOGIN_IN = 0;
public final static Integer USER_IS_LOGIN_ON = 1;
/**
* 操作日志状态0成功1失败
*/

View File

@ -8,6 +8,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tansci.common.WrapMapper;
import com.tansci.common.Wrapper;
import com.tansci.common.annotation.Log;
import com.tansci.common.constant.Constants;
import com.tansci.domain.SysLoginLog;
import com.tansci.domain.SysUser;
import com.tansci.domain.vo.SysUserVo;
@ -66,14 +68,16 @@ public class AuthController {
}
@ApiOperation(value = "在线用户", notes = "在线用户")
@Log(modul = "鉴权管理", type = Constants.SELECT, desc = "在线用户")
@GetMapping("/onlineUser")
public Wrapper<IPage<SysLoginLog>> onlineUser(Page page, String username) {
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysLoginLogService.onlineUser(page, username));
}
@ApiOperation(value = "踢人", notes = "踢人")
@GetMapping("/kick")
public Wrapper<Object> kick(String token) {
@Log(modul = "鉴权管理", type = Constants.UPDATE, desc = "踢人")
@GetMapping("/kick/{token}")
public Wrapper<Object> kick(@PathVariable String token) {
StpUtil.logoutByTokenValue(token);
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, "ok");
}

View File

@ -32,8 +32,16 @@ public class SysDictController {
@Autowired
private SysDictService sysDictService;
@ApiOperation(value = "列表树", notes = "列表树")
@Log(modul = "字典管理", type = Constants.SELECT, desc = "列表树")
@GetMapping("/tree")
@SaCheckPermission("dict:list")
public Wrapper<List<SysDict>> tree(SysDict dict) {
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysDictService.tree(dict));
}
@ApiOperation(value = "列表", notes = "列表")
@Log(modul = "字典管理-列表", type = Constants.SELECT, desc = "列表")
@Log(modul = "字典管理", type = Constants.SELECT, desc = "列表")
@GetMapping("/list")
@SaCheckPermission("dict:list")
public Wrapper<List<SysDict>> list(SysDict dict) {
@ -41,7 +49,7 @@ public class SysDictController {
}
@ApiOperation(value = "添加", notes = "添加")
@Log(modul = "字典管理-添加", type = Constants.INSERT, desc = "添加")
@Log(modul = "字典管理", type = Constants.INSERT, desc = "添加")
@PostMapping("/save")
@SaCheckPermission("dict:save")
public Wrapper<Object> save(@RequestBody SysDict dict) {
@ -51,7 +59,7 @@ public class SysDictController {
}
@ApiOperation(value = "删除", notes = "删除")
@Log(modul = "字典管理-删除", type = Constants.DELETE, desc = "删除")
@Log(modul = "字典管理", type = Constants.DELETE, desc = "删除")
@GetMapping("/delete/{id}")
@SaCheckPermission("dict:delete")
public Wrapper<Object> delete(@PathVariable String id) {
@ -59,7 +67,7 @@ public class SysDictController {
}
@ApiOperation(value = "修改", notes = "修改")
@Log(modul = "字典管理-修改", type = Constants.UPDATE, desc = "修改")
@Log(modul = "字典管理", type = Constants.UPDATE, desc = "修改")
@PostMapping("/update")
@SaCheckPermission("dict:update")
public Wrapper<Object> update(@RequestBody SysDict dict) {

View File

@ -37,14 +37,14 @@ public class SysLogController {
private SysOperLogService sysOperLogService;
@ApiOperation(value = "登录日志", notes = "登录日志")
@Log(modul = "日志管理-登录日志", type = Constants.DELETE, desc = "登录日志")
@Log(modul = "日志管理", type = Constants.DELETE, desc = "登录日志")
@GetMapping("/loginLog")
public Wrapper<IPage<SysLoginLog>> loginLog(Page page) {
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysLoginLogService.page(page));
}
@ApiOperation(value = "操作日志", notes = "操作日志")
@Log(modul = "日志管理-操作日志", type = Constants.DELETE, desc = "操作日志")
@Log(modul = "日志管理", type = Constants.DELETE, desc = "操作日志")
@GetMapping("/operLog")
public Wrapper<IPage<SysOperLog>> operLog(Page page) {
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysOperLogService.page(page));

View File

@ -34,14 +34,14 @@ public class SysMenuController {
private SysMenuService sysMenuService;
@ApiOperation(value = "当前用户权限菜单列表", notes = "当前用户权限菜单列表")
@Log(modul = "菜单管理-当前用户权限菜单列表", type = Constants.SELECT, desc = "当前用户权限菜单列表")
@Log(modul = "菜单管理", type = Constants.SELECT, desc = "当前用户权限菜单列表")
@GetMapping("/menus")
public Wrapper<List<SysMenuVo>> menus() {
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysMenuService.menus());
}
@ApiOperation(value = "菜单树", notes = "菜单树")
@Log(modul = "菜单管理-菜单树", type = Constants.SELECT, desc = "菜单树")
@Log(modul = "菜单管理", type = Constants.SELECT, desc = "菜单树")
@GetMapping("/tree")
@SaCheckPermission("menu:list")
public Wrapper<List<SysMenu>> tree(SysMenu menu) {
@ -49,7 +49,7 @@ public class SysMenuController {
}
@ApiOperation(value = "详情", notes = "详情")
@Log(modul = "菜单管理-详情", type = Constants.SELECT, desc = "详情")
@Log(modul = "菜单管理", type = Constants.SELECT, desc = "详情")
@GetMapping("/getById/{id}")
@SaCheckPermission("menu:view")
public Wrapper<SysMenu> getById(@PathVariable String id) {
@ -57,7 +57,7 @@ public class SysMenuController {
}
@ApiOperation(value = "添加", notes = "添加")
@Log(modul = "菜单管理-添加", type = Constants.INSERT, desc = "添加")
@Log(modul = "菜单管理", type = Constants.INSERT, desc = "添加")
@PostMapping("/save")
@SaCheckPermission("menu:save")
public Wrapper<Object> save(@RequestBody SysMenu menu) {
@ -68,7 +68,7 @@ public class SysMenuController {
}
@ApiOperation(value = "删除", notes = "删除")
@Log(modul = "菜单管理-删除", type = Constants.DELETE, desc = "删除")
@Log(modul = "菜单管理", type = Constants.DELETE, desc = "删除")
@GetMapping("/delete/{id}")
@SaCheckPermission("menu:delete")
public Wrapper<Object> delete(@PathVariable String id) {
@ -76,7 +76,7 @@ public class SysMenuController {
}
@ApiOperation(value = "修改", notes = "修改")
@Log(modul = "菜单管理-修改", type = Constants.UPDATE, desc = "修改")
@Log(modul = "菜单管理", type = Constants.UPDATE, desc = "修改")
@PostMapping("/update")
@SaCheckPermission("menu:update")
public Wrapper<Object> update(@RequestBody SysMenu menu) {

View File

@ -34,7 +34,7 @@ public class SysOrgController {
private SysOrgService sysOrgService;
@ApiOperation(value = "列表", notes = "列表")
@Log(modul = "组织管理-列表", type = Constants.SELECT, desc = "列表")
@Log(modul = "组织管理", type = Constants.SELECT, desc = "列表")
@GetMapping("/list")
@SaCheckPermission("org:list")
public Wrapper<List<SysOrg>> list(SysOrg org) {
@ -42,7 +42,7 @@ public class SysOrgController {
}
@ApiOperation(value = "添加", notes = "添加")
@Log(modul = "组织管理-添加", type = Constants.INSERT, desc = "添加")
@Log(modul = "组织管理", type = Constants.INSERT, desc = "添加")
@PostMapping("/save")
@SaCheckPermission("org:save")
public Wrapper<Object> save(@RequestBody SysOrg org) {
@ -54,7 +54,7 @@ public class SysOrgController {
}
@ApiOperation(value = "删除", notes = "删除")
@Log(modul = "组织管理-删除", type = Constants.DELETE, desc = "删除")
@Log(modul = "组织管理", type = Constants.DELETE, desc = "删除")
@GetMapping("/delete/{id}")
@SaCheckPermission("org:delete")
public Wrapper<Object> delete(@PathVariable String id) {
@ -62,7 +62,7 @@ public class SysOrgController {
}
@ApiOperation(value = "修改", notes = "修改")
@Log(modul = "组织管理-修改", type = Constants.UPDATE, desc = "修改")
@Log(modul = "组织管理", type = Constants.UPDATE, desc = "修改")
@PostMapping("/update")
@SaCheckPermission("org:update")
public Wrapper<Object> update(@RequestBody SysOrg org) {

View File

@ -34,14 +34,14 @@ public class SysRoleController {
private SysRoleService sysRoleService;
@ApiOperation(value = "分页", notes = "分页")
@Log(modul = "角色管理-分页", type = Constants.SELECT, desc = "列表")
@Log(modul = "角色管理", type = Constants.SELECT, desc = "列表")
@GetMapping("/page")
public Wrapper<IPage<SysRole>> page(Page page, SysRole role) {
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysRoleService.page(page, role));
}
@ApiOperation(value = "列表", notes = "列表")
@Log(modul = "角色管理-列表", type = Constants.SELECT, desc = "列表")
@Log(modul = "角色管理", type = Constants.SELECT, desc = "列表")
@GetMapping("/list")
@SaCheckPermission("role:list")
public Wrapper<List<SysRole>> list(SysRole role) {
@ -49,7 +49,7 @@ public class SysRoleController {
}
@ApiOperation(value = "添加", notes = "添加")
@Log(modul = "角色管理-添加", type = Constants.INSERT, desc = "添加")
@Log(modul = "角色管理", type = Constants.INSERT, desc = "添加")
@PostMapping("/save")
@SaCheckPermission("role:save")
public Wrapper<Object> save(@RequestBody SysRole role) {
@ -57,7 +57,7 @@ public class SysRoleController {
}
@ApiOperation(value = "删除", notes = "删除")
@Log(modul = "角色管理-删除", type = Constants.DELETE, desc = "删除")
@Log(modul = "角色管理", type = Constants.DELETE, desc = "删除")
@GetMapping("/delete/{id}")
@SaCheckPermission("role:delete")
public Wrapper<Object> delete(@PathVariable String id) {
@ -65,7 +65,7 @@ public class SysRoleController {
}
@ApiOperation(value = "修改", notes = "修改")
@Log(modul = "角色管理-修改", type = Constants.UPDATE, desc = "修改")
@Log(modul = "角色管理", type = Constants.UPDATE, desc = "修改")
@PostMapping("/update")
@SaCheckPermission("role:update")
public Wrapper<Object> update(@RequestBody SysRole role) {
@ -73,7 +73,7 @@ public class SysRoleController {
}
@ApiOperation(value = "数据权限", notes = "数据权限")
@Log(modul = "角色管理-数据权限", type = Constants.UPDATE, desc = "数据权限")
@Log(modul = "角色管理", type = Constants.UPDATE, desc = "数据权限")
@PostMapping("/dataPermissions")
@SaCheckPermission("role:data")
public Wrapper<Object> dataPermissions(@RequestBody SysRole role) {
@ -81,7 +81,7 @@ public class SysRoleController {
}
@ApiOperation(value = "获取权限组织", notes = "获取权限组织")
@Log(modul = "角色管理-获取权限组织", type = Constants.UPDATE, desc = "获取权限组织")
@Log(modul = "角色管理", type = Constants.UPDATE, desc = "获取权限组织")
@GetMapping("/orgList/{roleId}")
@SaCheckPermission("role:data")
public Wrapper<Object> orgList(@PathVariable String roleId) {
@ -89,7 +89,7 @@ public class SysRoleController {
}
@ApiOperation(value = "菜单权限", notes = "菜单权限")
@Log(modul = "角色管理-菜单权限", type = Constants.UPDATE, desc = "菜单权限")
@Log(modul = "角色管理", type = Constants.UPDATE, desc = "菜单权限")
@PostMapping("/menuPermissions")
@SaCheckPermission("role:menu")
public Wrapper<Object> menuPermissions(@RequestBody SysRole role) {
@ -97,7 +97,7 @@ public class SysRoleController {
}
@ApiOperation(value = "获取权限菜单", notes = "获取权限菜单")
@Log(modul = "角色管理-获取权限菜单", type = Constants.UPDATE, desc = "获取权限菜单")
@Log(modul = "角色管理", type = Constants.UPDATE, desc = "获取权限菜单")
@GetMapping("/menuList/{roleId}")
@SaCheckPermission("role:menu")
public Wrapper<Object> menuList(@PathVariable String roleId) {

View File

@ -34,14 +34,14 @@ public class SysUserController {
private SysUserService sysUserService;
@ApiOperation(value = "分页", notes = "分页")
@Log(modul = "用户管理-分页", type = Constants.SELECT, desc = "分页")
@Log(modul = "用户管理", type = Constants.SELECT, desc = "分页")
@GetMapping("/page")
public Wrapper<IPage<SysUser>> page(Page page, SysUser user) {
return WrapMapper.wrap(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, sysUserService.page(page, user));
}
@ApiOperation(value = "列表", notes = "列表")
@Log(modul = "用户管理-列表", type = Constants.SELECT, desc = "列表")
@Log(modul = "用户管理", type = Constants.SELECT, desc = "列表")
@GetMapping("/list")
@SaCheckPermission("user:list")
public Wrapper<List<SysUser>> list(SysUser user) {
@ -49,7 +49,7 @@ public class SysUserController {
}
@ApiOperation(value = "添加", notes = "添加")
@Log(modul = "用户管理-添加", type = Constants.INSERT, desc = "添加")
@Log(modul = "用户管理", type = Constants.INSERT, desc = "添加")
@PostMapping("/save")
@SaCheckPermission("user:save")
public Wrapper<Object> save(@RequestBody SysUser user) {
@ -57,7 +57,7 @@ public class SysUserController {
}
@ApiOperation(value = "修改", notes = "修改")
@Log(modul = "用户管理-修改", type = Constants.UPDATE, desc = "修改")
@Log(modul = "用户管理", type = Constants.UPDATE, desc = "修改")
@PostMapping("/update")
@SaCheckPermission("user:update")
public Wrapper<Object> update(@RequestBody SysUser user) {
@ -65,7 +65,7 @@ public class SysUserController {
}
@ApiOperation(value = "删除", notes = "删除")
@Log(modul = "用户管理-删除", type = Constants.DELETE, desc = "删除")
@Log(modul = "用户管理", type = Constants.DELETE, desc = "删除")
@GetMapping("/delete/{id}")
@SaCheckPermission("user:delete")
public Wrapper<Object> delete(@PathVariable String id) {
@ -73,7 +73,7 @@ public class SysUserController {
}
@ApiOperation(value = "修改密码", notes = "修改密码")
@Log(modul = "用户管理-修改密码", type = Constants.UPDATE, desc = "修改密码")
@Log(modul = "用户管理", type = Constants.UPDATE, desc = "修改密码")
@PostMapping("/modifyPass")
@SaCheckPermission("user:password")
public Wrapper<Object> modifyPass(@RequestBody SysUser user) {

View File

@ -57,6 +57,9 @@ public class SysLoginLog {
@ApiModelProperty(value = "token")
private String token;
@ApiModelProperty(value = "失败原因")
private String message;
@ApiModelProperty(value = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
private LocalDateTime createTime;

View File

@ -14,6 +14,8 @@ import java.util.List;
**/
public interface SysDictService extends IService<SysDict> {
List<SysDict> tree(SysDict dict);
List<SysDict> list(SysDict dict);
Object delete(String id);

View File

@ -24,10 +24,12 @@ import java.util.stream.Collectors;
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements SysDictService {
@Override
public List<SysDict> list(SysDict dict) {
public List<SysDict> tree(SysDict dict) {
List<SysDict> list = this.baseMapper.selectList(
Wrappers.<SysDict>lambdaQuery()
.eq(Objects.nonNull(dict.getParentId()), SysDict::getParentId, dict.getParentId())
.eq(Objects.nonNull(dict.getGroupName()), SysDict::getGroupName, dict.getGroupName())
.eq(Objects.nonNull(dict.getDicValue()), SysDict::getDicValue, dict.getDicValue())
.orderByDesc(SysDict::getUpdateTime)
);
list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SysDict::getId))), ArrayList::new));
@ -38,6 +40,17 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
return orgList;
}
@Override
public List<SysDict> list(SysDict dict) {
return this.baseMapper.selectList(
Wrappers.<SysDict>lambdaQuery()
.eq(Objects.nonNull(dict.getParentId()), SysDict::getParentId, dict.getParentId())
.eq(Objects.nonNull(dict.getGroupName()), SysDict::getGroupName, dict.getGroupName())
.eq(Objects.nonNull(dict.getDicValue()), SysDict::getDicValue, dict.getDicValue())
.orderByDesc(SysDict::getUpdateTime)
);
}
@Override
public Object delete(String id) {
List<SysDict> orgs = this.baseMapper.selectList(Wrappers.<SysDict>lambdaQuery().eq(SysDict::getParentId, id));

View File

@ -11,7 +11,9 @@ import com.tansci.service.SysLoginLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @ClassName SysLoginLogServiceImpl.java
@ -26,11 +28,15 @@ public class SysLoginLogServiceImpl extends ServiceImpl<SysLoginLogMapper, SysLo
@Override
public IPage<SysLoginLog> onlineUser(Page page, String username) {
List<String> tokens = StpUtil.searchTokenValue("", -1, 99999, true);
if (Objects.nonNull(tokens) && tokens.size() > 0) {
return this.baseMapper.selectPage(page,
Wrappers.<SysLoginLog>lambdaQuery()
.in(SysLoginLog::getToken, StpUtil.searchTokenValue("", -1, 0, true))
.in(SysLoginLog::getToken, tokens.stream().map(item -> item.replace("token:login:token:", "")).collect(Collectors.toList()))
.eq(Objects.nonNull(username), SysLoginLog::getUsername, username)
);
}
return new Page<>();
}
}

View File

@ -70,6 +70,7 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
.eq(SysMenu::getIsDel, Constants.NOT_DEL_FALG)
.eq(SysMenu::getIsShow, 1)
.eq(Objects.nonNull(menuIds) && menuIds.size() > 0, SysMenu::getId, menuIds)
.orderByAsc(SysMenu::getSort)
);
List<SysMenuVo> newList = new ArrayList<>();

View File

@ -126,15 +126,23 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
String code = (String) request.getSession().getAttribute("verifyCode");
if (Objects.isNull(user.getCode()) || !Objects.equals(code, user.getCode())) {
loginLog.setType("失败");
loginLog.setMessage("验证码有误");
throw new BusinessException("验证码有误,请重新获取!");
}
SysUser sysUser = this.baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, user.getUsername()));
if (Objects.isNull(sysUser) && !Objects.equals(sysUser.getPassword(), Sha256Util.getSHA256(user.getPassword()))) {
loginLog.setType("失败");
loginLog.setMessage("用户名或密码有误");
throw new BusinessException("登录失败,用户名或密码有误!");
}
if(Objects.equals(Constants.USER_IS_LOGIN_ON, sysUser.getIsLogin())){
loginLog.setType("失败");
loginLog.setMessage("该账号已被禁用");
throw new BusinessException("登录失败,该账号已被禁用!");
}
// 生成token
StpUtil.login(sysUser.getId());
loginLog.setToken(StpUtil.getTokenInfo().getTokenValue());