Browse Source

feat(系统模块): 添加异常信息管理功能

shizhongming 2 years ago
parent
commit
64de355a13
  1. 22
      src/modules/system/views/exception/SysExceptionListView.api.ts
  2. 160
      src/modules/system/views/exception/SysExceptionListView.config.ts
  3. 91
      src/modules/system/views/exception/SysExceptionListView.vue
  4. 33
      src/modules/system/views/exception/components/ExceptionDetailModal.vue
  5. 32
      src/modules/system/views/exception/lang/en_US.ts
  6. 32
      src/modules/system/views/exception/lang/zh_CN.ts

22
src/modules/system/views/exception/SysExceptionListView.api.ts

@ -0,0 +1,22 @@
import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
enum Api {
list = 'sys/exception/list',
getById = 'sys/exception/getById',
}
export const listApi = (params) => {
return defHttp.post({
service: ApiServiceEnum.SMART_SYSTEM,
url: Api.list,
data: params,
});
};
export const getById = (id) => {
return defHttp.post({
service: ApiServiceEnum.SMART_SYSTEM,
url: Api.getById,
data: id,
});
};

160
src/modules/system/views/exception/SysExceptionListView.config.ts

@ -0,0 +1,160 @@
import type { SmartColumn, SmartSearchFormSchema } from '@/components/SmartTable';
import { tableBooleanColumnClass } from '@/components/SmartTable';
export const getTableColumns = (): SmartColumn[] => {
return [
{
type: 'checkbox',
width: 60,
align: 'center',
fixed: 'left',
},
{
field: 'id',
visible: false,
title: '',
width: 120,
},
{
field: 'exceptionMessage',
fixed: 'left',
title: '{system.views.exception.title.exceptionMessage}',
width: 200,
},
{
field: 'requestIp',
title: '{system.views.exception.title.requestIp}',
width: 120,
},
{
field: 'serverIp',
title: '{system.views.exception.title.serverIp}',
width: 120,
},
{
field: 'requestPath',
title: '{system.views.exception.title.requestPath}',
width: 200,
},
{
field: 'operateBy',
title: '{system.views.exception.title.operateUser}',
width: 120,
},
{
field: 'createTime',
sortable: true,
title: '{common.table.createTime}',
width: 150,
},
{
...tableBooleanColumnClass('{system.views.exception.title.userFeedback}', 'userFeedback'),
width: 120,
sortable: true,
},
{
field: 'feedbackMessage',
title: '{system.views.exception.title.feedbackMessage}',
width: 160,
},
{
field: 'feedbackTime',
title: '{system.views.exception.title.feedbackTime}',
width: 150,
},
{
...tableBooleanColumnClass('{system.views.exception.title.resolved}', 'resolved'),
width: 120,
sortable: true,
},
{
field: 'resolvedMessage',
title: '{system.views.exception.title.resolvedMessage}',
width: 160,
},
{
field: 'resolvedUserId',
title: '{system.views.exception.title.resolvedUserId}',
width: 120,
},
{
field: 'resolvedTime',
title: '{system.views.exception.title.resolvedTime}',
width: 150,
},
{
title: '{common.table.operation}',
field: 'operation',
width: 120,
fixed: 'right',
slots: {
default: 'table-operation',
},
},
];
};
const getYesNoOptions = (t: Function) => {
return [
{
label: t('common.form.yes'),
value: 1,
},
{
label: t('common.form.no'),
value: 0,
},
];
};
export const getSearchFormSchemas = (t: Function): SmartSearchFormSchema[] => {
return [
{
label: t('system.views.exception.title.exceptionMessage'),
field: 'exceptionMessage',
component: 'Input',
searchSymbol: 'like',
componentProps: {
style: { width: '150px' },
},
},
{
label: t('system.views.exception.title.requestIp'),
field: 'requestIp',
component: 'Input',
searchSymbol: 'like',
componentProps: {
style: { width: '150px' },
},
},
{
label: t('system.views.exception.title.serverIp'),
field: 'serverIp',
component: 'Input',
searchSymbol: 'like',
componentProps: {
style: { width: '150px' },
},
},
{
label: t('system.views.exception.title.userFeedback'),
field: 'userFeedback',
component: 'Select',
searchSymbol: '=',
componentProps: {
options: getYesNoOptions(t),
style: { width: '150px' },
},
},
{
label: t('system.views.exception.title.resolved'),
field: 'resolved',
component: 'Select',
searchSymbol: '=',
componentProps: {
options: getYesNoOptions(t),
style: { width: '150px' },
},
},
];
};

91
src/modules/system/views/exception/SysExceptionListView.vue

