视图修改、接口修改

This commit is contained in:
2025-10-28 19:04:35 +08:00
parent 98c73632bd
commit c5c134fbb3
96 changed files with 7122 additions and 4194 deletions

View File

@@ -1,60 +1,65 @@
<template>
<div class="login-logs">
<div class="filter-bar">
<el-input
v-model="searchKeyword"
placeholder="搜索用户名..."
style="width: 200px"
clearable
<AdminLayout title="登录日志" subtitle="登录日志管理">
<div class="login-logs">
<div class="filter-bar">
<el-input
v-model="searchKeyword"
placeholder="搜索用户名..."
style="width: 200px"
clearable
/>
<el-select v-model="loginStatus" placeholder="登录状态" style="width: 150px" clearable>
<el-option label="成功" value="success" />
<el-option label="失败" value="failed" />
</el-select>
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
<el-button type="primary" @click="handleSearch">查询</el-button>
<el-button @click="handleExport">导出</el-button>
<el-button type="danger" @click="handleClear">清空日志</el-button>
</div>
<el-table :data="logs" style="width: 100%">
<el-table-column prop="username" label="用户名" width="120" />
<el-table-column prop="ipAddress" label="IP地址" width="140" />
<el-table-column prop="location" label="登录地点" width="150" />
<el-table-column prop="browser" label="浏览器" width="120" />
<el-table-column prop="os" label="操作系统" width="120" />
<el-table-column prop="status" label="状态" width="100">
<template #default="{ row }">
<el-tag :type="row.status === 'success' ? 'success' : 'danger'">
{{ row.status === 'success' ? '成功' : '失败' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="message" label="信息" min-width="150" />
<el-table-column prop="loginTime" label="登录时间" width="180" />
</el-table>
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
<el-select v-model="loginStatus" placeholder="登录状态" style="width: 150px" clearable>
<el-option label="成功" value="success" />
<el-option label="失败" value="failed" />
</el-select>
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
<el-button type="primary" @click="handleSearch">查询</el-button>
<el-button @click="handleExport">导出</el-button>
<el-button type="danger" @click="handleClear">清空日志</el-button>
</div>
<el-table :data="logs" style="width: 100%">
<el-table-column prop="username" label="用户名" width="120" />
<el-table-column prop="ipAddress" label="IP地址" width="140" />
<el-table-column prop="location" label="登录地点" width="150" />
<el-table-column prop="browser" label="浏览器" width="120" />
<el-table-column prop="os" label="操作系统" width="120" />
<el-table-column prop="status" label="状态" width="100">
<template #default="{ row }">
<el-tag :type="row.status === 'success' ? 'success' : 'danger'">
{{ row.status === 'success' ? '成功' : '失败' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="message" label="信息" min-width="150" />
<el-table-column prop="loginTime" label="登录时间" width="180" />
</el-table>
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</AdminLayout>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElInput, ElSelect, ElOption, ElDatePicker, ElButton, ElTable, ElTableColumn, ElTag, ElPagination, ElMessage, ElMessageBox } from 'element-plus';
import { AdminLayout } from '@/views/admin';
defineOptions({
name: 'LoginLogsView'
});
const searchKeyword = ref('');
const loginStatus = ref('');
const dateRange = ref<[Date, Date] | null>(null);

View File

@@ -1,72 +1,78 @@
<template>
<div class="operation-logs">
<div class="filter-bar">
<el-input
v-model="searchKeyword"
placeholder="搜索用户名或操作..."
style="width: 250px"
clearable
<AdminLayout title="操作日志" subtitle="操作日志管理">
<div class="operation-logs">
<div class="filter-bar">
<el-input
v-model="searchKeyword"
placeholder="搜索用户名或操作..."
style="width: 250px"
clearable
/>
<el-select v-model="operationType" placeholder="操作类型" style="width: 150px" clearable>
<el-option label="新增" value="create" />
<el-option label="修改" value="update" />
<el-option label="删除" value="delete" />
<el-option label="查询" value="read" />
</el-select>
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
<el-button type="primary" @click="handleSearch">查询</el-button>
<el-button @click="handleExport">导出</el-button>
</div>
<el-table :data="logs" style="width: 100%">
<el-table-column prop="username" label="操作人" width="120" />
<el-table-column prop="module" label="操作模块" width="120" />
<el-table-column prop="operation" label="操作类型" width="100">
<template #default="{ row }">
<el-tag :type="getOperationType(row.operation)">
{{ getOperationText(row.operation) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="description" label="操作描述" min-width="200" />
<el-table-column prop="ipAddress" label="IP地址" width="140" />
<el-table-column prop="duration" label="耗时(ms)" width="100" />
<el-table-column prop="status" label="状态" width="100">
<template #default="{ row }">
<el-tag :type="row.status === 'success' ? 'success' : 'danger'">
{{ row.status === 'success' ? '成功' : '失败' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="operationTime" label="操作时间" width="180" />
<el-table-column label="操作" width="100" fixed="right">
<template #default="{ row }">
<el-button size="small" @click="viewDetail(row)">详情</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
<el-select v-model="operationType" placeholder="操作类型" style="width: 150px" clearable>
<el-option label="新增" value="create" />
<el-option label="修改" value="update" />
<el-option label="删除" value="delete" />
<el-option label="查询" value="read" />
</el-select>
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
<el-button type="primary" @click="handleSearch">查询</el-button>
<el-button @click="handleExport">导出</el-button>
</div>
</AdminLayout>
<el-table :data="logs" style="width: 100%">
<el-table-column prop="username" label="操作人" width="120" />
<el-table-column prop="module" label="操作模块" width="120" />
<el-table-column prop="operation" label="操作类型" width="100">
<template #default="{ row }">
<el-tag :type="getOperationType(row.operation)">
{{ getOperationText(row.operation) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="description" label="操作描述" min-width="200" />
<el-table-column prop="ipAddress" label="IP地址" width="140" />
<el-table-column prop="duration" label="耗时(ms)" width="100" />
<el-table-column prop="status" label="状态" width="100">
<template #default="{ row }">
<el-tag :type="row.status === 'success' ? 'success' : 'danger'">
{{ row.status === 'success' ? '成功' : '失败' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="operationTime" label="操作时间" width="180" />
<el-table-column label="操作" width="100" fixed="right">
<template #default="{ row }">
<el-button size="small" @click="viewDetail(row)">详情</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElInput, ElSelect, ElOption, ElDatePicker, ElButton, ElTable, ElTableColumn, ElTag, ElPagination, ElMessage } from 'element-plus';
import { AdminLayout } from '@/views/admin';
defineOptions({
name: 'OperationLogsView'
});
const searchKeyword = ref('');
const operationType = ref('');
const dateRange = ref<[Date, Date] | null>(null);

View File

@@ -1,98 +1,103 @@
<template>
<div class="system-config">
<el-form :model="configForm" label-width="150px" class="config-form">
<el-divider content-position="left">基本设置</el-divider>
<el-form-item label="系统名称">
<el-input v-model="configForm.systemName" />
</el-form-item>
<AdminLayout title="系统配置" subtitle="系统配置">
<div class="system-config">
<el-form :model="configForm" label-width="150px" class="config-form">
<el-divider content-position="left">基本设置</el-divider>
<el-form-item label="系统名称">
<el-input v-model="configForm.systemName" />
</el-form-item>
<el-form-item label="系统Logo">
<el-upload
class="logo-uploader"
action="#"
:show-file-list="false"
:before-upload="beforeLogoUpload"
>
<img v-if="configForm.logo" :src="configForm.logo" class="logo-preview" />
<el-icon v-else class="logo-uploader-icon">+</el-icon>
</el-upload>
</el-form-item>
<el-form-item label="系统Logo">
<el-upload
class="logo-uploader"
action="#"
:show-file-list="false"
:before-upload="beforeLogoUpload"
>
<img v-if="configForm.logo" :src="configForm.logo" class="logo-preview" />
<el-icon v-else class="logo-uploader-icon">+</el-icon>
</el-upload>
</el-form-item>
<el-form-item label="版权信息">
<el-input v-model="configForm.copyright" />
</el-form-item>
<el-form-item label="版权信息">
<el-input v-model="configForm.copyright" />
</el-form-item>
<el-divider content-position="left">安全设置</el-divider>
<el-divider content-position="left">安全设置</el-divider>
<el-form-item label="启用验证码">
<el-switch v-model="configForm.enableCaptcha" />
</el-form-item>
<el-form-item label="启用验证码">
<el-switch v-model="configForm.enableCaptcha" />
</el-form-item>
<el-form-item label="密码最小长度">
<el-input-number v-model="configForm.minPasswordLength" :min="6" :max="20" />
</el-form-item>
<el-form-item label="密码最小长度">
<el-input-number v-model="configForm.minPasswordLength" :min="6" :max="20" />
</el-form-item>
<el-form-item label="会话超时(分钟)">
<el-input-number v-model="configForm.sessionTimeout" :min="5" :max="1440" />
</el-form-item>
<el-form-item label="会话超时(分钟)">
<el-input-number v-model="configForm.sessionTimeout" :min="5" :max="1440" />
</el-form-item>
<el-form-item label="登录失败锁定">
<el-switch v-model="configForm.enableLoginLock" />
</el-form-item>
<el-form-item label="登录失败锁定">
<el-switch v-model="configForm.enableLoginLock" />
</el-form-item>
<el-form-item label="锁定阈值(次)" v-if="configForm.enableLoginLock">
<el-input-number v-model="configForm.loginLockThreshold" :min="3" :max="10" />
</el-form-item>
<el-form-item label="锁定阈值(次)" v-if="configForm.enableLoginLock">
<el-input-number v-model="configForm.loginLockThreshold" :min="3" :max="10" />
</el-form-item>
<el-divider content-position="left">功能设置</el-divider>
<el-divider content-position="left">功能设置</el-divider>
<el-form-item label="启用用户注册">
<el-switch v-model="configForm.enableRegister" />
</el-form-item>
<el-form-item label="启用用户注册">
<el-switch v-model="configForm.enableRegister" />
</el-form-item>
<el-form-item label="启用评论功能">
<el-switch v-model="configForm.enableComment" />
</el-form-item>
<el-form-item label="启用评论功能">
<el-switch v-model="configForm.enableComment" />
</el-form-item>
<el-form-item label="启用文件上传">
<el-switch v-model="configForm.enableFileUpload" />
</el-form-item>
<el-form-item label="启用文件上传">
<el-switch v-model="configForm.enableFileUpload" />
</el-form-item>
<el-form-item label="文件上传大小限制(MB)">
<el-input-number v-model="configForm.maxFileSize" :min="1" :max="100" />
</el-form-item>
<el-form-item label="文件上传大小限制(MB)">
<el-input-number v-model="configForm.maxFileSize" :min="1" :max="100" />
</el-form-item>
<el-divider content-position="left">邮件设置</el-divider>
<el-divider content-position="left">邮件设置</el-divider>
<el-form-item label="启用邮件通知">
<el-switch v-model="configForm.enableEmail" />
</el-form-item>
<el-form-item label="启用邮件通知">
<el-switch v-model="configForm.enableEmail" />
</el-form-item>
<el-form-item label="SMTP服务器" v-if="configForm.enableEmail">
<el-input v-model="configForm.smtpHost" />
</el-form-item>
<el-form-item label="SMTP服务器" v-if="configForm.enableEmail">
<el-input v-model="configForm.smtpHost" />
</el-form-item>
<el-form-item label="SMTP端口" v-if="configForm.enableEmail">
<el-input-number v-model="configForm.smtpPort" :min="1" :max="65535" />
</el-form-item>
<el-form-item label="SMTP端口" v-if="configForm.enableEmail">
<el-input-number v-model="configForm.smtpPort" :min="1" :max="65535" />
</el-form-item>
<el-form-item label="发件人邮箱" v-if="configForm.enableEmail">
<el-input v-model="configForm.senderEmail" />
</el-form-item>
<el-form-item label="发件人邮箱" v-if="configForm.enableEmail">
<el-input v-model="configForm.senderEmail" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSave">保存配置</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
</div>
<el-form-item>
<el-button type="primary" @click="handleSave">保存配置</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
</div>
</AdminLayout>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElForm, ElFormItem, ElInput, ElInputNumber, ElSwitch, ElButton, ElDivider, ElUpload, ElIcon, ElMessage } from 'element-plus';
import { AdminLayout } from '@/views/admin';
defineOptions({
name: 'SystemConfigView'
});
const configForm = ref({
systemName: '红色思政学习平台',
logo: '',

View File

@@ -1,19 +1,21 @@
<template>
<div class="system-logs">
<h1 class="page-title">系统日志</h1>
<AdminLayout title="系统日志" subtitle="系统日志管理">
<div class="system-logs">
<h1 class="page-title">系统日志</h1>
<el-tabs v-model="activeTab">
<el-tab-pane label="登录日志" name="login">
<LoginLogs />
</el-tab-pane>
<el-tab-pane label="操作日志" name="operation">
<OperationLogs />
</el-tab-pane>
<el-tab-pane label="系统配置" name="config">
<SystemConfig />
</el-tab-pane>
</el-tabs>
</div>
<el-tabs v-model="activeTab">
<el-tab-pane label="登录日志" name="login">
<LoginLogs />
</el-tab-pane>
<el-tab-pane label="操作日志" name="operation">
<OperationLogs />
</el-tab-pane>
<el-tab-pane label="系统配置" name="config">
<SystemConfig />
</el-tab-pane>
</el-tabs>
</div>
</AdminLayout>
</template>
<script setup lang="ts">
@@ -22,7 +24,10 @@ import { ElTabs, ElTabPane } from 'element-plus';
import LoginLogs from './components/LoginLogs.vue';
import OperationLogs from './components/OperationLogs.vue';
import SystemConfig from './components/SystemConfig.vue';
import { AdminLayout } from '@/views/admin';
defineOptions({
name: 'SystemLogsView'
});
const activeTab = ref('login');
</script>