feat: 新增 ele 操作日志列表
							parent
							
								
									bdfbdf12c4
								
							
						
					
					
						commit
						822a0a151b
					
				|  | @ -0,0 +1,146 @@ | ||||||
|  | import type { VbenFormSchema } from '#/adapter/form'; | ||||||
|  | import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; | ||||||
|  | import type { SystemOperateLogApi } from '#/api/system/operate-log'; | ||||||
|  | 
 | ||||||
|  | import { useAccess } from '@vben/access'; | ||||||
|  | 
 | ||||||
|  | import { getSimpleUserList } from '#/api/system/user'; | ||||||
|  | import { getRangePickerDefaultProps } from '#/utils'; | ||||||
|  | 
 | ||||||
|  | const { hasAccessByCodes } = useAccess(); | ||||||
|  | 
 | ||||||
|  | /** 列表的搜索表单 */ | ||||||
|  | export function useGridFormSchema(): VbenFormSchema[] { | ||||||
|  |   return [ | ||||||
|  |     { | ||||||
|  |       fieldName: 'userId', | ||||||
|  |       label: '操作人', | ||||||
|  |       component: 'ApiSelect', | ||||||
|  |       componentProps: { | ||||||
|  |         api: getSimpleUserList, | ||||||
|  |         fieldNames: { | ||||||
|  |           label: 'nickname', | ||||||
|  |           value: 'id', | ||||||
|  |         }, | ||||||
|  |         allowClear: true, | ||||||
|  |         placeholder: '请选择操作人员', | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       fieldName: 'type', | ||||||
|  |       label: '操作模块', | ||||||
|  |       component: 'Input', | ||||||
|  |       componentProps: { | ||||||
|  |         allowClear: true, | ||||||
|  |         placeholder: '请输入操作模块', | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       fieldName: 'subType', | ||||||
|  |       label: '操作名', | ||||||
|  |       component: 'Input', | ||||||
|  |       componentProps: { | ||||||
|  |         allowClear: true, | ||||||
|  |         placeholder: '请输入操作名', | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       fieldName: 'action', | ||||||
|  |       label: '操作内容', | ||||||
|  |       component: 'Input', | ||||||
|  |       componentProps: { | ||||||
|  |         allowClear: true, | ||||||
|  |         placeholder: '请输入操作内容', | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       fieldName: 'createTime', | ||||||
|  |       label: '操作时间', | ||||||
|  |       component: 'RangePicker', | ||||||
|  |       componentProps: { | ||||||
|  |         ...getRangePickerDefaultProps(), | ||||||
|  |         allowClear: true, | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       fieldName: 'bizId', | ||||||
|  |       label: '业务编号', | ||||||
|  |       component: 'Input', | ||||||
|  |       componentProps: { | ||||||
|  |         allowClear: true, | ||||||
|  |         placeholder: '请输入业务编号', | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 列表的字段 */ | ||||||
|  | export function useGridColumns<T = SystemOperateLogApi.OperateLog>( | ||||||
|  |   onActionClick: OnActionClickFn<T>, | ||||||
|  | ): VxeTableGridOptions['columns'] { | ||||||
|  |   return [ | ||||||
|  |     { | ||||||
|  |       field: 'id', | ||||||
|  |       title: '日志编号', | ||||||
|  |       minWidth: 100, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'userName', | ||||||
|  |       title: '操作人', | ||||||
|  |       minWidth: 120, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'type', | ||||||
|  |       title: '操作模块', | ||||||
|  |       minWidth: 120, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'subType', | ||||||
|  |       title: '操作名', | ||||||
|  |       minWidth: 160, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'action', | ||||||
|  |       title: '操作内容', | ||||||
|  |       minWidth: 200, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'createTime', | ||||||
|  |       title: '操作时间', | ||||||
|  |       minWidth: 180, | ||||||
|  |       formatter: 'formatDateTime', | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'bizId', | ||||||
|  |       title: '业务编号', | ||||||
|  |       minWidth: 120, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'userIp', | ||||||
|  |       title: '操作IP', | ||||||
|  |       minWidth: 120, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: 'operation', | ||||||
|  |       title: '操作', | ||||||
|  |       minWidth: 120, | ||||||
|  |       align: 'center', | ||||||
|  |       fixed: 'right', | ||||||
|  |       cellRender: { | ||||||
|  |         attrs: { | ||||||
|  |           nameField: 'action', | ||||||
|  |           nameTitle: '操作日志', | ||||||
|  |           onClick: onActionClick, | ||||||
|  |         }, | ||||||
|  |         name: 'CellOperation', | ||||||
|  |         options: [ | ||||||
|  |           { | ||||||
|  |             code: 'detail', | ||||||
|  |             text: '详情', | ||||||
|  |             show: hasAccessByCodes(['system:operate-log:query']), | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,107 @@ | ||||||
|  | <script lang="ts" setup> | ||||||
|  | import type { | ||||||
|  |   OnActionClickParams, | ||||||
|  |   VxeTableGridOptions, | ||||||
|  | } from '#/adapter/vxe-table'; | ||||||
|  | import type { SystemOperateLogApi } from '#/api/system/operate-log'; | ||||||
|  | 
 | ||||||
|  | import { Page, useVbenModal } from '@vben/common-ui'; | ||||||
|  | import { Download } from '@vben/icons'; | ||||||
|  | import { downloadFileFromBlobPart } from '@vben/utils'; | ||||||
|  | 
 | ||||||
|  | import { ElButton } from 'element-plus'; | ||||||
|  | 
 | ||||||
|  | import { useVbenVxeGrid } from '#/adapter/vxe-table'; | ||||||
|  | import { exportOperateLog, getOperateLogPage } from '#/api/system/operate-log'; | ||||||
|  | import { DocAlert } from '#/components/doc-alert'; | ||||||
|  | import { $t } from '#/locales'; | ||||||
|  | 
 | ||||||
|  | import { useGridColumns, useGridFormSchema } from './data'; | ||||||
|  | import Detail from './modules/detail.vue'; | ||||||
|  | 
 | ||||||
|  | const [DetailModal, detailModalApi] = useVbenModal({ | ||||||
|  |   connectedComponent: Detail, | ||||||
|  |   destroyOnClose: true, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | /** 刷新表格 */ | ||||||
|  | function onRefresh() { | ||||||
|  |   gridApi.query(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 导出表格 */ | ||||||
|  | async function onExport() { | ||||||
|  |   const data = await exportOperateLog(await gridApi.formApi.getValues()); | ||||||
|  |   downloadFileFromBlobPart({ fileName: '操作日志.xls', source: data }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 查看操作日志详情 */ | ||||||
|  | function onDetail(row: SystemOperateLogApi.OperateLog) { | ||||||
|  |   detailModalApi.setData(row).open(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** 表格操作按钮的回调函数 */ | ||||||
|  | function onActionClick({ | ||||||
|  |   code, | ||||||
|  |   row, | ||||||
|  | }: OnActionClickParams<SystemOperateLogApi.OperateLog>) { | ||||||
|  |   switch (code) { | ||||||
|  |     case 'detail': { | ||||||
|  |       onDetail(row); | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const [Grid, gridApi] = useVbenVxeGrid({ | ||||||
|  |   formOptions: { | ||||||
|  |     schema: useGridFormSchema(), | ||||||
|  |   }, | ||||||
|  |   gridOptions: { | ||||||
|  |     columns: useGridColumns(onActionClick), | ||||||
|  |     height: 'auto', | ||||||
|  |     keepSource: true, | ||||||
|  |     proxyConfig: { | ||||||
|  |       ajax: { | ||||||
|  |         query: async ({ page }, formValues) => { | ||||||
|  |           return await getOperateLogPage({ | ||||||
|  |             pageNo: page.currentPage, | ||||||
|  |             pageSize: page.pageSize, | ||||||
|  |             ...formValues, | ||||||
|  |           }); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     rowConfig: { | ||||||
|  |       keyField: 'id', | ||||||
|  |     }, | ||||||
|  |     toolbarConfig: { | ||||||
|  |       refresh: { code: 'query' }, | ||||||
|  |       search: true, | ||||||
|  |     }, | ||||||
|  |   } as VxeTableGridOptions<SystemOperateLogApi.OperateLog>, | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <Page auto-content-height> | ||||||
|  |     <template #doc> | ||||||
|  |       <DocAlert title="系统日志" url="https://doc.iocoder.cn/system-log/" /> | ||||||
|  |     </template> | ||||||
|  | 
 | ||||||
|  |     <DetailModal @success="onRefresh" /> | ||||||
|  |     <Grid table-title="操作日志列表"> | ||||||
|  |       <template #toolbar-tools> | ||||||
|  |         <ElButton | ||||||
|  |           type="primary" | ||||||
|  |           class="ml-2" | ||||||
|  |           @click="onExport" | ||||||
|  |           v-access:code="['system:operate-log:export']" | ||||||
|  |         > | ||||||
|  |           <Download class="size-5" /> | ||||||
|  |           {{ $t('ui.actionTitle.export') }} | ||||||
|  |         </ElButton> | ||||||
|  |       </template> | ||||||
|  |     </Grid> | ||||||
|  |   </Page> | ||||||
|  | </template> | ||||||
|  | @ -0,0 +1,89 @@ | ||||||
|  | <script lang="ts" setup> | ||||||
|  | import type { SystemOperateLogApi } from '#/api/system/operate-log'; | ||||||
|  | 
 | ||||||
|  | import { ref } from 'vue'; | ||||||
|  | 
 | ||||||
|  | import { useVbenModal } from '@vben/common-ui'; | ||||||
|  | import { formatDateTime } from '@vben/utils'; | ||||||
|  | 
 | ||||||
|  | import { ElDescriptions, ElDescriptionsItem } from 'element-plus'; | ||||||
|  | 
 | ||||||
|  | const formData = ref<SystemOperateLogApi.OperateLog>(); | ||||||
|  | 
 | ||||||
|  | const [Modal, modalApi] = useVbenModal({ | ||||||
|  |   async onOpenChange(isOpen: boolean) { | ||||||
|  |     if (!isOpen) { | ||||||
|  |       formData.value = undefined; | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     // 加载数据 | ||||||
|  |     const data = modalApi.getData<SystemOperateLogApi.OperateLog>(); | ||||||
|  |     if (!data || !data.id) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     modalApi.lock(); | ||||||
|  |     try { | ||||||
|  |       formData.value = data; | ||||||
|  |     } finally { | ||||||
|  |       modalApi.unlock(); | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <Modal | ||||||
|  |     title="操作日志详情" | ||||||
|  |     class="w-1/2" | ||||||
|  |     :show-cancel-button="false" | ||||||
|  |     :show-confirm-button="false" | ||||||
|  |   > | ||||||
|  |     <ElDescriptions | ||||||
|  |       border | ||||||
|  |       :column="1" | ||||||
|  |       size="default" | ||||||
|  |       class="mx-4" | ||||||
|  |       :label-style="{ width: '110px' }" | ||||||
|  |     > | ||||||
|  |       <ElDescriptionsItem label="日志编号"> | ||||||
|  |         {{ formData?.id }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem label="链路追踪" v-if="formData?.traceId"> | ||||||
|  |         {{ formData?.traceId }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem label="操作人编号"> | ||||||
|  |         {{ formData?.userId }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem label="操作人名字"> | ||||||
|  |         {{ formData?.userName }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem label="操作人IP"> | ||||||
|  |         {{ formData?.userIp }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem label="操作人UA"> | ||||||
|  |         {{ formData?.userAgent }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem label="操作模块"> | ||||||
|  |         {{ formData?.type }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem label="操作名"> | ||||||
|  |         {{ formData?.subType }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem label="操作内容"> | ||||||
|  |         {{ formData?.action }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem v-if="formData?.extra" label="操作拓展参数"> | ||||||
|  |         {{ formData?.extra }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem label="请求URL"> | ||||||
|  |         {{ formData?.requestMethod }} {{ formData?.requestUrl }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem label="操作时间"> | ||||||
|  |         {{ formatDateTime(formData?.createTime || '') }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |       <ElDescriptionsItem label="业务编号"> | ||||||
|  |         {{ formData?.bizId }} | ||||||
|  |       </ElDescriptionsItem> | ||||||
|  |     </ElDescriptions> | ||||||
|  |   </Modal> | ||||||
|  | </template> | ||||||
		Loading…
	
		Reference in New Issue
	
	 puhui999
						puhui999