Files

683 lines
18 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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>