OperationLog.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <!--
  2. * @since: 2025-02-07
  3. * OperationLog.vue
  4. -->
  5. <template>
  6. <div class="login-log">
  7. <el-card class="mb-3 proCard">
  8. <el-space >
  9. <el-form ref="searchFormRef" :inline="true" :model="requestParams.queryParam" class="form-inline">
  10. <el-form-item prop="userName">
  11. <el-select v-model="requestParams.queryParam.queryType" placeholder="选择类型" class="type-select">
  12. <el-option
  13. v-for="item in queryTypeSelect"
  14. :key="item.value"
  15. :label="item.label"
  16. :value="item.value"
  17. />
  18. </el-select>
  19. <el-input v-model="requestParams.queryParam.queryTypeContent" clearable placeholder="请输入搜索关键字"
  20. @keyup.enter="queryOperationLogPage" :disabled="requestParams.queryParam.queryType ===''"/>
  21. </el-form-item>
  22. <el-form-item label="应用侧" prop="platform">
  23. <el-select v-model="requestParams.queryParam.platform" placeholder="请选择应用侧" clearable>
  24. <el-option :label="item.label" :value="item.label" v-for="item in platformList" :key="item.value" />
  25. </el-select>
  26. </el-form-item>
  27. <el-form-item label="所属模块" prop="module">
  28. <el-input v-model="requestParams.queryParam.module" clearable placeholder="请输入所属模块"
  29. @keyup.enter="queryOperationLogPage" />
  30. </el-form-item>
  31. <el-form-item label="操作类型" prop="operatorType">
  32. <el-select v-model="requestParams.queryParam.operatorType" placeholder="请选择操作类型" clearable>
  33. <el-option :label="item.label" :value="item.label" v-for="item in operationList" :key="item.value" />
  34. </el-select>
  35. </el-form-item>
  36. <el-form-item label="登录时间" prop="date">
  37. <el-date-picker
  38. v-model="requestParams.queryParam.date"
  39. type="daterange"
  40. placeholder="请选择登录时间"
  41. range-separator="~"
  42. start-placeholder="开始时间"
  43. end-placeholder="结束时间"
  44. clearable />
  45. </el-form-item>
  46. <el-form-item>
  47. <el-button type="primary" :icon="Search" @click="queryOperationLogPage">查询</el-button>
  48. <el-button :icon="Refresh" @click="handleResetForm(searchFormRef)">重置</el-button>
  49. </el-form-item>
  50. </el-form>
  51. </el-space>
  52. </el-card>
  53. <el-card>
  54. <template #header>
  55. <el-button type="primary" @click="handleExport()">导出数据</el-button>
  56. </template>
  57. <el-table height="calc(100vh - 340px)" :data="operationLogList" v-loading="loading">
  58. <el-table-column label="日志编号" width="100" prop="id" />
  59. <el-table-column label="账号" prop="realName" />
  60. <el-table-column label="姓名" prop="operatorName" />
  61. <el-table-column label="应用侧" prop="platform" >
  62. <template #default="{ row }">
  63. {{ row.platform === 'ADMIN' ? '管理侧' : '平台侧' }}
  64. </template>
  65. </el-table-column>
  66. <el-table-column label="所属模块" prop="module" />
  67. <el-table-column label="操作内容" prop="content" />
  68. <el-table-column label="操作类型" prop="operatorType" >
  69. <template #default="{ row }">
  70. {{ OperationType[row.operatorType] }}
  71. </template>
  72. </el-table-column>
  73. <el-table-column label="操作结果" prop="isSuccess" >
  74. <template #default="{ row }">
  75. <el-icon :size="24" color="#67C23A" v-if="row.isSuccess === LoginStatusEnum.SUCCESS"><SuccessFilled /></el-icon>
  76. <el-icon :size="24" color="#F56C6C" v-else><CircleCloseFilled /></el-icon>
  77. </template>
  78. </el-table-column>
  79. <el-table-column label="IP" prop="clientIp" />
  80. <el-table-column label="操作时间" prop="createdAt" />
  81. <el-table-column label="操作" width="160">
  82. <template #default="{ row }">
  83. <el-space>
  84. <el-button type="primary" text @click="openDrawer(row.id)" >详情</el-button>
  85. </el-space>
  86. </template>
  87. </el-table-column>
  88. </el-table>
  89. <section class="mt-4 flex justify-end">
  90. <el-pagination background layout="total, sizes, prev, pager, next" :page-sizes="[10, 30, 50]" :total="total"
  91. v-model:page-size="requestParams.pageSize" v-model:current-page="requestParams.pageNumber"
  92. @change="queryOperationLogPage" />
  93. </section>
  94. </el-card>
  95. <DetailDialog ref="drawerInstance" />
  96. </div>
  97. </template>
  98. <script setup lang="ts">
  99. import { ref, onMounted } from 'vue';
  100. import { Search, Refresh, Edit ,SuccessFilled, CircleCloseFilled} from '@element-plus/icons-vue';
  101. import { ElMessage, ElMessageBox } from 'element-plus';
  102. import { exportLoginLog } from '@/api/system/log';
  103. import { downloadByData } from '@/utils/file/download';
  104. import type { FormInstance } from 'element-plus'
  105. import DetailDialog from './DetailDialog.vue';
  106. import { platformList, operationList, queryTypeSelect, LoginStatusEnum, OperationType } from '@/types/log/constants';
  107. import userOperationQuery from '../hooks/userOperationQuery';
  108. const { requestParams, total, operationLogList, loading, queryOperationLogPage, resetRequestParams } = userOperationQuery();
  109. onMounted(async () => {
  110. queryOperationLogPage();
  111. });
  112. /* 导出数据 */
  113. const handleExport = () => {
  114. ElMessageBox.confirm('确定导出所查询数据?', '导出', {
  115. confirmButtonText: '确定',
  116. showCancelButton: true,
  117. type: 'warning',
  118. })
  119. .then(() => {
  120. exportLoginLog(requestParams).then(async (responnse) => {
  121. if (!responnse) {
  122. throw new Error('下载文件失败');
  123. }
  124. downloadByData(responnse, '操作日志.xlsx');
  125. ElMessage.success('下载文件成功');
  126. });
  127. })
  128. .catch(() => {
  129. ElMessage({
  130. type: 'info',
  131. message: '取消导出',
  132. });
  133. });
  134. }
  135. /* 重置 */
  136. const searchFormRef = ref<FormInstance>()
  137. const handleResetForm = (formEl: FormInstance | undefined) => {
  138. if (!formEl) return
  139. resetRequestParams();
  140. formEl.resetFields();
  141. queryOperationLogPage();
  142. }
  143. const drawerInstance = ref<InstanceType<typeof DetailDialog>>();
  144. const openDrawer = (id?: number) => {
  145. drawerInstance.value?.open(id);
  146. };
  147. </script>
  148. <style scoped lang="scss">
  149. .form-inline .el-input {
  150. --el-input-width: 160px;
  151. }
  152. .form-inline .el-select {
  153. --el-select-width: 160px;
  154. }
  155. </style>