Compare commits

...

2 Commits

Author SHA1 Message Date
joylink_fanyuhong
199e775f81 Merge branch 'develop' of https://gitea.joylink.club/joylink/xian-ncc-da-client into develop 2024-10-18 17:19:42 +08:00
joylink_fanyuhong
e90c25523e 接口调整暂时提交 2024-10-18 17:19:40 +08:00
7 changed files with 204 additions and 20 deletions

View File

@ -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;
} }

View File

@ -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;
}

View File

@ -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,
});
}
}); });
} }

View File

@ -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>

View File

@ -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>

View File

@ -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
View 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;
// },
},
});