feat: 添加用户协议和隐私协议支持,更新登录页和相关配置
This commit is contained in:
parent
47cf5fac01
commit
06cc8cbf7a
@ -1,6 +1,6 @@
|
||||
# 品牌自定义
|
||||
|
||||
Yuxi-Know 支持完整的品牌自定义,包括 Logo、组织名称、版权信息等,方便企业用户进行品牌定制。
|
||||
Yuxi-Know 支持完整的品牌自定义,包括 Logo、组织名称、版权信息、登录协议等,方便企业用户进行品牌定制。
|
||||
|
||||
## 品牌信息配置
|
||||
|
||||
@ -17,7 +17,8 @@ cp src/config/static/info.template.yaml src/config/static/info.local.yaml
|
||||
- 应用名称
|
||||
- 组织名称
|
||||
- Logo
|
||||
- 版权信息等
|
||||
- 版权信息
|
||||
- 登录页用户协议/隐私协议链接
|
||||
|
||||
### 步骤 3:指定配置文件
|
||||
|
||||
@ -31,6 +32,38 @@ YUXI_BRAND_FILE_PATH=src/config/static/info.local.yaml
|
||||
`info.local.yaml` > `info.template.yaml`(默认)
|
||||
:::
|
||||
|
||||
## 登录协议配置
|
||||
|
||||
登录页支持从品牌配置中读取用户协议与隐私协议链接。
|
||||
|
||||
### 配置项
|
||||
|
||||
在 `src/config/static/info.local.yaml` 的 `footer` 下新增以下字段:
|
||||
|
||||
```yaml
|
||||
footer:
|
||||
copyright: "© your org 2026"
|
||||
user_agreement_url: "/protocols/user-agreement.template.html"
|
||||
privacy_policy_url: "/protocols/privacy-policy.template.html"
|
||||
```
|
||||
|
||||
### 显示规则
|
||||
|
||||
- 当 `user_agreement_url` 和 `privacy_policy_url` 都有值时,登录页会显示协议勾选项。
|
||||
- 任一字段为空时,登录页不显示协议勾选项。
|
||||
- 未勾选协议时,提交登录/初始化会通过消息提示用户先同意协议。
|
||||
|
||||
### 协议模板文件
|
||||
|
||||
系统默认提供两个 HTML 模板文件:
|
||||
|
||||
- `web/public/protocols/user-agreement.template.html`
|
||||
- `web/public/protocols/privacy-policy.template.html`
|
||||
|
||||
你可以直接编辑这两个文件中的协议内容,并替换占位符(如 `{{ORG_NAME}}`、`{{PRODUCT_NAME}}`、`{{EFFECTIVE_DATE}}`)。
|
||||
|
||||
如果你有自己的协议页面,也可以将 `user_agreement_url` 和 `privacy_policy_url` 指向自定义路径或外部链接。
|
||||
|
||||
### Icon 定制
|
||||
|
||||
系统预设了多种 Icon,如需更多图标,可以从 `lucide-vue-next` 中引入。
|
||||
|
||||
@ -51,3 +51,5 @@ actions:
|
||||
# 页脚信息
|
||||
footer:
|
||||
copyright: "© 江南语析 2026 v0.5.1"
|
||||
user_agreement_url: "/protocols/user-agreement.template.html"
|
||||
privacy_policy_url: "/protocols/privacy-policy.template.html"
|
||||
|
||||
145
web/public/protocols/privacy-policy.template.html
Normal file
145
web/public/protocols/privacy-policy.template.html
Normal file
@ -0,0 +1,145 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>隐私协议</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #f5f7fb;
|
||||
--card: #ffffff;
|
||||
--text: #1f2937;
|
||||
--subtle: #6b7280;
|
||||
--line: #e5e7eb;
|
||||
--brand: #2563eb;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 960px;
|
||||
margin: 40px auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--card);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
padding: 28px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.meta {
|
||||
color: var(--subtle);
|
||||
font-size: 14px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 24px 0 10px;
|
||||
font-size: 20px;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0 0 12px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin-top: 24px;
|
||||
padding: 14px 16px;
|
||||
border-left: 3px solid var(--brand);
|
||||
background: #eff6ff;
|
||||
color: #1e3a8a;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--brand);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
<article class="card">
|
||||
<h1>隐私协议</h1>
|
||||
<div class="meta">适用组织:{{ORG_NAME}} | 生效日期:{{EFFECTIVE_DATE}}</div>
|
||||
|
||||
<p>
|
||||
{{PRODUCT_NAME}} 非常重视您的个人信息与隐私保护。我们将依据适用法律法规,采取合理措施保障您的个人信息安全。
|
||||
</p>
|
||||
|
||||
<h2>一、我们收集的信息</h2>
|
||||
<ul>
|
||||
<li>账号信息:例如用户 ID、手机号等您主动提供的信息。</li>
|
||||
<li>使用信息:例如访问时间、操作日志、设备信息等系统运行所需信息。</li>
|
||||
<li>业务数据:您在使用平台过程中上传或生成的数据内容。</li>
|
||||
</ul>
|
||||
|
||||
<h2>二、信息使用目的</h2>
|
||||
<ul>
|
||||
<li>用于提供、维护和优化平台服务。</li>
|
||||
<li>用于账号安全管理、风险识别和问题排查。</li>
|
||||
<li>用于履行法律法规规定的义务。</li>
|
||||
</ul>
|
||||
|
||||
<h2>三、信息共享与披露</h2>
|
||||
<p>
|
||||
除法律法规另有规定,或获得您的明确授权外,我们不会向第三方出售您的个人信息。
|
||||
在确有必要共享时,我们会要求接收方遵守相应的数据保护义务。
|
||||
</p>
|
||||
|
||||
<h2>四、信息存储与保护</h2>
|
||||
<p>
|
||||
我们采取访问控制、加密存储、日志审计等安全措施保护您的信息。
|
||||
但请理解,互联网环境并非绝对安全,我们将持续提升安全能力。
|
||||
</p>
|
||||
|
||||
<h2>五、您的权利</h2>
|
||||
<ul>
|
||||
<li>您有权访问、更正、删除您的相关信息。</li>
|
||||
<li>您有权撤回授权并申请注销账号(法律法规另有规定除外)。</li>
|
||||
<li>您有权就隐私问题向我们提出咨询和投诉。</li>
|
||||
</ul>
|
||||
|
||||
<h2>六、协议更新</h2>
|
||||
<p>
|
||||
本隐私协议可能根据法律法规及业务变化进行更新。更新后将通过平台公告或页面提示方式发布。
|
||||
</p>
|
||||
|
||||
<h2>七、联系我们</h2>
|
||||
<p>
|
||||
如您对本隐私协议有疑问,可通过平台公开联系方式与我们联系。
|
||||
</p>
|
||||
|
||||
<div class="notice">
|
||||
提示:本文件为模板协议,请在上线前替换 {{ORG_NAME}}、{{PRODUCT_NAME}}、{{EFFECTIVE_DATE}} 等占位内容,并由法务审核。
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
142
web/public/protocols/user-agreement.template.html
Normal file
142
web/public/protocols/user-agreement.template.html
Normal file
@ -0,0 +1,142 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>用户协议</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #f5f7fb;
|
||||
--card: #ffffff;
|
||||
--text: #1f2937;
|
||||
--subtle: #6b7280;
|
||||
--line: #e5e7eb;
|
||||
--brand: #2563eb;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 960px;
|
||||
margin: 40px auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--card);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
padding: 28px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.meta {
|
||||
color: var(--subtle);
|
||||
font-size: 14px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 24px 0 10px;
|
||||
font-size: 20px;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0 0 12px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin-top: 24px;
|
||||
padding: 14px 16px;
|
||||
border-left: 3px solid var(--brand);
|
||||
background: #eff6ff;
|
||||
color: #1e3a8a;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--brand);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
<article class="card">
|
||||
<h1>用户协议</h1>
|
||||
<div class="meta">适用组织:{{ORG_NAME}} | 生效日期:{{EFFECTIVE_DATE}}</div>
|
||||
|
||||
<p>
|
||||
欢迎使用 {{PRODUCT_NAME}}。在使用本平台提供的服务前,请仔细阅读并充分理解本协议。
|
||||
您在登录、注册或继续使用本平台服务时,即视为已阅读并同意本协议全部内容。
|
||||
</p>
|
||||
|
||||
<h2>一、服务说明</h2>
|
||||
<p>
|
||||
本平台提供与知识库管理、知识图谱、智能问答等相关的技术服务。平台有权在合理范围内调整服务内容、服务方式或功能入口。
|
||||
</p>
|
||||
|
||||
<h2>二、账号与安全</h2>
|
||||
<ul>
|
||||
<li>您应提供真实、准确、完整的注册信息,并及时更新。</li>
|
||||
<li>您应妥善保管账号与密码,并对账号下的全部行为承担责任。</li>
|
||||
<li>若发现账号存在异常使用,请立即通知平台处理。</li>
|
||||
</ul>
|
||||
|
||||
<h2>三、使用规范</h2>
|
||||
<ul>
|
||||
<li>不得利用平台从事违法违规活动,不得侵害他人合法权益。</li>
|
||||
<li>不得上传、发布或传播含有恶意代码、侵权或其他非法内容的信息。</li>
|
||||
<li>不得干扰平台正常运行或绕过平台安全机制。</li>
|
||||
</ul>
|
||||
|
||||
<h2>四、知识产权</h2>
|
||||
<p>
|
||||
平台相关软件、技术、界面及文档的知识产权归平台或其权利人所有。未经许可,任何人不得擅自复制、修改、传播或用于其他商业用途。
|
||||
</p>
|
||||
|
||||
<h2>五、责任限制</h2>
|
||||
<p>
|
||||
在法律允许范围内,平台对因不可抗力、网络故障、第三方原因等导致的服务中断或数据异常不承担责任。
|
||||
</p>
|
||||
|
||||
<h2>六、协议变更</h2>
|
||||
<p>
|
||||
平台可根据业务发展和法律法规要求更新本协议。更新后的协议在发布后生效。若您继续使用服务,视为接受更新后的协议。
|
||||
</p>
|
||||
|
||||
<h2>七、联系我们</h2>
|
||||
<p>
|
||||
如您对本协议有任何疑问,请通过平台公布的联系方式与我们联系。
|
||||
</p>
|
||||
|
||||
<div class="notice">
|
||||
提示:本文件为模板协议,请在上线前替换 {{ORG_NAME}}、{{PRODUCT_NAME}}、{{EFFECTIVE_DATE}} 等占位内容,并由法务审核。
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@ -36,12 +36,12 @@ export const useInfoStore = defineStore('info', () => {
|
||||
const actions = computed(() => infoConfig.value.actions || [])
|
||||
|
||||
// 计算属性 - 页脚信息
|
||||
const footer = computed(
|
||||
() =>
|
||||
infoConfig.value.footer || {
|
||||
copyright: ''
|
||||
}
|
||||
)
|
||||
const footer = computed(() => ({
|
||||
copyright: '',
|
||||
user_agreement_url: '',
|
||||
privacy_policy_url: '',
|
||||
...(infoConfig.value.footer || {})
|
||||
}))
|
||||
|
||||
// 动作方法
|
||||
function setInfoConfig(newConfig) {
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<!-- 服务状态提示 -->
|
||||
<div v-if="serverStatus === 'error'" class="server-status-alert">
|
||||
<div class="alert-content">
|
||||
<exclamation-circle-outlined class="alert-icon" />
|
||||
<exclamation-circle-icon class="alert-icon" size="20" />
|
||||
<div class="alert-text">
|
||||
<div class="alert-title">服务端连接失败</div>
|
||||
<div class="alert-message">{{ serverError }}</div>
|
||||
@ -17,18 +17,14 @@
|
||||
<!-- 顶部导航:品牌名称 & 操作按钮 -->
|
||||
<nav class="login-navbar">
|
||||
<div class="navbar-content">
|
||||
<div class="brand-container">
|
||||
<div class="brand-container" @click="goHome" style="cursor: pointer">
|
||||
<img v-if="brandLogo" :src="brandLogo" alt="logo" class="brand-logo" />
|
||||
<h1 class="brand-text">
|
||||
<span v-if="brandOrgName" class="brand-org">{{ brandOrgName }}</span>
|
||||
<span v-if="brandOrgName && brandName !== brandOrgName" class="brand-separator"></span>
|
||||
<span class="brand-main">{{ brandName }}</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="login-top-action">
|
||||
<a-button type="text" size="small" class="back-home-btn" @click="goHome">
|
||||
返回首页
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@ -122,6 +118,30 @@
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="showAgreementConsent" class="agreement-form-item">
|
||||
<div class="agreement-row">
|
||||
<a-checkbox v-model:checked="agreementAccepted">
|
||||
登录即代表同意
|
||||
<a
|
||||
class="agreement-link"
|
||||
:href="userAgreementUrl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@click.stop
|
||||
>《用户协议》</a
|
||||
>
|
||||
<a
|
||||
class="agreement-link"
|
||||
:href="privacyPolicyUrl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@click.stop
|
||||
>《隐私协议》</a
|
||||
>
|
||||
</a-checkbox>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<a-button type="primary" html-type="submit" :loading="loading" block
|
||||
>创建管理员账户</a-button
|
||||
@ -140,7 +160,7 @@
|
||||
>
|
||||
<a-input v-model:value="loginForm.loginId" placeholder="用户ID或手机号">
|
||||
<template #prefix>
|
||||
<user-outlined />
|
||||
<user-icon size="18"/>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
@ -152,17 +172,32 @@
|
||||
>
|
||||
<a-input-password v-model:value="loginForm.password">
|
||||
<template #prefix>
|
||||
<lock-outlined />
|
||||
<lock-icon size="18" />
|
||||
</template>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<div class="login-options">
|
||||
<a-checkbox v-model:checked="rememberMe" @click="showDevMessage"
|
||||
>记住我</a-checkbox
|
||||
>
|
||||
<a class="forgot-password" @click="showDevMessage">忘记密码?</a>
|
||||
<a-form-item v-if="showAgreementConsent" class="agreement-form-item">
|
||||
<div class="agreement-row">
|
||||
<a-checkbox v-model:checked="agreementAccepted">
|
||||
登录即代表同意
|
||||
<a
|
||||
class="agreement-link"
|
||||
:href="userAgreementUrl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@click.stop
|
||||
>《用户协议》</a
|
||||
>
|
||||
<a
|
||||
class="agreement-link"
|
||||
:href="privacyPolicyUrl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@click.stop
|
||||
>《隐私协议》</a
|
||||
>
|
||||
</a-checkbox>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
@ -179,30 +214,6 @@
|
||||
<span v-else>登录</span>
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
|
||||
<!-- 第三方登录选项 -->
|
||||
<div class="third-party-login">
|
||||
<div class="divider">
|
||||
<span>其他登录方式</span>
|
||||
</div>
|
||||
<div class="login-icons">
|
||||
<a-tooltip title="微信登录">
|
||||
<a-button shape="circle" class="login-icon" @click="showDevMessage">
|
||||
<template #icon><wechat-outlined /></template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="企业微信登录">
|
||||
<a-button shape="circle" class="login-icon" @click="showDevMessage">
|
||||
<template #icon><qrcode-outlined /></template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="飞书登录">
|
||||
<a-button shape="circle" class="login-icon" @click="showDevMessage">
|
||||
<template #icon><thunderbolt-outlined /></template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
@ -222,10 +233,6 @@
|
||||
<a href="https://github.com/xerrors" target="_blank">联系我们</a>
|
||||
<span class="divider">|</span>
|
||||
<a href="https://github.com/xerrors/Yuxi-Know" target="_blank">使用帮助</a>
|
||||
<span class="divider">|</span>
|
||||
<a href="https://github.com/xerrors/Yuxi-Know/blob/main/LICENSE" target="_blank"
|
||||
>隐私政策</a
|
||||
>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
© {{ new Date().getFullYear() }} {{ brandName }}. All Rights Reserved.
|
||||
@ -243,13 +250,10 @@ import { useAgentStore } from '@/stores/agent'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { healthApi } from '@/apis/system_api'
|
||||
import {
|
||||
UserOutlined,
|
||||
LockOutlined,
|
||||
WechatOutlined,
|
||||
QrcodeOutlined,
|
||||
ThunderboltOutlined,
|
||||
ExclamationCircleOutlined
|
||||
} from '@ant-design/icons-vue'
|
||||
User as UserIcon,
|
||||
Lock as LockIcon,
|
||||
AlertCircle as ExclamationCircleIcon
|
||||
} from 'lucide-vue-next'
|
||||
const router = useRouter()
|
||||
const userStore = useUserStore()
|
||||
const infoStore = useInfoStore()
|
||||
@ -259,6 +263,9 @@ const agentStore = useAgentStore()
|
||||
const loginBgImage = computed(() => {
|
||||
return infoStore.organization?.login_bg || '/login-bg.jpg'
|
||||
})
|
||||
const brandLogo = computed(() => {
|
||||
return infoStore.organization?.logo || ''
|
||||
})
|
||||
const brandOrgName = computed(() => {
|
||||
return infoStore.organization?.name?.trim() || ''
|
||||
})
|
||||
@ -272,22 +279,21 @@ const brandName = computed(() => {
|
||||
|
||||
return orgName || brandNameRaw
|
||||
})
|
||||
const brandSubtitle = computed(() => {
|
||||
const rawSubtitle = infoStore.branding?.subtitle ?? ''
|
||||
const trimmed = rawSubtitle.trim()
|
||||
return trimmed || '大模型驱动的知识库管理工具'
|
||||
const userAgreementUrl = computed(() => {
|
||||
return infoStore.footer?.user_agreement_url?.trim() || ''
|
||||
})
|
||||
const brandDescription = computed(() => {
|
||||
const rawDescription = infoStore.branding?.description ?? ''
|
||||
const trimmed = rawDescription.trim()
|
||||
return trimmed || '结合知识库与知识图谱,提供更准确、更全面的回答'
|
||||
const privacyPolicyUrl = computed(() => {
|
||||
return infoStore.footer?.privacy_policy_url?.trim() || ''
|
||||
})
|
||||
const showAgreementConsent = computed(() => {
|
||||
return Boolean(userAgreementUrl.value && privacyPolicyUrl.value)
|
||||
})
|
||||
|
||||
// 状态
|
||||
const isFirstRun = ref(false)
|
||||
const loading = ref(false)
|
||||
const errorMessage = ref('')
|
||||
const rememberMe = ref(false)
|
||||
const agreementAccepted = ref(false)
|
||||
const serverStatus = ref('loading')
|
||||
const serverError = ref('')
|
||||
const healthChecking = ref(false)
|
||||
@ -311,11 +317,6 @@ const adminForm = reactive({
|
||||
phone_number: '' // 手机号字段(可选)
|
||||
})
|
||||
|
||||
// 开发中功能提示
|
||||
const showDevMessage = () => {
|
||||
message.info('该功能正在开发中,敬请期待!')
|
||||
}
|
||||
|
||||
const goHome = () => {
|
||||
router.push('/')
|
||||
}
|
||||
@ -373,6 +374,16 @@ const validateConfirmPassword = async (rule, value) => {
|
||||
}
|
||||
}
|
||||
|
||||
const ensureAgreementAccepted = () => {
|
||||
if (!showAgreementConsent.value || agreementAccepted.value) {
|
||||
return true
|
||||
}
|
||||
|
||||
const warningMessage = '请先阅读并同意《用户协议》《隐私协议》'
|
||||
message.warning(warningMessage)
|
||||
return false
|
||||
}
|
||||
|
||||
// 处理登录
|
||||
const handleLogin = async () => {
|
||||
// 如果当前被锁定,不允许登录
|
||||
@ -381,6 +392,10 @@ const handleLogin = async () => {
|
||||
return
|
||||
}
|
||||
|
||||
if (!ensureAgreementAccepted()) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
loading.value = true
|
||||
errorMessage.value = ''
|
||||
@ -473,6 +488,10 @@ const handleLogin = async () => {
|
||||
|
||||
// 处理初始化管理员
|
||||
const handleInitialize = async () => {
|
||||
if (!ensureAgreementAccepted()) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
loading.value = true
|
||||
errorMessage.value = ''
|
||||
@ -585,6 +604,11 @@ onUnmounted(() => {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.brand-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -616,6 +640,18 @@ onUnmounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.brand-logo {
|
||||
height: 32px;
|
||||
width: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.top-logo {
|
||||
height: 32px;
|
||||
width: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.back-home-btn {
|
||||
color: var(--gray-600);
|
||||
font-size: 14px;
|
||||
@ -711,6 +747,10 @@ onUnmounted(() => {
|
||||
font-size: 16px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
:deep(.ant-input-prefix) {
|
||||
margin-right: 8px;
|
||||
color: var(--gray-500);
|
||||
}
|
||||
}
|
||||
|
||||
.third-party-login {
|
||||
@ -767,15 +807,28 @@ onUnmounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.login-options {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
.agreement-form-item {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.forgot-password {
|
||||
.agreement-row {
|
||||
font-size: 13px;
|
||||
color: var(--gray-600);
|
||||
line-height: 1.6;
|
||||
|
||||
:deep(.ant-checkbox-wrapper) {
|
||||
display: inline-flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
:deep(.ant-checkbox + span) {
|
||||
padding-inline-start: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.agreement-link {
|
||||
color: var(--main-color);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user