|
|
@@ -0,0 +1,369 @@
|
|
|
+<!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="format-detection" content="telephone=no">
|
|
|
+ <title>与U宝对话</title>
|
|
|
+ <style>
|
|
|
+ :root {
|
|
|
+ --bg: #f4f6fb;
|
|
|
+ --text: #151515;
|
|
|
+ --muted: #aaaaaa;
|
|
|
+ --orange: #f47d1f;
|
|
|
+ --safe-bottom: env(safe-area-inset-bottom, 0px);
|
|
|
+ }
|
|
|
+
|
|
|
+ * {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ html {
|
|
|
+ -webkit-tap-highlight-color: transparent;
|
|
|
+ }
|
|
|
+
|
|
|
+ body {
|
|
|
+ font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
|
+ background: var(--bg);
|
|
|
+ color: var(--text);
|
|
|
+ min-height: 100vh;
|
|
|
+ padding-bottom: calc(88px + var(--safe-bottom));
|
|
|
+ }
|
|
|
+
|
|
|
+ .nav {
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ z-index: 10;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 10px 12px;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .nav__close {
|
|
|
+ width: 36px;
|
|
|
+ height: 36px;
|
|
|
+ border: none;
|
|
|
+ background: transparent;
|
|
|
+ font-size: 22px;
|
|
|
+ line-height: 36px;
|
|
|
+ color: #151515;
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .nav__center {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 0;
|
|
|
+ text-align: center;
|
|
|
+ padding: 0 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .nav__title {
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #151515;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ }
|
|
|
+
|
|
|
+ .nav__url {
|
|
|
+ margin-top: 2px;
|
|
|
+ font-size: 11px;
|
|
|
+ color: var(--muted);
|
|
|
+ }
|
|
|
+
|
|
|
+ .nav__side {
|
|
|
+ width: 36px;
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .hero {
|
|
|
+ padding: 16px 15px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .hero__title {
|
|
|
+ font-size: 20px;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: 1.4;
|
|
|
+ word-break: break-word;
|
|
|
+ }
|
|
|
+
|
|
|
+ .hero__meta {
|
|
|
+ margin-top: 8px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: var(--muted);
|
|
|
+ line-height: 1.4;
|
|
|
+ }
|
|
|
+
|
|
|
+ .hero__divider {
|
|
|
+ margin-top: 14px;
|
|
|
+ height: 1px;
|
|
|
+ background: rgba(170, 170, 170, 0.25);
|
|
|
+ }
|
|
|
+
|
|
|
+ .conversation {
|
|
|
+ padding: 14px 15px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .row {
|
|
|
+ display: flex;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .row--user {
|
|
|
+ justify-content: flex-end;
|
|
|
+ }
|
|
|
+
|
|
|
+ .row--ai {
|
|
|
+ justify-content: flex-start;
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-bubble {
|
|
|
+ max-width: 78%;
|
|
|
+ padding: 10px 12px;
|
|
|
+ background: var(--orange);
|
|
|
+ border-radius: 6px;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 1.5;
|
|
|
+ white-space: pre-wrap;
|
|
|
+ word-break: break-word;
|
|
|
+ }
|
|
|
+
|
|
|
+ .ai-card {
|
|
|
+ width: 100%;
|
|
|
+ padding: 14px 13px;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 8px;
|
|
|
+ box-shadow: 0 1px 6px rgba(0, 0, 0, 0.04);
|
|
|
+ }
|
|
|
+
|
|
|
+ .ai-card__text {
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 1.65;
|
|
|
+ white-space: pre-wrap;
|
|
|
+ word-break: break-word;
|
|
|
+ text-align: left;
|
|
|
+ }
|
|
|
+
|
|
|
+ .fallback-card {
|
|
|
+ margin: 14px 15px 0;
|
|
|
+ padding: 14px 13px;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .empty {
|
|
|
+ padding: 48px 20px;
|
|
|
+ text-align: center;
|
|
|
+ color: var(--muted);
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .footer {
|
|
|
+ position: fixed;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ z-index: 20;
|
|
|
+ padding: 10px 15px calc(10px + var(--safe-bottom));
|
|
|
+ background: linear-gradient(180deg, rgba(244, 246, 251, 0) 0%, #f4f6fb 36%);
|
|
|
+ }
|
|
|
+
|
|
|
+ .continue-btn {
|
|
|
+ width: 100%;
|
|
|
+ height: 44px;
|
|
|
+ border: none;
|
|
|
+ border-radius: 999px;
|
|
|
+ background: linear-gradient(90deg, #ffb347 0%, #f47d1f 55%, #ff7849 100%);
|
|
|
+ box-shadow: 0 4px 12px rgba(244, 125, 31, 0.28);
|
|
|
+ color: #fff;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+ <header class="nav">
|
|
|
+ <button type="button" class="nav__close" id="btnClose" aria-label="关闭">×</button>
|
|
|
+ <div class="nav__center">
|
|
|
+ <div class="nav__title" id="navTitle">与AI助手-U宝</div>
|
|
|
+ <div class="nav__url">www.ailien.shop</div>
|
|
|
+ </div>
|
|
|
+ <div class="nav__side"></div>
|
|
|
+ </header>
|
|
|
+
|
|
|
+ <main id="main">
|
|
|
+ <div class="empty">对话内容加载中…</div>
|
|
|
+ </main>
|
|
|
+
|
|
|
+ <footer class="footer">
|
|
|
+ <button type="button" class="continue-btn" id="btnContinue">和U宝继续聊 →</button>
|
|
|
+ </footer>
|
|
|
+
|
|
|
+ <script>
|
|
|
+ (function () {
|
|
|
+ var SHARE_URL = "www.ailien.shop";
|
|
|
+ var APP_DEEPLINK = "shopro://pages/aiSearchResult/index?pageType=home";
|
|
|
+
|
|
|
+ function escHtml(s) {
|
|
|
+ return String(s || "")
|
|
|
+ .replace(/&/g, "&")
|
|
|
+ .replace(/</g, "<")
|
|
|
+ .replace(/>/g, ">")
|
|
|
+ .replace(/"/g, """);
|
|
|
+ }
|
|
|
+
|
|
|
+ function getQueryParam(name) {
|
|
|
+ var m = new RegExp("[?&]" + name + "=([^&]*)").exec(window.location.search);
|
|
|
+ if (!m) return "";
|
|
|
+ try {
|
|
|
+ return decodeURIComponent(m[1].replace(/\+/g, " "));
|
|
|
+ } catch (e) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function parsePayload() {
|
|
|
+ var raw = getQueryParam("payload");
|
|
|
+ if (!raw) return null;
|
|
|
+ try {
|
|
|
+ return JSON.parse(raw);
|
|
|
+ } catch (e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function getFirstUserQuestion(messages) {
|
|
|
+ var list = Array.isArray(messages) ? messages : [];
|
|
|
+ for (var i = 0; i < list.length; i++) {
|
|
|
+ var m = list[i];
|
|
|
+ if (!m || m.role !== "user") continue;
|
|
|
+ if (m.isImage) return "[图片]";
|
|
|
+ var t = String(m.content || "").trim();
|
|
|
+ if (t) return t;
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ function formatDiscussionTitle(question) {
|
|
|
+ var q = String(question || "").trim();
|
|
|
+ if (!q) return "与AI助手对话";
|
|
|
+ if (q.slice(-3) === "的讨论") return q;
|
|
|
+ return q + "的讨论";
|
|
|
+ }
|
|
|
+
|
|
|
+ function formatNavTitle(question) {
|
|
|
+ var titled = formatDiscussionTitle(question);
|
|
|
+ var maxLen = 14;
|
|
|
+ var short = titled.length > maxLen ? titled.slice(0, maxLen) + "..." : titled;
|
|
|
+ return short + "-U宝";
|
|
|
+ }
|
|
|
+
|
|
|
+ function formatDate(ts) {
|
|
|
+ var d = ts ? new Date(Number(ts)) : new Date();
|
|
|
+ if (isNaN(d.getTime())) d = new Date();
|
|
|
+ return d.getFullYear() + "年" + (d.getMonth() + 1) + "月" + d.getDate() + "日";
|
|
|
+ }
|
|
|
+
|
|
|
+ function renderMessages(messages) {
|
|
|
+ var html = "";
|
|
|
+ var list = Array.isArray(messages) ? messages : [];
|
|
|
+ for (var i = 0; i < list.length; i++) {
|
|
|
+ var msg = list[i];
|
|
|
+ if (!msg) continue;
|
|
|
+ if (msg.role === "user") {
|
|
|
+ var userText = msg.isImage ? "[图片]" : String(msg.content || "").trim();
|
|
|
+ if (!userText) continue;
|
|
|
+ html +=
|
|
|
+ '<div class="row row--user"><div class="user-bubble">' +
|
|
|
+ escHtml(userText) +
|
|
|
+ "</div></div>";
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (msg.role === "ai") {
|
|
|
+ var aiText = String(msg.content || "").trim();
|
|
|
+ if (!aiText) continue;
|
|
|
+ html +=
|
|
|
+ '<div class="row row--ai"><div class="ai-card"><div class="ai-card__text">' +
|
|
|
+ escHtml(aiText) +
|
|
|
+ "</div></div></div>";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return html;
|
|
|
+ }
|
|
|
+
|
|
|
+ function render(data) {
|
|
|
+ var main = document.getElementById("main");
|
|
|
+ var navTitle = document.getElementById("navTitle");
|
|
|
+ if (!data) {
|
|
|
+ main.innerHTML = '<div class="empty">对话内容不存在或链接已失效</div>';
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ var messages = data.messages || [];
|
|
|
+ var firstQuestion =
|
|
|
+ String(data.firstQuestion || "").trim() || getFirstUserQuestion(messages);
|
|
|
+ var pageTitle = formatDiscussionTitle(firstQuestion);
|
|
|
+ var dateText = formatDate(data.shareTime);
|
|
|
+
|
|
|
+ navTitle.textContent = formatNavTitle(firstQuestion);
|
|
|
+ document.title = pageTitle;
|
|
|
+
|
|
|
+ var bodyHtml =
|
|
|
+ '<section class="hero">' +
|
|
|
+ '<h1 class="hero__title">' +
|
|
|
+ escHtml(pageTitle) +
|
|
|
+ "</h1>" +
|
|
|
+ '<p class="hero__meta">' +
|
|
|
+ escHtml(dateText) +
|
|
|
+ " · 内容由AI生成,不能完全保障真实</p>" +
|
|
|
+ '<div class="hero__divider"></div>' +
|
|
|
+ "</section>";
|
|
|
+
|
|
|
+ var convHtml = renderMessages(messages);
|
|
|
+ if (convHtml) {
|
|
|
+ bodyHtml += '<section class="conversation">' + convHtml + "</section>";
|
|
|
+ } else if (data.content) {
|
|
|
+ bodyHtml +=
|
|
|
+ '<section class="fallback-card"><div class="ai-card__text">' +
|
|
|
+ escHtml(data.content) +
|
|
|
+ "</div></section>";
|
|
|
+ } else {
|
|
|
+ bodyHtml += '<div class="empty">暂无对话内容</div>';
|
|
|
+ }
|
|
|
+
|
|
|
+ main.innerHTML = bodyHtml;
|
|
|
+ }
|
|
|
+
|
|
|
+ function openApp() {
|
|
|
+ var start = Date.now();
|
|
|
+ window.location.href = APP_DEEPLINK;
|
|
|
+ setTimeout(function () {
|
|
|
+ if (Date.now() - start < 2800) {
|
|
|
+ window.location.href = "https://www.ailien.shop/";
|
|
|
+ }
|
|
|
+ }, 2500);
|
|
|
+ }
|
|
|
+
|
|
|
+ document.getElementById("btnClose").addEventListener("click", function () {
|
|
|
+ if (window.history.length > 1) {
|
|
|
+ window.history.back();
|
|
|
+ } else if (typeof WeixinJSBridge !== "undefined") {
|
|
|
+ WeixinJSBridge.call("closeWindow");
|
|
|
+ } else {
|
|
|
+ window.close();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ document.getElementById("btnContinue").addEventListener("click", openApp);
|
|
|
+
|
|
|
+ render(parsePayload());
|
|
|
+ })();
|
|
|
+ </script>
|
|
|
+</body>
|
|
|
+</html>
|