shareAiConsult.html 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
  6. <meta name="format-detection" content="telephone=no">
  7. <title>与U宝对话</title>
  8. <style>
  9. :root {
  10. --bg: #f4f6fb;
  11. --text: #151515;
  12. --muted: #aaaaaa;
  13. --orange: #f47d1f;
  14. --safe-bottom: env(safe-area-inset-bottom, 0px);
  15. }
  16. * {
  17. margin: 0;
  18. padding: 0;
  19. box-sizing: border-box;
  20. }
  21. html {
  22. -webkit-tap-highlight-color: transparent;
  23. }
  24. body {
  25. font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
  26. background: var(--bg);
  27. color: var(--text);
  28. min-height: 100vh;
  29. padding-bottom: calc(88px + var(--safe-bottom));
  30. }
  31. .hero {
  32. padding: 16px 15px 0;
  33. }
  34. .hero__title {
  35. font-size: 20px;
  36. font-weight: 700;
  37. line-height: 1.4;
  38. word-break: break-word;
  39. }
  40. .hero__meta {
  41. margin-top: 8px;
  42. font-size: 12px;
  43. color: var(--muted);
  44. line-height: 1.4;
  45. }
  46. .hero__divider {
  47. margin-top: 14px;
  48. height: 1px;
  49. background: rgba(170, 170, 170, 0.25);
  50. }
  51. .conversation {
  52. padding: 14px 15px 0;
  53. }
  54. .row {
  55. display: flex;
  56. margin-bottom: 12px;
  57. }
  58. .row--user {
  59. justify-content: flex-end;
  60. }
  61. .row--ai {
  62. justify-content: flex-start;
  63. }
  64. .user-bubble {
  65. max-width: 78%;
  66. padding: 10px 12px;
  67. background: var(--orange);
  68. border-radius: 6px;
  69. color: #fff;
  70. font-size: 15px;
  71. font-weight: 500;
  72. line-height: 1.5;
  73. white-space: pre-wrap;
  74. word-break: break-word;
  75. }
  76. .ai-card {
  77. width: 100%;
  78. padding: 14px 13px;
  79. background: #fff;
  80. border-radius: 8px;
  81. box-shadow: 0 1px 6px rgba(0, 0, 0, 0.04);
  82. }
  83. .ai-card__text {
  84. font-size: 14px;
  85. line-height: 1.65;
  86. white-space: pre-wrap;
  87. word-break: break-word;
  88. text-align: left;
  89. }
  90. .fallback-card {
  91. margin: 14px 15px 0;
  92. padding: 14px 13px;
  93. background: #fff;
  94. border-radius: 8px;
  95. }
  96. .empty {
  97. padding: 48px 20px;
  98. text-align: center;
  99. color: var(--muted);
  100. font-size: 14px;
  101. }
  102. .footer {
  103. position: fixed;
  104. left: 0;
  105. right: 0;
  106. bottom: 0;
  107. z-index: 20;
  108. padding: 10px 15px calc(10px + var(--safe-bottom));
  109. background: linear-gradient(180deg, rgba(244, 246, 251, 0) 0%, #f4f6fb 36%);
  110. }
  111. .continue-btn {
  112. width: 100%;
  113. height: 44px;
  114. border: none;
  115. border-radius: 999px;
  116. background: linear-gradient(90deg, #ffb347 0%, #f47d1f 55%, #ff7849 100%);
  117. box-shadow: 0 4px 12px rgba(244, 125, 31, 0.28);
  118. color: #fff;
  119. font-size: 16px;
  120. font-weight: 600;
  121. }
  122. </style>
  123. </head>
  124. <body>
  125. <main id="main">
  126. <div class="empty">对话内容加载中…</div>
  127. </main>
  128. <footer class="footer">
  129. <button type="button" class="continue-btn" id="btnContinue">和U宝继续聊 →</button>
  130. </footer>
  131. <script>
  132. (function () {
  133. var APP_DEEPLINK = "shopro://pages/aiSearchResult/index?pageType=home";
  134. function escHtml(s) {
  135. return String(s || "")
  136. .replace(/&/g, "&amp;")
  137. .replace(/</g, "&lt;")
  138. .replace(/>/g, "&gt;")
  139. .replace(/"/g, "&quot;");
  140. }
  141. function getQueryParam(name) {
  142. var m = new RegExp("[?&]" + name + "=([^&]*)").exec(window.location.search);
  143. if (!m) return "";
  144. try {
  145. return decodeURIComponent(m[1].replace(/\+/g, " "));
  146. } catch (e) {
  147. return "";
  148. }
  149. }
  150. function parsePayload() {
  151. var raw = getQueryParam("payload");
  152. if (!raw) return null;
  153. try {
  154. return JSON.parse(raw);
  155. } catch (e) {
  156. return null;
  157. }
  158. }
  159. function getFirstUserQuestion(messages) {
  160. var list = Array.isArray(messages) ? messages : [];
  161. for (var i = 0; i < list.length; i++) {
  162. var m = list[i];
  163. if (!m || m.role !== "user") continue;
  164. if (m.isImage) return "[图片]";
  165. var t = String(m.content || "").trim();
  166. if (t) return t;
  167. }
  168. return "";
  169. }
  170. function formatDiscussionTitle(question) {
  171. var q = String(question || "").trim();
  172. if (!q) return "与AI助手对话";
  173. if (q.slice(-3) === "的讨论") return q;
  174. return q + "的讨论";
  175. }
  176. function formatDate(ts) {
  177. var d = ts ? new Date(Number(ts)) : new Date();
  178. if (isNaN(d.getTime())) d = new Date();
  179. return d.getFullYear() + "年" + (d.getMonth() + 1) + "月" + d.getDate() + "日";
  180. }
  181. function renderMessages(messages) {
  182. var html = "";
  183. var list = Array.isArray(messages) ? messages : [];
  184. for (var i = 0; i < list.length; i++) {
  185. var msg = list[i];
  186. if (!msg) continue;
  187. if (msg.role === "user") {
  188. var userText = msg.isImage ? "[图片]" : String(msg.content || "").trim();
  189. if (!userText) continue;
  190. html +=
  191. '<div class="row row--user"><div class="user-bubble">' +
  192. escHtml(userText) +
  193. "</div></div>";
  194. continue;
  195. }
  196. if (msg.role === "ai") {
  197. var aiText = String(msg.content || "").trim();
  198. if (!aiText) continue;
  199. html +=
  200. '<div class="row row--ai"><div class="ai-card"><div class="ai-card__text">' +
  201. escHtml(aiText) +
  202. "</div></div></div>";
  203. }
  204. }
  205. return html;
  206. }
  207. function render(data) {
  208. var main = document.getElementById("main");
  209. if (!data) {
  210. main.innerHTML = '<div class="empty">对话内容不存在或链接已失效</div>';
  211. return;
  212. }
  213. var messages = data.messages || [];
  214. var firstQuestion =
  215. String(data.firstQuestion || "").trim() || getFirstUserQuestion(messages);
  216. var pageTitle = formatDiscussionTitle(firstQuestion);
  217. var dateText = formatDate(data.shareTime);
  218. document.title = pageTitle;
  219. var bodyHtml =
  220. '<section class="hero">' +
  221. '<h1 class="hero__title">' +
  222. escHtml(pageTitle) +
  223. "</h1>" +
  224. '<p class="hero__meta">' +
  225. escHtml(dateText) +
  226. " · 内容由AI生成,不能完全保障真实</p>" +
  227. '<div class="hero__divider"></div>' +
  228. "</section>";
  229. var convHtml = renderMessages(messages);
  230. if (convHtml) {
  231. bodyHtml += '<section class="conversation">' + convHtml + "</section>";
  232. } else if (data.content) {
  233. bodyHtml +=
  234. '<section class="fallback-card"><div class="ai-card__text">' +
  235. escHtml(data.content) +
  236. "</div></section>";
  237. } else {
  238. bodyHtml += '<div class="empty">暂无对话内容</div>';
  239. }
  240. main.innerHTML = bodyHtml;
  241. }
  242. function openApp() {
  243. var start = Date.now();
  244. window.location.href = APP_DEEPLINK;
  245. setTimeout(function () {
  246. if (Date.now() - start < 2800) {
  247. window.location.href = "https://www.ailien.shop/";
  248. }
  249. }, 2500);
  250. }
  251. document.getElementById("btnContinue").addEventListener("click", openApp);
  252. render(parsePayload());
  253. })();
  254. </script>
  255. </body>
  256. </html>