feat(report): add slow API ranking module for admin
This commit is contained in:
@@ -10,6 +10,11 @@ export async function fetchDockerStats() {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchRequestMetrics() {
|
||||||
|
const { data } = await api.get('/request_metrics')
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
export async function fetchTaskStats() {
|
export async function fetchTaskStats() {
|
||||||
const { data } = await api.get('/task/stats')
|
const { data } = await api.get('/task/stats')
|
||||||
return data
|
return data
|
||||||
@@ -29,4 +34,3 @@ export async function clearOldTaskLogs(days) {
|
|||||||
const { data } = await api.post('/task/logs/clear', { days })
|
const { data } = await api.post('/task/logs/clear', { days })
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
|
|
||||||
import { fetchFeedbackStats } from '../api/feedbacks'
|
import { fetchFeedbackStats } from '../api/feedbacks'
|
||||||
import { fetchEmailStats } from '../api/email'
|
import { fetchEmailStats } from '../api/email'
|
||||||
import { fetchDockerStats, fetchRunningTasks, fetchServerInfo, fetchTaskStats } from '../api/tasks'
|
import { fetchDockerStats, fetchRequestMetrics, fetchRunningTasks, fetchServerInfo, fetchTaskStats } from '../api/tasks'
|
||||||
import { fetchBrowserPoolStats } from '../api/browser_pool'
|
import { fetchBrowserPoolStats } from '../api/browser_pool'
|
||||||
import { fetchSystemConfig } from '../api/system'
|
import { fetchSystemConfig } from '../api/system'
|
||||||
import MetricGrid from '../components/MetricGrid.vue'
|
import MetricGrid from '../components/MetricGrid.vue'
|
||||||
@@ -37,6 +37,7 @@ const serverInfo = ref(null)
|
|||||||
const dockerStats = ref(null)
|
const dockerStats = ref(null)
|
||||||
const browserPoolStats = ref(null)
|
const browserPoolStats = ref(null)
|
||||||
const systemConfig = ref(null)
|
const systemConfig = ref(null)
|
||||||
|
const requestMetrics = ref(null)
|
||||||
const queueTab = ref('running')
|
const queueTab = ref('running')
|
||||||
|
|
||||||
function recordUpdatedAt() {
|
function recordUpdatedAt() {
|
||||||
@@ -67,6 +68,23 @@ function percentText(value) {
|
|||||||
return `${Math.round(parsePercent(value))}%`
|
return `${Math.round(parsePercent(value))}%`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatMs(value) {
|
||||||
|
const n = Number(value)
|
||||||
|
if (!Number.isFinite(n) || n < 0) return '-'
|
||||||
|
if (n >= 100) return `${Math.round(n)}ms`
|
||||||
|
return `${n.toFixed(1)}ms`
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatUnixTime(value) {
|
||||||
|
const ts = Number(value)
|
||||||
|
if (!Number.isFinite(ts) || ts <= 0) return '-'
|
||||||
|
try {
|
||||||
|
return new Date(ts * 1000).toLocaleTimeString('zh-CN', { hour12: false, timeZone: 'Asia/Shanghai' })
|
||||||
|
} catch {
|
||||||
|
return '-'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function sourceLabel(source) {
|
function sourceLabel(source) {
|
||||||
const raw = String(source ?? '').trim()
|
const raw = String(source ?? '').trim()
|
||||||
if (!raw) return '手动'
|
if (!raw) return '手动'
|
||||||
@@ -288,6 +306,38 @@ const workerModuleItems = computed(() => [
|
|||||||
{ label: '任务队列', value: browserPoolQueueSize.value },
|
{ label: '任务队列', value: browserPoolQueueSize.value },
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const requestTopPaths = computed(() => {
|
||||||
|
const rows = requestMetrics.value?.top_paths
|
||||||
|
if (!Array.isArray(rows)) return []
|
||||||
|
return rows.slice(0, 3)
|
||||||
|
})
|
||||||
|
|
||||||
|
const requestModuleItems = computed(() => {
|
||||||
|
const items = [
|
||||||
|
{ label: '总请求', value: normalizeCount(requestMetrics.value?.total_requests) },
|
||||||
|
{ label: 'API请求', value: normalizeCount(requestMetrics.value?.api_requests) },
|
||||||
|
{ label: '慢请求', value: normalizeCount(requestMetrics.value?.slow_requests) },
|
||||||
|
{ label: '错误请求', value: normalizeCount(requestMetrics.value?.error_requests) },
|
||||||
|
]
|
||||||
|
|
||||||
|
requestTopPaths.value.forEach((row, index) => {
|
||||||
|
const pathText = String(row?.path || '-')
|
||||||
|
items.push({
|
||||||
|
label: `慢接口${index + 1}`,
|
||||||
|
value: `${pathText} · 峰值 ${formatMs(row?.max_ms)}`,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return items
|
||||||
|
})
|
||||||
|
|
||||||
|
const requestModuleDesc = computed(() => {
|
||||||
|
const avgMs = formatMs(requestMetrics.value?.avg_duration_ms)
|
||||||
|
const maxMs = formatMs(requestMetrics.value?.max_duration_ms)
|
||||||
|
const lastAt = formatUnixTime(requestMetrics.value?.last_request_ts)
|
||||||
|
return `均值 ${avgMs} · 峰值 ${maxMs} · 最近 ${lastAt}`
|
||||||
|
})
|
||||||
|
|
||||||
const configModuleItems = computed(() => [
|
const configModuleItems = computed(() => [
|
||||||
{ label: '定时任务', value: scheduleEnabled.value ? '启用' : '关闭' },
|
{ label: '定时任务', value: scheduleEnabled.value ? '启用' : '关闭' },
|
||||||
{ label: '执行时间', value: scheduleTime.value || '-' },
|
{ label: '执行时间', value: scheduleTime.value || '-' },
|
||||||
@@ -342,6 +392,13 @@ const mobileModules = computed(() => [
|
|||||||
tone: 'green',
|
tone: 'green',
|
||||||
items: resourceModuleItems.value,
|
items: resourceModuleItems.value,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'request',
|
||||||
|
title: '接口性能',
|
||||||
|
desc: requestModuleDesc.value,
|
||||||
|
tone: 'purple',
|
||||||
|
items: requestModuleItems.value,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'worker',
|
key: 'worker',
|
||||||
title: '截图线程池',
|
title: '截图线程池',
|
||||||
@@ -374,6 +431,7 @@ async function refreshAll(options = {}) {
|
|||||||
serverResult,
|
serverResult,
|
||||||
dockerResult,
|
dockerResult,
|
||||||
browserPoolResult,
|
browserPoolResult,
|
||||||
|
requestMetricsResult,
|
||||||
configResult,
|
configResult,
|
||||||
] = await Promise.allSettled([
|
] = await Promise.allSettled([
|
||||||
fetchTaskStats(),
|
fetchTaskStats(),
|
||||||
@@ -383,6 +441,7 @@ async function refreshAll(options = {}) {
|
|||||||
fetchServerInfo(),
|
fetchServerInfo(),
|
||||||
fetchDockerStats(),
|
fetchDockerStats(),
|
||||||
fetchBrowserPoolStats(),
|
fetchBrowserPoolStats(),
|
||||||
|
fetchRequestMetrics(),
|
||||||
fetchSystemConfig(),
|
fetchSystemConfig(),
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -393,6 +452,7 @@ async function refreshAll(options = {}) {
|
|||||||
if (serverResult.status === 'fulfilled') serverInfo.value = serverResult.value
|
if (serverResult.status === 'fulfilled') serverInfo.value = serverResult.value
|
||||||
if (dockerResult.status === 'fulfilled') dockerStats.value = dockerResult.value
|
if (dockerResult.status === 'fulfilled') dockerStats.value = dockerResult.value
|
||||||
if (browserPoolResult.status === 'fulfilled') browserPoolStats.value = browserPoolResult.value
|
if (browserPoolResult.status === 'fulfilled') browserPoolStats.value = browserPoolResult.value
|
||||||
|
if (requestMetricsResult.status === 'fulfilled') requestMetrics.value = requestMetricsResult.value
|
||||||
if (configResult.status === 'fulfilled') systemConfig.value = configResult.value
|
if (configResult.status === 'fulfilled') systemConfig.value = configResult.value
|
||||||
|
|
||||||
await refreshStats?.()
|
await refreshStats?.()
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from app_logger import get_logger
|
|||||||
from flask import jsonify, session
|
from flask import jsonify, session
|
||||||
from routes.admin_api import admin_api_bp
|
from routes.admin_api import admin_api_bp
|
||||||
from routes.decorators import admin_required
|
from routes.decorators import admin_required
|
||||||
|
from services.request_metrics import get_request_metrics_snapshot
|
||||||
from services.time_utils import BEIJING_TZ, get_beijing_now
|
from services.time_utils import BEIJING_TZ, get_beijing_now
|
||||||
|
|
||||||
logger = get_logger("app")
|
logger = get_logger("app")
|
||||||
@@ -25,6 +26,10 @@ _DOCKER_STATS_CACHE_TTL = max(2.0, float(os.environ.get("ADMIN_DOCKER_STATS_CACH
|
|||||||
_docker_stats_cache: dict[str, object] = {"expires_at_monotonic": 0.0, "data": None}
|
_docker_stats_cache: dict[str, object] = {"expires_at_monotonic": 0.0, "data": None}
|
||||||
_docker_stats_cache_lock = threading.Lock()
|
_docker_stats_cache_lock = threading.Lock()
|
||||||
|
|
||||||
|
_REQUEST_METRICS_CACHE_TTL = max(1.0, float(os.environ.get("ADMIN_REQUEST_METRICS_CACHE_TTL_SECONDS", "3")))
|
||||||
|
_request_metrics_cache: dict[str, object] = {"expires_at_monotonic": 0.0, "data": None}
|
||||||
|
_request_metrics_cache_lock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
def _get_system_stats_cached() -> dict:
|
def _get_system_stats_cached() -> dict:
|
||||||
now = time.monotonic()
|
now = time.monotonic()
|
||||||
@@ -43,6 +48,23 @@ def _get_system_stats_cached() -> dict:
|
|||||||
return dict(fresh_data)
|
return dict(fresh_data)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_request_metrics_cached() -> dict:
|
||||||
|
now = time.monotonic()
|
||||||
|
with _request_metrics_cache_lock:
|
||||||
|
expires_at = float(_request_metrics_cache.get("expires_at_monotonic") or 0.0)
|
||||||
|
cached_data = _request_metrics_cache.get("data")
|
||||||
|
if isinstance(cached_data, dict) and now < expires_at:
|
||||||
|
return dict(cached_data)
|
||||||
|
|
||||||
|
fresh_data = get_request_metrics_snapshot() or {}
|
||||||
|
|
||||||
|
with _request_metrics_cache_lock:
|
||||||
|
_request_metrics_cache["data"] = dict(fresh_data)
|
||||||
|
_request_metrics_cache["expires_at_monotonic"] = now + _REQUEST_METRICS_CACHE_TTL
|
||||||
|
|
||||||
|
return dict(fresh_data)
|
||||||
|
|
||||||
|
|
||||||
@admin_api_bp.route("/stats", methods=["GET"])
|
@admin_api_bp.route("/stats", methods=["GET"])
|
||||||
@admin_required
|
@admin_required
|
||||||
def get_system_stats():
|
def get_system_stats():
|
||||||
@@ -52,6 +74,18 @@ def get_system_stats():
|
|||||||
return jsonify(stats)
|
return jsonify(stats)
|
||||||
|
|
||||||
|
|
||||||
|
@admin_api_bp.route("/request_metrics", methods=["GET"])
|
||||||
|
@admin_required
|
||||||
|
def get_request_metrics():
|
||||||
|
"""获取请求级监控指标"""
|
||||||
|
try:
|
||||||
|
metrics = _get_request_metrics_cached()
|
||||||
|
return jsonify(metrics)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(f"获取请求级监控指标失败: {e}")
|
||||||
|
return jsonify({"error": "获取请求级监控指标失败"}), 500
|
||||||
|
|
||||||
|
|
||||||
@admin_api_bp.route("/browser_pool/stats", methods=["GET"])
|
@admin_api_bp.route("/browser_pool/stats", methods=["GET"])
|
||||||
@admin_required
|
@admin_required
|
||||||
def get_browser_pool_stats():
|
def get_browser_pool_stats():
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"_MetricGrid-D-x_tNsK.js": {
|
"_MetricGrid-CPdC57ab.js": {
|
||||||
"file": "assets/MetricGrid-D-x_tNsK.js",
|
"file": "assets/MetricGrid-CPdC57ab.js",
|
||||||
"name": "MetricGrid",
|
"name": "MetricGrid",
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html",
|
"index.html",
|
||||||
@@ -14,29 +14,29 @@
|
|||||||
"file": "assets/MetricGrid-yP_dkP6X.css",
|
"file": "assets/MetricGrid-yP_dkP6X.css",
|
||||||
"src": "_MetricGrid-yP_dkP6X.css"
|
"src": "_MetricGrid-yP_dkP6X.css"
|
||||||
},
|
},
|
||||||
"_email-BYiWDIoy.js": {
|
"_email-DgztAWKJ.js": {
|
||||||
"file": "assets/email-BYiWDIoy.js",
|
"file": "assets/email-DgztAWKJ.js",
|
||||||
"name": "email",
|
"name": "email",
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html"
|
"index.html"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"_system-Bvj77zeB.js": {
|
"_system-1p1K-j-4.js": {
|
||||||
"file": "assets/system-Bvj77zeB.js",
|
"file": "assets/system-1p1K-j-4.js",
|
||||||
"name": "system",
|
"name": "system",
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html"
|
"index.html"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"_tasks-BZsqSMnk.js": {
|
"_tasks-Y3hOqi3L.js": {
|
||||||
"file": "assets/tasks-BZsqSMnk.js",
|
"file": "assets/tasks-Y3hOqi3L.js",
|
||||||
"name": "tasks",
|
"name": "tasks",
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html"
|
"index.html"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"_users-Kctz2ziD.js": {
|
"_users-kt1Evatk.js": {
|
||||||
"file": "assets/users-Kctz2ziD.js",
|
"file": "assets/users-kt1Evatk.js",
|
||||||
"name": "users",
|
"name": "users",
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html"
|
"index.html"
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"index.html": {
|
"index.html": {
|
||||||
"file": "assets/index-iyjFO6XY.js",
|
"file": "assets/index-bXG7gEdM.js",
|
||||||
"name": "index",
|
"name": "index",
|
||||||
"src": "index.html",
|
"src": "index.html",
|
||||||
"isEntry": true,
|
"isEntry": true,
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/AnnouncementsPage.vue": {
|
"src/pages/AnnouncementsPage.vue": {
|
||||||
"file": "assets/AnnouncementsPage-BZGpQqUL.js",
|
"file": "assets/AnnouncementsPage-fRPrWBwG.js",
|
||||||
"name": "AnnouncementsPage",
|
"name": "AnnouncementsPage",
|
||||||
"src": "src/pages/AnnouncementsPage.vue",
|
"src": "src/pages/AnnouncementsPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -116,14 +116,14 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/EmailPage.vue": {
|
"src/pages/EmailPage.vue": {
|
||||||
"file": "assets/EmailPage-CfIczE0i.js",
|
"file": "assets/EmailPage-CFpw2E0J.js",
|
||||||
"name": "EmailPage",
|
"name": "EmailPage",
|
||||||
"src": "src/pages/EmailPage.vue",
|
"src": "src/pages/EmailPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_email-BYiWDIoy.js",
|
"_email-DgztAWKJ.js",
|
||||||
"index.html",
|
"index.html",
|
||||||
"_MetricGrid-D-x_tNsK.js",
|
"_MetricGrid-CPdC57ab.js",
|
||||||
"_vendor-element-CJoVtPsD.js",
|
"_vendor-element-CJoVtPsD.js",
|
||||||
"_vendor-sLgkZK1v.js",
|
"_vendor-sLgkZK1v.js",
|
||||||
"_vendor-vue-CWkOjFoA.js",
|
"_vendor-vue-CWkOjFoA.js",
|
||||||
@@ -134,13 +134,13 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/FeedbacksPage.vue": {
|
"src/pages/FeedbacksPage.vue": {
|
||||||
"file": "assets/FeedbacksPage-yGzwD6JV.js",
|
"file": "assets/FeedbacksPage-BXNEKJpt.js",
|
||||||
"name": "FeedbacksPage",
|
"name": "FeedbacksPage",
|
||||||
"src": "src/pages/FeedbacksPage.vue",
|
"src": "src/pages/FeedbacksPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html",
|
"index.html",
|
||||||
"_MetricGrid-D-x_tNsK.js",
|
"_MetricGrid-CPdC57ab.js",
|
||||||
"_vendor-element-CJoVtPsD.js",
|
"_vendor-element-CJoVtPsD.js",
|
||||||
"_vendor-sLgkZK1v.js",
|
"_vendor-sLgkZK1v.js",
|
||||||
"_vendor-vue-CWkOjFoA.js",
|
"_vendor-vue-CWkOjFoA.js",
|
||||||
@@ -151,13 +151,13 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/LogsPage.vue": {
|
"src/pages/LogsPage.vue": {
|
||||||
"file": "assets/LogsPage-WmQFhJZO.js",
|
"file": "assets/LogsPage-xSURzHTt.js",
|
||||||
"name": "LogsPage",
|
"name": "LogsPage",
|
||||||
"src": "src/pages/LogsPage.vue",
|
"src": "src/pages/LogsPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_users-Kctz2ziD.js",
|
"_users-kt1Evatk.js",
|
||||||
"_tasks-BZsqSMnk.js",
|
"_tasks-Y3hOqi3L.js",
|
||||||
"index.html",
|
"index.html",
|
||||||
"_vendor-element-CJoVtPsD.js",
|
"_vendor-element-CJoVtPsD.js",
|
||||||
"_vendor-sLgkZK1v.js",
|
"_vendor-sLgkZK1v.js",
|
||||||
@@ -169,33 +169,33 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/ReportPage.vue": {
|
"src/pages/ReportPage.vue": {
|
||||||
"file": "assets/ReportPage-BkIhdzJa.js",
|
"file": "assets/ReportPage-BITaX3hh.js",
|
||||||
"name": "ReportPage",
|
"name": "ReportPage",
|
||||||
"src": "src/pages/ReportPage.vue",
|
"src": "src/pages/ReportPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_vendor-element-CJoVtPsD.js",
|
"_vendor-element-CJoVtPsD.js",
|
||||||
"index.html",
|
"index.html",
|
||||||
"_email-BYiWDIoy.js",
|
"_email-DgztAWKJ.js",
|
||||||
"_tasks-BZsqSMnk.js",
|
"_tasks-Y3hOqi3L.js",
|
||||||
"_system-Bvj77zeB.js",
|
"_system-1p1K-j-4.js",
|
||||||
"_MetricGrid-D-x_tNsK.js",
|
"_MetricGrid-CPdC57ab.js",
|
||||||
"_vendor-sLgkZK1v.js",
|
"_vendor-sLgkZK1v.js",
|
||||||
"_vendor-vue-CWkOjFoA.js",
|
"_vendor-vue-CWkOjFoA.js",
|
||||||
"_vendor-axios-B9ygI19o.js"
|
"_vendor-axios-B9ygI19o.js"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"assets/ReportPage-CnNjCmpq.css"
|
"assets/ReportPage-21i0jfUn.css"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/SecurityPage.vue": {
|
"src/pages/SecurityPage.vue": {
|
||||||
"file": "assets/SecurityPage-Ay9lQdJs.js",
|
"file": "assets/SecurityPage-CQuWzZ_p.js",
|
||||||
"name": "SecurityPage",
|
"name": "SecurityPage",
|
||||||
"src": "src/pages/SecurityPage.vue",
|
"src": "src/pages/SecurityPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html",
|
"index.html",
|
||||||
"_MetricGrid-D-x_tNsK.js",
|
"_MetricGrid-CPdC57ab.js",
|
||||||
"_vendor-element-CJoVtPsD.js",
|
"_vendor-element-CJoVtPsD.js",
|
||||||
"_vendor-sLgkZK1v.js",
|
"_vendor-sLgkZK1v.js",
|
||||||
"_vendor-vue-CWkOjFoA.js",
|
"_vendor-vue-CWkOjFoA.js",
|
||||||
@@ -206,7 +206,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/SettingsPage.vue": {
|
"src/pages/SettingsPage.vue": {
|
||||||
"file": "assets/SettingsPage-D1k6_4Nn.js",
|
"file": "assets/SettingsPage-Ct3Jh1K3.js",
|
||||||
"name": "SettingsPage",
|
"name": "SettingsPage",
|
||||||
"src": "src/pages/SettingsPage.vue",
|
"src": "src/pages/SettingsPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -222,12 +222,12 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/SystemPage.vue": {
|
"src/pages/SystemPage.vue": {
|
||||||
"file": "assets/SystemPage-wAMFferr.js",
|
"file": "assets/SystemPage-DE9Z1xG-.js",
|
||||||
"name": "SystemPage",
|
"name": "SystemPage",
|
||||||
"src": "src/pages/SystemPage.vue",
|
"src": "src/pages/SystemPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_system-Bvj77zeB.js",
|
"_system-1p1K-j-4.js",
|
||||||
"index.html",
|
"index.html",
|
||||||
"_vendor-element-CJoVtPsD.js",
|
"_vendor-element-CJoVtPsD.js",
|
||||||
"_vendor-sLgkZK1v.js",
|
"_vendor-sLgkZK1v.js",
|
||||||
@@ -239,12 +239,12 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/UsersPage.vue": {
|
"src/pages/UsersPage.vue": {
|
||||||
"file": "assets/UsersPage-B5MDfX7T.js",
|
"file": "assets/UsersPage-BqAhpZky.js",
|
||||||
"name": "UsersPage",
|
"name": "UsersPage",
|
||||||
"src": "src/pages/UsersPage.vue",
|
"src": "src/pages/UsersPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_users-Kctz2ziD.js",
|
"_users-kt1Evatk.js",
|
||||||
"index.html",
|
"index.html",
|
||||||
"_vendor-element-CJoVtPsD.js",
|
"_vendor-element-CJoVtPsD.js",
|
||||||
"_vendor-sLgkZK1v.js",
|
"_vendor-sLgkZK1v.js",
|
||||||
|
|||||||
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
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
import{_}from"./index-iyjFO6XY.js";import{aW as c,z as s,A as t,R as r,ak as u,E as p,B as o,N as l,S as y,L as h,K as i,O as k,Q as n,P as v,D as f}from"./vendor-sLgkZK1v.js";const b={class:"metric-top"},x={key:0,class:"metric-icon"},B={class:"metric-label"},N={class:"metric-value"},g={key:0,class:"metric-hint app-muted"},C={__name:"MetricGrid",props:{items:{type:Array,default:()=>[]},loading:{type:Boolean,default:!1},minWidth:{type:Number,default:180}},setup(a){return(V,z)=>{const d=c("el-icon"),m=c("el-skeleton");return t(),s("div",{class:"metric-grid",style:f({"--metric-min":`${a.minWidth}px`})},[(t(!0),s(r,null,u(a.items,e=>(t(),s("div",{key:e?.key||e?.label,class:p(["metric-card",`metric-tone--${e?.tone||"blue"}`])},[o("div",b,[e?.icon?(t(),s("div",x,[y(d,null,{default:h(()=>[(t(),i(k(e.icon)))]),_:2},1024)])):l("",!0),o("div",B,n(e?.label||"-"),1)]),o("div",N,[a.loading?(t(),i(m,{key:0,rows:1,animated:""})):(t(),s(r,{key:1},[v(n(e?.value??0),1)],64))]),e?.hint||e?.sub?(t(),s("div",g,n(e?.hint||e?.sub),1)):l("",!0)],2))),128))],4)}}},S=_(C,[["__scopeId","data-v-00e217d4"]]);export{S as M};
|
import{_}from"./index-bXG7gEdM.js";import{aW as c,z as s,A as t,R as r,ak as u,E as p,B as o,N as l,S as y,L as h,K as i,O as k,Q as n,P as v,D as f}from"./vendor-sLgkZK1v.js";const b={class:"metric-top"},x={key:0,class:"metric-icon"},B={class:"metric-label"},N={class:"metric-value"},g={key:0,class:"metric-hint app-muted"},C={__name:"MetricGrid",props:{items:{type:Array,default:()=>[]},loading:{type:Boolean,default:!1},minWidth:{type:Number,default:180}},setup(a){return(V,z)=>{const d=c("el-icon"),m=c("el-skeleton");return t(),s("div",{class:"metric-grid",style:f({"--metric-min":`${a.minWidth}px`})},[(t(!0),s(r,null,u(a.items,e=>(t(),s("div",{key:e?.key||e?.label,class:p(["metric-card",`metric-tone--${e?.tone||"blue"}`])},[o("div",b,[e?.icon?(t(),s("div",x,[y(d,null,{default:h(()=>[(t(),i(k(e.icon)))]),_:2},1024)])):l("",!0),o("div",B,n(e?.label||"-"),1)]),o("div",N,[a.loading?(t(),i(m,{key:0,rows:1,animated:""})):(t(),s(r,{key:1},[v(n(e?.value??0),1)],64))]),e?.hint||e?.sub?(t(),s("div",g,n(e?.hint||e?.sub),1)):l("",!0)],2))),128))],4)}}},S=_(C,[["__scopeId","data-v-00e217d4"]]);export{S as M};
|
||||||
1
static/admin/assets/ReportPage-21i0jfUn.css
Normal file
1
static/admin/assets/ReportPage-21i0jfUn.css
Normal file
File diff suppressed because one or more lines are too long
1
static/admin/assets/ReportPage-BITaX3hh.js
Normal file
1
static/admin/assets/ReportPage-BITaX3hh.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
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
import{a as m,_ as h}from"./index-iyjFO6XY.js";import{f as u,E as x}from"./vendor-element-CJoVtPsD.js";import{r as p,aW as i,z as T,A as P,B as r,S as a,L as o,P as b}from"./vendor-sLgkZK1v.js";import"./vendor-vue-CWkOjFoA.js";import"./vendor-axios-B9ygI19o.js";async function S(l){const{data:s}=await m.put("/admin/username",{new_username:l});return s}async function A(l){const{data:s}=await m.put("/admin/password",{new_password:l});return s}async function C(){const{data:l}=await m.post("/logout");return l}const E={class:"page-stack"},U={__name:"SettingsPage",setup(l){const s=p(""),d=p(""),n=p(!1);function k(t){const e=String(t||"");return e.length<8?{ok:!1,message:"密码长度至少8位"}:e.length>128?{ok:!1,message:"密码长度不能超过128个字符"}:!/[a-zA-Z]/.test(e)||!/\d/.test(e)?{ok:!1,message:"密码必须包含字母和数字"}:{ok:!0,message:""}}async function f(){try{await C()}catch{}finally{window.location.href="/yuyx"}}async function B(){const t=s.value.trim();if(!t){u.error("请输入新用户名");return}try{await x.confirm(`确定将管理员用户名修改为「${t}」吗?修改后需要重新登录。`,"修改用户名",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await S(t),u.success("用户名修改成功,请重新登录"),s.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}async function V(){const t=d.value;if(!t){u.error("请输入新密码");return}const e=k(t);if(!e.ok){u.error(e.message);return}try{await x.confirm("确定修改管理员密码吗?修改后需要重新登录。","修改密码",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await A(t),u.success("密码修改成功,请重新登录"),d.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}return(t,e)=>{const g=i("el-input"),v=i("el-form-item"),w=i("el-form"),y=i("el-button"),_=i("el-card");return P(),T("div",E,[e[7]||(e[7]=r("div",{class:"app-page-title"},[r("h2",null,"设置"),r("span",{class:"app-muted"},"管理员账号设置")],-1)),a(_,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:o(()=>[e[3]||(e[3]=r("h3",{class:"section-title"},"修改管理员用户名",-1)),a(w,{"label-width":"120px"},{default:o(()=>[a(v,{label:"新用户名"},{default:o(()=>[a(g,{modelValue:s.value,"onUpdate:modelValue":e[0]||(e[0]=c=>s.value=c),placeholder:"输入新用户名",disabled:n.value},null,8,["modelValue","disabled"])]),_:1})]),_:1}),a(y,{type:"primary",loading:n.value,onClick:B},{default:o(()=>[...e[2]||(e[2]=[b("保存用户名",-1)])]),_:1},8,["loading"])]),_:1}),a(_,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:o(()=>[e[5]||(e[5]=r("h3",{class:"section-title"},"修改管理员密码",-1)),a(w,{"label-width":"120px"},{default:o(()=>[a(v,{label:"新密码"},{default:o(()=>[a(g,{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(y,{type:"primary",loading:n.value,onClick:V},{default:o(()=>[...e[4]||(e[4]=[b("保存密码",-1)])]),_:1},8,["loading"]),e[6]||(e[6]=r("div",{class:"help"},"建议使用更强密码(至少8位且包含字母与数字)。",-1))]),_:1})])}}},W=h(U,[["__scopeId","data-v-83d3840a"]]);export{W as default};
|
import{a as m,_ as h}from"./index-bXG7gEdM.js";import{f as u,E as x}from"./vendor-element-CJoVtPsD.js";import{r as p,aW as i,z as T,A as P,B as r,S as a,L as o,P as b}from"./vendor-sLgkZK1v.js";import"./vendor-vue-CWkOjFoA.js";import"./vendor-axios-B9ygI19o.js";async function S(l){const{data:s}=await m.put("/admin/username",{new_username:l});return s}async function A(l){const{data:s}=await m.put("/admin/password",{new_password:l});return s}async function C(){const{data:l}=await m.post("/logout");return l}const E={class:"page-stack"},U={__name:"SettingsPage",setup(l){const s=p(""),d=p(""),n=p(!1);function k(t){const e=String(t||"");return e.length<8?{ok:!1,message:"密码长度至少8位"}:e.length>128?{ok:!1,message:"密码长度不能超过128个字符"}:!/[a-zA-Z]/.test(e)||!/\d/.test(e)?{ok:!1,message:"密码必须包含字母和数字"}:{ok:!0,message:""}}async function f(){try{await C()}catch{}finally{window.location.href="/yuyx"}}async function B(){const t=s.value.trim();if(!t){u.error("请输入新用户名");return}try{await x.confirm(`确定将管理员用户名修改为「${t}」吗?修改后需要重新登录。`,"修改用户名",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await S(t),u.success("用户名修改成功,请重新登录"),s.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}async function V(){const t=d.value;if(!t){u.error("请输入新密码");return}const e=k(t);if(!e.ok){u.error(e.message);return}try{await x.confirm("确定修改管理员密码吗?修改后需要重新登录。","修改密码",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await A(t),u.success("密码修改成功,请重新登录"),d.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}return(t,e)=>{const g=i("el-input"),v=i("el-form-item"),w=i("el-form"),y=i("el-button"),_=i("el-card");return P(),T("div",E,[e[7]||(e[7]=r("div",{class:"app-page-title"},[r("h2",null,"设置"),r("span",{class:"app-muted"},"管理员账号设置")],-1)),a(_,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:o(()=>[e[3]||(e[3]=r("h3",{class:"section-title"},"修改管理员用户名",-1)),a(w,{"label-width":"120px"},{default:o(()=>[a(v,{label:"新用户名"},{default:o(()=>[a(g,{modelValue:s.value,"onUpdate:modelValue":e[0]||(e[0]=c=>s.value=c),placeholder:"输入新用户名",disabled:n.value},null,8,["modelValue","disabled"])]),_:1})]),_:1}),a(y,{type:"primary",loading:n.value,onClick:B},{default:o(()=>[...e[2]||(e[2]=[b("保存用户名",-1)])]),_:1},8,["loading"])]),_:1}),a(_,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:o(()=>[e[5]||(e[5]=r("h3",{class:"section-title"},"修改管理员密码",-1)),a(w,{"label-width":"120px"},{default:o(()=>[a(v,{label:"新密码"},{default:o(()=>[a(g,{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(y,{type:"primary",loading:n.value,onClick:V},{default:o(()=>[...e[4]||(e[4]=[b("保存密码",-1)])]),_:1},8,["loading"]),e[6]||(e[6]=r("div",{class:"help"},"建议使用更强密码(至少8位且包含字母与数字)。",-1))]),_:1})])}}},W=h(U,[["__scopeId","data-v-83d3840a"]]);export{W as default};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import{f as Ve,u as Y}from"./system-Bvj77zeB.js";import{a as P,_ as ge}from"./index-iyjFO6XY.js";import{E as ne,f as m}from"./vendor-element-CJoVtPsD.js";import{r as n,c as ke,w as xe,a1 as be,v as we,aW as v,b7 as Ue,M as Ce,A as V,z as g,B as s,S as l,L as t,P as k,N as Z,Q as ee}from"./vendor-sLgkZK1v.js";import"./vendor-vue-CWkOjFoA.js";import"./vendor-axios-B9ygI19o.js";async function le(r={}){const{data:c}=await P.get("/kdocs/status",{params:r});return c}async function Pe(r={}){const c={force:!0,...r},{data:x}=await P.post("/kdocs/qr",c);return x}async function Ie(){const{data:r}=await P.post("/kdocs/clear-login",{});return r}async function Ae(){const{data:r}=await P.get("/proxy/config");return r}async function Ne(r){const{data:c}=await P.post("/proxy/config",r);return c}async function Se(r){const{data:c}=await P.post("/proxy/test",r);return c}const De={class:"page-stack"},Ke={class:"config-grid"},Ee={class:"row-actions"},Be={class:"row-actions"},Te={class:"row-actions"},Le={class:"section-head"},Qe={class:"status-inline app-muted"},$e={key:0},he={key:1},qe={key:2},Me={class:"kdocs-inline"},Re={class:"kdocs-range"},ze={class:"row-actions"},Fe={key:0,class:"help"},He={key:1,class:"help"},Oe={class:"kdocs-qr"},Ge=["src"],We={__name:"SystemPage",setup(r){const c=n(!1),x=n(2),A=n(1),N=n(3),I=n(!1),f=n(""),S=n(3),D=n(!1),K=n(10),E=n(7),B=n(!1),T=n(""),L=n(""),Q=n(""),$=n(0),h=n("A"),q=n("D"),M=n(0),R=n(0),z=n(!1),F=n(""),p=n({}),b=n(!1),w=n(""),ae=n(!1),H=n(!1),U=n(!1),C=n(!1),O=n("");let G=null;const oe=ke(()=>H.value||U.value||C.value);function d(a){if(!a){O.value="";return}const e=new Date().toLocaleTimeString("zh-CN",{hour12:!1});O.value=`${a} (${e})`}async function ue(){c.value=!0;try{const[a,e,i]=await Promise.all([Ve(),Ae(),le().catch(()=>({}))]);x.value=a.max_concurrent_global??2,A.value=a.max_concurrent_per_account??1,N.value=a.max_screenshot_concurrent??3,D.value=(a.auto_approve_enabled??0)===1,K.value=a.auto_approve_hourly_limit??10,E.value=a.auto_approve_vip_days??7,I.value=(e.proxy_enabled??0)===1,f.value=e.proxy_api_url||"",S.value=e.proxy_expire_minutes??3,B.value=(a.kdocs_enabled??0)===1,T.value=a.kdocs_doc_url||"",L.value=a.kdocs_default_unit||"",Q.value=a.kdocs_sheet_name||"",$.value=a.kdocs_sheet_index??0,h.value=(a.kdocs_unit_column||"A").toUpperCase(),q.value=(a.kdocs_image_column||"D").toUpperCase(),M.value=a.kdocs_row_start??0,R.value=a.kdocs_row_end??0,z.value=(a.kdocs_admin_notify_enabled??0)===1,F.value=a.kdocs_admin_notify_email||"",p.value=i||{}}catch{}finally{c.value=!1}}async function de(){const a={max_concurrent_global:Number(x.value),max_concurrent_per_account:Number(A.value),max_screenshot_concurrent:Number(N.value)};try{await ne.confirm(`确定更新并发配置吗?
|
import{f as Ve,u as Y}from"./system-1p1K-j-4.js";import{a as P,_ as ge}from"./index-bXG7gEdM.js";import{E as ne,f as m}from"./vendor-element-CJoVtPsD.js";import{r as n,c as ke,w as xe,a1 as be,v as we,aW as v,b7 as Ue,M as Ce,A as V,z as g,B as s,S as l,L as t,P as k,N as Z,Q as ee}from"./vendor-sLgkZK1v.js";import"./vendor-vue-CWkOjFoA.js";import"./vendor-axios-B9ygI19o.js";async function le(r={}){const{data:c}=await P.get("/kdocs/status",{params:r});return c}async function Pe(r={}){const c={force:!0,...r},{data:x}=await P.post("/kdocs/qr",c);return x}async function Ie(){const{data:r}=await P.post("/kdocs/clear-login",{});return r}async function Ae(){const{data:r}=await P.get("/proxy/config");return r}async function Ne(r){const{data:c}=await P.post("/proxy/config",r);return c}async function Se(r){const{data:c}=await P.post("/proxy/test",r);return c}const De={class:"page-stack"},Ke={class:"config-grid"},Ee={class:"row-actions"},Be={class:"row-actions"},Te={class:"row-actions"},Le={class:"section-head"},Qe={class:"status-inline app-muted"},$e={key:0},he={key:1},qe={key:2},Me={class:"kdocs-inline"},Re={class:"kdocs-range"},ze={class:"row-actions"},Fe={key:0,class:"help"},He={key:1,class:"help"},Oe={class:"kdocs-qr"},Ge=["src"],We={__name:"SystemPage",setup(r){const c=n(!1),x=n(2),A=n(1),N=n(3),I=n(!1),f=n(""),S=n(3),D=n(!1),K=n(10),E=n(7),B=n(!1),T=n(""),L=n(""),Q=n(""),$=n(0),h=n("A"),q=n("D"),M=n(0),R=n(0),z=n(!1),F=n(""),p=n({}),b=n(!1),w=n(""),ae=n(!1),H=n(!1),U=n(!1),C=n(!1),O=n("");let G=null;const oe=ke(()=>H.value||U.value||C.value);function d(a){if(!a){O.value="";return}const e=new Date().toLocaleTimeString("zh-CN",{hour12:!1});O.value=`${a} (${e})`}async function ue(){c.value=!0;try{const[a,e,i]=await Promise.all([Ve(),Ae(),le().catch(()=>({}))]);x.value=a.max_concurrent_global??2,A.value=a.max_concurrent_per_account??1,N.value=a.max_screenshot_concurrent??3,D.value=(a.auto_approve_enabled??0)===1,K.value=a.auto_approve_hourly_limit??10,E.value=a.auto_approve_vip_days??7,I.value=(e.proxy_enabled??0)===1,f.value=e.proxy_api_url||"",S.value=e.proxy_expire_minutes??3,B.value=(a.kdocs_enabled??0)===1,T.value=a.kdocs_doc_url||"",L.value=a.kdocs_default_unit||"",Q.value=a.kdocs_sheet_name||"",$.value=a.kdocs_sheet_index??0,h.value=(a.kdocs_unit_column||"A").toUpperCase(),q.value=(a.kdocs_image_column||"D").toUpperCase(),M.value=a.kdocs_row_start??0,R.value=a.kdocs_row_end??0,z.value=(a.kdocs_admin_notify_enabled??0)===1,F.value=a.kdocs_admin_notify_email||"",p.value=i||{}}catch{}finally{c.value=!1}}async function de(){const a={max_concurrent_global:Number(x.value),max_concurrent_per_account:Number(A.value),max_screenshot_concurrent:Number(N.value)};try{await ne.confirm(`确定更新并发配置吗?
|
||||||
|
|
||||||
全局并发数: ${a.max_concurrent_global}
|
全局并发数: ${a.max_concurrent_global}
|
||||||
单账号并发数: ${a.max_concurrent_per_account}
|
单账号并发数: ${a.max_concurrent_per_account}
|
||||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
import{a as n}from"./index-iyjFO6XY.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{o as a,i as b,l as c,c as f,e as u};
|
import{a as n}from"./index-bXG7gEdM.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{o as a,i as b,l as c,c as f,e as u};
|
||||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
import{a}from"./index-iyjFO6XY.js";async function o(){const{data:t}=await a.get("/system/config");return t}async function e(t){const{data:n}=await a.post("/system/config",t);return n}export{o as f,e as u};
|
import{a}from"./index-bXG7gEdM.js";async function o(){const{data:t}=await a.get("/system/config");return t}async function e(t){const{data:n}=await a.post("/system/config",t);return n}export{o as f,e as u};
|
||||||
@@ -1 +0,0 @@
|
|||||||
import{a}from"./index-iyjFO6XY.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
static/admin/assets/tasks-Y3hOqi3L.js
Normal file
1
static/admin/assets/tasks-Y3hOqi3L.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{a}from"./index-bXG7gEdM.js";async function e(){const{data:t}=await a.get("/server/info");return t}async function c(){const{data:t}=await a.get("/docker_stats");return t}async function r(){const{data:t}=await a.get("/request_metrics");return t}async function o(){const{data:t}=await a.get("/task/stats");return t}async function i(){const{data:t}=await a.get("/task/running");return t}async function u(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{i as a,e as b,c,r as d,u as e,o as f,f as g};
|
||||||
@@ -1 +1 @@
|
|||||||
import{a as t}from"./index-iyjFO6XY.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{a as t}from"./index-bXG7gEdM.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,7 +5,7 @@
|
|||||||
<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-iyjFO6XY.js"></script>
|
<script type="module" crossorigin src="./assets/index-bXG7gEdM.js"></script>
|
||||||
<link rel="modulepreload" crossorigin href="./assets/vendor-sLgkZK1v.js">
|
<link rel="modulepreload" crossorigin href="./assets/vendor-sLgkZK1v.js">
|
||||||
<link rel="modulepreload" crossorigin href="./assets/vendor-element-CJoVtPsD.js">
|
<link rel="modulepreload" crossorigin href="./assets/vendor-element-CJoVtPsD.js">
|
||||||
<link rel="modulepreload" crossorigin href="./assets/vendor-vue-CWkOjFoA.js">
|
<link rel="modulepreload" crossorigin href="./assets/vendor-vue-CWkOjFoA.js">
|
||||||
|
|||||||
Reference in New Issue
Block a user