@ -0,0 +1,91 @@
<template>
<div class="full-height page-container">
<SmartTable @register="registerTable" :size="getTableSize">
<template #table-operation="{ row }">
<SmartVxeTableAction :actions="getTableActions(row)" />
</template>
</SmartTable>
<ExceptionDetailModal @register="registerModal" />
</div>
</template>
<script lang="ts" setup>
import {
useSmartTable,
SmartTable,
SmartVxeTableAction,
ActionItem,
} from '@/components/SmartTable';
import { useModal } from '@/components/Modal';
import { useI18n } from '@/hooks/web/useI18n';
import { useSizeSetting } from '@/hooks/setting/UseSizeSetting';
import { getSearchFormSchemas, getTableColumns } from './SysExceptionListView.config';
import { listApi } from './SysExceptionListView.api';
import ExceptionDetailModal from './components/ExceptionDetailModal.vue';
const { t } = useI18n();
const { getTableSize } = useSizeSetting();
const getTableActions = (row): ActionItem[] => {
return [
{
label: t('system.views.exception.title.showStackTrace'),
onClick: () => {
openModal(true, row.id);
},
},
];
};
const [registerModal, { openModal }] = useModal();
const [registerTable] = useSmartTable({
id: 'smart-system-tool-exception',
customConfig: { storage: true },
border: true,
showOverflow: 'tooltip',
height: 'auto',
stripe: true,
pagerConfig: true,
useSearchForm: true,
searchFormConfig: {
layout: 'inline',
searchWithSymbol: true,
schemas: getSearchFormSchemas(t),
colon: true,
actionColOptions: {
span: undefined,
},
compact: true,
},
toolbarConfig: {
refresh: true,
zoom: true,
column: { columnOrder: true },
},
sortConfig: {
remote: true,
defaultSort: {
field: 'createTime',
order: 'desc',
},
},
columns: getTableColumns(),
columnConfig: {
resizable: true,
},
proxyConfig: {
ajax: {
query: ({ ajaxParameter }) =>
listApi({
sortName: 'createTime',
sortOrder: 'desc',
...ajaxParameter,
}),
},
},
});
</script>
<style scoped></style>

33
src/modules/system/views/exception/components/ExceptionDetailModal.vue

@ -0,0 +1,33 @@
<template>
<BasicModal
defaultFullscreen
@register="registerModal"
:title="$t('system.views.exception.title.stackTrace')"
>
<div style=" height: 100%;overflow: auto">
<div style="white-space: pre">
{{ exceptionData.stackTrace }}
</div>
</div>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { useModalInner, BasicModal } from '@/components/Modal';
import { getById } from '../SysExceptionListView.api';
const exceptionData = ref<Recordable>({});
const [registerModal, { changeLoading }] = useModalInner(async (id) => {
exceptionData.value = {};
try {
changeLoading(true);
exceptionData.value = await getById(id);
} finally {
changeLoading(false);
}
});
</script>
<style scoped></style>

32
src/modules/system/views/exception/lang/en_US.ts

@ -0,0 +1,32 @@
/**
*
*/
export default {
trans: true,
key: 'system.views.exception',
data: {
title: {
exceptionMessage: 'Error message',
requestIp: 'Request IP',
serverIp: 'Server IP',
requestPath: 'Request path',
operateUser: 'Operate user',
userFeedback: 'Feedback',
feedbackMessage: 'Feedback Message',
feedbackTime: 'Feedback time',
resolved: 'Resolved',
resolvedMessage: 'Resolved message',
resolvedUserId: 'Resolved user',
resolvedTime: 'Resolved time',
showStackTrace: 'Show stackTrace',
stackTrace: 'Stack trace',
},
validate: {},
rules: {},
search: {
exceptionMessage: 'Please select the error message',
requestIp: 'Please select the request IP',
serverIp: 'Please select the server IP',
},
},
};

32
src/modules/system/views/exception/lang/zh_CN.ts

@ -0,0 +1,32 @@
/**
*
*/
export default {
trans: true,
key: 'system.views.exception',
data: {
title: {
exceptionMessage: '异常信息',
requestIp: '请求IP',
serverIp: '服务器IP',
requestPath: '请求路径',
operateUser: '操作人员',
userFeedback: '用户是否反馈',
feedbackMessage: '用户反馈信息',
feedbackTime: '反馈时间',
resolved: '是否已处理',
resolvedMessage: '处理信息',
resolvedUserId: '处理人员ID',
resolvedTime: '处理时间',
showStackTrace: '查看堆栈信息',
stackTrace: '堆栈信息',
},
validate: {},
rules: {},
search: {
exceptionMessage: '请输入异常信息',
requestIp: '请输入请求IP',
serverIp: '请输入服务器IP',
},
},
};
Loading…
Cancel
Save