feat: unify login UI and improve kdocs defaults
This commit is contained in:
@@ -240,31 +240,49 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="auth-wrap">
|
<div class="login-page">
|
||||||
<el-card shadow="never" class="auth-card" :body-style="{ padding: '22px' }">
|
<div class="login-container">
|
||||||
<div class="brand">
|
<div class="login-header">
|
||||||
<div class="brand-title">知识管理平台</div>
|
<span class="login-badge">用户登录</span>
|
||||||
<div class="brand-sub app-muted">用户登录</div>
|
<h1>用户登录系统</h1>
|
||||||
|
<p>知识管理平台</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form label-position="top">
|
<div class="form-group">
|
||||||
<el-form-item label="用户名">
|
<label for="username">用户账号</label>
|
||||||
<el-input v-model="form.username" placeholder="请输入用户名" autocomplete="username" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="密码">
|
|
||||||
<el-input
|
<el-input
|
||||||
|
id="username"
|
||||||
|
v-model="form.username"
|
||||||
|
class="login-input"
|
||||||
|
placeholder="请输入用户名"
|
||||||
|
autocomplete="username"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">密码</label>
|
||||||
|
<el-input
|
||||||
|
id="password"
|
||||||
v-model="form.password"
|
v-model="form.password"
|
||||||
|
class="login-input"
|
||||||
type="password"
|
type="password"
|
||||||
show-password
|
show-password
|
||||||
placeholder="请输入密码"
|
placeholder="请输入密码"
|
||||||
autocomplete="current-password"
|
autocomplete="current-password"
|
||||||
@keyup.enter="onSubmit"
|
@keyup.enter="onSubmit"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</div>
|
||||||
|
|
||||||
<el-form-item v-if="needCaptcha" label="验证码">
|
<div v-if="needCaptcha" class="form-group">
|
||||||
|
<label for="captcha">验证码</label>
|
||||||
<div class="captcha-row">
|
<div class="captcha-row">
|
||||||
<el-input v-model="form.captcha" placeholder="请输入验证码" @keyup.enter="onSubmit" />
|
<el-input
|
||||||
|
id="captcha"
|
||||||
|
v-model="form.captcha"
|
||||||
|
class="login-input captcha-input"
|
||||||
|
placeholder="请输入验证码"
|
||||||
|
@keyup.enter="onSubmit"
|
||||||
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="captchaImage"
|
v-if="captchaImage"
|
||||||
class="captcha-img"
|
class="captcha-img"
|
||||||
@@ -273,23 +291,29 @@ onMounted(async () => {
|
|||||||
title="点击刷新"
|
title="点击刷新"
|
||||||
@click="refreshLoginCaptcha"
|
@click="refreshLoginCaptcha"
|
||||||
/>
|
/>
|
||||||
<el-button @click="refreshLoginCaptcha">刷新</el-button>
|
<button type="button" class="captcha-refresh" @click="refreshLoginCaptcha">刷新</button>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<div class="links">
|
|
||||||
<el-button text type="primary" @click="openForgot">忘记密码?</el-button>
|
|
||||||
<el-button v-if="showResendLink" text type="primary" @click="openResend">重发验证邮件</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-button type="primary" class="submit-btn" :loading="loading" @click="onSubmit">登录</el-button>
|
<button type="button" class="btn-login" :disabled="loading" @click="onSubmit">
|
||||||
|
{{ loading ? '登录中...' : '登录系统' }}
|
||||||
|
</button>
|
||||||
|
|
||||||
<div class="foot">
|
<div class="action-links">
|
||||||
<span class="app-muted">还没有账号?</span>
|
<button type="button" class="link-btn" @click="openForgot">忘记密码?</button>
|
||||||
<el-button link type="primary" @click="goRegister">立即注册</el-button>
|
<button v-if="showResendLink" type="button" class="link-btn" @click="openResend">重发验证邮件</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="register-row">
|
||||||
|
<span>还没有账号?</span>
|
||||||
|
<button type="button" class="link-btn" @click="goRegister">立即注册</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="back-link">
|
||||||
|
<span>管理员请前往</span>
|
||||||
|
<a href="/yuyx">后台登录</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-dialog v-model="forgotOpen" title="找回密码" width="min(560px, 92vw)">
|
<el-dialog v-model="forgotOpen" title="找回密码" width="min(560px, 92vw)">
|
||||||
<el-alert
|
<el-alert
|
||||||
@@ -376,61 +400,181 @@ onMounted(async () => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.auth-wrap {
|
.login-page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
position: relative;
|
||||||
|
background: linear-gradient(135deg, #eef2ff 0%, #f6f7fb 45%, #ecfeff 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.auth-card {
|
.login-page::before {
|
||||||
|
content: '';
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background:
|
||||||
|
radial-gradient(800px 500px at 15% 20%, rgba(59, 130, 246, 0.18), transparent 60%),
|
||||||
|
radial-gradient(700px 420px at 85% 70%, rgba(124, 58, 237, 0.16), transparent 55%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 420px;
|
max-width: 420px;
|
||||||
border-radius: var(--app-radius);
|
background: #fff;
|
||||||
border: 1px solid var(--app-border);
|
border-radius: 16px;
|
||||||
box-shadow: var(--app-shadow);
|
box-shadow: 0 18px 60px rgba(17, 24, 39, 0.15);
|
||||||
|
border: 1px solid rgba(17, 24, 39, 0.08);
|
||||||
|
padding: 38px 34px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand {
|
.login-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-badge {
|
||||||
|
display: inline-block;
|
||||||
|
background: rgba(59, 130, 246, 0.1);
|
||||||
|
color: #1d4ed8;
|
||||||
|
padding: 6px 14px;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand-title {
|
.login-header h1 {
|
||||||
font-size: 18px;
|
font-size: 24px;
|
||||||
font-weight: 900;
|
color: #111827;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
letter-spacing: 0.2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand-sub {
|
.login-header p {
|
||||||
margin-top: 4px;
|
margin: 0;
|
||||||
font-size: 12px;
|
color: #6b7280;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.links {
|
.form-group {
|
||||||
display: flex;
|
margin-bottom: 20px;
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 10px;
|
|
||||||
margin: 2px 0 10px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.submit-btn {
|
.form-group label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #111827;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-input :deep(.el-input__wrapper) {
|
||||||
|
border-radius: 10px;
|
||||||
|
min-height: 44px;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
box-shadow: 0 0 0 1px rgba(17, 24, 39, 0.14) inset;
|
||||||
|
transition: box-shadow 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-input :deep(.el-input__wrapper.is-focus) {
|
||||||
|
box-shadow: 0 0 0 1px rgba(59, 130, 246, 0.7) inset, 0 0 0 4px rgba(59, 130, 246, 0.16);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-input :deep(.el-input__inner) {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-login {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 800;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.15s, filter 0.15s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.foot {
|
.btn-login:hover:not(:disabled) {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
filter: brightness(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-login:active:not(:disabled) {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-login:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-links {
|
||||||
margin-top: 14px;
|
margin-top: 14px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-btn {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
color: #2563eb;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-btn:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.register-row {
|
||||||
|
margin-top: 16px;
|
||||||
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 6px;
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
color: #6b7280;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-link {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 18px;
|
||||||
|
color: #6b7280;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-link a {
|
||||||
|
margin-left: 6px;
|
||||||
|
color: #2563eb;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-link a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-form {
|
.dialog-form {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.captcha-row {
|
.captcha-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -438,17 +582,62 @@ onMounted(async () => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.captcha-input {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.captcha-img {
|
.captcha-img {
|
||||||
height: 40px;
|
height: 46px;
|
||||||
border: 1px solid var(--app-border);
|
border: 1px solid rgba(17, 24, 39, 0.14);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.captcha-refresh {
|
||||||
|
height: 44px;
|
||||||
|
padding: 0 14px;
|
||||||
|
border: 1px solid rgba(17, 24, 39, 0.14);
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #f8fafc;
|
||||||
|
color: #111827;
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captcha-refresh:hover {
|
||||||
|
background: #f1f5f9;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
|
.login-page {
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 20px 12px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-container {
|
||||||
|
max-width: 100%;
|
||||||
|
padding: 28px 20px;
|
||||||
|
border-radius: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-header h1 {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-login {
|
||||||
|
padding: 13px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.captcha-img {
|
.captcha-img {
|
||||||
height: 38px;
|
height: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.captcha-refresh {
|
||||||
|
height: 42px;
|
||||||
|
padding: 0 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -59,7 +59,10 @@ def get_kdocs_status_api():
|
|||||||
uploader = get_kdocs_uploader()
|
uploader = get_kdocs_uploader()
|
||||||
status = uploader.get_status()
|
status = uploader.get_status()
|
||||||
live = str(request.args.get("live", "")).lower() in ("1", "true", "yes")
|
live = str(request.args.get("live", "")).lower() in ("1", "true", "yes")
|
||||||
if live:
|
|
||||||
|
# 重启后首次查询时(last_login_ok is None)自动做一次实时状态校验
|
||||||
|
should_live_check = live or status.get("last_login_ok") is None
|
||||||
|
if should_live_check:
|
||||||
live_status = uploader.refresh_login_status()
|
live_status = uploader.refresh_login_status()
|
||||||
if live_status.get("success"):
|
if live_status.get("success"):
|
||||||
logged_in = bool(live_status.get("logged_in"))
|
logged_in = bool(live_status.get("logged_in"))
|
||||||
|
|||||||
@@ -234,10 +234,12 @@ def get_user_email():
|
|||||||
@login_required
|
@login_required
|
||||||
def get_user_kdocs_settings():
|
def get_user_kdocs_settings():
|
||||||
"""获取当前用户的金山文档设置"""
|
"""获取当前用户的金山文档设置"""
|
||||||
settings = database.get_user_kdocs_settings(current_user.id)
|
settings = database.get_user_kdocs_settings(current_user.id) or {}
|
||||||
if not settings:
|
cfg = database.get_system_config() or {}
|
||||||
return jsonify({"kdocs_unit": "", "kdocs_auto_upload": 0})
|
default_unit = (cfg.get("kdocs_default_unit") or "").strip() or "道县"
|
||||||
return jsonify(settings)
|
kdocs_unit = (settings.get("kdocs_unit") or "").strip() or default_unit
|
||||||
|
kdocs_auto_upload = 1 if int(settings.get("kdocs_auto_upload", 0) or 0) == 1 else 0
|
||||||
|
return jsonify({"kdocs_unit": kdocs_unit, "kdocs_auto_upload": kdocs_auto_upload})
|
||||||
|
|
||||||
|
|
||||||
@api_user_bp.route("/api/user/kdocs", methods=["POST"])
|
@api_user_bp.route("/api/user/kdocs", methods=["POST"])
|
||||||
@@ -265,8 +267,14 @@ def update_user_kdocs_settings():
|
|||||||
):
|
):
|
||||||
return jsonify({"error": "更新失败"}), 400
|
return jsonify({"error": "更新失败"}), 400
|
||||||
|
|
||||||
settings = database.get_user_kdocs_settings(current_user.id) or {"kdocs_unit": "", "kdocs_auto_upload": 0}
|
settings = database.get_user_kdocs_settings(current_user.id) or {}
|
||||||
return jsonify({"success": True, "settings": settings})
|
cfg = database.get_system_config() or {}
|
||||||
|
default_unit = (cfg.get("kdocs_default_unit") or "").strip() or "道县"
|
||||||
|
response_settings = {
|
||||||
|
"kdocs_unit": (settings.get("kdocs_unit") or "").strip() or default_unit,
|
||||||
|
"kdocs_auto_upload": 1 if int(settings.get("kdocs_auto_upload", 0) or 0) == 1 else 0,
|
||||||
|
}
|
||||||
|
return jsonify({"success": True, "settings": response_settings})
|
||||||
|
|
||||||
|
|
||||||
@api_user_bp.route("/api/user/bind-email", methods=["POST"])
|
@api_user_bp.route("/api/user/bind-email", methods=["POST"])
|
||||||
@@ -405,6 +413,14 @@ def get_kdocs_status_for_user():
|
|||||||
login_required_flag = status.get("login_required", False)
|
login_required_flag = status.get("login_required", False)
|
||||||
last_login_ok = status.get("last_login_ok")
|
last_login_ok = status.get("last_login_ok")
|
||||||
|
|
||||||
|
# 重启后首次查询时,状态可能还是 None,这里做一次轻量实时校验
|
||||||
|
if last_login_ok is None:
|
||||||
|
live_status = kdocs.refresh_login_status()
|
||||||
|
if live_status.get("success"):
|
||||||
|
logged_in = bool(live_status.get("logged_in"))
|
||||||
|
login_required_flag = not logged_in
|
||||||
|
last_login_ok = logged_in
|
||||||
|
|
||||||
# 判断是否在线
|
# 判断是否在线
|
||||||
is_online = not login_required_flag and last_login_ok is True
|
is_online = not login_required_flag and last_login_ok is True
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
@@ -13,7 +14,6 @@ import email_service
|
|||||||
from api_browser import APIBrowser, get_cookie_jar_path, is_cookie_jar_fresh
|
from api_browser import APIBrowser, get_cookie_jar_path, is_cookie_jar_fresh
|
||||||
from app_config import get_config
|
from app_config import get_config
|
||||||
from app_logger import get_logger
|
from app_logger import get_logger
|
||||||
from app_security import sanitize_filename
|
|
||||||
from browser_pool_worker import get_browser_worker_pool
|
from browser_pool_worker import get_browser_worker_pool
|
||||||
from services.client_log import log_to_client
|
from services.client_log import log_to_client
|
||||||
from services.runtime import get_socketio
|
from services.runtime import get_socketio
|
||||||
@@ -264,12 +264,46 @@ def _build_screenshot_targets(browse_type: str) -> tuple[str, str, str]:
|
|||||||
return index_url, target_url, run_script
|
return index_url, target_url, run_script
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_screenshot_name(value: str, *, fallback: str = "账号") -> str:
|
||||||
|
"""规范化截图文件名中的账号名,尽量保留中文。"""
|
||||||
|
label = str(value or "").strip() or fallback
|
||||||
|
label = label.replace("/", "_").replace("\\", "_")
|
||||||
|
label = re.sub(r"\s+", "", label)
|
||||||
|
label = re.sub(r"[^0-9A-Za-z_\-.一-鿿]", "_", label)
|
||||||
|
label = re.sub(r"_+", "_", label).strip("._-")
|
||||||
|
return label or fallback
|
||||||
|
|
||||||
|
|
||||||
|
def _next_screenshot_sequence(username_prefix: str, account_label: str, date_str: str) -> int:
|
||||||
|
"""按“用户+账号+日期”计算下一个截图序号。"""
|
||||||
|
pattern = re.compile(
|
||||||
|
rf"^{re.escape(username_prefix)}_{re.escape(account_label)}_{date_str}_(\d{{3}})\.jpg$",
|
||||||
|
re.IGNORECASE,
|
||||||
|
)
|
||||||
|
|
||||||
|
max_seq = 0
|
||||||
|
try:
|
||||||
|
with os.scandir(SCREENSHOTS_DIR) as entries:
|
||||||
|
for entry in entries:
|
||||||
|
if not entry.is_file():
|
||||||
|
continue
|
||||||
|
matched = pattern.match(entry.name)
|
||||||
|
if not matched:
|
||||||
|
continue
|
||||||
|
max_seq = max(max_seq, int(matched.group(1)))
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return max_seq + 1
|
||||||
|
|
||||||
|
|
||||||
def _build_screenshot_output_path(username_prefix: str, account, browse_type: str) -> tuple[str, str]:
|
def _build_screenshot_output_path(username_prefix: str, account, browse_type: str) -> tuple[str, str]:
|
||||||
"""构建截图输出文件名与路径。"""
|
"""构建截图输出文件名与路径(账号备注 + 日期 + 序号)。"""
|
||||||
timestamp = get_beijing_now().strftime("%Y%m%d_%H%M%S")
|
del browse_type
|
||||||
login_account = account.remark if account.remark else account.username
|
date_str = get_beijing_now().strftime("%Y%m%d")
|
||||||
raw_filename = f"{username_prefix}_{login_account}_{browse_type}_{timestamp}.jpg"
|
account_label = _normalize_screenshot_name(account.remark or account.username, fallback=account.username)
|
||||||
screenshot_filename = sanitize_filename(raw_filename)
|
seq = _next_screenshot_sequence(username_prefix, account_label, date_str)
|
||||||
|
screenshot_filename = f"{username_prefix}_{account_label}_{date_str}_{seq:03d}.jpg"
|
||||||
return screenshot_filename, os.path.join(SCREENSHOTS_DIR, screenshot_filename)
|
return screenshot_filename, os.path.join(SCREENSHOTS_DIR, screenshot_filename)
|
||||||
|
|
||||||
|
|
||||||
@@ -379,11 +413,13 @@ def _enqueue_kdocs_upload_if_needed(user_id: int, account_id: str, account, scre
|
|||||||
if int(user_cfg.get("kdocs_auto_upload", 0) or 0) != 1:
|
if int(user_cfg.get("kdocs_auto_upload", 0) or 0) != 1:
|
||||||
return
|
return
|
||||||
|
|
||||||
unit = (user_cfg.get("kdocs_unit") or cfg.get("kdocs_default_unit") or "").strip()
|
user_unit = (user_cfg.get("kdocs_unit") or "").strip()
|
||||||
|
default_unit = (cfg.get("kdocs_default_unit") or "").strip() or "道县"
|
||||||
|
unit = user_unit or default_unit
|
||||||
|
if not user_unit:
|
||||||
|
log_to_client(f"未配置县区,使用默认县区: {unit}", user_id, account_id)
|
||||||
|
|
||||||
name = (account.remark or "").strip()
|
name = (account.remark or "").strip()
|
||||||
if not unit:
|
|
||||||
log_to_client("表格上传跳过: 未配置县区", user_id, account_id)
|
|
||||||
return
|
|
||||||
if not name:
|
if not name:
|
||||||
log_to_client("表格上传跳过: 账号备注为空", user_id, account_id)
|
log_to_client("表格上传跳过: 账号备注为空", user_id, account_id)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"_accounts-Bta9cdL5.js": {
|
"_accounts-Cq6KNxFR.js": {
|
||||||
"file": "assets/accounts-Bta9cdL5.js",
|
"file": "assets/accounts-Cq6KNxFR.js",
|
||||||
"name": "accounts",
|
"name": "accounts",
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html"
|
"index.html"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"_auth--ytvFYf6.js": {
|
"_auth-CjQgMKAl.js": {
|
||||||
"file": "assets/auth--ytvFYf6.js",
|
"file": "assets/auth-CjQgMKAl.js",
|
||||||
"name": "auth",
|
"name": "auth",
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html"
|
"index.html"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"index.html": {
|
"index.html": {
|
||||||
"file": "assets/index-CPwwGffH.js",
|
"file": "assets/index-DMtbRy1f.js",
|
||||||
"name": "index",
|
"name": "index",
|
||||||
"src": "index.html",
|
"src": "index.html",
|
||||||
"isEntry": true,
|
"isEntry": true,
|
||||||
@@ -32,12 +32,12 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/AccountsPage.vue": {
|
"src/pages/AccountsPage.vue": {
|
||||||
"file": "assets/AccountsPage-D3MJyXUD.js",
|
"file": "assets/AccountsPage-xwYY9lse.js",
|
||||||
"name": "AccountsPage",
|
"name": "AccountsPage",
|
||||||
"src": "src/pages/AccountsPage.vue",
|
"src": "src/pages/AccountsPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_accounts-Bta9cdL5.js",
|
"_accounts-Cq6KNxFR.js",
|
||||||
"index.html"
|
"index.html"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
@@ -45,51 +45,51 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/LoginPage.vue": {
|
"src/pages/LoginPage.vue": {
|
||||||
"file": "assets/LoginPage-Cz6slTnR.js",
|
"file": "assets/LoginPage-BchU6qog.js",
|
||||||
"name": "LoginPage",
|
"name": "LoginPage",
|
||||||
"src": "src/pages/LoginPage.vue",
|
"src": "src/pages/LoginPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html",
|
"index.html",
|
||||||
"_auth--ytvFYf6.js"
|
"_auth-CjQgMKAl.js"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"assets/LoginPage-CnwOLKJz.css"
|
"assets/LoginPage-Dra3USJu.css"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/RegisterPage.vue": {
|
"src/pages/RegisterPage.vue": {
|
||||||
"file": "assets/RegisterPage-D46uldFj.js",
|
"file": "assets/RegisterPage-CwVejO-I.js",
|
||||||
"name": "RegisterPage",
|
"name": "RegisterPage",
|
||||||
"src": "src/pages/RegisterPage.vue",
|
"src": "src/pages/RegisterPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html",
|
"index.html",
|
||||||
"_auth--ytvFYf6.js"
|
"_auth-CjQgMKAl.js"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"assets/RegisterPage-BOcNcW5D.css"
|
"assets/RegisterPage-BOcNcW5D.css"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/ResetPasswordPage.vue": {
|
"src/pages/ResetPasswordPage.vue": {
|
||||||
"file": "assets/ResetPasswordPage-CO1hZug-.js",
|
"file": "assets/ResetPasswordPage-Cp3rzSEn.js",
|
||||||
"name": "ResetPasswordPage",
|
"name": "ResetPasswordPage",
|
||||||
"src": "src/pages/ResetPasswordPage.vue",
|
"src": "src/pages/ResetPasswordPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"index.html",
|
"index.html",
|
||||||
"_auth--ytvFYf6.js"
|
"_auth-CjQgMKAl.js"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"assets/ResetPasswordPage-DybfLMAw.css"
|
"assets/ResetPasswordPage-DybfLMAw.css"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/SchedulesPage.vue": {
|
"src/pages/SchedulesPage.vue": {
|
||||||
"file": "assets/SchedulesPage-CliP1bMU.js",
|
"file": "assets/SchedulesPage-BebL6WA6.js",
|
||||||
"name": "SchedulesPage",
|
"name": "SchedulesPage",
|
||||||
"src": "src/pages/SchedulesPage.vue",
|
"src": "src/pages/SchedulesPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
"imports": [
|
"imports": [
|
||||||
"_accounts-Bta9cdL5.js",
|
"_accounts-Cq6KNxFR.js",
|
||||||
"index.html"
|
"index.html"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/ScreenshotsPage.vue": {
|
"src/pages/ScreenshotsPage.vue": {
|
||||||
"file": "assets/ScreenshotsPage-CqETBpbn.js",
|
"file": "assets/ScreenshotsPage-M4eRrqBg.js",
|
||||||
"name": "ScreenshotsPage",
|
"name": "ScreenshotsPage",
|
||||||
"src": "src/pages/ScreenshotsPage.vue",
|
"src": "src/pages/ScreenshotsPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"src/pages/VerifyResultPage.vue": {
|
"src/pages/VerifyResultPage.vue": {
|
||||||
"file": "assets/VerifyResultPage-XFuV1ie5.js",
|
"file": "assets/VerifyResultPage-D9tJlwTO.js",
|
||||||
"name": "VerifyResultPage",
|
"name": "VerifyResultPage",
|
||||||
"src": "src/pages/VerifyResultPage.vue",
|
"src": "src/pages/VerifyResultPage.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
1
static/app/assets/AccountsPage-xwYY9lse.js
Normal file
1
static/app/assets/AccountsPage-xwYY9lse.js
Normal file
File diff suppressed because one or more lines are too long
1
static/app/assets/LoginPage-BchU6qog.js
Normal file
1
static/app/assets/LoginPage-BchU6qog.js
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
.auth-wrap[data-v-9eb557e5]{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}.auth-card[data-v-9eb557e5]{width:100%;max-width:420px;border-radius:var(--app-radius);border:1px solid var(--app-border);box-shadow:var(--app-shadow)}.brand[data-v-9eb557e5]{margin-bottom:14px}.brand-title[data-v-9eb557e5]{font-size:18px;font-weight:900}.brand-sub[data-v-9eb557e5]{margin-top:4px;font-size:12px}.links[data-v-9eb557e5]{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:2px 0 10px;flex-wrap:wrap}.submit-btn[data-v-9eb557e5]{width:100%}.foot[data-v-9eb557e5]{margin-top:14px;display:flex;align-items:center;justify-content:center;gap:6px}.dialog-form[data-v-9eb557e5]{margin-top:10px}.captcha-row[data-v-9eb557e5]{display:flex;align-items:center;gap:10px;width:100%}.captcha-img[data-v-9eb557e5]{height:40px;border:1px solid var(--app-border);border-radius:8px;cursor:pointer;-webkit-user-select:none;user-select:none}@media(max-width:480px){.captcha-img[data-v-9eb557e5]{height:38px}}
|
|
||||||
File diff suppressed because one or more lines are too long
1
static/app/assets/LoginPage-Dra3USJu.css
Normal file
1
static/app/assets/LoginPage-Dra3USJu.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.login-page[data-v-60947b3b]{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px;position:relative;background:linear-gradient(135deg,#eef2ff,#f6f7fb 45%,#ecfeff)}.login-page[data-v-60947b3b]:before{content:"";position:fixed;inset:0;background:radial-gradient(800px 500px at 15% 20%,rgba(59,130,246,.18),transparent 60%),radial-gradient(700px 420px at 85% 70%,rgba(124,58,237,.16),transparent 55%);pointer-events:none}.login-container[data-v-60947b3b]{width:100%;max-width:420px;background:#fff;border-radius:16px;box-shadow:0 18px 60px #11182726;border:1px solid rgba(17,24,39,.08);padding:38px 34px;position:relative;z-index:1}.login-header[data-v-60947b3b]{text-align:center;margin-bottom:28px}.login-badge[data-v-60947b3b]{display:inline-block;background:#3b82f61a;color:#1d4ed8;padding:6px 14px;border-radius:999px;font-size:12px;font-weight:700;margin-bottom:14px}.login-header h1[data-v-60947b3b]{font-size:24px;color:#111827;margin:0 0 10px;letter-spacing:.2px}.login-header p[data-v-60947b3b]{margin:0;color:#6b7280;font-size:14px}.form-group[data-v-60947b3b]{margin-bottom:20px}.form-group label[data-v-60947b3b]{display:block;margin-bottom:8px;color:#111827;font-weight:700;font-size:13px}.login-input[data-v-60947b3b] .el-input__wrapper{border-radius:10px;min-height:44px;background:#ffffffe6;box-shadow:0 0 0 1px #11182724 inset;transition:box-shadow .2s}.login-input[data-v-60947b3b] .el-input__wrapper.is-focus{box-shadow:0 0 0 1px #3b82f6b3 inset,0 0 0 4px #3b82f629}.login-input[data-v-60947b3b] .el-input__inner{font-size:14px}.btn-login[data-v-60947b3b]{width:100%;padding:12px;border:none;border-radius:10px;background:linear-gradient(135deg,#2563eb,#7c3aed);color:#fff;font-size:16px;font-weight:800;cursor:pointer;transition:transform .15s,filter .15s}.btn-login[data-v-60947b3b]:hover:not(:disabled){transform:translateY(-2px);filter:brightness(1.02)}.btn-login[data-v-60947b3b]:active:not(:disabled){transform:translateY(0)}.btn-login[data-v-60947b3b]:disabled{cursor:not-allowed;opacity:.8}.action-links[data-v-60947b3b]{margin-top:14px;display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap}.link-btn[data-v-60947b3b]{border:none;background:none;color:#2563eb;font-size:13px;font-weight:700;cursor:pointer;padding:0}.link-btn[data-v-60947b3b]:hover{text-decoration:underline}.register-row[data-v-60947b3b]{margin-top:16px;display:flex;justify-content:center;align-items:center;gap:8px;color:#6b7280;font-size:13px}.back-link[data-v-60947b3b]{text-align:center;margin-top:18px;color:#6b7280;font-size:13px}.back-link a[data-v-60947b3b]{margin-left:6px;color:#2563eb;text-decoration:none;font-weight:700}.back-link a[data-v-60947b3b]:hover{text-decoration:underline}.dialog-form[data-v-60947b3b]{margin-top:10px}.alert[data-v-60947b3b]{margin-top:12px}.captcha-row[data-v-60947b3b]{display:flex;align-items:center;gap:10px;width:100%}.captcha-input[data-v-60947b3b]{flex:1;min-width:0}.captcha-img[data-v-60947b3b]{height:46px;border:1px solid rgba(17,24,39,.14);border-radius:8px;cursor:pointer;-webkit-user-select:none;user-select:none}.captcha-refresh[data-v-60947b3b]{height:44px;padding:0 14px;border:1px solid rgba(17,24,39,.14);border-radius:10px;background:#f8fafc;color:#111827;font-size:13px;cursor:pointer}.captcha-refresh[data-v-60947b3b]:hover{background:#f1f5f9}@media(max-width:480px){.login-page[data-v-60947b3b]{align-items:flex-start;padding:20px 12px 12px}.login-container[data-v-60947b3b]{max-width:100%;padding:28px 20px;border-radius:14px}.login-header h1[data-v-60947b3b]{font-size:22px}.btn-login[data-v-60947b3b]{padding:13px;font-size:15px}.captcha-img[data-v-60947b3b]{height:42px}.captcha-refresh[data-v-60947b3b]{height:42px;padding:0 12px}}
|
||||||
@@ -1 +1 @@
|
|||||||
import{_ as M,r as j,a as d,c as B,o as A,b as U,d as l,w as o,e as v,u as H,f as b,g as n,h as N,i as E,j as P,t as q,k as S,E as c,v as z}from"./index-CPwwGffH.js";import{g as F,f as G,b as J}from"./auth--ytvFYf6.js";const O={class:"auth-wrap"},Q={class:"hint app-muted"},W={class:"captcha-row"},X=["src"],Y={class:"actions"},Z={__name:"RegisterPage",setup($){const T=H(),a=j({username:"",password:"",confirm_password:"",email:"",captcha:""}),f=d(!1),w=d(""),h=d(""),V=d(!1),t=d(""),_=d(""),k=d(""),K=B(()=>f.value?"邮箱 *":"邮箱(可选)"),R=B(()=>f.value?"必填,用于账号验证":"选填,用于找回密码和接收通知");async function y(){try{const u=await F();h.value=u?.session_id||"",w.value=u?.captcha_image||"",a.captcha=""}catch{h.value="",w.value=""}}async function D(){try{const u=await G();f.value=!!u?.register_verify_enabled}catch{f.value=!1}}function I(){t.value="",_.value="",k.value=""}async function C(){I();const u=a.username.trim(),e=a.password,g=a.confirm_password,s=a.email.trim(),i=a.captcha.trim();if(u.length<3){t.value="用户名至少3个字符",c.error(t.value);return}const p=z(e);if(!p.ok){t.value=p.message||"密码格式不正确",c.error(t.value);return}if(e!==g){t.value="两次输入的密码不一致",c.error(t.value);return}if(f.value&&!s){t.value="请填写邮箱地址用于账号验证",c.error(t.value);return}if(s&&!s.includes("@")){t.value="邮箱格式不正确",c.error(t.value);return}if(!i){t.value="请输入验证码",c.error(t.value);return}V.value=!0;try{const m=await J({username:u,password:e,email:s,captcha_session:h.value,captcha:i});_.value=m?.message||"注册成功",k.value=m?.need_verify?"请检查您的邮箱(包括垃圾邮件文件夹)":"",c.success("注册成功"),a.username="",a.password="",a.confirm_password="",a.email="",a.captcha="",setTimeout(()=>{window.location.href="/login"},3e3)}catch(m){const x=m?.response?.data;t.value=x?.error||"注册失败",c.error(t.value),await y()}finally{V.value=!1}}function L(){T.push("/login")}return A(async()=>{await y(),await D()}),(u,e)=>{const g=v("el-alert"),s=v("el-input"),i=v("el-form-item"),p=v("el-button"),m=v("el-form"),x=v("el-card");return b(),U("div",O,[l(x,{shadow:"never",class:"auth-card","body-style":{padding:"22px"}},{default:o(()=>[e[11]||(e[11]=n("div",{class:"brand"},[n("div",{class:"brand-title"},"知识管理平台"),n("div",{class:"brand-sub app-muted"},"用户注册")],-1)),t.value?(b(),N(g,{key:0,type:"error",closable:!1,title:t.value,"show-icon":"",class:"alert"},null,8,["title"])):E("",!0),_.value?(b(),N(g,{key:1,type:"success",closable:!1,title:_.value,description:k.value,"show-icon":"",class:"alert"},null,8,["title","description"])):E("",!0),l(m,{"label-position":"top"},{default:o(()=>[l(i,{label:"用户名 *"},{default:o(()=>[l(s,{modelValue:a.username,"onUpdate:modelValue":e[0]||(e[0]=r=>a.username=r),placeholder:"至少3个字符",autocomplete:"username"},null,8,["modelValue"]),e[5]||(e[5]=n("div",{class:"hint app-muted"},"至少3个字符",-1))]),_:1}),l(i,{label:"密码 *"},{default:o(()=>[l(s,{modelValue:a.password,"onUpdate:modelValue":e[1]||(e[1]=r=>a.password=r),type:"password","show-password":"",placeholder:"至少8位且包含字母和数字",autocomplete:"new-password"},null,8,["modelValue"]),e[6]||(e[6]=n("div",{class:"hint app-muted"},"至少8位且包含字母和数字",-1))]),_:1}),l(i,{label:"确认密码 *"},{default:o(()=>[l(s,{modelValue:a.confirm_password,"onUpdate:modelValue":e[2]||(e[2]=r=>a.confirm_password=r),type:"password","show-password":"",placeholder:"请再次输入密码",autocomplete:"new-password",onKeyup:P(C,["enter"])},null,8,["modelValue"])]),_:1}),l(i,{label:K.value},{default:o(()=>[l(s,{modelValue:a.email,"onUpdate:modelValue":e[3]||(e[3]=r=>a.email=r),placeholder:"name@example.com",autocomplete:"email"},null,8,["modelValue"]),n("div",Q,q(R.value),1)]),_:1},8,["label"]),l(i,{label:"验证码 *"},{default:o(()=>[n("div",W,[l(s,{modelValue:a.captcha,"onUpdate:modelValue":e[4]||(e[4]=r=>a.captcha=r),placeholder:"请输入验证码",onKeyup:P(C,["enter"])},null,8,["modelValue"]),w.value?(b(),U("img",{key:0,class:"captcha-img",src:w.value,alt:"验证码",title:"点击刷新",onClick:y},null,8,X)):E("",!0),l(p,{onClick:y},{default:o(()=>[...e[7]||(e[7]=[S("刷新",-1)])]),_:1})])]),_:1})]),_:1}),l(p,{type:"primary",class:"submit-btn",loading:V.value,onClick:C},{default:o(()=>[...e[8]||(e[8]=[S("注册",-1)])]),_:1},8,["loading"]),n("div",Y,[e[10]||(e[10]=n("span",{class:"app-muted"},"已有账号?",-1)),l(p,{link:"",type:"primary",onClick:L},{default:o(()=>[...e[9]||(e[9]=[S("立即登录",-1)])]),_:1})])]),_:1})])}}},te=M(Z,[["__scopeId","data-v-a9d7804f"]]);export{te as default};
|
import{_ as M,r as j,a as d,c as B,o as A,b as U,e as l,h as o,g as v,u as H,i as b,d as n,j as N,f as E,w as P,t as q,k as S,E as c,v as z}from"./index-DMtbRy1f.js";import{g as F,f as G,b as J}from"./auth-CjQgMKAl.js";const O={class:"auth-wrap"},Q={class:"hint app-muted"},W={class:"captcha-row"},X=["src"],Y={class:"actions"},Z={__name:"RegisterPage",setup($){const T=H(),a=j({username:"",password:"",confirm_password:"",email:"",captcha:""}),f=d(!1),w=d(""),h=d(""),V=d(!1),t=d(""),_=d(""),k=d(""),K=B(()=>f.value?"邮箱 *":"邮箱(可选)"),R=B(()=>f.value?"必填,用于账号验证":"选填,用于找回密码和接收通知");async function y(){try{const u=await F();h.value=u?.session_id||"",w.value=u?.captcha_image||"",a.captcha=""}catch{h.value="",w.value=""}}async function D(){try{const u=await G();f.value=!!u?.register_verify_enabled}catch{f.value=!1}}function I(){t.value="",_.value="",k.value=""}async function C(){I();const u=a.username.trim(),e=a.password,g=a.confirm_password,s=a.email.trim(),i=a.captcha.trim();if(u.length<3){t.value="用户名至少3个字符",c.error(t.value);return}const p=z(e);if(!p.ok){t.value=p.message||"密码格式不正确",c.error(t.value);return}if(e!==g){t.value="两次输入的密码不一致",c.error(t.value);return}if(f.value&&!s){t.value="请填写邮箱地址用于账号验证",c.error(t.value);return}if(s&&!s.includes("@")){t.value="邮箱格式不正确",c.error(t.value);return}if(!i){t.value="请输入验证码",c.error(t.value);return}V.value=!0;try{const m=await J({username:u,password:e,email:s,captcha_session:h.value,captcha:i});_.value=m?.message||"注册成功",k.value=m?.need_verify?"请检查您的邮箱(包括垃圾邮件文件夹)":"",c.success("注册成功"),a.username="",a.password="",a.confirm_password="",a.email="",a.captcha="",setTimeout(()=>{window.location.href="/login"},3e3)}catch(m){const x=m?.response?.data;t.value=x?.error||"注册失败",c.error(t.value),await y()}finally{V.value=!1}}function L(){T.push("/login")}return A(async()=>{await y(),await D()}),(u,e)=>{const g=v("el-alert"),s=v("el-input"),i=v("el-form-item"),p=v("el-button"),m=v("el-form"),x=v("el-card");return b(),U("div",O,[l(x,{shadow:"never",class:"auth-card","body-style":{padding:"22px"}},{default:o(()=>[e[11]||(e[11]=n("div",{class:"brand"},[n("div",{class:"brand-title"},"知识管理平台"),n("div",{class:"brand-sub app-muted"},"用户注册")],-1)),t.value?(b(),N(g,{key:0,type:"error",closable:!1,title:t.value,"show-icon":"",class:"alert"},null,8,["title"])):E("",!0),_.value?(b(),N(g,{key:1,type:"success",closable:!1,title:_.value,description:k.value,"show-icon":"",class:"alert"},null,8,["title","description"])):E("",!0),l(m,{"label-position":"top"},{default:o(()=>[l(i,{label:"用户名 *"},{default:o(()=>[l(s,{modelValue:a.username,"onUpdate:modelValue":e[0]||(e[0]=r=>a.username=r),placeholder:"至少3个字符",autocomplete:"username"},null,8,["modelValue"]),e[5]||(e[5]=n("div",{class:"hint app-muted"},"至少3个字符",-1))]),_:1}),l(i,{label:"密码 *"},{default:o(()=>[l(s,{modelValue:a.password,"onUpdate:modelValue":e[1]||(e[1]=r=>a.password=r),type:"password","show-password":"",placeholder:"至少8位且包含字母和数字",autocomplete:"new-password"},null,8,["modelValue"]),e[6]||(e[6]=n("div",{class:"hint app-muted"},"至少8位且包含字母和数字",-1))]),_:1}),l(i,{label:"确认密码 *"},{default:o(()=>[l(s,{modelValue:a.confirm_password,"onUpdate:modelValue":e[2]||(e[2]=r=>a.confirm_password=r),type:"password","show-password":"",placeholder:"请再次输入密码",autocomplete:"new-password",onKeyup:P(C,["enter"])},null,8,["modelValue"])]),_:1}),l(i,{label:K.value},{default:o(()=>[l(s,{modelValue:a.email,"onUpdate:modelValue":e[3]||(e[3]=r=>a.email=r),placeholder:"name@example.com",autocomplete:"email"},null,8,["modelValue"]),n("div",Q,q(R.value),1)]),_:1},8,["label"]),l(i,{label:"验证码 *"},{default:o(()=>[n("div",W,[l(s,{modelValue:a.captcha,"onUpdate:modelValue":e[4]||(e[4]=r=>a.captcha=r),placeholder:"请输入验证码",onKeyup:P(C,["enter"])},null,8,["modelValue"]),w.value?(b(),U("img",{key:0,class:"captcha-img",src:w.value,alt:"验证码",title:"点击刷新",onClick:y},null,8,X)):E("",!0),l(p,{onClick:y},{default:o(()=>[...e[7]||(e[7]=[S("刷新",-1)])]),_:1})])]),_:1})]),_:1}),l(p,{type:"primary",class:"submit-btn",loading:V.value,onClick:C},{default:o(()=>[...e[8]||(e[8]=[S("注册",-1)])]),_:1},8,["loading"]),n("div",Y,[e[10]||(e[10]=n("span",{class:"app-muted"},"已有账号?",-1)),l(p,{link:"",type:"primary",onClick:L},{default:o(()=>[...e[9]||(e[9]=[S("立即登录",-1)])]),_:1})])]),_:1})])}}},te=M(Z,[["__scopeId","data-v-a9d7804f"]]);export{te as default};
|
||||||
@@ -1 +1 @@
|
|||||||
import{_ as L,a as n,l as M,r as U,c as j,o as F,m as K,b as v,d as s,w as a,e as l,u as D,f as w,g as m,F as T,k,h as q,i as x,j as z,t as G,v as H,E as y}from"./index-CPwwGffH.js";import{c as J}from"./auth--ytvFYf6.js";const O={class:"auth-wrap"},Q={class:"actions"},W={class:"actions"},X={key:0,class:"app-muted"},Y={__name:"ResetPasswordPage",setup(Z){const B=M(),A=D(),r=n(String(B.params.token||"")),i=n(!0),b=n(""),t=U({newPassword:"",confirmPassword:""}),g=n(!1),_=n(""),d=n(0);let u=null;function C(){if(typeof window>"u")return null;const o=window.__APP_INITIAL_STATE__;return!o||typeof o!="object"?null:(window.__APP_INITIAL_STATE__=null,o)}const I=j(()=>!!(i.value&&r.value&&!_.value));function S(){A.push("/login")}function N(){d.value=3,u=window.setInterval(()=>{d.value-=1,d.value<=0&&(window.clearInterval(u),u=null,window.location.href="/login")},1e3)}async function V(){if(!I.value)return;const o=t.newPassword,e=t.confirmPassword,c=H(o);if(!c.ok){y.error(c.message);return}if(o!==e){y.error("两次输入的密码不一致");return}g.value=!0;try{await J({token:r.value,new_password:o}),_.value="密码重置成功!3秒后跳转到登录页面...",y.success("密码重置成功"),N()}catch(p){const f=p?.response?.data;y.error(f?.error||"重置失败")}finally{g.value=!1}}return F(()=>{const o=C();o?.page==="reset_password"?(r.value=String(o?.token||r.value||""),i.value=!!o?.valid,b.value=o?.error_message||(i.value?"":"重置链接无效或已过期,请重新申请密码重置")):r.value||(i.value=!1,b.value="重置链接无效或已过期,请重新申请密码重置")}),K(()=>{u&&window.clearInterval(u)}),(o,e)=>{const c=l("el-alert"),p=l("el-button"),f=l("el-input"),h=l("el-form-item"),R=l("el-form"),E=l("el-card");return w(),v("div",O,[s(E,{shadow:"never",class:"auth-card","body-style":{padding:"22px"}},{default:a(()=>[e[5]||(e[5]=m("div",{class:"brand"},[m("div",{class:"brand-title"},"知识管理平台"),m("div",{class:"brand-sub app-muted"},"重置密码")],-1)),i.value?(w(),v(T,{key:1},[_.value?(w(),q(c,{key:0,type:"success",closable:!1,title:"重置成功",description:_.value,"show-icon":"",class:"alert"},null,8,["description"])):x("",!0),s(R,{"label-position":"top"},{default:a(()=>[s(h,{label:"新密码(至少8位且包含字母和数字)"},{default:a(()=>[s(f,{modelValue:t.newPassword,"onUpdate:modelValue":e[0]||(e[0]=P=>t.newPassword=P),type:"password","show-password":"",placeholder:"请输入新密码",autocomplete:"new-password"},null,8,["modelValue"])]),_:1}),s(h,{label:"确认密码"},{default:a(()=>[s(f,{modelValue:t.confirmPassword,"onUpdate:modelValue":e[1]||(e[1]=P=>t.confirmPassword=P),type:"password","show-password":"",placeholder:"请再次输入新密码",autocomplete:"new-password",onKeyup:z(V,["enter"])},null,8,["modelValue"])]),_:1})]),_:1}),s(p,{type:"primary",class:"submit-btn",loading:g.value,disabled:!I.value,onClick:V},{default:a(()=>[...e[3]||(e[3]=[k(" 确认重置 ",-1)])]),_:1},8,["loading","disabled"]),m("div",W,[s(p,{link:"",type:"primary",onClick:S},{default:a(()=>[...e[4]||(e[4]=[k("返回登录",-1)])]),_:1}),d.value>0?(w(),v("span",X,G(d.value)+" 秒后自动跳转…",1)):x("",!0)])],64)):(w(),v(T,{key:0},[s(c,{type:"error",closable:!1,title:"链接已失效",description:b.value,"show-icon":""},null,8,["description"]),m("div",Q,[s(p,{type:"primary",onClick:S},{default:a(()=>[...e[2]||(e[2]=[k("返回登录",-1)])]),_:1})])],64))]),_:1})])}}},oe=L(Y,[["__scopeId","data-v-0bbb511c"]]);export{oe as default};
|
import{_ as L,a as n,l as M,r as U,c as j,o as F,m as K,b as v,e as s,h as a,g as l,u as D,i as w,d as m,F as T,k,j as q,f as x,w as z,t as G,v as H,E as y}from"./index-DMtbRy1f.js";import{c as J}from"./auth-CjQgMKAl.js";const O={class:"auth-wrap"},Q={class:"actions"},W={class:"actions"},X={key:0,class:"app-muted"},Y={__name:"ResetPasswordPage",setup(Z){const B=M(),A=D(),r=n(String(B.params.token||"")),i=n(!0),b=n(""),t=U({newPassword:"",confirmPassword:""}),g=n(!1),_=n(""),d=n(0);let u=null;function C(){if(typeof window>"u")return null;const o=window.__APP_INITIAL_STATE__;return!o||typeof o!="object"?null:(window.__APP_INITIAL_STATE__=null,o)}const I=j(()=>!!(i.value&&r.value&&!_.value));function S(){A.push("/login")}function N(){d.value=3,u=window.setInterval(()=>{d.value-=1,d.value<=0&&(window.clearInterval(u),u=null,window.location.href="/login")},1e3)}async function V(){if(!I.value)return;const o=t.newPassword,e=t.confirmPassword,c=H(o);if(!c.ok){y.error(c.message);return}if(o!==e){y.error("两次输入的密码不一致");return}g.value=!0;try{await J({token:r.value,new_password:o}),_.value="密码重置成功!3秒后跳转到登录页面...",y.success("密码重置成功"),N()}catch(p){const f=p?.response?.data;y.error(f?.error||"重置失败")}finally{g.value=!1}}return F(()=>{const o=C();o?.page==="reset_password"?(r.value=String(o?.token||r.value||""),i.value=!!o?.valid,b.value=o?.error_message||(i.value?"":"重置链接无效或已过期,请重新申请密码重置")):r.value||(i.value=!1,b.value="重置链接无效或已过期,请重新申请密码重置")}),K(()=>{u&&window.clearInterval(u)}),(o,e)=>{const c=l("el-alert"),p=l("el-button"),f=l("el-input"),h=l("el-form-item"),R=l("el-form"),E=l("el-card");return w(),v("div",O,[s(E,{shadow:"never",class:"auth-card","body-style":{padding:"22px"}},{default:a(()=>[e[5]||(e[5]=m("div",{class:"brand"},[m("div",{class:"brand-title"},"知识管理平台"),m("div",{class:"brand-sub app-muted"},"重置密码")],-1)),i.value?(w(),v(T,{key:1},[_.value?(w(),q(c,{key:0,type:"success",closable:!1,title:"重置成功",description:_.value,"show-icon":"",class:"alert"},null,8,["description"])):x("",!0),s(R,{"label-position":"top"},{default:a(()=>[s(h,{label:"新密码(至少8位且包含字母和数字)"},{default:a(()=>[s(f,{modelValue:t.newPassword,"onUpdate:modelValue":e[0]||(e[0]=P=>t.newPassword=P),type:"password","show-password":"",placeholder:"请输入新密码",autocomplete:"new-password"},null,8,["modelValue"])]),_:1}),s(h,{label:"确认密码"},{default:a(()=>[s(f,{modelValue:t.confirmPassword,"onUpdate:modelValue":e[1]||(e[1]=P=>t.confirmPassword=P),type:"password","show-password":"",placeholder:"请再次输入新密码",autocomplete:"new-password",onKeyup:z(V,["enter"])},null,8,["modelValue"])]),_:1})]),_:1}),s(p,{type:"primary",class:"submit-btn",loading:g.value,disabled:!I.value,onClick:V},{default:a(()=>[...e[3]||(e[3]=[k(" 确认重置 ",-1)])]),_:1},8,["loading","disabled"]),m("div",W,[s(p,{link:"",type:"primary",onClick:S},{default:a(()=>[...e[4]||(e[4]=[k("返回登录",-1)])]),_:1}),d.value>0?(w(),v("span",X,G(d.value)+" 秒后自动跳转…",1)):x("",!0)])],64)):(w(),v(T,{key:0},[s(c,{type:"error",closable:!1,title:"链接已失效",description:b.value,"show-icon":""},null,8,["description"]),m("div",Q,[s(p,{type:"primary",onClick:S},{default:a(()=>[...e[2]||(e[2]=[k("返回登录",-1)])]),_:1})])],64))]),_:1})])}}},oe=L(Y,[["__scopeId","data-v-0bbb511c"]]);export{oe as default};
|
||||||
1
static/app/assets/SchedulesPage-BebL6WA6.js
Normal file
1
static/app/assets/SchedulesPage-BebL6WA6.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
static/app/assets/ScreenshotsPage-M4eRrqBg.js
Normal file
1
static/app/assets/ScreenshotsPage-M4eRrqBg.js
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
import{_ as U,a as o,c as I,o as E,m as R,b as k,d as i,w as s,e as d,u as W,f as _,g as l,i as B,h as $,k as T,t as v}from"./index-CPwwGffH.js";const j={class:"auth-wrap"},z={class:"actions"},D={key:0,class:"countdown app-muted"},M={__name:"VerifyResultPage",setup(q){const x=W(),p=o(!1),f=o(""),m=o(""),w=o(""),y=o(""),r=o(""),u=o(""),c=o(""),n=o(0);let a=null;function C(){if(typeof window>"u")return null;const e=window.__APP_INITIAL_STATE__;return!e||typeof e!="object"?null:(window.__APP_INITIAL_STATE__=null,e)}function N(e){const t=!!e?.success;p.value=t,f.value=e?.title||(t?"验证成功":"验证失败"),m.value=e?.message||e?.error_message||(t?"操作已完成,现在可以继续使用系统。":"操作失败,请稍后重试。"),w.value=e?.primary_label||(t?"立即登录":"重新注册"),y.value=e?.primary_url||(t?"/login":"/register"),r.value=e?.secondary_label||(t?"":"返回登录"),u.value=e?.secondary_url||(t?"":"/login"),c.value=e?.redirect_url||(t?"/login":""),n.value=Number(e?.redirect_seconds||(t?5:0))||0}const A=I(()=>!!(r.value&&u.value)),b=I(()=>!!(c.value&&n.value>0));async function g(e){if(e){if(e.startsWith("http://")||e.startsWith("https://")){window.location.href=e;return}await x.push(e)}}function P(){b.value&&(a=window.setInterval(()=>{n.value-=1,n.value<=0&&(window.clearInterval(a),a=null,window.location.href=c.value)},1e3))}return E(()=>{const e=C();N(e),P()}),R(()=>{a&&window.clearInterval(a)}),(e,t)=>{const h=d("el-button"),V=d("el-result"),L=d("el-card");return _(),k("div",j,[i(L,{shadow:"never",class:"auth-card","body-style":{padding:"22px"}},{default:s(()=>[t[2]||(t[2]=l("div",{class:"brand"},[l("div",{class:"brand-title"},"知识管理平台"),l("div",{class:"brand-sub app-muted"},"验证结果")],-1)),i(V,{icon:p.value?"success":"error",title:f.value,"sub-title":m.value,class:"result"},{extra:s(()=>[l("div",z,[i(h,{type:"primary",onClick:t[0]||(t[0]=S=>g(y.value))},{default:s(()=>[T(v(w.value),1)]),_:1}),A.value?(_(),$(h,{key:0,onClick:t[1]||(t[1]=S=>g(u.value))},{default:s(()=>[T(v(r.value),1)]),_:1})):B("",!0)]),b.value?(_(),k("div",D,v(n.value)+" 秒后自动跳转... ",1)):B("",!0)]),_:1},8,["icon","title","sub-title"])]),_:1})])}}},G=U(M,[["__scopeId","data-v-1fc6b081"]]);export{G as default};
|
import{_ as U,a as o,c as I,o as E,m as R,b as k,e as i,h as s,g as d,u as j,i as _,d as l,f as B,j as W,k as T,t as v}from"./index-DMtbRy1f.js";const $={class:"auth-wrap"},z={class:"actions"},D={key:0,class:"countdown app-muted"},M={__name:"VerifyResultPage",setup(q){const x=j(),p=o(!1),f=o(""),m=o(""),w=o(""),y=o(""),r=o(""),u=o(""),c=o(""),n=o(0);let a=null;function C(){if(typeof window>"u")return null;const e=window.__APP_INITIAL_STATE__;return!e||typeof e!="object"?null:(window.__APP_INITIAL_STATE__=null,e)}function N(e){const t=!!e?.success;p.value=t,f.value=e?.title||(t?"验证成功":"验证失败"),m.value=e?.message||e?.error_message||(t?"操作已完成,现在可以继续使用系统。":"操作失败,请稍后重试。"),w.value=e?.primary_label||(t?"立即登录":"重新注册"),y.value=e?.primary_url||(t?"/login":"/register"),r.value=e?.secondary_label||(t?"":"返回登录"),u.value=e?.secondary_url||(t?"":"/login"),c.value=e?.redirect_url||(t?"/login":""),n.value=Number(e?.redirect_seconds||(t?5:0))||0}const A=I(()=>!!(r.value&&u.value)),b=I(()=>!!(c.value&&n.value>0));async function g(e){if(e){if(e.startsWith("http://")||e.startsWith("https://")){window.location.href=e;return}await x.push(e)}}function P(){b.value&&(a=window.setInterval(()=>{n.value-=1,n.value<=0&&(window.clearInterval(a),a=null,window.location.href=c.value)},1e3))}return E(()=>{const e=C();N(e),P()}),R(()=>{a&&window.clearInterval(a)}),(e,t)=>{const h=d("el-button"),V=d("el-result"),L=d("el-card");return _(),k("div",$,[i(L,{shadow:"never",class:"auth-card","body-style":{padding:"22px"}},{default:s(()=>[t[2]||(t[2]=l("div",{class:"brand"},[l("div",{class:"brand-title"},"知识管理平台"),l("div",{class:"brand-sub app-muted"},"验证结果")],-1)),i(V,{icon:p.value?"success":"error",title:f.value,"sub-title":m.value,class:"result"},{extra:s(()=>[l("div",z,[i(h,{type:"primary",onClick:t[0]||(t[0]=S=>g(y.value))},{default:s(()=>[T(v(w.value),1)]),_:1}),A.value?(_(),W(h,{key:0,onClick:t[1]||(t[1]=S=>g(u.value))},{default:s(()=>[T(v(r.value),1)]),_:1})):B("",!0)]),b.value?(_(),k("div",D,v(n.value)+" 秒后自动跳转... ",1)):B("",!0)]),_:1},8,["icon","title","sub-title"])]),_:1})])}}},G=U(M,[["__scopeId","data-v-1fc6b081"]]);export{G as default};
|
||||||
@@ -1 +1 @@
|
|||||||
import{p as c}from"./index-CPwwGffH.js";async function o(t={}){const{data:a}=await c.get("/accounts",{params:t});return a}async function u(t){const{data:a}=await c.post("/accounts",t);return a}async function r(t,a){const{data:n}=await c.put(`/accounts/${t}`,a);return n}async function e(t){const{data:a}=await c.delete(`/accounts/${t}`);return a}async function i(t,a){const{data:n}=await c.put(`/accounts/${t}/remark`,a);return n}async function p(t,a){const{data:n}=await c.post(`/accounts/${t}/start`,a);return n}async function d(t){const{data:a}=await c.post(`/accounts/${t}/stop`,{});return a}async function f(t){const{data:a}=await c.post("/accounts/batch/start",t);return a}async function w(t){const{data:a}=await c.post("/accounts/batch/stop",t);return a}async function y(){const{data:t}=await c.post("/accounts/clear",{});return t}async function A(t,a={}){const{data:n}=await c.post(`/accounts/${t}/screenshot`,a);return n}export{w as a,f as b,y as c,d,e,o as f,u as g,i as h,p as s,A as t,r as u};
|
import{p as c}from"./index-DMtbRy1f.js";async function o(t={}){const{data:a}=await c.get("/accounts",{params:t});return a}async function u(t){const{data:a}=await c.post("/accounts",t);return a}async function r(t,a){const{data:n}=await c.put(`/accounts/${t}`,a);return n}async function e(t){const{data:a}=await c.delete(`/accounts/${t}`);return a}async function i(t,a){const{data:n}=await c.put(`/accounts/${t}/remark`,a);return n}async function p(t,a){const{data:n}=await c.post(`/accounts/${t}/start`,a);return n}async function d(t){const{data:a}=await c.post(`/accounts/${t}/stop`,{});return a}async function f(t){const{data:a}=await c.post("/accounts/batch/start",t);return a}async function w(t){const{data:a}=await c.post("/accounts/batch/stop",t);return a}async function y(){const{data:t}=await c.post("/accounts/clear",{});return t}async function A(t,a={}){const{data:n}=await c.post(`/accounts/${t}/screenshot`,a);return n}export{w as a,f as b,y as c,d,e,o as f,u as g,i as h,p as s,A as t,r as u};
|
||||||
@@ -1 +1 @@
|
|||||||
import{p as s}from"./index-CPwwGffH.js";async function r(){const{data:a}=await s.get("/email/verify-status");return a}async function o(){const{data:a}=await s.post("/generate_captcha",{});return a}async function e(a){const{data:t}=await s.post("/login",a);return t}async function i(a){const{data:t}=await s.post("/register",a);return t}async function c(a){const{data:t}=await s.post("/resend-verify-email",a);return t}async function f(a){const{data:t}=await s.post("/forgot-password",a);return t}async function u(a){const{data:t}=await s.post("/reset-password-confirm",a);return t}export{f as a,i as b,u as c,r as f,o as g,e as l,c as r};
|
import{p as s}from"./index-DMtbRy1f.js";async function r(){const{data:a}=await s.get("/email/verify-status");return a}async function o(){const{data:a}=await s.post("/generate_captcha",{});return a}async function e(a){const{data:t}=await s.post("/login",a);return t}async function i(a){const{data:t}=await s.post("/register",a);return t}async function c(a){const{data:t}=await s.post("/resend-verify-email",a);return t}async function f(a){const{data:t}=await s.post("/forgot-password",a);return t}async function u(a){const{data:t}=await s.post("/reset-password-confirm",a);return t}export{f as a,i as b,u as c,r as f,o as g,e as l,c as r};
|
||||||
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||||
<title>知识管理平台</title>
|
<title>知识管理平台</title>
|
||||||
<script type="module" crossorigin src="./assets/index-CPwwGffH.js"></script>
|
<script type="module" crossorigin src="./assets/index-DMtbRy1f.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="./assets/index-BVjJVlht.css">
|
<link rel="stylesheet" crossorigin href="./assets/index-BVjJVlht.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Reference in New Issue
Block a user