Compare commits
2 Commits
00da31059b
...
199e775f81
Author | SHA1 | Date | |
---|---|---|---|
|
199e775f81 | ||
|
e90c25523e |
@ -5,10 +5,16 @@ const LogUriBase = '/api/log';
|
|||||||
|
|
||||||
export interface Record {
|
export interface Record {
|
||||||
id: number;
|
id: number;
|
||||||
|
faceName: string;
|
||||||
eventType: string;
|
eventType: string;
|
||||||
|
subEventType: string;
|
||||||
|
uri: string;
|
||||||
|
method: string;
|
||||||
|
parameters: string;
|
||||||
|
requestSuccess: boolean;
|
||||||
|
userName: string;
|
||||||
fromUserId: number;
|
fromUserId: number;
|
||||||
mobile: string;
|
mobile: string;
|
||||||
userName: string;
|
|
||||||
createDateTime: string;
|
createDateTime: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,3 +72,46 @@ export async function pageQuery(
|
|||||||
});
|
});
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户登出
|
||||||
|
*/
|
||||||
|
export async function logout(): Promise<string> {
|
||||||
|
const response = await api.post(`${UserUriBase}/logout`);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface tokenInfo {
|
||||||
|
token: string;
|
||||||
|
remainingSecond: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新token
|
||||||
|
*/
|
||||||
|
export async function refreshToken(): Promise<tokenInfo> {
|
||||||
|
const response = await api.post(`${UserUriBase}/refresh/token`);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface role {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
roleConfig: {
|
||||||
|
lineId: number;
|
||||||
|
lineType: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
interface userInfo {
|
||||||
|
remainingSecond: number;
|
||||||
|
roles: role[];
|
||||||
|
defaultRole: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户信息
|
||||||
|
*/
|
||||||
|
export async function getUserInfo(): Promise<userInfo> {
|
||||||
|
const response = await api.post(`${UserUriBase}/info`);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
@ -124,6 +124,8 @@ import {
|
|||||||
webSocketConnect,
|
webSocketConnect,
|
||||||
closeWebSocketConnect,
|
closeWebSocketConnect,
|
||||||
} from 'src/components/webSocketConnect';
|
} from 'src/components/webSocketConnect';
|
||||||
|
import { logout } from 'src/api/UserApi';
|
||||||
|
import { ApiError } from 'src/boot/axios';
|
||||||
|
|
||||||
const leftDrawerOpen = ref(false);
|
const leftDrawerOpen = ref(false);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -210,9 +212,18 @@ function logOut() {
|
|||||||
message: '确认是否登出?',
|
message: '确认是否登出?',
|
||||||
cancel: true,
|
cancel: true,
|
||||||
persistent: true,
|
persistent: true,
|
||||||
}).onOk(() => {
|
}).onOk(async () => {
|
||||||
|
try {
|
||||||
|
await logout();
|
||||||
clearJwtToken();
|
clearJwtToken();
|
||||||
router.push({ name: 'login' });
|
router.push({ name: 'login' });
|
||||||
|
} catch (err) {
|
||||||
|
const apiErr = err as ApiError;
|
||||||
|
$q.notify({
|
||||||
|
type: 'negative',
|
||||||
|
message: apiErr.title,
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="q-pa-md">
|
<div class="q-pa-md">
|
||||||
<q-table
|
<q-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
title="报警记录"
|
title="登录记录"
|
||||||
:style="{ height: tableHeight + 'px' }"
|
:style="{ height: tableHeight + 'px' }"
|
||||||
class="my-sticky-virtscroll-table"
|
class="my-sticky-virtscroll-table"
|
||||||
:rows="rows"
|
:rows="rows"
|
||||||
@ -15,6 +15,15 @@
|
|||||||
binary-state-sort
|
binary-state-sort
|
||||||
@request="onRequest"
|
@request="onRequest"
|
||||||
>
|
>
|
||||||
|
<template v-slot:body-cell-subEventType="props">
|
||||||
|
<q-td :props="props">
|
||||||
|
<div class="q-gutter-sm row justify-center">
|
||||||
|
<q-chip outline size="sm" color="primary">
|
||||||
|
{{ getSubEventType(props.row.subEventType) }}
|
||||||
|
</q-chip>
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
<!-- <template v-slot:top-right>
|
<!-- <template v-slot:top-right>
|
||||||
<q-input
|
<q-input
|
||||||
dense
|
dense
|
||||||
@ -78,24 +87,36 @@ onMounted(() => {
|
|||||||
|
|
||||||
const columnDefs: QTableColumn[] = [
|
const columnDefs: QTableColumn[] = [
|
||||||
{ name: 'id', label: 'ID', field: 'id', align: 'center' },
|
{ name: 'id', label: 'ID', field: 'id', align: 'center' },
|
||||||
|
{
|
||||||
|
name: 'subEventType',
|
||||||
|
label: '操作',
|
||||||
|
field: 'subEventType',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'faceName',
|
||||||
|
label: '接口名称',
|
||||||
|
field: 'faceName',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'userName',
|
name: 'userName',
|
||||||
label: '操作人员',
|
label: '操作人员',
|
||||||
field: 'userName',
|
field: 'userName',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'mobile',
|
|
||||||
label: '手机号',
|
|
||||||
field: 'mobile',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'createDateTime',
|
name: 'createDateTime',
|
||||||
label: '记录时间',
|
label: '记录时间',
|
||||||
field: 'createDateTime',
|
field: 'createDateTime',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'requestSuccess',
|
||||||
|
label: '请求成功',
|
||||||
|
field: 'requestSuccess',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
@ -135,4 +156,21 @@ async function onRequest(props: any) {
|
|||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSubEventType(type: string) {
|
||||||
|
switch (type) {
|
||||||
|
case 'LOGIN':
|
||||||
|
return '登录';
|
||||||
|
case 'LOGOUT':
|
||||||
|
return '登出';
|
||||||
|
case 'QUERY':
|
||||||
|
return '查询';
|
||||||
|
case 'SAVE_OR_UPDATE':
|
||||||
|
return '保存';
|
||||||
|
case 'DELETE':
|
||||||
|
return '删除';
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="q-pa-md">
|
<div class="q-pa-md">
|
||||||
<q-table
|
<q-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
title="报警记录"
|
title="操作记录"
|
||||||
:style="{ height: tableHeight + 'px' }"
|
:style="{ height: tableHeight + 'px' }"
|
||||||
class="my-sticky-virtscroll-table"
|
class="my-sticky-virtscroll-table"
|
||||||
:rows="rows"
|
:rows="rows"
|
||||||
@ -15,6 +15,15 @@
|
|||||||
binary-state-sort
|
binary-state-sort
|
||||||
@request="onRequest"
|
@request="onRequest"
|
||||||
>
|
>
|
||||||
|
<template v-slot:body-cell-subEventType="props">
|
||||||
|
<q-td :props="props">
|
||||||
|
<div class="q-gutter-sm row justify-center">
|
||||||
|
<q-chip outline size="sm" color="primary">
|
||||||
|
{{ getSubEventType(props.row.subEventType) }}
|
||||||
|
</q-chip>
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</template>
|
||||||
<!-- <template v-slot:top-right>
|
<!-- <template v-slot:top-right>
|
||||||
<q-input
|
<q-input
|
||||||
dense
|
dense
|
||||||
@ -78,24 +87,36 @@ onMounted(() => {
|
|||||||
|
|
||||||
const columnDefs: QTableColumn[] = [
|
const columnDefs: QTableColumn[] = [
|
||||||
{ name: 'id', label: 'ID', field: 'id', align: 'center' },
|
{ name: 'id', label: 'ID', field: 'id', align: 'center' },
|
||||||
|
{
|
||||||
|
name: 'subEventType',
|
||||||
|
label: '操作',
|
||||||
|
field: 'subEventType',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'faceName',
|
||||||
|
label: '接口名称',
|
||||||
|
field: 'faceName',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'userName',
|
name: 'userName',
|
||||||
label: '操作人员',
|
label: '操作人员',
|
||||||
field: 'userName',
|
field: 'userName',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'mobile',
|
|
||||||
label: '手机号',
|
|
||||||
field: 'mobile',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'createDateTime',
|
name: 'createDateTime',
|
||||||
label: '记录时间',
|
label: '记录时间',
|
||||||
field: 'createDateTime',
|
field: 'createDateTime',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'requestSuccess',
|
||||||
|
label: '请求成功',
|
||||||
|
field: 'requestSuccess',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
@ -135,4 +156,21 @@ async function onRequest(props: any) {
|
|||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSubEventType(type: string) {
|
||||||
|
switch (type) {
|
||||||
|
case 'LOGIN':
|
||||||
|
return '登录';
|
||||||
|
case 'LOGOUT':
|
||||||
|
return '登出';
|
||||||
|
case 'QUERY':
|
||||||
|
return '查询';
|
||||||
|
case 'SAVE_OR_UPDATE':
|
||||||
|
return '保存';
|
||||||
|
case 'DELETE':
|
||||||
|
return '删除';
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -7,7 +7,9 @@ import {
|
|||||||
} from 'vue-router';
|
} from 'vue-router';
|
||||||
|
|
||||||
import routes from './routes';
|
import routes from './routes';
|
||||||
import { getJwtToken } from 'src/configs/TokenManage';
|
import { getJwtToken, saveJwtToken } from 'src/configs/TokenManage';
|
||||||
|
import { getUserInfo, refreshToken } from 'src/api/UserApi';
|
||||||
|
import { useUserStore } from 'src/stores/user-store';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If not building with SSR mode, you can
|
* If not building with SSR mode, you can
|
||||||
@ -42,10 +44,37 @@ export default route(function (/* { store, ssrContext } */) {
|
|||||||
if (!getJwtToken()) {
|
if (!getJwtToken()) {
|
||||||
next({ path: '/login' });
|
next({ path: '/login' });
|
||||||
} else {
|
} else {
|
||||||
|
try {
|
||||||
|
const userInfo = await getUserInfo();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
userStore.defaultRole = userInfo.defaultRole;
|
||||||
|
userStore.roles = userInfo.roles;
|
||||||
|
userStore.remainingSecond = userInfo.remainingSecond;
|
||||||
|
setTimeout(
|
||||||
|
() => handleRefreshToken(),
|
||||||
|
userInfo.remainingSecond * 1000 - 10000
|
||||||
|
);
|
||||||
next();
|
next();
|
||||||
|
} catch (e) {
|
||||||
|
console.error('获取用户信息出错:', e);
|
||||||
|
next({ path: '/login' });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return Router;
|
return Router;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function handleRefreshToken() {
|
||||||
|
try {
|
||||||
|
const tokenInfo = await refreshToken();
|
||||||
|
saveJwtToken(tokenInfo.token);
|
||||||
|
setTimeout(
|
||||||
|
() => handleRefreshToken(),
|
||||||
|
tokenInfo.remainingSecond * 1000 - 10000
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('刷新 token 出错:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
19
src/stores/user-store.ts
Normal file
19
src/stores/user-store.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { role } from 'src/api/UserApi';
|
||||||
|
|
||||||
|
export const useUserStore = defineStore('user', {
|
||||||
|
state: () => ({
|
||||||
|
remainingSecond: 0,
|
||||||
|
roles: [] as role[],
|
||||||
|
defaultRole: '',
|
||||||
|
}),
|
||||||
|
getters: {},
|
||||||
|
actions: {
|
||||||
|
// setRemainingSecond(remainingSecond: number) {
|
||||||
|
// this.remainingSecond = remainingSecond;
|
||||||
|
// },
|
||||||
|
// setDefaultRole(defaultRole: string) {
|
||||||
|
// this.defaultRole = defaultRole;
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user