feat: 更新App.vue和BiliAuthView.vue组件,优化主题颜色和认证流程界面

- 在App.vue中调整主题颜色设置,提升可读性和对比度
- 在BiliAuthView.vue中重构认证流程界面,增强用户体验,添加响应式设计
- 更新IndexView.vue和ManageLayout.vue中的按钮和提示信息,提升界面一致性
- 在PointUserLayout.vue中优化认证提示信息,明确用户操作步骤
This commit is contained in:
Megghy
2025-06-12 09:30:43 +08:00
parent 8fd182acae
commit 9583280323
5 changed files with 579 additions and 221 deletions

View File

@@ -63,45 +63,48 @@ watchEffect(() => {
const themeOverrides = computed(() => { const themeOverrides = computed(() => {
return { return {
common: { common: {
// 主色调 (中蓝色基调,调整对比) // 主色调 (中蓝色基调,提升可读性并增强对比)
primaryColor: '#5A7A9E', primaryColor: '#4D6E9C',
primaryColorHover: '#7390B1', // 略微提亮悬浮色 primaryColorHover: '#6483A9', // 略微提亮悬浮色
primaryColorPressed: '#4F7094', // 调整按下色,避免在暗色模式下过暗 primaryColorPressed: '#365A7D', // 调整按下色,避免在暗色模式下过暗
primaryColorSuppl: '#8CA6C1', // 调整补充色,使其与背景有区分 primaryColorSuppl: '#809BC1', // 调整补充色,使其与背景有区分
// 信息色 (浅蓝色基调,调整对比度) // 信息色 (浅蓝色基调,提升对比度)
infoColor: '#8CB1C7', // 稍微加深基础信息 infoColorHover: '#79AFDE', // 提亮悬浮
infoColorHover: '#A6C3D6', // 提亮悬浮 infoColorPressed: '#4B8AC3', // 调整按下
infoColorPressed: '#7DA0B5', // 调整按下色
infoColorSuppl: '#D0DDE8', // 调整补充色
// 成功色 (柔和青绿) // 成功色 (柔和青绿, 增强对比)
successColor: '#4DB6AC', successColor: '#3AA89C',
successColorHover: '#6BC4B9', // 调整悬浮色 successColorHover: '#5AB9AE', // 调整悬浮色
successColorPressed: '#3E9A90', // 调整按下色 successColorPressed: '#2C8C82', // 调整按下色
successColorSuppl: '#C1E7E2', // 调整补充色 successColorSuppl: '#B4E4DF', // 调整补充色
// 警告色 (柔和橙色) // 警告色 (柔和橙色, 微调对比)
warningColor: '#FFB74D', warningColor: '#FFA64D',
warningColorHover: '#FFC870', // 调整悬浮色 warningColorHover: '#FFBA70', // 调整悬浮色
warningColorPressed: '#F8A830', // 调整按下色 warningColorPressed: '#E89530', // 调整按下色
warningColorSuppl: '#FFE9C7', // 调整补充色 warningColorSuppl: '#FFE2C2', // 调整补充色
// 错误色 (柔和红色)
errorColor: '#E57373',
errorColorHover: '#EC8F8F', // 调整悬浮色
errorColorPressed: '#D96060', // 调整按下色
errorColorSuppl: '#F5C7C7', // 调整补充色
// 错误色 (柔和红色, 微调对比)
errorColor: '#E16565',
errorColorHover: '#EA8282', // 调整悬浮色
errorColorPressed: '#D44848', // 调整按下色
errorColorSuppl: '#F3C0C0', // 调整补充色
// 保持字体设置 // 保持字体设置
fontFamily: fontFamily:
'Inter ,"Noto Sans SC",-apple-system,blinkmacsystemfont,"Segoe UI",roboto,"Helvetica Neue",arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"!important', 'Inter ,"Noto Sans SC",-apple-system,blinkmacsystemfont,"Segoe UI",roboto,"Helvetica Neue",arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"!important',
// 文本颜色 (提升可读性, 但不过度突兀)
textColorBase: isDarkMode.value ? '#ECECEC' : '#333333',
textColor1: isDarkMode.value ? '#E6E6E6' : '#333333',
textColor2: isDarkMode.value ? '#CCCCCC' : '#4F4F4F',
textColor3: isDarkMode.value ? '#AAAAAA' : '#656565',
}, },
Tooltip: { Tooltip: {
color: isDarkMode.value ? '#48484e' : '#FFFFFF', color: isDarkMode.value ? '#48484e' : '#FFFFFF',
textColor: isDarkMode.value ? '#FFFFFF' : '#333639', textColor: isDarkMode.value ? '#FFFFFF' : '#333333',
} },
}; };
}) })
const body = document.body; const body = document.body;

View File

@@ -31,7 +31,7 @@ type AuthStartModel = {
const message = useMessage() const message = useMessage()
const breakpoints = useVueUseBreakpoints(breakpointsTailwind) const breakpoints = useVueUseBreakpoints(breakpointsTailwind)
const isSmallScreen = breakpoints.smaller('sm') const isSmallScreen = breakpoints.smaller('md')
const guidKey = useStorage('Bili.Auth.Key', uuidv4()) const guidKey = useStorage('Bili.Auth.Key', uuidv4())
const currentToken = useStorage<string>('Bili.Auth.Selected', null) const currentToken = useStorage<string>('Bili.Auth.Selected', null)
@@ -122,189 +122,221 @@ onMounted(async () => {
</script> </script>
<template> <template>
<NFlex <div class="auth-container">
justify="center"
align="center"
style="min-height: 100vh; padding: 20px; box-sizing: border-box"
>
<NCard <NCard
embedded embedded
style="width: 100%; max-width: 1000px" class="auth-card"
> >
<template #header> <template #header>
<NText style="font-size: 1.2em; font-weight: bold"> <div class="auth-header">
Bilibili 身份验证 <NText class="auth-title">
</NText> Bilibili 身份验证
</NText>
</div>
</template> </template>
<NFlex
:wrap="false" <div class="auth-content">
:vertical="isSmallScreen" <!-- 步骤指示器 -->
> <div class="steps-container">
<NSteps <NSteps
:current="currentStep + 1" :current="currentStep + 1"
vertical vertical
style="min-width: 200px; max-width: 300px; margin-bottom: 20px" :size="isSmallScreen ? 'small' : 'medium'"
> class="auth-steps"
<NStep >
title="准备认证" <NStep
description="就是开始认证前的一个步骤" title="准备认证"
/> description="开始认证前的准备工作"
<NStep />
title="进行认证" <NStep
description="你需要在指定直播间输入一串验证码来证明自己的身份" title="进行认证"
/> description="在指定直播间输入验证码"
<NStep />
title="认证完成" <NStep
description="现在就已经通过了认证!" title="认证完成"
/> description="验证成功,获取登录链接"
</NSteps> />
<div style="flex-grow: 1; padding-left: 20px; border-left: 1px solid var(--n-border-color); min-width: 0;"> </NSteps>
<template v-if="currentStep == 1"> </div>
<NFlex
vertical <!-- 内容区域 -->
justify="center" <div class="content-container">
align="center" <!-- 步骤1: 进行认证 -->
style="width: 100%; height: 100%; padding-top: 20px; min-height: 250px;" <div
> v-if="currentStep === 1"
<template v-if="!timeOut"> class="step-content"
>
<template v-if="!timeOut">
<div class="auth-progress">
<NSpin size="large" /> <NSpin size="large" />
<NText style="margin-top: 15px; font-size: 1.1em;"> <NText class="countdown-text">
剩余时间<NCountdown :duration="timeLeft" /> 剩余时间<NCountdown :duration="timeLeft" />
</NText> </NText>
</div>
<div class="verification-section">
<NText <NText
depth="3" depth="2"
style="margin-top: 20px;" class="instruction-text"
> >
请复制下方的认证码并前往指定直播间发送 请复制下方的认证码并前往指定直播间发送
</NText> </NText>
<NInputGroup style="margin-top: 10px; max-width: 300px;">
<NInput <div class="code-input-section">
:value="startModel?.code" <NInputGroup class="code-input-group">
readonly <NInput
placeholder="认证码" :value="startModel?.code"
style="text-align: center; font-size: 1.2em; letter-spacing: 2px;" readonly
/> placeholder="认证码"
<NButton class="code-input"
type="primary" />
@click="copyCode" <NButton
> type="primary"
复制 class="copy-button"
</NButton> @click="copyCode"
</NInputGroup> >
复制
</NButton>
</NInputGroup>
</div>
<NButton <NButton
type="info" type="info"
tag="a" tag="a"
:href="'https://live.bilibili.com/' + startModel?.targetRoomId" :href="'https://live.bilibili.com/' + startModel?.targetRoomId"
target="_blank" target="_blank"
style="margin-top: 20px" class="live-room-button"
size="large"
> >
前往直播间 前往直播间
</NButton> </NButton>
</template> </div>
<NAlert </template>
v-else
type="error" <NAlert
title="认证超时" v-else
style="width: 100%; max-width: 400px;" type="error"
> title="认证超时"
<NFlex justify="center"> class="timeout-alert"
<NButton
type="error"
style="margin-top: 10px"
@click="
() => {
currentStep = 0
timeOut = false
}
"
>
重新开始认证
</NButton>
</NFlex>
</NAlert>
</NFlex>
</template>
<template v-else-if="currentStep == 0">
<NSpace
vertical
align="stretch"
style="width: 100%; padding-top: 10px"
> >
<NAlert type="info"> <div class="timeout-content">
<NText> <NText depth="3">
点击 认证时间已过请重新开始认证流程
<NText
type="primary"
strong
>
开始认证
</NText>
后请在 5 分钟之内使用
<NText
strong
type="primary"
>
需要认证的账户
</NText>
在指定的直播间直播间内发送给出的验证码
</NText> </NText>
</NAlert> <NButton
<NFlex type="error"
justify="center" size="large"
style="margin-top: 20px" class="restart-button"
@click="
() => {
currentStep = 0
timeOut = false
}
"
>
重新开始认证
</NButton>
</div>
</NAlert>
</div>
<!-- 步骤0: 准备认证 -->
<div
v-else-if="currentStep === 0"
class="step-content"
>
<div class="start-section">
<NAlert
type="info"
class="info-alert"
> >
<div class="info-content">
<NText>
点击 <NText
type="primary"
strong
>
开始认证
</NText> 后请在 5 分钟之内使用
<NText
strong
type="primary"
>
需要认证的B站账户
</NText>
在指定的直播间内发送给出的验证码
</NText>
</div>
</NAlert>
<div class="start-button-section">
<NButton <NButton
size="large" size="large"
type="primary" type="primary"
class="start-button"
@click="onStartVerify" @click="onStartVerify"
> >
开始认证 开始认证
</NButton> </NButton>
</NFlex> </div>
</NSpace> </div>
</template> </div>
<template v-else-if="currentStep == 2">
<NSpace <!-- 步骤2: 认证完成 -->
vertical <div
align="stretch" v-else-if="currentStep === 2"
style="width: 100%; padding-top: 10px" class="step-content"
> >
<div class="success-section">
<NAlert <NAlert
type="success" type="success"
title="验证成功!" title="验证成功!"
style="margin-bottom: 15px" class="success-alert"
> >
你已完成验证! 请妥善保存你的登陆链接, 请勿让其他人获取. 丢失后可以再次通过认证流程获得. <div class="success-content">
<br> <NText>
要在其他地方登陆, 或者需要重新登陆的话把这个链接复制到浏览器地址栏打开即可 您已完成验证请妥善保存您的登录链接请勿让其他人获取
丢失后可以再次通过认证流程获得
</NText>
<br><br>
<NText depth="2">
要在其他地方登录或者需要重新登录时
请将此链接复制到浏览器地址栏打开即可
</NText>
</div>
</NAlert> </NAlert>
<NText strong>
你的登陆链接为: <div class="login-link-section">
</NText> <NText
<NInput strong
:value="`${CURRENT_HOST}bili-user?auth=${currentToken}`" class="link-label"
type="textarea"
readonly
style="margin-top: 5px"
/>
<NFlex
justify="end"
style="margin-top: 10px"
>
<NButton
type="primary"
@click="copyCode"
> >
复制登陆链接 您的登录链接
</NButton> </NText>
</NFlex> <NInput
<NFlex :value="`${CURRENT_HOST}bili-user?auth=${currentToken}`"
justify="center" type="textarea"
style="margin-top: 20px" readonly
:wrap="true" class="login-link-input"
> :autosize="{ minRows: 2, maxRows: 4 }"
/>
<div class="link-actions">
<NButton
type="primary"
size="large"
class="copy-link-button"
@click="copyCode"
>
复制登录链接
</NButton>
</div>
</div>
<div class="action-buttons">
<NButton <NButton
type="primary" type="primary"
size="large"
class="dashboard-button"
@click="$router.push({ name: 'bili-user' })" @click="$router.push({ name: 'bili-user' })"
> >
前往个人中心 前往个人中心
@@ -322,17 +354,285 @@ onMounted(async () => {
" "
> >
<template #trigger> <template #trigger>
<NButton type="warning"> <NButton
type="warning"
size="large"
class="auth-other-button"
>
认证其他账号 认证其他账号
</NButton> </NButton>
</template> </template>
这将会登出当前已认证的账号, 请先在认证其他账号前保存的登链接 这将会登出当前已认证的账号请先保存的登链接再认证其他账号
</NPopconfirm> </NPopconfirm>
</NFlex> </div>
</NSpace> </div>
</template> </div>
</div> </div>
</NFlex> </div>
</NCard> </NCard>
</NFlex> </div>
</template> </template>
<style scoped>
.auth-container {
min-height: 100vh;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(135deg, var(--n-color-target) 0%, var(--n-modal-color) 100%);
}
.auth-card {
width: 100%;
max-width: 1000px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
border-radius: 12px;
}
.auth-header {
text-align: center;
padding: 10px 0;
}
.auth-title {
font-size: 1.5em;
font-weight: 600;
color: var(--n-text-color);
}
.auth-content {
display: flex;
gap: 30px;
min-height: 400px;
border-top: 1px solid var(--n-border-color);
}
.steps-container {
flex-shrink: 0;
min-width: 240px;
display: flex;
justify-content: center;
align-items: center;
}
.auth-steps {
padding: 20px 0;
}
.content-container {
flex: 1;
padding-left: 30px;
border-left: 1px solid var(--n-border-color);
display: flex;
margin-top: 20px;
align-items: center;
justify-content: center;
}
.step-content {
width: 100%;
max-width: 500px;
}
/* 进行认证步骤样式 */
.auth-progress {
text-align: center;
margin-bottom: 40px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.countdown-text {
margin-top: 20px;
font-size: 1.1em;
font-weight: 500;
}
.verification-section {
text-align: center;
}
.instruction-text {
margin-bottom: 20px;
line-height: 1.6;
}
.code-input-section {
margin: 25px 0;
}
.code-input-group {
max-width: 320px;
margin: 0 auto;
}
.code-input {
text-align: center;
font-size: 1.3em;
letter-spacing: 3px;
font-weight: 600;
}
.copy-button {
font-weight: 500;
}
.live-room-button {
margin-top: 25px;
font-weight: 500;
padding: 0 30px;
}
.timeout-alert {
text-align: center;
}
.timeout-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.restart-button {
font-weight: 500;
padding: 0 30px;
}
/* 准备认证步骤样式 */
.start-section {
text-align: center;
}
.info-alert {
margin-bottom: 30px;
}
.info-content {
line-height: 1.7;
}
.start-button-section {
margin-top: 30px;
}
.start-button {
font-weight: 500;
padding: 0 40px;
height: 50px;
font-size: 1.1em;
}
/* 认证完成步骤样式 */
.success-section {
text-align: center;
}
.success-alert {
margin-bottom: 30px;
text-align: left;
}
.success-content {
line-height: 1.7;
}
.login-link-section {
margin-bottom: 30px;
text-align: left;
}
.link-label {
display: block;
margin-bottom: 10px;
font-size: 1.05em;
}
.login-link-input {
margin-bottom: 15px;
font-family: monospace;
}
.link-actions {
text-align: right;
}
.copy-link-button {
font-weight: 500;
}
.action-buttons {
display: flex;
gap: 15px;
justify-content: center;
flex-wrap: wrap;
}
.dashboard-button,
.auth-other-button {
font-weight: 500;
padding: 0 25px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.auth-container {
padding: 15px;
}
.auth-content {
flex-direction: column;
gap: 20px;
min-height: auto;
}
.steps-container {
min-width: auto;
}
.content-container {
padding-left: 0;
border-left: none;
border-top: 1px solid var(--n-border-color);
padding-top: 20px;
}
.auth-title {
font-size: 1.3em;
}
.code-input {
font-size: 1.1em;
letter-spacing: 2px;
}
.action-buttons {
flex-direction: column;
align-items: stretch;
}
.dashboard-button,
.auth-other-button {
width: 100%;
}
}
@media (max-width: 480px) {
.auth-container {
padding: 10px;
}
.start-button {
width: 100%;
max-width: 280px;
}
.live-room-button {
width: 100%;
max-width: 200px;
}
}
</style>

View File

@@ -153,47 +153,95 @@ onMounted(async () => {
一个给主播提供便利功能的网站 😊 一个给主播提供便利功能的网站 😊
</NText> </NText>
<span /> <span />
<!-- 主播 / 观众入口 -->
<NSpace <NSpace
justify="center" justify="center"
align="center" align="center"
> >
<NSpace align="center"> <NFlex
<NSpace :wrap="false"
vertical justify="center"
justify="end" align="center"
> style="gap: 24px; margin-top: 10px;"
<NText >
style="font-size: medium" <!-- 主播入口 -->
italic <NTooltip placement="bottom">
> <template #trigger>
我是主播 <NCard
</NText> hoverable
<NButton style="width: 240px; background: rgba(255, 255, 255, 0.15); cursor: pointer; border: none;"
type="primary" @click="$router.push({ name: 'manage-index' })"
size="small" >
@click="$router.push({ name: 'manage-index' })" <NFlex
> vertical
开始使用 align="center"
</NButton> justify="center"
</NSpace> :size="8"
<NSpace vertical> >
<NText <NIcon
style="font-size: medium" :component="PersonFeedback24Filled"
italic size="36"
> color="white"
我是观众 />
</NText> <NText style="font-size: 1.2rem; font-weight: 500; color: white;">
<NButton 我是主播
type="primary" </NText>
size="small" <NButton
secondary type="primary"
bordered secondary
@click="$router.push({ name: 'bili-user' })" size="small"
> >
用户主页 开始使用
</NButton> </NButton>
</NSpace> </NFlex>
</NSpace> </NCard>
</template>
进入主播后台管理直播相关工具与设置
</NTooltip>
<!-- 观众入口 -->
<NTooltip placement="bottom">
<template #trigger>
<NCard
hoverable
style="width: 240px; background: rgba(255, 255, 255, 0.15); cursor: pointer; border: none;"
@click="$router.push({ name: 'bili-user' })"
>
<NFlex
vertical
align="center"
justify="center"
:size="8"
>
<NIcon
:component="Chat24Filled"
size="36"
color="white"
/>
<NText style="font-size: 1.2rem; font-weight: 500; color: white;">
我是观众
</NText>
<NButton
type="info"
secondary
size="small"
>
用户主页
</NButton>
</NFlex>
</NCard>
</template>
进入个人主页查看积分与互动记录
</NTooltip>
</NFlex>
</NSpace>
<!-- 其他操作按钮 -->
<NSpace
justify="center"
align="center"
style="margin-top: 20px;"
>
<NButton <NButton
size="large" size="large"
@click="$router.push('/@Megghy')" @click="$router.push('/@Megghy')"
@@ -491,7 +539,9 @@ onMounted(async () => {
<style lang="stylus" scoped> <style lang="stylus" scoped>
.index-background .index-background
display: abslute; position: relative;
/* 保证全屏高度,避免底部留白 */
min-height: 100vh;
background: #8360c3; /* fallback for old browsers */ background: #8360c3; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #2ebf91, #8360c3); /* Chrome 10-25, Safari 5.1-6 */ background: -webkit-linear-gradient(to right, #2ebf91, #8360c3); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #2ebf91, #8360c3); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ background: linear-gradient(to right, #2ebf91, #8360c3); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */

View File

@@ -604,7 +604,12 @@ onMounted(() => {
depth="3" depth="3"
style="text-align: center; margin-top: 8px;" style="text-align: center; margin-top: 8px;"
> >
我们已向您的邮箱发送了验证链接请查收并点击链接完成验证 我们已向您的邮箱 <NText
type="primary"
strong
>
{{ accountInfo?.bindEmail }}
</NText> 发送了验证链接请查收并点击链接完成验证
</NText> </NText>
</NFlex> </NFlex>

View File

@@ -279,7 +279,7 @@ onMounted(async () => {
<NResult <NResult
status="error" status="error"
title="你还未进行过B站账户验证" title="你还未进行过B站账户验证"
description="请先进行认证" description="请先进行认证. 如果你已经认证过, 请直接访问认证完成时给出的链接"
style="padding-top: 64px" style="padding-top: 64px"
> >
<template #footer> <template #footer>