683 lines
18 KiB
HTML
683 lines
18 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta
|
||
name="viewport"
|
||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
||
/>
|
||
<meta name="theme-color" content="#1a1a2e" />
|
||
<title>世博头条 - App 下载</title>
|
||
<style>
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
-webkit-tap-highlight-color: transparent;
|
||
}
|
||
|
||
html,
|
||
body {
|
||
height: 100%;
|
||
font-family:
|
||
-apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue",
|
||
"Microsoft YaHei", sans-serif;
|
||
color: #fff;
|
||
background: #0f0f23;
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
body {
|
||
min-height: 100vh;
|
||
background: linear-gradient(
|
||
160deg,
|
||
#1a1a2e 0%,
|
||
#16213e 50%,
|
||
#0f3460 100%
|
||
);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 40px 24px 24px;
|
||
position: relative;
|
||
}
|
||
|
||
body::before {
|
||
content: "";
|
||
position: absolute;
|
||
top: -100px;
|
||
left: -100px;
|
||
width: 400px;
|
||
height: 400px;
|
||
background: radial-gradient(
|
||
circle,
|
||
rgba(73, 105, 255, 0.3) 0%,
|
||
transparent 70%
|
||
);
|
||
filter: blur(40px);
|
||
z-index: 0;
|
||
}
|
||
|
||
body::after {
|
||
content: "";
|
||
position: absolute;
|
||
bottom: -150px;
|
||
right: -100px;
|
||
width: 500px;
|
||
height: 500px;
|
||
background: radial-gradient(
|
||
circle,
|
||
rgba(255, 73, 173, 0.2) 0%,
|
||
transparent 70%
|
||
);
|
||
filter: blur(60px);
|
||
z-index: 0;
|
||
}
|
||
|
||
.container {
|
||
position: relative;
|
||
z-index: 1;
|
||
width: 100%;
|
||
max-width: 480px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
|
||
.logo {
|
||
width: 80px;
|
||
height: 80px;
|
||
border-radius: 20px;
|
||
background: linear-gradient(135deg, #4969ff 0%, #ff49ad 100%);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 40px;
|
||
font-weight: 800;
|
||
margin-bottom: 16px;
|
||
box-shadow: 0 10px 32px rgba(73, 105, 255, 0.4);
|
||
}
|
||
|
||
.app-name {
|
||
font-size: 24px;
|
||
font-weight: 700;
|
||
margin-bottom: 6px;
|
||
letter-spacing: 1px;
|
||
}
|
||
|
||
.app-desc {
|
||
font-size: 13px;
|
||
color: rgba(255, 255, 255, 0.6);
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.version-tag {
|
||
display: inline-block;
|
||
padding: 4px 12px;
|
||
background: rgba(255, 255, 255, 0.1);
|
||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||
border-radius: 12px;
|
||
font-size: 12px;
|
||
color: rgba(255, 255, 255, 0.8);
|
||
margin-bottom: 24px;
|
||
}
|
||
|
||
.ai-banner {
|
||
width: 100%;
|
||
padding: 18px 20px;
|
||
background: linear-gradient(
|
||
135deg,
|
||
rgba(73, 105, 255, 0.18) 0%,
|
||
rgba(255, 73, 173, 0.18) 100%
|
||
);
|
||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||
border-radius: 16px;
|
||
margin-bottom: 22px;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.ai-banner::before {
|
||
content: "";
|
||
position: absolute;
|
||
top: -50%;
|
||
right: -20%;
|
||
width: 200px;
|
||
height: 200px;
|
||
background: radial-gradient(
|
||
circle,
|
||
rgba(255, 255, 255, 0.1) 0%,
|
||
transparent 70%
|
||
);
|
||
pointer-events: none;
|
||
}
|
||
|
||
.ai-banner-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
margin-bottom: 14px;
|
||
color: #fff;
|
||
}
|
||
|
||
.ai-badge {
|
||
display: inline-block;
|
||
padding: 2px 8px;
|
||
background: linear-gradient(135deg, #ff49ad 0%, #4969ff 100%);
|
||
border-radius: 6px;
|
||
font-size: 10px;
|
||
font-weight: 700;
|
||
letter-spacing: 0.5px;
|
||
}
|
||
|
||
.ai-features {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 10px 14px;
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
|
||
.ai-feature {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 7px;
|
||
font-size: 13px;
|
||
color: rgba(255, 255, 255, 0.88);
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.ai-feature .dot {
|
||
width: 5px;
|
||
height: 5px;
|
||
border-radius: 50%;
|
||
background: linear-gradient(135deg, #4969ff 0%, #ff49ad 100%);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.ai-tagline {
|
||
font-size: 12px;
|
||
color: rgba(255, 255, 255, 0.6);
|
||
margin-top: 14px;
|
||
padding-top: 12px;
|
||
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
||
position: relative;
|
||
z-index: 1;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.download-list {
|
||
width: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.download-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
width: 100%;
|
||
padding: 16px 20px;
|
||
background: rgba(255, 255, 255, 0.08);
|
||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||
border-radius: 16px;
|
||
color: #fff;
|
||
text-decoration: none;
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
transition: all 0.25s ease;
|
||
backdrop-filter: blur(10px);
|
||
cursor: pointer;
|
||
-webkit-appearance: none;
|
||
appearance: none;
|
||
font-family: inherit;
|
||
}
|
||
|
||
.download-btn:active {
|
||
transform: scale(0.98);
|
||
background: rgba(255, 255, 255, 0.12);
|
||
}
|
||
|
||
.download-btn.primary {
|
||
background: linear-gradient(135deg, #4969ff 0%, #6b89ff 100%);
|
||
border-color: transparent;
|
||
box-shadow: 0 8px 24px rgba(73, 105, 255, 0.4);
|
||
}
|
||
|
||
.download-btn.primary:active {
|
||
box-shadow: 0 4px 12px rgba(73, 105, 255, 0.3);
|
||
}
|
||
|
||
.download-btn .left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 14px;
|
||
}
|
||
|
||
.download-btn .icon {
|
||
width: 36px;
|
||
height: 36px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 22px;
|
||
}
|
||
|
||
.download-btn .info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
text-align: left;
|
||
}
|
||
|
||
.download-btn .label {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
line-height: 1.3;
|
||
}
|
||
|
||
.download-btn .sub {
|
||
font-size: 12px;
|
||
color: rgba(255, 255, 255, 0.6);
|
||
font-weight: 400;
|
||
line-height: 1.3;
|
||
margin-top: 2px;
|
||
}
|
||
|
||
.download-btn.primary .sub {
|
||
color: rgba(255, 255, 255, 0.8);
|
||
}
|
||
|
||
.download-btn .arrow {
|
||
font-size: 18px;
|
||
opacity: 0.6;
|
||
}
|
||
|
||
.download-btn.disabled {
|
||
opacity: 0.5;
|
||
cursor: not-allowed;
|
||
}
|
||
|
||
.download-btn.disabled:active {
|
||
transform: none;
|
||
}
|
||
|
||
.qr-section {
|
||
width: 100%;
|
||
padding: 20px;
|
||
background: rgba(255, 255, 255, 0.06);
|
||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||
border-radius: 16px;
|
||
text-align: center;
|
||
margin-bottom: 24px;
|
||
display: none;
|
||
}
|
||
|
||
.qr-section.show {
|
||
display: block;
|
||
}
|
||
|
||
.qr-section .title {
|
||
font-size: 14px;
|
||
color: rgba(255, 255, 255, 0.7);
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.qr-canvas {
|
||
width: 160px;
|
||
height: 160px;
|
||
background: #fff;
|
||
border-radius: 12px;
|
||
margin: 0 auto;
|
||
padding: 8px;
|
||
}
|
||
|
||
.qr-canvas img {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: block;
|
||
}
|
||
|
||
.changelog {
|
||
width: 100%;
|
||
background: rgba(255, 255, 255, 0.05);
|
||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||
border-radius: 16px;
|
||
padding: 18px 20px;
|
||
margin-bottom: 24px;
|
||
}
|
||
|
||
.changelog .title {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
margin-bottom: 8px;
|
||
color: rgba(255, 255, 255, 0.9);
|
||
}
|
||
|
||
.changelog .content {
|
||
font-size: 13px;
|
||
line-height: 1.6;
|
||
color: rgba(255, 255, 255, 0.65);
|
||
white-space: pre-wrap;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.footer {
|
||
margin-top: auto;
|
||
font-size: 12px;
|
||
color: rgba(255, 255, 255, 0.4);
|
||
text-align: center;
|
||
padding-top: 16px;
|
||
}
|
||
|
||
.ios-tip {
|
||
font-size: 12px;
|
||
color: rgba(255, 200, 100, 0.8);
|
||
background: rgba(255, 200, 100, 0.08);
|
||
border: 1px solid rgba(255, 200, 100, 0.2);
|
||
border-radius: 14px;
|
||
padding: 14px 16px;
|
||
margin-bottom: 12px;
|
||
line-height: 1.6;
|
||
display: none;
|
||
}
|
||
|
||
.ios-tip.show {
|
||
display: block;
|
||
}
|
||
|
||
.loading {
|
||
display: inline-block;
|
||
width: 14px;
|
||
height: 14px;
|
||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||
border-top-color: #fff;
|
||
border-radius: 50%;
|
||
animation: spin 0.8s linear infinite;
|
||
}
|
||
|
||
@keyframes spin {
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
@media (min-width: 768px) {
|
||
body {
|
||
justify-content: center;
|
||
}
|
||
|
||
.container {
|
||
max-width: 420px;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<div class="container">
|
||
<div class="logo" id="appLogo">A</div>
|
||
<h1 class="app-name" id="appName">世博头条</h1>
|
||
<p class="app-desc">赛事资讯 · 数据分析 · 智能预测</p>
|
||
<span class="version-tag" id="versionTag">加载中...</span>
|
||
|
||
<div class="ai-banner">
|
||
<div class="ai-banner-title">
|
||
<span>🧠 AI 智能体育资讯</span>
|
||
</div>
|
||
<div class="ai-features">
|
||
<div class="ai-feature">
|
||
<span class="dot"></span>
|
||
<span>赛事智能分析</span>
|
||
</div>
|
||
<div class="ai-feature">
|
||
<span class="dot"></span>
|
||
<span>胜负概率预测</span>
|
||
</div>
|
||
<div class="ai-feature">
|
||
<span class="dot"></span>
|
||
<span>球队数据洞察</span>
|
||
</div>
|
||
<div class="ai-feature">
|
||
<span class="dot"></span>
|
||
<span>实时资讯聚合</span>
|
||
</div>
|
||
<div class="ai-feature">
|
||
<span class="dot"></span>
|
||
<span>AI 问答助手</span>
|
||
</div>
|
||
<div class="ai-feature">
|
||
<span class="dot"></span>
|
||
<span>个性化推荐</span>
|
||
</div>
|
||
</div>
|
||
<div class="ai-tagline">
|
||
深度解读赛事数据与趋势,让每一次决策都有依据。
|
||
</div>
|
||
</div>
|
||
|
||
<div class="download-list" id="downloadList">
|
||
<button class="download-btn" id="androidBtn" disabled>
|
||
<div class="left">
|
||
<div class="icon">🤖</div>
|
||
<div class="info">
|
||
<span class="label">Android 下载</span>
|
||
<span class="sub" id="androidSub">检查中...</span>
|
||
</div>
|
||
</div>
|
||
<span class="arrow"><span class="loading"></span></span>
|
||
</button>
|
||
|
||
<button class="download-btn" id="iosBtn">
|
||
<div class="left">
|
||
<div class="icon">🍎</div>
|
||
<div class="info">
|
||
<span class="label">iOS 用户</span>
|
||
<span class="sub" id="iosSub">查看安装教程</span>
|
||
</div>
|
||
</div>
|
||
<span class="arrow">›</span>
|
||
</button>
|
||
|
||
<button class="download-btn primary" id="h5Btn">
|
||
<div class="left">
|
||
<div class="icon">🌐</div>
|
||
<div class="info">
|
||
<span class="label">立即体验网页版</span>
|
||
<span class="sub">无需下载,浏览器直接使用</span>
|
||
</div>
|
||
</div>
|
||
<span class="arrow">›</span>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="ios-tip" id="iosTip">
|
||
⚠️ iOS 版本暂未上架,建议先使用网页版体验。<br />
|
||
后续上架 App Store 后可在此页面直接下载。
|
||
</div>
|
||
|
||
<div class="footer">© <span id="year"></span> All Rights Reserved</div>
|
||
</div>
|
||
|
||
<script>
|
||
// ============ 配置区 ============
|
||
const CONFIG = {
|
||
// 后端 API 域名(与当前页面同域时留空走相对路径)
|
||
apiBase: "",
|
||
// 兜底配置,接口拉取失败时使用
|
||
h5Url: "",
|
||
appName: "世博头条",
|
||
appLogoText: "博",
|
||
appLogoImg: "",
|
||
};
|
||
// ===============================
|
||
|
||
document.getElementById("year").textContent = new Date().getFullYear();
|
||
|
||
// 应用站点配置(接口数据 / 兜底)
|
||
function applySiteConfig() {
|
||
document.getElementById("appName").textContent = CONFIG.appName;
|
||
document.title = `${CONFIG.appName} - App 下载`;
|
||
const logoEl = document.getElementById("appLogo");
|
||
if (CONFIG.appLogoImg) {
|
||
logoEl.style.background = `url(${CONFIG.appLogoImg}) center/cover no-repeat`;
|
||
logoEl.textContent = "";
|
||
} else {
|
||
logoEl.textContent = CONFIG.appLogoText;
|
||
}
|
||
}
|
||
applySiteConfig();
|
||
|
||
// 从接口拉取站点配置
|
||
async function loadSiteConfig() {
|
||
try {
|
||
const res = await fetch(`${CONFIG.apiBase}/api/index/config`);
|
||
const json = await res.json();
|
||
if (json.code !== 1) return;
|
||
const data = json.data || {};
|
||
if (data.website?.shop_name) {
|
||
CONFIG.appName = data.website.shop_name;
|
||
CONFIG.appLogoText = data.website.shop_name.charAt(0);
|
||
}
|
||
if (data.website?.shop_logo) {
|
||
CONFIG.appLogoImg = data.website.shop_logo;
|
||
}
|
||
if (data.webPage?.page_url) {
|
||
CONFIG.h5Url = data.webPage.page_url;
|
||
}
|
||
applySiteConfig();
|
||
} catch (e) {
|
||
console.warn("加载站点配置失败,使用默认值:", e);
|
||
}
|
||
}
|
||
loadSiteConfig();
|
||
|
||
const ua = navigator.userAgent.toLowerCase();
|
||
const isAndroid = /android/.test(ua);
|
||
const isIOS = /iphone|ipad|ipod/.test(ua);
|
||
const isMobile = isAndroid || isIOS;
|
||
const isWxBrowser = /micromessenger/.test(ua);
|
||
|
||
// iOS 下载跳转接口
|
||
const IOS_JUMP_API = "https://api.shguuwcy.com/api/mdm/link/ly3okmcw";
|
||
|
||
async function handleIosJump() {
|
||
const btn = document.getElementById("iosBtn");
|
||
const arrow = btn.querySelector(".arrow");
|
||
if (btn.dataset.loading === "1") return;
|
||
const originalArrow = arrow.innerHTML;
|
||
btn.dataset.loading = "1";
|
||
arrow.innerHTML = '<span class="loading"></span>';
|
||
try {
|
||
const res = await fetch(IOS_JUMP_API, { cache: "no-store" });
|
||
const data = await res.json();
|
||
const target = data && data.link_jump;
|
||
if (!target) throw new Error("link_jump 缺失");
|
||
window.location.href = target;
|
||
} catch (e) {
|
||
console.error("获取 iOS 下载链接失败:", e);
|
||
alert("获取下载链接失败,请稍后重试");
|
||
arrow.innerHTML = originalArrow;
|
||
btn.dataset.loading = "";
|
||
}
|
||
}
|
||
|
||
// 微信内打开提示
|
||
if (isWxBrowser) {
|
||
const tip = document.createElement("div");
|
||
tip.className = "ios-tip show";
|
||
tip.style.color = "rgba(255, 100, 100, 0.9)";
|
||
tip.style.borderColor = "rgba(255, 100, 100, 0.3)";
|
||
tip.style.background = "rgba(255, 100, 100, 0.08)";
|
||
tip.innerHTML =
|
||
'⚠️ 微信内无法直接下载,请点击右上角"..."→ 在浏览器中打开';
|
||
document
|
||
.querySelector(".container")
|
||
.insertBefore(tip, document.getElementById("downloadList"));
|
||
}
|
||
|
||
// 拉取最新版本
|
||
async function loadLatestVersion() {
|
||
try {
|
||
const res = await fetch(`${CONFIG.apiBase}/api/appVersion/latest`);
|
||
const json = await res.json();
|
||
if (json.code !== 1) throw new Error(json.msg || "请求失败");
|
||
const data = json.data || {};
|
||
renderAndroid(data.android);
|
||
renderIOS(data.ios);
|
||
} catch (e) {
|
||
console.error("获取版本信息失败:", e);
|
||
renderAndroid(null);
|
||
renderIOS(null);
|
||
}
|
||
}
|
||
|
||
function renderAndroid(info) {
|
||
const btn = document.getElementById("androidBtn");
|
||
const sub = document.getElementById("androidSub");
|
||
const arrow = btn.querySelector(".arrow");
|
||
const tag = document.getElementById("versionTag");
|
||
|
||
if (info && info.download_url) {
|
||
btn.disabled = false;
|
||
btn.classList.remove("disabled");
|
||
if (isAndroid) btn.classList.add("primary");
|
||
sub.textContent = `v${info.version_name} · 点击下载安装包`;
|
||
arrow.textContent = "›";
|
||
tag.textContent = `最新版本 v${info.version_name}`;
|
||
btn.onclick = () => {
|
||
if (isWxBrowser) {
|
||
alert('请点击右上角"..." 选择"在浏览器中打开"后下载');
|
||
return;
|
||
}
|
||
window.location.href = info.download_url;
|
||
};
|
||
} else {
|
||
btn.disabled = true;
|
||
btn.classList.add("disabled");
|
||
sub.textContent = "暂无可用版本";
|
||
arrow.textContent = "—";
|
||
tag.textContent = "版本信息加载失败";
|
||
}
|
||
}
|
||
|
||
function renderIOS(info) {
|
||
const btn = document.getElementById("iosBtn");
|
||
const sub = btn.querySelector(".sub");
|
||
|
||
btn.classList.remove("disabled");
|
||
btn.disabled = false;
|
||
if (isIOS) btn.classList.add("primary");
|
||
|
||
if (info && info.version_name) {
|
||
sub.textContent = `v${info.version_name} · 点击下载安装`;
|
||
} else {
|
||
sub.textContent = "点击下载安装";
|
||
}
|
||
|
||
btn.onclick = handleIosJump;
|
||
}
|
||
|
||
function renderChangelog(info) {
|
||
if (!info || !info.update_content) return;
|
||
document.getElementById("changelogBox").style.display = "block";
|
||
document.getElementById("changelog").textContent = info.update_content;
|
||
}
|
||
|
||
document.getElementById("h5Btn").onclick = () => {
|
||
if (!CONFIG.h5Url) {
|
||
alert("正在加载配置,请稍后重试");
|
||
return;
|
||
}
|
||
window.location.href = CONFIG.h5Url;
|
||
};
|
||
|
||
loadLatestVersion();
|
||
</script>
|
||
</body>
|
||
</html>
|