优化报表页面,移除统计页面
This commit is contained in:
@@ -5,7 +5,6 @@ import { ElMessageBox } from 'element-plus'
|
|||||||
import {
|
import {
|
||||||
Bell,
|
Bell,
|
||||||
ChatLineSquare,
|
ChatLineSquare,
|
||||||
DataAnalysis,
|
|
||||||
Document,
|
Document,
|
||||||
List,
|
List,
|
||||||
Message,
|
Message,
|
||||||
@@ -106,7 +105,6 @@ const menuItems = [
|
|||||||
{ path: '/reports', label: '报表', icon: Document },
|
{ path: '/reports', label: '报表', icon: Document },
|
||||||
{ path: '/users', label: '用户', icon: User, badgeKey: 'resets' },
|
{ path: '/users', label: '用户', icon: User, badgeKey: 'resets' },
|
||||||
{ path: '/feedbacks', label: '反馈', icon: ChatLineSquare, badgeKey: 'feedbacks' },
|
{ path: '/feedbacks', label: '反馈', icon: ChatLineSquare, badgeKey: 'feedbacks' },
|
||||||
{ path: '/stats', label: '统计', icon: DataAnalysis },
|
|
||||||
{ path: '/logs', label: '任务日志', icon: List },
|
{ path: '/logs', label: '任务日志', icon: List },
|
||||||
{ path: '/announcements', label: '公告', icon: Bell },
|
{ path: '/announcements', label: '公告', icon: Bell },
|
||||||
{ path: '/email', label: '邮件', icon: Message },
|
{ path: '/email', label: '邮件', icon: Message },
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,480 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
|
||||||
|
|
||||||
import { fetchDockerStats, fetchRunningTasks, fetchServerInfo, fetchTaskStats } from '../api/tasks'
|
|
||||||
import { getTaskSourceMeta } from '../utils/taskSource'
|
|
||||||
|
|
||||||
const initialLoading = ref(true)
|
|
||||||
const lastUpdatedAt = ref('')
|
|
||||||
|
|
||||||
const server = ref({
|
|
||||||
cpu_percent: '-',
|
|
||||||
memory_used: '-',
|
|
||||||
memory_total: '-',
|
|
||||||
disk_used: '-',
|
|
||||||
disk_total: '-',
|
|
||||||
uptime: '-',
|
|
||||||
})
|
|
||||||
|
|
||||||
const docker = ref({
|
|
||||||
status: 'Unknown',
|
|
||||||
memory_usage: 'N/A',
|
|
||||||
memory_limit: 'N/A',
|
|
||||||
memory_percent: 'N/A',
|
|
||||||
uptime: 'N/A',
|
|
||||||
})
|
|
||||||
|
|
||||||
const taskStats = ref({
|
|
||||||
today: { success_tasks: 0, failed_tasks: 0, total_items: 0, total_attachments: 0 },
|
|
||||||
total: { success_tasks: 0, failed_tasks: 0, total_items: 0, total_attachments: 0 },
|
|
||||||
})
|
|
||||||
|
|
||||||
const monitor = ref({
|
|
||||||
running_count: 0,
|
|
||||||
queuing_count: 0,
|
|
||||||
max_concurrent: 0,
|
|
||||||
running: [],
|
|
||||||
queuing: [],
|
|
||||||
})
|
|
||||||
|
|
||||||
const statusColorMap = {
|
|
||||||
初始化: '#6b7280',
|
|
||||||
正在登录: '#f59e0b',
|
|
||||||
正在浏览: '#10b981',
|
|
||||||
浏览完成: '#3b82f6',
|
|
||||||
正在截图: '#06b6d4',
|
|
||||||
}
|
|
||||||
|
|
||||||
function statusColor(text) {
|
|
||||||
return statusColorMap[text] || '#6b7280'
|
|
||||||
}
|
|
||||||
|
|
||||||
const serverMemoryDisplay = computed(() => `${server.value.memory_used} / ${server.value.memory_total}`)
|
|
||||||
const serverDiskDisplay = computed(() => `${server.value.disk_used} / ${server.value.disk_total}`)
|
|
||||||
|
|
||||||
let stop = false
|
|
||||||
let timer = null
|
|
||||||
|
|
||||||
function recordUpdatedAt() {
|
|
||||||
try {
|
|
||||||
lastUpdatedAt.value = new Date().toLocaleTimeString('zh-CN', { hour12: false, timeZone: 'Asia/Shanghai' })
|
|
||||||
} catch {
|
|
||||||
lastUpdatedAt.value = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadOnce() {
|
|
||||||
try {
|
|
||||||
const [serverInfo, dockerInfo, taskStat, running] = await Promise.all([
|
|
||||||
fetchServerInfo(),
|
|
||||||
fetchDockerStats(),
|
|
||||||
fetchTaskStats(),
|
|
||||||
fetchRunningTasks(),
|
|
||||||
])
|
|
||||||
|
|
||||||
server.value = serverInfo || server.value
|
|
||||||
docker.value = dockerInfo || docker.value
|
|
||||||
taskStats.value = taskStat || taskStats.value
|
|
||||||
monitor.value = running || monitor.value
|
|
||||||
recordUpdatedAt()
|
|
||||||
} catch {
|
|
||||||
// handled by interceptor
|
|
||||||
} finally {
|
|
||||||
initialLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loop() {
|
|
||||||
if (stop) return
|
|
||||||
const start = Date.now()
|
|
||||||
await loadOnce()
|
|
||||||
if (stop) return
|
|
||||||
const elapsed = Date.now() - start
|
|
||||||
// server/info 正常会阻塞约 1s;如果异常很快失败,避免疯狂重试
|
|
||||||
timer = window.setTimeout(loop, elapsed < 900 ? 1000 : 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
stop = false
|
|
||||||
loop()
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
stop = true
|
|
||||||
if (timer) window.clearTimeout(timer)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="page-stack" v-loading="initialLoading">
|
|
||||||
<div class="app-page-title">
|
|
||||||
<h2>统计</h2>
|
|
||||||
<span class="app-muted">{{ lastUpdatedAt ? `最后更新:${lastUpdatedAt}` : '实时更新' }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-row :gutter="12">
|
|
||||||
<el-col :xs="12" :sm="8" :md="6">
|
|
||||||
<el-card shadow="never" class="metric-card" :body-style="{ padding: '14px' }">
|
|
||||||
<div class="metric-label">CPU</div>
|
|
||||||
<div class="metric-value">{{ server.cpu_percent }}%</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="12" :sm="8" :md="6">
|
|
||||||
<el-card shadow="never" class="metric-card" :body-style="{ padding: '14px' }">
|
|
||||||
<div class="metric-label">内存</div>
|
|
||||||
<div class="metric-value">{{ serverMemoryDisplay }}</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="12" :sm="8" :md="6">
|
|
||||||
<el-card shadow="never" class="metric-card" :body-style="{ padding: '14px' }">
|
|
||||||
<div class="metric-label">磁盘</div>
|
|
||||||
<div class="metric-value">{{ serverDiskDisplay }}</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="12" :sm="8" :md="6">
|
|
||||||
<el-card shadow="never" class="metric-card" :body-style="{ padding: '14px' }">
|
|
||||||
<div class="metric-label">容器内存</div>
|
|
||||||
<div class="metric-value">{{ docker.memory_limit !== 'N/A' ? `${docker.memory_usage} / ${docker.memory_limit}` : docker.memory_usage }}</div>
|
|
||||||
<div v-if="docker.memory_percent !== 'N/A'" class="metric-sub app-muted">{{ docker.memory_percent }}</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row :gutter="12">
|
|
||||||
<el-col :xs="24" :md="14">
|
|
||||||
<el-card shadow="never" class="card" :body-style="{ padding: '16px' }">
|
|
||||||
<div class="section-head">
|
|
||||||
<h3 class="section-title">实时监控</h3>
|
|
||||||
<span class="app-muted">最大并发:{{ monitor.max_concurrent }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-row :gutter="12" class="count-row">
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-card shadow="never" class="count-card ok" :body-style="{ padding: '12px' }">
|
|
||||||
<div class="count-value">{{ monitor.running_count }}</div>
|
|
||||||
<div class="count-label">运行中</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-card shadow="never" class="count-card warn" :body-style="{ padding: '12px' }">
|
|
||||||
<div class="count-value">{{ monitor.queuing_count }}</div>
|
|
||||||
<div class="count-label">排队中</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-card shadow="never" class="count-card" :body-style="{ padding: '12px' }">
|
|
||||||
<div class="count-value">{{ monitor.max_concurrent }}</div>
|
|
||||||
<div class="count-label">并发上限</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<div class="sub-title">运行中任务</div>
|
|
||||||
<div v-if="monitor.running.length === 0" class="empty app-muted">暂无运行中的任务</div>
|
|
||||||
<div v-else class="task-list">
|
|
||||||
<div v-for="t in monitor.running" :key="`r-${t.account_id}`" class="task-item">
|
|
||||||
<div class="task-left">
|
|
||||||
<div class="task-line">
|
|
||||||
<el-tag :type="getTaskSourceMeta(t.source).type" effect="light" size="small">
|
|
||||||
{{ getTaskSourceMeta(t.source).label }}
|
|
||||||
</el-tag>
|
|
||||||
<span class="task-user">{{ t.user_username }}</span>
|
|
||||||
<span class="app-muted">→</span>
|
|
||||||
<span class="task-account">{{ t.username }}</span>
|
|
||||||
<el-tag effect="plain" size="small">{{ t.browse_type }}</el-tag>
|
|
||||||
</div>
|
|
||||||
<div class="task-line2">
|
|
||||||
<span class="dot" :style="{ background: statusColor(t.detail_status) }"></span>
|
|
||||||
<span class="task-status" :style="{ color: statusColor(t.detail_status) }">{{ t.detail_status }}</span>
|
|
||||||
<span v-if="t.progress_items || t.progress_attachments" class="app-muted"
|
|
||||||
>内容/附件:{{ t.progress_items }} / {{ t.progress_attachments }}</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="task-right">{{ t.elapsed_display }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-title">排队中任务</div>
|
|
||||||
<div v-if="monitor.queuing.length === 0" class="empty app-muted">暂无排队中的任务</div>
|
|
||||||
<div v-else class="task-list">
|
|
||||||
<div v-for="t in monitor.queuing" :key="`q-${t.account_id}`" class="task-item queue">
|
|
||||||
<div class="task-left">
|
|
||||||
<div class="task-line">
|
|
||||||
<el-tag :type="getTaskSourceMeta(t.source).type" effect="light" size="small">
|
|
||||||
{{ getTaskSourceMeta(t.source).label }}
|
|
||||||
</el-tag>
|
|
||||||
<span class="task-user">{{ t.user_username }}</span>
|
|
||||||
<span class="app-muted">→</span>
|
|
||||||
<span class="task-account">{{ t.username }}</span>
|
|
||||||
<el-tag effect="plain" size="small">{{ t.browse_type }}</el-tag>
|
|
||||||
</div>
|
|
||||||
<div class="task-line2">
|
|
||||||
<span class="dot" style="background: #f59e0b"></span>
|
|
||||||
<span class="task-status" style="color: #f59e0b">{{ t.detail_status || '等待资源' }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="task-right warn">{{ t.elapsed_display }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :xs="24" :md="10">
|
|
||||||
<el-card shadow="never" class="card" :body-style="{ padding: '16px' }">
|
|
||||||
<div class="section-head">
|
|
||||||
<h3 class="section-title">任务统计</h3>
|
|
||||||
<span class="app-muted">运行:{{ server.uptime }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stat-grid">
|
|
||||||
<div class="stat-box ok">
|
|
||||||
<div class="stat-name">成功任务</div>
|
|
||||||
<div class="stat-row">
|
|
||||||
<span class="stat-big">{{ taskStats.today.success_tasks }}</span>
|
|
||||||
<span class="app-muted">今日</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-row2 app-muted">累计:{{ taskStats.total.success_tasks }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-box err">
|
|
||||||
<div class="stat-name">失败任务</div>
|
|
||||||
<div class="stat-row">
|
|
||||||
<span class="stat-big">{{ taskStats.today.failed_tasks }}</span>
|
|
||||||
<span class="app-muted">今日</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-row2 app-muted">累计:{{ taskStats.total.failed_tasks }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-box info">
|
|
||||||
<div class="stat-name">浏览内容</div>
|
|
||||||
<div class="stat-row">
|
|
||||||
<span class="stat-big">{{ taskStats.today.total_items }}</span>
|
|
||||||
<span class="app-muted">今日</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-row2 app-muted">累计:{{ taskStats.total.total_items }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-box info2">
|
|
||||||
<div class="stat-name">查看附件</div>
|
|
||||||
<div class="stat-row">
|
|
||||||
<span class="stat-big">{{ taskStats.today.total_attachments }}</span>
|
|
||||||
<span class="app-muted">今日</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-row2 app-muted">累计:{{ taskStats.total.total_attachments }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.page-stack {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metric-card,
|
|
||||||
.card {
|
|
||||||
border-radius: var(--app-radius);
|
|
||||||
border: 1px solid var(--app-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.metric-label {
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--app-muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
.metric-value {
|
|
||||||
margin-top: 6px;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metric-sub {
|
|
||||||
margin-top: 4px;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-head {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 10px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-title {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
|
|
||||||
.count-row {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.count-card {
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px solid var(--app-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.count-card.ok {
|
|
||||||
background: rgba(16, 185, 129, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.count-card.warn {
|
|
||||||
background: rgba(245, 158, 11, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.count-value {
|
|
||||||
font-size: 22px;
|
|
||||||
font-weight: 900;
|
|
||||||
line-height: 1.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.count-label {
|
|
||||||
margin-top: 4px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--app-muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-title {
|
|
||||||
margin-top: 14px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty {
|
|
||||||
padding: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 10px;
|
|
||||||
padding: 10px 12px;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px solid var(--app-border);
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-item.queue {
|
|
||||||
background: rgba(245, 158, 11, 0.06);
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-line {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-line2 {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 8px;
|
|
||||||
margin-top: 6px;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-user {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-account {
|
|
||||||
font-weight: 700;
|
|
||||||
color: #2563eb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot {
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
border-radius: 999px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-status {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-right {
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: #10b981;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-right.warn {
|
|
||||||
color: #f59e0b;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.task-item {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-right {
|
|
||||||
align-self: flex-end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-box {
|
|
||||||
border-radius: 12px;
|
|
||||||
border: 1px solid var(--app-border);
|
|
||||||
padding: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-box.ok {
|
|
||||||
background: rgba(16, 185, 129, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-box.err {
|
|
||||||
background: rgba(239, 68, 68, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-box.info {
|
|
||||||
background: rgba(59, 130, 246, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-box.info2 {
|
|
||||||
background: rgba(6, 182, 212, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-name {
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 800;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-big {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 900;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-row2 {
|
|
||||||
margin-top: 6px;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -5,7 +5,6 @@ import AdminLayout from '../layouts/AdminLayout.vue'
|
|||||||
const ReportPage = () => import('../pages/ReportPage.vue')
|
const ReportPage = () => import('../pages/ReportPage.vue')
|
||||||
const UsersPage = () => import('../pages/UsersPage.vue')
|
const UsersPage = () => import('../pages/UsersPage.vue')
|
||||||
const FeedbacksPage = () => import('../pages/FeedbacksPage.vue')
|
const FeedbacksPage = () => import('../pages/FeedbacksPage.vue')
|
||||||
const StatsPage = () => import('../pages/StatsPage.vue')
|
|
||||||
const LogsPage = () => import('../pages/LogsPage.vue')
|
const LogsPage = () => import('../pages/LogsPage.vue')
|
||||||
const AnnouncementsPage = () => import('../pages/AnnouncementsPage.vue')
|
const AnnouncementsPage = () => import('../pages/AnnouncementsPage.vue')
|
||||||
const EmailPage = () => import('../pages/EmailPage.vue')
|
const EmailPage = () => import('../pages/EmailPage.vue')
|
||||||
@@ -19,10 +18,10 @@ const routes = [
|
|||||||
children: [
|
children: [
|
||||||
{ path: '', redirect: '/reports' },
|
{ path: '', redirect: '/reports' },
|
||||||
{ path: '/pending', redirect: '/reports' },
|
{ path: '/pending', redirect: '/reports' },
|
||||||
|
{ path: '/stats', redirect: '/reports' },
|
||||||
{ path: '/reports', name: 'reports', component: ReportPage },
|
{ path: '/reports', name: 'reports', component: ReportPage },
|
||||||
{ path: '/users', name: 'users', component: UsersPage },
|
{ path: '/users', name: 'users', component: UsersPage },
|
||||||
{ path: '/feedbacks', name: 'feedbacks', component: FeedbacksPage },
|
{ path: '/feedbacks', name: 'feedbacks', component: FeedbacksPage },
|
||||||
{ path: '/stats', name: 'stats', component: StatsPage },
|
|
||||||
{ path: '/logs', name: 'logs', component: LogsPage },
|
{ path: '/logs', name: 'logs', component: LogsPage },
|
||||||
{ path: '/announcements', name: 'announcements', component: AnnouncementsPage },
|
{ path: '/announcements', name: 'announcements', component: AnnouncementsPage },
|
||||||
{ path: '/email', name: 'email', component: EmailPage },
|
{ path: '/email', name: 'email', component: EmailPage },
|
||||||
|
|||||||
@@ -1,38 +1,34 @@
|
|||||||
{
|
{
|
||||||
"_email-DiVz51rK.js": {
|
"_email-BV9AnvmL.js": {
|
||||||
"file": "assets/email-DiVz51rK.js",
|
"file": "assets/email-BV9AnvmL.js",
|
||||||
"name": "email",
|
"name": "email",
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html"
|
"index.html"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"_taskSource-CFicR2zp.js": {
|
"_tasks-qpTYE_u9.js": {
|
||||||
"file": "assets/taskSource-CFicR2zp.js",
|
"file": "assets/tasks-qpTYE_u9.js",
|
||||||
"name": "taskSource"
|
|
||||||
},
|
|
||||||
"_tasks-Bpfaxqqb.js": {
|
|
||||||
"file": "assets/tasks-Bpfaxqqb.js",
|
|
||||||
"name": "tasks",
|
"name": "tasks",
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html"
|
"index.html"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"_update-B-ZRn1LV.js": {
|
"_update-DfOjb_I1.js": {
|
||||||
"file": "assets/update-B-ZRn1LV.js",
|
"file": "assets/update-DfOjb_I1.js",
|
||||||
"name": "update",
|
"name": "update",
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html"
|
"index.html"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"_users-CgASQeNW.js": {
|
"_users-BhMai3uM.js": {
|
||||||
"file": "assets/users-CgASQeNW.js",
|
"file": "assets/users-BhMai3uM.js",
|
||||||
"name": "users",
|
"name": "users",
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html"
|
"index.html"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"index.html": {
|
"index.html": {
|
||||||
"file": "assets/index-Do26tg8I.js",
|
"file": "assets/index-DJ3M_U2-.js",
|
||||||
"name": "index",
|
"name": "index",
|
||||||
"src": "index.html",
|
"src": "index.html",
|
||||||
"isEntry": true,
|
"isEntry": true,
|
||||||
@@ -40,7 +36,6 @@
|
|||||||
"src/pages/ReportPage.vue",
|
"src/pages/ReportPage.vue",
|
||||||
"src/pages/UsersPage.vue",
|
"src/pages/UsersPage.vue",
|
||||||
"src/pages/FeedbacksPage.vue",
|
"src/pages/FeedbacksPage.vue",
|
||||||
"src/pages/StatsPage.vue",
|
|
||||||
"src/pages/LogsPage.vue",
|
"src/pages/LogsPage.vue",
|
||||||
"src/pages/AnnouncementsPage.vue",
|
"src/pages/AnnouncementsPage.vue",
|
||||||
"src/pages/EmailPage.vue",
|
"src/pages/EmailPage.vue",
|
||||||
@@ -48,11 +43,11 @@
|
|||||||
"src/pages/SettingsPage.vue"
|
"src/pages/SettingsPage.vue"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"assets/index-C73IFBwi.css"
|
"assets/index-2V61oOJ0.css"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/AnnouncementsPage.vue": {
|
"src/pages/AnnouncementsPage.vue": {
|
||||||
"file": "assets/AnnouncementsPage-BoMMAWcs.js",
|
"file": "assets/AnnouncementsPage-D3-leUXL.js",
|
||||||
"name": "AnnouncementsPage",
|
"name": "AnnouncementsPage",
|
||||||
"src": "src/pages/AnnouncementsPage.vue",
|
"src": "src/pages/AnnouncementsPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -64,12 +59,12 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/EmailPage.vue": {
|
"src/pages/EmailPage.vue": {
|
||||||
"file": "assets/EmailPage-VvSoafV1.js",
|
"file": "assets/EmailPage-CQQbxruj.js",
|
||||||
"name": "EmailPage",
|
"name": "EmailPage",
|
||||||
"src": "src/pages/EmailPage.vue",
|
"src": "src/pages/EmailPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_email-DiVz51rK.js",
|
"_email-BV9AnvmL.js",
|
||||||
"index.html"
|
"index.html"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
@@ -77,7 +72,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/FeedbacksPage.vue": {
|
"src/pages/FeedbacksPage.vue": {
|
||||||
"file": "assets/FeedbacksPage-DSgG1B6b.js",
|
"file": "assets/FeedbacksPage-Bazxwg3y.js",
|
||||||
"name": "FeedbacksPage",
|
"name": "FeedbacksPage",
|
||||||
"src": "src/pages/FeedbacksPage.vue",
|
"src": "src/pages/FeedbacksPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -89,14 +84,13 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/LogsPage.vue": {
|
"src/pages/LogsPage.vue": {
|
||||||
"file": "assets/LogsPage-D1qK6xGt.js",
|
"file": "assets/LogsPage-Bx0aa_bn.js",
|
||||||
"name": "LogsPage",
|
"name": "LogsPage",
|
||||||
"src": "src/pages/LogsPage.vue",
|
"src": "src/pages/LogsPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_users-CgASQeNW.js",
|
"_users-BhMai3uM.js",
|
||||||
"_tasks-Bpfaxqqb.js",
|
"_tasks-qpTYE_u9.js",
|
||||||
"_taskSource-CFicR2zp.js",
|
|
||||||
"index.html"
|
"index.html"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
@@ -104,22 +98,22 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/ReportPage.vue": {
|
"src/pages/ReportPage.vue": {
|
||||||
"file": "assets/ReportPage-BtciWYlz.js",
|
"file": "assets/ReportPage-DxWg5wJn.js",
|
||||||
"name": "ReportPage",
|
"name": "ReportPage",
|
||||||
"src": "src/pages/ReportPage.vue",
|
"src": "src/pages/ReportPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html",
|
"index.html",
|
||||||
"_email-DiVz51rK.js",
|
"_email-BV9AnvmL.js",
|
||||||
"_tasks-Bpfaxqqb.js",
|
"_tasks-qpTYE_u9.js",
|
||||||
"_update-B-ZRn1LV.js"
|
"_update-DfOjb_I1.js"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"assets/ReportPage-Ds4jOTh9.css"
|
"assets/ReportPage-TpqQWWvU.css"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/SettingsPage.vue": {
|
"src/pages/SettingsPage.vue": {
|
||||||
"file": "assets/SettingsPage-Bw9iP0hP.js",
|
"file": "assets/SettingsPage-DzBEGicw.js",
|
||||||
"name": "SettingsPage",
|
"name": "SettingsPage",
|
||||||
"src": "src/pages/SettingsPage.vue",
|
"src": "src/pages/SettingsPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -130,27 +124,13 @@
|
|||||||
"assets/SettingsPage-DGdwb4W2.css"
|
"assets/SettingsPage-DGdwb4W2.css"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/StatsPage.vue": {
|
|
||||||
"file": "assets/StatsPage-BumsyjN6.js",
|
|
||||||
"name": "StatsPage",
|
|
||||||
"src": "src/pages/StatsPage.vue",
|
|
||||||
"isDynamicEntry": true,
|
|
||||||
"imports": [
|
|
||||||
"_tasks-Bpfaxqqb.js",
|
|
||||||
"_taskSource-CFicR2zp.js",
|
|
||||||
"index.html"
|
|
||||||
],
|
|
||||||
"css": [
|
|
||||||
"assets/StatsPage-CiLeKa5o.css"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"src/pages/SystemPage.vue": {
|
"src/pages/SystemPage.vue": {
|
||||||
"file": "assets/SystemPage-CosZ9Vtj.js",
|
"file": "assets/SystemPage-DxT5Bmy6.js",
|
||||||
"name": "SystemPage",
|
"name": "SystemPage",
|
||||||
"src": "src/pages/SystemPage.vue",
|
"src": "src/pages/SystemPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_update-B-ZRn1LV.js",
|
"_update-DfOjb_I1.js",
|
||||||
"index.html"
|
"index.html"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
@@ -158,12 +138,12 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/UsersPage.vue": {
|
"src/pages/UsersPage.vue": {
|
||||||
"file": "assets/UsersPage-C6sG2ovw.js",
|
"file": "assets/UsersPage-D0YtBHGu.js",
|
||||||
"name": "UsersPage",
|
"name": "UsersPage",
|
||||||
"src": "src/pages/UsersPage.vue",
|
"src": "src/pages/UsersPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_users-CgASQeNW.js",
|
"_users-BhMai3uM.js",
|
||||||
"index.html"
|
"index.html"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
static/admin/assets/FeedbacksPage-Bazxwg3y.js
Normal file
1
static/admin/assets/FeedbacksPage-Bazxwg3y.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
static/admin/assets/LogsPage-Bx0aa_bn.js
Normal file
1
static/admin/assets/LogsPage-Bx0aa_bn.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
.page-stack[data-v-e84f7d23]{display:flex;flex-direction:column;gap:12px}.title-group[data-v-e84f7d23]{display:flex;flex-direction:column;gap:2px}.toolbar[data-v-e84f7d23]{display:flex;gap:10px;align-items:center;flex-wrap:wrap}.card[data-v-e84f7d23]{border-radius:var(--app-radius);border:1px solid var(--app-border)}.metric-label[data-v-e84f7d23]{font-size:12px;color:var(--app-muted)}.metric-value[data-v-e84f7d23]{margin-top:6px;font-size:22px;font-weight:900;line-height:1.1}.section-head[data-v-e84f7d23]{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:12px}.section-title[data-v-e84f7d23]{margin:0;font-size:14px;font-weight:800}.kv[data-v-e84f7d23]{border:1px solid var(--app-border);border-radius:12px;padding:12px;background:#fff}.kv-v[data-v-e84f7d23]{font-size:18px;font-weight:900;line-height:1.1}.kv-k[data-v-e84f7d23]{margin-top:6px;font-size:12px}.ok[data-v-e84f7d23]{color:#047857}.warn[data-v-e84f7d23]{color:#b45309}.err[data-v-e84f7d23]{color:#b91c1c}.divider[data-v-e84f7d23]{height:1px;background:var(--app-border);margin:14px 0}.sys-grid[data-v-e84f7d23]{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}.sys-item[data-v-e84f7d23]{border:1px solid var(--app-border);border-radius:12px;padding:12px;background:#fff}.sys-k[data-v-e84f7d23]{font-size:12px}.sys-sub[data-v-e84f7d23]{margin-top:8px;font-size:12px}.desc-inline[data-v-e84f7d23]{margin-left:8px}.sub-title[data-v-e84f7d23]{font-size:13px;font-weight:800;margin-bottom:10px}.type-grid[data-v-e84f7d23]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.type-item[data-v-e84f7d23]{border:1px solid var(--app-border);border-radius:12px;padding:12px;background:#fff}.type-v[data-v-e84f7d23]{font-size:16px;font-weight:900}.type-k[data-v-e84f7d23]{margin-top:6px;font-size:12px}.table-wrap[data-v-e84f7d23]{overflow-x:auto}.help[data-v-e84f7d23]{margin-top:10px;font-size:12px}@media(max-width:768px){.sys-grid[data-v-e84f7d23]{grid-template-columns:1fr}}
|
|
||||||
1
static/admin/assets/ReportPage-DxWg5wJn.js
Normal file
1
static/admin/assets/ReportPage-DxWg5wJn.js
Normal file
File diff suppressed because one or more lines are too long
1
static/admin/assets/ReportPage-TpqQWWvU.css
Normal file
1
static/admin/assets/ReportPage-TpqQWWvU.css
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
import{D as m,_ as T,r as p,a as h,b as r,d as a,w as s,e as u,h as k,j as b,q as d,E as x}from"./index-Do26tg8I.js";async function C(o){const{data:t}=await m.put("/admin/username",{new_username:o});return t}async function E(o){const{data:t}=await m.put("/admin/password",{new_password:o});return t}async function P(){const{data:o}=await m.post("/logout");return o}const U={class:"page-stack"},N={__name:"SettingsPage",setup(o){const t=p(""),i=p(""),n=p(!1);async function f(){try{await P()}catch{}finally{window.location.href="/yuyx"}}async function V(){const l=t.value.trim();if(!l){d.error("请输入新用户名");return}try{await x.confirm(`确定将管理员用户名修改为「${l}」吗?修改后需要重新登录。`,"修改用户名",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await C(l),d.success("用户名修改成功,请重新登录"),t.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}async function B(){const l=i.value;if(!l){d.error("请输入新密码");return}if(l.length<6){d.error("密码至少6个字符");return}try{await x.confirm("确定修改管理员密码吗?修改后需要重新登录。","修改密码",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await E(l),d.success("密码修改成功,请重新登录"),i.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}return(l,e)=>{const w=u("el-input"),v=u("el-form-item"),y=u("el-form"),_=u("el-button"),g=u("el-card");return k(),h("div",U,[e[7]||(e[7]=r("div",{class:"app-page-title"},[r("h2",null,"设置"),r("span",{class:"app-muted"},"管理员账号设置")],-1)),a(g,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:s(()=>[e[3]||(e[3]=r("h3",{class:"section-title"},"修改管理员用户名",-1)),a(y,{"label-width":"120px"},{default:s(()=>[a(v,{label:"新用户名"},{default:s(()=>[a(w,{modelValue:t.value,"onUpdate:modelValue":e[0]||(e[0]=c=>t.value=c),placeholder:"输入新用户名",disabled:n.value},null,8,["modelValue","disabled"])]),_:1})]),_:1}),a(_,{type:"primary",loading:n.value,onClick:V},{default:s(()=>[...e[2]||(e[2]=[b("保存用户名",-1)])]),_:1},8,["loading"])]),_:1}),a(g,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:s(()=>[e[5]||(e[5]=r("h3",{class:"section-title"},"修改管理员密码",-1)),a(y,{"label-width":"120px"},{default:s(()=>[a(v,{label:"新密码"},{default:s(()=>[a(w,{modelValue:i.value,"onUpdate:modelValue":e[1]||(e[1]=c=>i.value=c),type:"password","show-password":"",placeholder:"输入新密码",disabled:n.value},null,8,["modelValue","disabled"])]),_:1})]),_:1}),a(_,{type:"primary",loading:n.value,onClick:B},{default:s(()=>[...e[4]||(e[4]=[b("保存密码",-1)])]),_:1},8,["loading"]),e[6]||(e[6]=r("div",{class:"help"},"建议使用更强密码(至少8位且包含字母与数字)。",-1))]),_:1})])}}},M=T(N,[["__scopeId","data-v-2f4b840f"]]);export{M as default};
|
|
||||||
1
static/admin/assets/SettingsPage-DzBEGicw.js
Normal file
1
static/admin/assets/SettingsPage-DzBEGicw.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{S as m,_ as T,r as p,e as h,f as r,g as a,w as s,n as u,x as k,y as x,L as i,K as b}from"./index-DJ3M_U2-.js";async function C(o){const{data:t}=await m.put("/admin/username",{new_username:o});return t}async function P(o){const{data:t}=await m.put("/admin/password",{new_password:o});return t}async function U(){const{data:o}=await m.post("/logout");return o}const E={class:"page-stack"},N={__name:"SettingsPage",setup(o){const t=p(""),d=p(""),n=p(!1);async function f(){try{await U()}catch{}finally{window.location.href="/yuyx"}}async function V(){const l=t.value.trim();if(!l){i.error("请输入新用户名");return}try{await b.confirm(`确定将管理员用户名修改为「${l}」吗?修改后需要重新登录。`,"修改用户名",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await C(l),i.success("用户名修改成功,请重新登录"),t.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}async function B(){const l=d.value;if(!l){i.error("请输入新密码");return}if(l.length<6){i.error("密码至少6个字符");return}try{await b.confirm("确定修改管理员密码吗?修改后需要重新登录。","修改密码",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await P(l),i.success("密码修改成功,请重新登录"),d.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}return(l,e)=>{const w=u("el-input"),y=u("el-form-item"),v=u("el-form"),_=u("el-button"),g=u("el-card");return k(),h("div",E,[e[7]||(e[7]=r("div",{class:"app-page-title"},[r("h2",null,"设置"),r("span",{class:"app-muted"},"管理员账号设置")],-1)),a(g,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:s(()=>[e[3]||(e[3]=r("h3",{class:"section-title"},"修改管理员用户名",-1)),a(v,{"label-width":"120px"},{default:s(()=>[a(y,{label:"新用户名"},{default:s(()=>[a(w,{modelValue:t.value,"onUpdate:modelValue":e[0]||(e[0]=c=>t.value=c),placeholder:"输入新用户名",disabled:n.value},null,8,["modelValue","disabled"])]),_:1})]),_:1}),a(_,{type:"primary",loading:n.value,onClick:V},{default:s(()=>[...e[2]||(e[2]=[x("保存用户名",-1)])]),_:1},8,["loading"])]),_:1}),a(g,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:s(()=>[e[5]||(e[5]=r("h3",{class:"section-title"},"修改管理员密码",-1)),a(v,{"label-width":"120px"},{default:s(()=>[a(y,{label:"新密码"},{default:s(()=>[a(w,{modelValue:d.value,"onUpdate:modelValue":e[1]||(e[1]=c=>d.value=c),type:"password","show-password":"",placeholder:"输入新密码",disabled:n.value},null,8,["modelValue","disabled"])]),_:1})]),_:1}),a(_,{type:"primary",loading:n.value,onClick:B},{default:s(()=>[...e[4]||(e[4]=[x("保存密码",-1)])]),_:1},8,["loading"]),e[6]||(e[6]=r("div",{class:"help"},"建议使用更强密码(至少8位且包含字母与数字)。",-1))]),_:1})])}}},A=T(N,[["__scopeId","data-v-2f4b840f"]]);export{A as default};
|
||||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
.page-stack[data-v-84b6799b]{display:flex;flex-direction:column;gap:12px}.metric-card[data-v-84b6799b],.card[data-v-84b6799b]{border-radius:var(--app-radius);border:1px solid var(--app-border)}.metric-label[data-v-84b6799b]{font-size:12px;color:var(--app-muted)}.metric-value[data-v-84b6799b]{margin-top:6px;font-size:18px;font-weight:800}.metric-sub[data-v-84b6799b]{margin-top:4px;font-size:12px}.section-head[data-v-84b6799b]{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:12px}.section-title[data-v-84b6799b]{margin:0;font-size:14px;font-weight:800}.count-row[data-v-84b6799b]{margin-bottom:10px}.count-card[data-v-84b6799b]{border-radius:10px;border:1px solid var(--app-border)}.count-card.ok[data-v-84b6799b]{background:#10b98114}.count-card.warn[data-v-84b6799b]{background:#f59e0b14}.count-value[data-v-84b6799b]{font-size:22px;font-weight:900;line-height:1.1}.count-label[data-v-84b6799b]{margin-top:4px;font-size:12px;color:var(--app-muted)}.sub-title[data-v-84b6799b]{margin-top:14px;margin-bottom:8px;font-size:13px;font-weight:800}.empty[data-v-84b6799b]{padding:10px 0}.task-list[data-v-84b6799b]{display:flex;flex-direction:column;gap:8px}.task-item[data-v-84b6799b]{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;padding:10px 12px;border-radius:10px;border:1px solid var(--app-border);background:#fff}.task-item.queue[data-v-84b6799b]{background:#f59e0b0f}.task-line[data-v-84b6799b]{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.task-line2[data-v-84b6799b]{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:6px;font-size:12px}.task-user[data-v-84b6799b]{font-weight:600}.task-account[data-v-84b6799b]{font-weight:700;color:#2563eb}.dot[data-v-84b6799b]{width:8px;height:8px;border-radius:999px;display:inline-block}.task-status[data-v-84b6799b]{font-weight:700}.task-right[data-v-84b6799b]{font-size:12px;font-weight:700;color:#10b981;white-space:nowrap}.task-right.warn[data-v-84b6799b]{color:#f59e0b}@media(max-width:768px){.task-item[data-v-84b6799b]{flex-direction:column}.task-right[data-v-84b6799b]{align-self:flex-end}}.stat-grid[data-v-84b6799b]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.stat-box[data-v-84b6799b]{border-radius:12px;border:1px solid var(--app-border);padding:12px}.stat-box.ok[data-v-84b6799b]{background:#10b98114}.stat-box.err[data-v-84b6799b]{background:#ef444414}.stat-box.info[data-v-84b6799b]{background:#3b82f614}.stat-box.info2[data-v-84b6799b]{background:#06b6d414}.stat-name[data-v-84b6799b]{font-size:12px;font-weight:800;margin-bottom:6px}.stat-row[data-v-84b6799b]{display:flex;align-items:baseline;gap:8px}.stat-big[data-v-84b6799b]{font-size:20px;font-weight:900}.stat-row2[data-v-84b6799b]{margin-top:6px;font-size:12px}
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
static/admin/assets/UsersPage-D0YtBHGu.js
Normal file
1
static/admin/assets/UsersPage-D0YtBHGu.js
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
import{D as n}from"./index-Do26tg8I.js";async function i(){const{data:a}=await n.get("/email/settings");return a}async function e(a){const{data:t}=await n.post("/email/settings",a);return t}async function c(){const{data:a}=await n.get("/email/stats");return a}async function o(a){const{data:t}=await n.get("/email/logs",{params:a});return t}async function l(a){const{data:t}=await n.post("/email/logs/cleanup",{days:a});return t}export{i as a,o as b,l as c,c as f,e as u};
|
import{S as n}from"./index-DJ3M_U2-.js";async function i(){const{data:a}=await n.get("/email/settings");return a}async function e(a){const{data:t}=await n.post("/email/settings",a);return t}async function c(){const{data:a}=await n.get("/email/stats");return a}async function o(a){const{data:t}=await n.get("/email/logs",{params:a});return t}async function l(a){const{data:t}=await n.post("/email/logs/cleanup",{days:a});return t}export{i as a,o as b,l as c,c as f,e as u};
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
function s(t){return String(t||"").trim()}function a(t){return!t.startsWith("user_scheduled")||!t.includes(":")?"":t.split(":",2)[1]||""}function i(t){const e=s(t);if(!e||e==="manual")return{group:"manual",label:"手动",type:"success",tooltip:""};if(e==="scheduled")return{group:"scheduled",label:"定时任务",type:"primary",tooltip:"系统定时"};if(e.startsWith("user_scheduled")){const u=a(e),r=String(u||"").replace(/^batch_/,"");return{group:"scheduled",label:"定时任务",type:"primary",tooltip:r?`用户定时批次:${r}`:"用户定时"}}return{group:"manual",label:"手动",type:"success",tooltip:{batch:"手动批量",manual_screenshot:"手动截图",immediate:"立即执行",resumed:"断点恢复"}[e]||e}}export{i as g};
|
|
||||||
@@ -1 +1 @@
|
|||||||
import{D as a}from"./index-Do26tg8I.js";async function c(){const{data:t}=await a.get("/server/info");return t}async function e(){const{data:t}=await a.get("/docker_stats");return t}async function o(){const{data:t}=await a.get("/task/stats");return t}async function r(){const{data:t}=await a.get("/task/running");return t}async function i(t){const{data:s}=await a.get("/task/logs",{params:t});return s}async function f(t){const{data:s}=await a.post("/task/logs/clear",{days:t});return s}export{r as a,c as b,e as c,i as d,f as e,o as f};
|
import{S as a}from"./index-DJ3M_U2-.js";async function c(){const{data:t}=await a.get("/server/info");return t}async function e(){const{data:t}=await a.get("/docker_stats");return t}async function o(){const{data:t}=await a.get("/task/stats");return t}async function r(){const{data:t}=await a.get("/task/running");return t}async function i(t){const{data:s}=await a.get("/task/logs",{params:t});return s}async function f(t){const{data:s}=await a.post("/task/logs/clear",{days:t});return s}export{r as a,c as b,e as c,i as d,f as e,o as f};
|
||||||
@@ -1 +1 @@
|
|||||||
import{D as a}from"./index-Do26tg8I.js";async function s(){const{data:t}=await a.get("/system/config");return t}async function c(t){const{data:e}=await a.post("/system/config",t);return e}async function u(){const{data:t}=await a.post("/schedule/execute",{});return t}async function o(){const{data:t}=await a.get("/update/status");return t}async function r(){const{data:t}=await a.get("/update/result");return t}async function d(t={}){const{data:e}=await a.get("/update/log",{params:t});return e}async function i(){const{data:t}=await a.post("/update/check",{});return t}async function f(t={}){const{data:e}=await a.post("/update/run",t);return e}export{o as a,r as b,d as c,f as d,u as e,s as f,i as r,c as u};
|
import{S as a}from"./index-DJ3M_U2-.js";async function s(){const{data:t}=await a.get("/system/config");return t}async function c(t){const{data:e}=await a.post("/system/config",t);return e}async function u(){const{data:t}=await a.post("/schedule/execute",{});return t}async function o(){const{data:t}=await a.get("/update/status");return t}async function r(){const{data:t}=await a.get("/update/result");return t}async function d(t={}){const{data:e}=await a.get("/update/log",{params:t});return e}async function i(){const{data:t}=await a.post("/update/check",{});return t}async function f(t={}){const{data:e}=await a.post("/update/run",t);return e}export{o as a,r as b,d as c,f as d,u as e,s as f,i as r,c as u};
|
||||||
@@ -1 +1 @@
|
|||||||
import{D as t}from"./index-Do26tg8I.js";async function n(){const{data:s}=await t.get("/users");return s}async function o(s){const{data:a}=await t.post(`/users/${s}/approve`);return a}async function c(s){const{data:a}=await t.post(`/users/${s}/reject`);return a}async function i(s){const{data:a}=await t.delete(`/users/${s}`);return a}async function u(s,a){const{data:e}=await t.post(`/users/${s}/vip`,{days:a});return e}async function p(s){const{data:a}=await t.delete(`/users/${s}/vip`);return a}async function d(s,a){const{data:e}=await t.post(`/users/${s}/reset_password`,{new_password:a});return e}export{o as a,p as b,d as c,i as d,n as f,c as r,u as s};
|
import{S as t}from"./index-DJ3M_U2-.js";async function n(){const{data:s}=await t.get("/users");return s}async function o(s){const{data:a}=await t.post(`/users/${s}/approve`);return a}async function c(s){const{data:a}=await t.post(`/users/${s}/reject`);return a}async function i(s){const{data:a}=await t.delete(`/users/${s}`);return a}async function u(s,a){const{data:e}=await t.post(`/users/${s}/vip`,{days:a});return e}async function p(s){const{data:a}=await t.delete(`/users/${s}/vip`);return a}async function d(s,a){const{data:e}=await t.post(`/users/${s}/reset_password`,{new_password:a});return e}export{o as a,p as b,d as c,i as d,n as f,c as r,u as s};
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>后台管理 - 知识管理平台</title>
|
<title>后台管理 - 知识管理平台</title>
|
||||||
<script type="module" crossorigin src="./assets/index-Do26tg8I.js"></script>
|
<script type="module" crossorigin src="./assets/index-DJ3M_U2-.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="./assets/index-C73IFBwi.css">
|
<link rel="stylesheet" crossorigin href="./assets/index-2V61oOJ0.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user