修复官网选购咨询入口与图片失败降级
This commit is contained in:
1 parent
d8224ec5b7
commit
08ffc51894
5 files changed
+463
-89
No files matched your search
@@ -0,0 +1,25 @@
|
||||
<script setup>
|
||||
/** 官网可配置图片统一处理加载失败;替代内容由调用处提供,不伪造头像或二维码。 */
|
||||
import { ref, watch } from "vue";
|
||||
|
||||
defineOptions({ inheritAttrs: false });
|
||||
const props = defineProps({ src: String, alt: String });
|
||||
const failed = ref(false);
|
||||
watch(
|
||||
() => props.src,
|
||||
() => {
|
||||
failed.value = false;
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<img
|
||||
v-if="src && !failed"
|
||||
v-bind="$attrs"
|
||||
:src="src"
|
||||
:alt="alt"
|
||||
@error="failed = true"
|
||||
/>
|
||||
<slot v-else />
|
||||
</template>
|
||||
@@ -22,6 +22,7 @@ import { createVNode } from "vue";
|
||||
import { openBlock } from "vue";
|
||||
import { normalizeStyle } from "vue";
|
||||
import { NuxtLink } from "#components";
|
||||
import OfficialImage from "~/components/OfficialImage.vue";
|
||||
import { i as useOfficialSiteContent_i } from "~/lib/useOfficialSiteContent.js";
|
||||
import { n as useOfficialSiteContent_n } from "~/lib/useOfficialSiteContent.js";
|
||||
import { r as useOfficialSiteContent_r } from "~/lib/useOfficialSiteContent.js";
|
||||
@@ -32,7 +33,6 @@ var S = {
|
||||
C = {
|
||||
class: `official-header-inner`,
|
||||
},
|
||||
w = [`src`, `alt`],
|
||||
T = {
|
||||
key: 1,
|
||||
class: `official-brand-mark`,
|
||||
@@ -69,7 +69,6 @@ var S = {
|
||||
I = {
|
||||
class: `official-footer-brand`,
|
||||
},
|
||||
te = [`src`, `alt`],
|
||||
L = {
|
||||
key: 1,
|
||||
class: `official-brand-mark`,
|
||||
@@ -94,7 +93,6 @@ var S = {
|
||||
key: 3,
|
||||
class: `official-footer-qr`,
|
||||
},
|
||||
K = [`src`, `alt`],
|
||||
q = {
|
||||
class: `official-footer-bottom`,
|
||||
},
|
||||
@@ -149,28 +147,26 @@ var S = {
|
||||
},
|
||||
{
|
||||
default: withCtx(() => [
|
||||
unref($)
|
||||
? (openBlock(),
|
||||
createElementBlock(
|
||||
`img`,
|
||||
{
|
||||
key: 0,
|
||||
class: `official-brand-image`,
|
||||
src: unref($),
|
||||
alt: unref(Y).brand.name,
|
||||
},
|
||||
null,
|
||||
8,
|
||||
w,
|
||||
))
|
||||
: (openBlock(),
|
||||
createElementBlock(`span`, T, [
|
||||
...(i[3] ||= [
|
||||
createElementVNode(`span`, null, null, -1),
|
||||
createElementVNode(`span`, null, null, -1),
|
||||
createElementVNode(`span`, null, null, -1),
|
||||
createVNode(
|
||||
OfficialImage,
|
||||
{
|
||||
class: `official-brand-image`,
|
||||
src: unref($),
|
||||
alt: unref(Y).brand.name,
|
||||
},
|
||||
{
|
||||
default: withCtx(() => [
|
||||
createElementVNode(`span`, T, [
|
||||
createElementVNode(`span`),
|
||||
createElementVNode(`span`),
|
||||
createElementVNode(`span`),
|
||||
]),
|
||||
])),
|
||||
]),
|
||||
_: 1,
|
||||
},
|
||||
8,
|
||||
[`src`, `alt`],
|
||||
),
|
||||
createElementVNode(`span`, E, [
|
||||
createElementVNode(
|
||||
`strong`,
|
||||
@@ -337,28 +333,26 @@ var S = {
|
||||
},
|
||||
{
|
||||
default: withCtx(() => [
|
||||
unref($)
|
||||
? (openBlock(),
|
||||
createElementBlock(
|
||||
`img`,
|
||||
{
|
||||
key: 0,
|
||||
class: `official-brand-image`,
|
||||
src: unref($),
|
||||
alt: unref(Y).brand.name,
|
||||
},
|
||||
null,
|
||||
8,
|
||||
te,
|
||||
))
|
||||
: (openBlock(),
|
||||
createElementBlock(`span`, L, [
|
||||
...(i[5] ||= [
|
||||
createElementVNode(`span`, null, null, -1),
|
||||
createElementVNode(`span`, null, null, -1),
|
||||
createElementVNode(`span`, null, null, -1),
|
||||
createVNode(
|
||||
OfficialImage,
|
||||
{
|
||||
class: `official-brand-image`,
|
||||
src: unref($),
|
||||
alt: unref(Y).brand.name,
|
||||
},
|
||||
{
|
||||
default: withCtx(() => [
|
||||
createElementVNode(`span`, L, [
|
||||
createElementVNode(`span`),
|
||||
createElementVNode(`span`),
|
||||
createElementVNode(`span`),
|
||||
]),
|
||||
])),
|
||||
]),
|
||||
_: 1,
|
||||
},
|
||||
8,
|
||||
[`src`, `alt`],
|
||||
),
|
||||
createElementVNode(`span`, R, [
|
||||
createElementVNode(
|
||||
`strong`,
|
||||
@@ -523,17 +517,26 @@ var S = {
|
||||
unref(Y).footer.qrImage
|
||||
? (openBlock(),
|
||||
createElementBlock(`div`, G, [
|
||||
createElementVNode(
|
||||
`img`,
|
||||
createVNode(
|
||||
OfficialImage,
|
||||
{
|
||||
src: unref(useOfficialSiteContent_i)(
|
||||
unref(Y).footer.qrImage,
|
||||
),
|
||||
alt: unref(Y).footer.qrCaption,
|
||||
},
|
||||
null,
|
||||
{
|
||||
default: withCtx(() => [
|
||||
createElementVNode(
|
||||
`span`,
|
||||
null,
|
||||
`二维码暂时无法显示,请使用工单咨询`,
|
||||
),
|
||||
]),
|
||||
_: 1,
|
||||
},
|
||||
8,
|
||||
K,
|
||||
[`src`, `alt`],
|
||||
),
|
||||
createElementVNode(
|
||||
`span`,
|
||||
|
||||
@@ -25,7 +25,7 @@ var n = {
|
||||
},
|
||||
{
|
||||
label: `订购产品`,
|
||||
href: `/cart`,
|
||||
href: `/products`,
|
||||
is_show: !0,
|
||||
},
|
||||
{
|
||||
@@ -68,7 +68,7 @@ var n = {
|
||||
},
|
||||
],
|
||||
buttonLabel: `浏览产品服务`,
|
||||
buttonHref: `/login?redirect=%2Fproducts`,
|
||||
buttonHref: `/products`,
|
||||
secondaryLabel: `了解基础设施`,
|
||||
secondaryHref: `#infrastructure`,
|
||||
metric: {
|
||||
@@ -124,7 +124,7 @@ var n = {
|
||||
},
|
||||
],
|
||||
buttonLabel: `查看云服务器`,
|
||||
href: `/login?redirect=%2Fcloud-servers`,
|
||||
href: `/products/cloud-server`,
|
||||
is_show: !0,
|
||||
},
|
||||
{
|
||||
@@ -149,7 +149,7 @@ var n = {
|
||||
},
|
||||
],
|
||||
buttonLabel: `查看物理服务器`,
|
||||
href: `/login?redirect=%2Fdedicated-servers`,
|
||||
href: `/products/dedicated-server`,
|
||||
is_show: !0,
|
||||
},
|
||||
{
|
||||
@@ -173,8 +173,8 @@ var n = {
|
||||
is_show: !0,
|
||||
},
|
||||
],
|
||||
buttonLabel: `了解机柜托管`,
|
||||
href: `/login?redirect=%2Fcolocations`,
|
||||
buttonLabel: `登录咨询机柜托管`,
|
||||
href: `/tickets/create`,
|
||||
is_show: !0,
|
||||
},
|
||||
],
|
||||
@@ -251,7 +251,7 @@ var n = {
|
||||
title: `为你的下一个项目选好基础设施`,
|
||||
description: `浏览可用产品方案,或进入客户中心配置服务、管理实例与订单。`,
|
||||
buttonLabel: `前往产品目录`,
|
||||
buttonHref: `/login?redirect=%2Fproducts`,
|
||||
buttonHref: `/products`,
|
||||
secondaryLabel: `登录客户中心`,
|
||||
secondaryHref: `/login`,
|
||||
},
|
||||
@@ -263,17 +263,17 @@ var n = {
|
||||
links: [
|
||||
{
|
||||
label: `云服务器`,
|
||||
href: `/login?redirect=%2Fcloud-servers`,
|
||||
href: `/products/cloud-server`,
|
||||
is_show: !0,
|
||||
},
|
||||
{
|
||||
label: `物理服务器`,
|
||||
href: `/login?redirect=%2Fdedicated-servers`,
|
||||
href: `/products/dedicated-server`,
|
||||
is_show: !0,
|
||||
},
|
||||
{
|
||||
label: `机柜托管`,
|
||||
href: `/login?redirect=%2Fcolocations`,
|
||||
href: `/tickets/create`,
|
||||
is_show: !0,
|
||||
},
|
||||
],
|
||||
@@ -359,8 +359,44 @@ function i(e, t) {
|
||||
function a() {
|
||||
return JSON.parse(JSON.stringify(n));
|
||||
}
|
||||
// 只迁移已确认的站内旧购买目的地;CMS 自定义外链、文案及其余账号入口保持原样。
|
||||
const purchaseDestinations = new Map([
|
||||
["/products", "/products"],
|
||||
["/cloud-servers", "/products/cloud-server"],
|
||||
["/dedicated-servers", "/products/dedicated-server"],
|
||||
["/colocations", "/tickets/create"],
|
||||
]);
|
||||
function purchaseHref(value) {
|
||||
if (typeof value !== "string" || !/^\/(?!\/)/.test(value)) return value;
|
||||
try {
|
||||
const url = new URL(value, window.location.origin);
|
||||
const target =
|
||||
url.pathname === "/login"
|
||||
? new URL(
|
||||
url.searchParams.get("redirect") || "/",
|
||||
window.location.origin,
|
||||
)
|
||||
: url;
|
||||
if (target.origin !== window.location.origin) return value;
|
||||
const destination = purchaseDestinations.get(target.pathname);
|
||||
return destination ? destination + target.search + target.hash : value;
|
||||
} catch {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
// 在 CMS 入模处处理所有链接字段,头尾、商品卡及主按钮不会各自保留不同的旧规则。
|
||||
function normalizeLinks(value) {
|
||||
if (Array.isArray(value)) return value.map(normalizeLinks);
|
||||
if (!r(value)) return value;
|
||||
return Object.fromEntries(
|
||||
Object.entries(value).map(([key, entry]) => [
|
||||
key,
|
||||
/href$/i.test(key) ? purchaseHref(entry) : normalizeLinks(entry),
|
||||
]),
|
||||
);
|
||||
}
|
||||
function o(e) {
|
||||
return i(n, e);
|
||||
return normalizeLinks(i(n, e));
|
||||
}
|
||||
// 链接允许站内路径、锚点、HTTP(S)/mailto/tel;未知协议和反斜杠回落为不可跳转的 #。
|
||||
function s(e) {
|
||||
|
||||
+55
-29
@@ -25,6 +25,7 @@ import { normalizeStyle } from "vue";
|
||||
import { useHead } from "#app";
|
||||
import { NuxtLink } from "#components";
|
||||
import { Icon } from "#components";
|
||||
import OfficialImage from "~/components/OfficialImage.vue";
|
||||
import { i as useOfficialSiteContent_i } from "~/lib/useOfficialSiteContent.js";
|
||||
import { n as useOfficialSiteContent_n } from "~/lib/useOfficialSiteContent.js";
|
||||
import { r as useOfficialSiteContent_r } from "~/lib/useOfficialSiteContent.js";
|
||||
@@ -162,7 +163,6 @@ var x = {
|
||||
he = {
|
||||
class: `official-review-person`,
|
||||
},
|
||||
ge = [`src`, `alt`],
|
||||
_e = {
|
||||
key: 1,
|
||||
class: `official-review-avatar`,
|
||||
@@ -639,6 +639,13 @@ var x = {
|
||||
1032,
|
||||
[`to`],
|
||||
),
|
||||
n.href === `/tickets/create`
|
||||
? createElementVNode(
|
||||
`p`,
|
||||
null,
|
||||
`机柜托管及定制方案请登录后提交工单咨询`,
|
||||
)
|
||||
: createCommentVNode(``, !0),
|
||||
],
|
||||
4,
|
||||
)
|
||||
@@ -922,35 +929,33 @@ var x = {
|
||||
1,
|
||||
),
|
||||
createElementVNode(`div`, he, [
|
||||
unref(
|
||||
useOfficialSiteContent_i,
|
||||
)(t.avatar)
|
||||
? (openBlock(),
|
||||
createElementBlock(
|
||||
`img`,
|
||||
{
|
||||
key: 0,
|
||||
src: unref(
|
||||
useOfficialSiteContent_i,
|
||||
)(t.avatar),
|
||||
alt: t.author,
|
||||
},
|
||||
null,
|
||||
8,
|
||||
ge,
|
||||
))
|
||||
: (openBlock(),
|
||||
createElementBlock(
|
||||
`span`,
|
||||
_e,
|
||||
toDisplayString(
|
||||
t.author.slice(
|
||||
0,
|
||||
1,
|
||||
) || `客`,
|
||||
createVNode(
|
||||
OfficialImage,
|
||||
{
|
||||
src: unref(
|
||||
useOfficialSiteContent_i,
|
||||
)(t.avatar),
|
||||
alt: t.author,
|
||||
},
|
||||
{
|
||||
default: withCtx(() => [
|
||||
createElementVNode(
|
||||
`span`,
|
||||
_e,
|
||||
toDisplayString(
|
||||
t.author.slice(
|
||||
0,
|
||||
1,
|
||||
) || `客`,
|
||||
),
|
||||
1,
|
||||
),
|
||||
1,
|
||||
)),
|
||||
]),
|
||||
_: 2,
|
||||
},
|
||||
1032,
|
||||
[`src`, `alt`],
|
||||
),
|
||||
createElementVNode(
|
||||
`div`,
|
||||
null,
|
||||
@@ -1011,6 +1016,27 @@ var x = {
|
||||
),
|
||||
1,
|
||||
),
|
||||
!unref(X).footer.phone &&
|
||||
!unref(X).footer.email &&
|
||||
!unref(X).footer.address
|
||||
? createElementVNode(`p`, null, [
|
||||
createTextVNode(
|
||||
`机柜托管及定制方案:`,
|
||||
),
|
||||
createVNode(
|
||||
f,
|
||||
{ to: `/tickets/create` },
|
||||
{
|
||||
default: withCtx(() => [
|
||||
createTextVNode(
|
||||
`登录后提交工单咨询`,
|
||||
),
|
||||
]),
|
||||
_: 1,
|
||||
},
|
||||
),
|
||||
])
|
||||
: createCommentVNode(``, !0),
|
||||
]),
|
||||
createElementVNode(`div`, xe, [
|
||||
createVNode(
|
||||
|
||||
Reference in new issue
Block a user