Files
medical-mall/pages/mall/admin/maintain/security/system-log/index.uvue
2026-03-18 08:36:49 +08:00

296 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="admin-page">
<view class="admin-sections">
<!-- 搜索栏 -->
<view class="admin-card filter-card">
<view class="filter-row">
<view class="filter-item">
<text class="label">选择时间:</text>
<view class="filter-date-range">
<input class="filter-input date-input" placeholder="开始日期" />
<text class="date-sep">-</text>
<input class="filter-input date-input" placeholder="结束日期" />
</view>
</view>
<view class="filter-item">
<text class="label">名称:</text>
<view class="filter-select">
<text class="select-placeholder">请选择</text>
<text class="arrow">▼</text>
</view>
</view>
<view class="filter-item">
<text class="label">链接:</text>
<input class="filter-input" placeholder="请输入链接" />
</view>
<view class="filter-item">
<text class="label">IP</text>
<input class="filter-input" placeholder="请输入IP" />
</view>
<button class="btn primary" @click="onSearch">搜索</button>
</view>
</view>
<!-- 内容区 -->
<view class="admin-card content-card">
<!-- 表格 -->
<view class="table-container list-table">
<view class="table-header">
<view class="col col-id"><text>ID</text></view>
<view class="col col-user"><text>ID/名称</text></view>
<view class="col col-action"><text>操作</text></view>
<view class="col col-link"><text>链接</text></view>
<view class="col col-ip"><text>操作IP</text></view>
<view class="col col-type"><text>类型</text></view>
<view class="col col-time"><text>操作时间</text></view>
</view>
<view class="table-body">
<view v-for="item in pagedList" :key="item.id" class="table-row">
<view class="col col-id"><text>{{ item.id }}</text></view>
<view class="col col-user"><text>{{ item.user }}</text></view>
<view class="col col-action"><text>{{ item.action }}</text></view>
<view class="col col-link"><text>{{ item.link }}</text></view>
<view class="col col-ip"><text>{{ item.ip }}</text></view>
<view class="col col-type"><text>{{ item.type }}</text></view>
<view class="col col-time"><text>{{ item.time }}</text></view>
</view>
</view>
</view>
<CommonPagination
v-if="total > 0"
:total="total"
:loading="false"
:currentPage="currentPage"
:pageSize="pageSize"
:pageSizeOptionLabels="pageSizeOptionLabels"
:pageSizeIndex="pageSizeIndex"
:visiblePages="visiblePages"
:totalPage="totalPage"
:jumpPageInput="jumpPageInput"
@page-size-change="handlePageSizeChange"
@page-change="handlePageChange"
@update:jumpPageInput="(val: string) => { jumpPageInput.value = val }"
@jump-page="handleJumpPage"
/>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, computed } from 'vue'
import CommonPagination from '@/components/CommonPagination/CommonPagination.uvue'
const dataList = ref([
{ id: 585387, user: '5 / demo', action: '系统日志', link: 'system/log', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:49' },
{ id: 585386, user: '5 / demo', action: '系统日志管理员搜索条件', link: 'system/log/search_admin', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:49' },
{ id: 585385, user: '5 / demo', action: '自定义事件类型', link: 'system/event/mark', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:49' },
{ id: 585384, user: '5 / demo', action: '自定义事件列表', link: 'system/event/list', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:49' },
{ id: 585383, user: '5 / demo', action: '积分配置编辑表单', link: 'marketing/integral_config/edit_basics', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:48' },
{ id: 585382, user: '5 / demo', action: '基本配置编辑头部数据', link: 'setting/config/header_basics', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:48' },
{ id: 585381, user: '5 / demo', action: '保存权限菜单', link: 'setting/menus', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:48' },
{ id: 585380, user: '5 / demo', action: '定时任务类型', link: 'system/crontab/mark', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:47' },
{ id: 585379, user: '5 / demo', action: '定时任务列表', link: 'system/crontab/list', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:47' },
{ id: 585378, user: '5 / demo', action: '保存组合数据', link: 'setting/group', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:47' },
{ id: 585377, user: '5 / demo', action: '保存系统配置分类', link: 'setting/config_class', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:47' },
{ id: 585376, user: '5 / demo', action: '神识别相册管理', link: 'system/gallery', ip: '115.29.168.1', type: 'system', time: '2026-02-11 18:45' },
{ id: 585375, user: '3 / admin', action: '订单列表', link: 'order/list', ip: '116.228.88.5', type: 'system', time: '2026-02-11 18:43' },
{ id: 585374, user: '3 / admin', action: '商品列表', link: 'product/list', ip: '116.228.88.5', type: 'system', time: '2026-02-11 18:42' },
{ id: 585373, user: '3 / admin', action: '用户列表', link: 'user/list', ip: '116.228.88.5', type: 'system', time: '2026-02-11 18:41' },
{ id: 585372, user: '5 / demo', action: '分销分红记录', link: 'distribution/brokerage', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:40' },
{ id: 585371, user: '5 / demo', action: '财务提现列表', link: 'finance/withdraw', ip: '223.104.72.77', type: 'system', time: '2026-02-11 18:39' },
{ id: 585370, user: '3 / admin', action: '商品分类列表', link: 'product/category', ip: '116.228.88.5', type: 'system', time: '2026-02-11 18:38' },
{ id: 585369, user: '1 / 超级管理员', action: '系统监控', link: 'system/monitor', ip: '127.0.0.1', type: 'system', time: '2026-02-11 18:37' }
])
// ========== MOCK DATA END ==========
// ========== PAGINATION STATE ==========
const currentPage = ref(1)
const pageSize = ref(15)
const jumpPageInput = ref('')
const pageSizeOptions = [10, 15, 20, 30, 50]
const pageSizeOptionLabels = computed(() => pageSizeOptions.map((n: number) => `${n}条/页`))
const pageSizeIndex = computed(() => { const idx = pageSizeOptions.indexOf(pageSize.value); return idx >= 0 ? idx : 0 })
const total = computed(() => dataList.value.length)
const totalPage = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)))
const pagedList = computed(() => {
const start = (currentPage.value - 1) * pageSize.value
return dataList.value.slice(start, start + pageSize.value)
})
const visiblePages = computed((): number[] => {
const t = totalPage.value; const cur = currentPage.value
if (t <= 7) return Array.from({ length: t }, (_: any, i: number) => i + 1)
if (cur <= 4) return [1, 2, 3, 4, 5, -1, t]
if (cur >= t - 3) return [1, -1, t - 4, t - 3, t - 2, t - 1, t]
return [1, -1, cur - 1, cur, cur + 1, -1, t]
})
const handlePageChange = (p: number) => { currentPage.value = p }
const handlePageSizeChange = (e: any) => {
const idx = Number(e.detail.value)
pageSize.value = pageSizeOptions[idx] ?? pageSizeOptions[0]
currentPage.value = 1
}
const handleJumpPage = () => {
const p = parseInt(jumpPageInput.value)
if (!isNaN(p) && p >= 1 && p <= totalPage.value) currentPage.value = p
}
// ========== END PAGINATION STATE ==========
function onSearch() {
uni.showToast({ title: '搜索中...', icon: 'none' })
}
</script>
<style scoped lang="scss">
.admin-page {
/* 使用 Layout 的背景和内边距 */
min-height: 100vh;
}
.admin-card {
background-color: #fff;
border-radius: 4px;
padding: 20px;
margin-bottom: 20px;
}
.filter-row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
gap: 16px;
}
.filter-item {
display: flex;
flex-direction: row;
align-items: center;
}
.label {
font-size: 14px;
color: #333;
white-space: nowrap;
}
.filter-date-range {
display: flex;
flex-direction: row;
align-items: center;
border: 1px solid #d9d9d9;
border-radius: 2px;
padding: 0 10px;
height: 32px;
}
.date-input {
width: 100px;
border: none;
height: 100%;
}
.date-sep {
margin: 0 8px;
color: #bfbfbf;
}
.filter-select {
width: 120px;
height: 32px;
border: 1px solid #d9d9d9;
border-radius: 2px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 0 10px;
}
.select-placeholder {
color: #bfbfbf;
font-size: 14px;
}
.arrow {
font-size: 10px;
color: #bfbfbf;
}
.filter-input {
width: 150px;
height: 32px;
border: 1px solid #d9d9d9;
border-radius: 2px;
padding: 0 10px;
font-size: 14px;
}
.btn {
height: 32px;
padding: 0 20px;
border-radius: 2px;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: 1px solid #d9d9d9;
background-color: #fff;
}
.btn.primary {
background-color: #1890ff;
border-color: #1890ff;
color: #fff;
}
.table-container {
width: 100%;
border: 1px solid #f0f0f0;
}
.table-header {
display: flex;
flex-direction: row;
background-color: #fafafa;
border-bottom: 1px solid #f0f0f0;
}
.table-row {
display: flex;
flex-direction: row;
border-bottom: 1px solid #f0f0f0;
}
.col {
padding: 12px 16px;
display: flex;
align-items: center;
font-size: 14px;
color: #333;
}
.col-id { width: 80px; }
.col-user { width: 120px; }
.col-action { flex: 2; }
.col-link { flex: 2; }
.col-ip { width: 150px; }
.col-type { width: 100px; }
.col-time { width: 180px; }
.pagination {
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
.page-info {
font-size: 14px;
color: #999;
}
</style>