V001
This commit is contained in:
1 parent
d5d4a6f3bf
commit
fb1a79a3e9
27 files changed
+708
-75
No files matched your search
@@ -0,0 +1,305 @@
|
||||
<template>
|
||||
<div class="ep" :class="'ep--' + tone">
|
||||
<!-- 顶部渐变头图:品牌 + 大号状态码,延续首页 hero 的视觉语言 -->
|
||||
<header class="ep-hero">
|
||||
<div class="ep-hero-inner">
|
||||
<div class="ep-brand">
|
||||
<a-avatar shape="square" :size="26" src="/youjia.svg" />
|
||||
<span>{{ siteTitle }}</span>
|
||||
</div>
|
||||
<div class="ep-code">{{ code }}</div>
|
||||
<div class="ep-tag">{{ badge }}</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 悬浮卡片:图标 + 说明 + 可能原因 + 操作 -->
|
||||
<section class="ep-card">
|
||||
<div class="ep-icon">
|
||||
<slot name="icon" />
|
||||
</div>
|
||||
|
||||
<h1 class="ep-title">{{ title }}</h1>
|
||||
<p class="ep-desc">{{ description }}</p>
|
||||
|
||||
<div v-if="reasons && reasons.length" class="ep-reasons">
|
||||
<div class="ep-reasons-title">可能的原因</div>
|
||||
<ul>
|
||||
<li v-for="(item, i) in reasons" :key="i">{{ item }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p v-if="from" class="ep-from">
|
||||
出错的地址:<code>{{ from }}</code>
|
||||
</p>
|
||||
|
||||
<div class="ep-actions">
|
||||
<slot name="actions" />
|
||||
</div>
|
||||
|
||||
<p v-if="hint" class="ep-hint">{{ hint }}</p>
|
||||
</section>
|
||||
|
||||
<footer class="ep-footer">
|
||||
<span>{{ copy }}</span>
|
||||
<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">{{ beian }}</a>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { WebSitePolicy } from "@/policy/custom/webSitePolicy";
|
||||
|
||||
/**
|
||||
* 错误页通用外壳(401 / 403 / 404 共用)。
|
||||
* 只负责排版与主题,具体文案、图标、按钮由三个错误页各自提供。
|
||||
*/
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
/** 状态码,如 401 */
|
||||
code: string;
|
||||
/** 状态码下方的短标签,如「未认证」 */
|
||||
badge?: string;
|
||||
/** 主题色:blue(品牌蓝青,默认)/ amber(警示)/ violet(找不到) */
|
||||
tone?: "blue" | "amber" | "violet";
|
||||
/** 主标题:一句话说清出了什么问题 */
|
||||
title: string;
|
||||
/** 副标题:补充说明 */
|
||||
description?: string;
|
||||
/** 可能的原因清单 */
|
||||
reasons?: string[];
|
||||
/** 出错的地址(404 用 ?from= 带过来) */
|
||||
from?: string;
|
||||
/** 兜底提示,如「如需权限请联系管理员」 */
|
||||
hint?: string;
|
||||
}>(),
|
||||
{ badge: "", tone: "blue", description: "", reasons: () => [], from: "", hint: "" },
|
||||
);
|
||||
|
||||
const siteTitle = WebSitePolicy.Title;
|
||||
const copy = WebSitePolicy.Copy;
|
||||
const beian = WebSitePolicy.Beian;
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ep {
|
||||
/* 主题色:默认品牌蓝→青渐变,amber / violet 用于区分不同错误类型 */
|
||||
--ep-from: #1677ff;
|
||||
--ep-to: #36cfc9;
|
||||
--ep-shadow: rgba(22, 119, 255, 0.18);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
background: #f5f6f8;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.ep--amber {
|
||||
--ep-from: #fa8c16;
|
||||
--ep-to: #ffc53d;
|
||||
--ep-shadow: rgba(250, 140, 22, 0.18);
|
||||
}
|
||||
|
||||
.ep--violet {
|
||||
--ep-from: #722ed1;
|
||||
--ep-to: #b37feb;
|
||||
--ep-shadow: rgba(114, 46, 209, 0.18);
|
||||
}
|
||||
|
||||
/* ---------- 头图 ---------- */
|
||||
.ep-hero {
|
||||
padding: 16px 16px 44px;
|
||||
border-radius: 0 0 22px 22px;
|
||||
background: linear-gradient(135deg, var(--ep-from) 0%, var(--ep-to) 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 6px 18px var(--ep-shadow);
|
||||
}
|
||||
|
||||
.ep-hero-inner {
|
||||
width: 100%;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.ep-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
.ep-code {
|
||||
margin-top: 8px;
|
||||
font-size: 52px;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
letter-spacing: 2px;
|
||||
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.ep-tag {
|
||||
margin-top: 6px;
|
||||
font-size: 12px;
|
||||
letter-spacing: 1px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* ---------- 悬浮卡片 ---------- */
|
||||
.ep-card {
|
||||
flex: 0 0 auto;
|
||||
margin: -28px 16px 18px;
|
||||
padding: 18px 16px 20px;
|
||||
border-radius: 20px;
|
||||
background: #fff;
|
||||
box-shadow: 0 8px 24px rgba(15, 35, 60, 0.08);
|
||||
}
|
||||
|
||||
.ep-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-bottom: 12px;
|
||||
border-radius: 14px;
|
||||
font-size: 24px;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--ep-from) 0%, var(--ep-to) 100%);
|
||||
box-shadow: 0 2px 8px var(--ep-shadow);
|
||||
}
|
||||
|
||||
.ep-title {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
line-height: 1.4;
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
.ep-desc {
|
||||
margin: 6px 0 0;
|
||||
font-size: 13.5px;
|
||||
line-height: 1.65;
|
||||
color: #646a73;
|
||||
}
|
||||
|
||||
.ep-reasons {
|
||||
margin-top: 14px;
|
||||
padding: 12px 12px 10px;
|
||||
border: 1px solid #eef0f4;
|
||||
border-radius: 14px;
|
||||
background: #f7f9fc;
|
||||
}
|
||||
|
||||
.ep-reasons-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-bottom: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
.ep-reasons-title::before {
|
||||
content: "";
|
||||
width: 3px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
background: var(--ep-from);
|
||||
}
|
||||
|
||||
.ep-reasons ul {
|
||||
margin: 0;
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
.ep-reasons li {
|
||||
margin: 4px 0;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
color: #646a73;
|
||||
}
|
||||
|
||||
.ep-from {
|
||||
margin: 12px 0 0;
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
color: #8a919f;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.ep-from code {
|
||||
padding: 1px 6px;
|
||||
border-radius: 6px;
|
||||
background: #f2f4f8;
|
||||
color: #1f2329;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.ep-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.ep-hint {
|
||||
margin: 14px 0 0;
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
color: #8a919f;
|
||||
}
|
||||
|
||||
/* ---------- 底部信息 ---------- */
|
||||
.ep-footer {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 4px;
|
||||
padding: 0 16px 14px;
|
||||
font-size: 11px;
|
||||
line-height: 16px;
|
||||
color: #8a919f;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ep-footer a {
|
||||
color: #8a919f;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: #1677ff;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- 宽屏(手机优先,这里只是放大与居中) ---------- */
|
||||
@media (min-width: 576px) {
|
||||
.ep-hero {
|
||||
padding: 22px 24px 56px;
|
||||
}
|
||||
|
||||
.ep-code {
|
||||
font-size: 64px;
|
||||
}
|
||||
|
||||
.ep-card {
|
||||
width: 100%;
|
||||
max-width: 460px;
|
||||
margin: -34px auto 20px;
|
||||
padding: 22px 22px 24px;
|
||||
}
|
||||
|
||||
/* 宽屏按钮横排,主操作在左,更符合桌面习惯 */
|
||||
.ep-actions {
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
gap: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user