feat: add Douyin card jump landing page

This commit is contained in:
2026-09-01 11:14:13 +08:00
commit 0571835458
11 changed files with 409 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
note.md
+25
View File
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="点击一下咨询" property="og:title" />
<meta content="获取最新报价" property="og:description" />
<meta content="https://st.ipao.vip/v1/card.jpg" property="og:image" />
<base href="https://st.ipao.vip/v1/">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport" />
<title></title>
</head>
<body>
<div id="app"></div>
<script>
var script = document.createElement('script');
script.src = 'landing.js?v=' + new Date().getTime();
document.body.appendChild(script);
</script>
</body>
</html>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

+13
View File
@@ -0,0 +1,13 @@
{
"code": 1001,
"message": "成功",
"data": {
"platform": "douyin",
"icon": "https://st.ipao.vip/v1/card.jpg",
"title": "立即咨询",
"url": "weixin://dl/business/?appid=wx6b31e32cf6bc142a&path=pages/price-query/price-query",
"desc": "正在前往咨询",
"isForbid": false
},
"success": true
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

+114
View File
@@ -0,0 +1,114 @@
(function () {
'use strict';
// 显示错误页面
function showErrorPage(message) {
const appContainer = document.getElementById('app');
if (appContainer) {
// 添加样式
const style = document.createElement('style');
style.textContent = `
* {
padding: 0;
margin: 0;
}
body {
background: #fff;
overflow: hidden;
}
.icon {
width: 50px;
height: 50px;
background: url('https://st.ipao.vip/v1/warn.png') no-repeat;
margin: 100px auto 10px;
background-position: center;
background-size: 100%;
}
.error {
text-align: center;
font-size: 17px;
font-weight: bold;
padding: 15px 0;
}
`;
document.head.appendChild(style);
appContainer.innerHTML = `<div class="icon"></div><p class="error">${message}</p>`;
}
}
// 动态加载CSS文件
function loadCSS(href) {
return new Promise((resolve, reject) => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = href;
link.onload = resolve;
link.onerror = reject;
document.head.appendChild(link);
});
}
// 动态加载JS文件
function loadJS(src) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.onload = resolve;
script.onerror = reject;
document.body.appendChild(script);
});
}
// 初始化函数
async function init() {
try {
const url = `https://st.ipao.vip/v1/config.json`;
// 从API获取配置
const response = await fetch(url, {
method: 'GET',
cache: 'no-cache',
});
const result = await response.json();
if (!result.success) {
showErrorPage(result.message || '链接配置获取失败');
return;
}
// 检查微信外链状态
if (result.data) {
const wechatLink = result.data;
// 检查链接是否停用 (后端返回 Boolean 类型, true 表示审核拒绝/停用)
if (wechatLink.isForbid === true) {
showErrorPage('链接已停用');
return;
}
}
// 将配置数据存储到全局变量,供后续脚本使用
window.LANDING_CONFIG = result.data;
// 保存原始目标链接到全局变量
// window.ORIGINAL_TARGET_URL = result.data.originalTargetUrl;
// 根据landingType动态加载对应的资源
const timestamp = Math.floor(Date.now() / 1000);
await loadCSS('landpage.css?v=' + timestamp);
await loadJS('landpage.js?v=' + timestamp);
} catch (error) {
showErrorPage('链接配置加载失败');
}
}
// 页面加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
+135
View File
@@ -0,0 +1,135 @@
* {
padding: 0;
margin: 0;
}
@media (max-width: 768px) {
body {
width: 100%;
height: 100vh;
background: #fff;
overflow: hidden;
}
}
@media screen and (max-width: 3000px) and (min-width: 768px) {
body {
background: #fff;
overflow: hidden;
margin: 0 auto;
}
#app {
padding-top: 40px;
width: 350px;
height: 100vh;
background: url("https://st.ipao.vip/v1/app.png") no-repeat;
background-size: 100%;
margin: 50px auto 0;
}
}
.ssl_tips_container {
display: flex;
justify-content: center;
padding: 15px 0;
}
.ssl_tips {
display: flex;
align-items: center;
}
.ssl_logo {
width: 20px;
height: 20px;
margin-right: 3px;
background: url("https://st.ipao.vip/v1/ssl.png") no-repeat;
background-position: center;
background-size: 80%;
}
.ssl_text {
flex: 1;
font-size: 14px;
color: #999;
}
.jump_gif {
width: 50%;
margin: 50px auto 0;
}
.jump_gif img {
width: 100%;
}
.jump_text {
text-align: center;
font-size: 16px;
color: #666;
margin-top: 80px;
}
.jump_button_tips {
text-align: center;
color: #ccc;
margin-top: 10px;
font-size: 15px;
}
.jump_button {
width: 50%;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
background: #0ccf67;
border-radius: 15px;
margin: 20px auto 0;
font-size: 16px;
animation: breathe 1s ease-in-out infinite;
transform-origin: center;
}
.a-jump {
text-decoration: none;
-webkit-tap-highlight-color: rgba(255, 0, 0, 0);
}
@keyframes breathe {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
.powerby {
position: fixed;
bottom: 20px;
left: 0;
right: 0;
margin: 0 auto;
color: #ccc;
font-size: 13px;
text-align: center;
}
.icon {
width: 50px;
height: 50px;
background: url("https://st.ipao.vip/v1/warn.png") no-repeat;
margin: 100px auto 10px;
background-position: center;
background-size: 100%;
}
.error {
text-align: center;
font-size: 17px;
font-weight: bold;
padding: 15px 0;
}
+121
View File
@@ -0,0 +1,121 @@
(function () {
const currentURL = window.location.href;
const url = new URL(currentURL);
// 获取所有URL参数,用于传递给目标页面
const allParams = new URLSearchParams(url.search);
// 构建带参数的目标URL函数
function buildTargetUrl(baseUrl) {
try {
const targetUrl = new URL(baseUrl);
// 将当前页面的所有参数添加到目标URL中(除了jwid和key,避免冲突)
for (const [key, value] of allParams) {
if (key !== 'key') {
targetUrl.searchParams.set(key, value);
}
}
return targetUrl.toString();
} catch (e) {
// 如果目标URL格式不正确,返回原始URL
return baseUrl;
}
}
// Main processing function
async function processLinkData(res) {
const app = document.getElementById('app');
const platform = res.platform || 'douyin';
const jump_gif = 'https://st.ipao.vip/v1/' + platform + '.gif';
// 1. 设置 favicon
const favicon = document.createElement('link');
favicon.rel = 'shortcut icon';
favicon.href = res.icon;
document.head.appendChild(favicon);
// 2. 设置 desc
const desc = document.createElement('meta');
desc.name = 'description';
desc.content = res.desc || '';
document.head.appendChild(desc);
// 3. 设置 title
document.title = res.title;
// 构建带参数的目标URL
const targetUrlWithParams = buildTargetUrl(res.url);
// const targetUrlWithParams = res.url;
// 以下域名的目标地址不使用iframe内嵌模式
const jw_url_arr = ['work.weixin.qq.com', 'weixin://', 'www.iesdouyin.com', 'v.douyin.com'];
let noiframe = jw_url_arr.some(sub => res.url.includes(sub));
if (res.url.includes('mp.weixin.qq.com')) {
noiframe = false;
}
if (noiframe) {
app.innerHTML = `
<div class="ssl_tips_container">
<div class="ssl_tips">
<span class="ssl_logo"></span>
<span class="ssl_text">本页面已启用SSL安全加密</span>
</div>
</div>
<div class="jump_gif"><img src="${jump_gif}" /></div>
<div class="jump_text">正在自动跳转...</div>
<div class="jump_button_tips">如没有自动跳转请点击按钮</div>
<a href="${targetUrlWithParams}" class="a-jump">
<div class="jump_button">点击跳转</div>
</a>
<div class="powerby"></div>
<iframe src="${targetUrlWithParams}" style="opacity:0;"></iframe>
`;
} else {
app.innerHTML = `
<iframe src="${targetUrlWithParams}" allowfullscreen style="width: 100%;height: 100vh;border: none;"></iframe>
`;
}
if (res.url.includes('www.iesdouyin.com') || res.url.includes('mp.weixin.qq.com')) {
location.href = targetUrlWithParams;
}
// Safari、微信环境自动跳转
if (isSafari()) location.href = targetUrlWithParams;
if (isWeChat() && res.url.includes('work.weixin.qq.com')) location.href = targetUrlWithParams;
}
// Use data from landing.js to avoid duplicate request
processLinkData(window.LANDING_CONFIG);
// 显示状态消息页面
function showStatusMessage(message) {
const app = document.getElementById('app');
if (app) {
app.innerHTML = `<div class="icon"></div><p class="error">${message}</p>`;
}
}
// Safari环境检测
function isSafari() {
const ua = navigator.userAgent.toLowerCase();
return ua.includes('safari') && !ua.includes('chrome');
}
// 微信环境检测
function isWeChat() {
return /MicroMessenger/i.test(navigator.userAgent);
}
// 微信环境隐藏右上角菜单
// 如果不需要隐藏请将下方代码删除
document.addEventListener('WeixinJSBridgeReady', function () {
if (typeof WeixinJSBridge !== 'undefined') {
WeixinJSBridge.call('hideOptionMenu');
}
});
})();
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB