lxr 6 дней назад
Родитель
Сommit
1a8eae5d08
1 измененных файлов с 99 добавлено и 2 удалено
  1. 99 2
      HBuilderProjects/shareAiConsult.html

+ 99 - 2
HBuilderProjects/shareAiConsult.html

@@ -125,6 +125,20 @@
       text-align: left;
       text-align: left;
     }
     }
 
 
+    .ai-card__image {
+      display: block;
+      max-width: 100%;
+      height: auto;
+      margin: 8px 0;
+      border-radius: 6px;
+    }
+
+    .user-bubble__image {
+      display: block;
+      max-width: 180px;
+      border-radius: 4px;
+    }
+
     .fallback-card {
     .fallback-card {
       margin: 14px 15px 0;
       margin: 14px 15px 0;
       padding: 14px 13px;
       padding: 14px 13px;
@@ -314,6 +328,82 @@
           .replace(/"/g, """);
           .replace(/"/g, """);
       }
       }
 
 
+      var IMAGE_EXT = "(?:jpe?g|png|gif|webp|bmp|avif)";
+      var IMAGE_URL_PATTERN =
+        "https?:\\/\\/[^\\s))\\]]+\\." + IMAGE_EXT + "(?:\\?[^\\s))\\]]*)?";
+
+      function isInsideImageUrlSyntax(full, offset) {
+        if (offset >= 2 && full.slice(offset - 2, offset) === "](") return true;
+        if (offset >= 1 && full[offset - 1] === "(") return true;
+        if (offset >= 6 && full.slice(offset - 6, offset) === "{{IMG|") return true;
+        return false;
+      }
+
+      /** AI 回复常见:店名(https://...jpg) — 转为可渲染的图片占位 */
+      function embedInlineImageUrls(text) {
+        if (text == null) return "";
+        var t = String(text);
+
+        t = t.replace(
+          new RegExp("([^\\n((]+?)\\((" + IMAGE_URL_PATTERN + ")\\)", "gi"),
+          function (_, label, url) {
+            var name = String(label).trim();
+            if (!name) return "\n\n{{IMG|" + url + "|}}\n\n";
+            var alt = name.length > 24 ? "图片" : name.replace(/[\[\]]/g, "");
+            return name + "\n\n{{IMG|" + url + "|" + alt + "}}\n\n";
+          }
+        );
+
+        t = t.replace(
+          new RegExp("\\((" + IMAGE_URL_PATTERN + ")\\)", "gi"),
+          function (_, url) {
+            return "\n\n{{IMG|" + url + "|}}\n\n";
+          }
+        );
+
+        t = t.replace(new RegExp(IMAGE_URL_PATTERN, "gi"), function (url, offset, full) {
+          if (isInsideImageUrlSyntax(full, offset)) return url;
+          return "\n\n{{IMG|" + url + "|}}\n\n";
+        });
+
+        return t.replace(/\n{3,}/g, "\n\n");
+      }
+
+      function formatTextBlockHtml(text) {
+        return escHtml(text).replace(/\n/g, "<br>");
+      }
+
+      function buildAiImageTag(url, alt) {
+        var safeUrl = escHtml(url);
+        var safeAlt = escHtml(alt || "图片");
+        return (
+          '<img class="ai-card__image" src="' +
+          safeUrl +
+          '" alt="' +
+          safeAlt +
+          '" loading="lazy" decoding="async" />'
+        );
+      }
+
+      function renderAiContentHtml(text) {
+        var t = embedInlineImageUrls(text);
+        var html = "";
+        var tokenRe = /\{\{IMG\|([^|]+)\|([^}]*)\}\}/g;
+        var lastIndex = 0;
+        var match;
+        while ((match = tokenRe.exec(t)) !== null) {
+          if (match.index > lastIndex) {
+            html += formatTextBlockHtml(t.slice(lastIndex, match.index));
+          }
+          html += buildAiImageTag(match[1], match[2]);
+          lastIndex = tokenRe.lastIndex;
+        }
+        if (lastIndex < t.length) {
+          html += formatTextBlockHtml(t.slice(lastIndex));
+        }
+        return html;
+      }
+
       function q(name) {
       function q(name) {
         try {
         try {
           var v = new URLSearchParams(location.search || "").get(name);
           var v = new URLSearchParams(location.search || "").get(name);
@@ -375,7 +465,14 @@
           var msg = list[i];
           var msg = list[i];
           if (!msg) continue;
           if (!msg) continue;
           if (msg.role === "user") {
           if (msg.role === "user") {
-            var userText = msg.isImage ? "[图片]" : String(msg.content || "").trim();
+            if (msg.isImage && msg.imageUrl) {
+              html +=
+                '<div class="row row--user"><div class="user-bubble"><img class="user-bubble__image" src="' +
+                escHtml(msg.imageUrl) +
+                '" alt="图片" loading="lazy" decoding="async" /></div></div>';
+              continue;
+            }
+            var userText = String(msg.content || "").trim();
             if (!userText) continue;
             if (!userText) continue;
             html +=
             html +=
               '<div class="row row--user"><div class="user-bubble">' +
               '<div class="row row--user"><div class="user-bubble">' +
@@ -388,7 +485,7 @@
             if (!aiText) continue;
             if (!aiText) continue;
             html +=
             html +=
               '<div class="row row--ai"><div class="ai-card"><div class="ai-card__text">' +
               '<div class="row row--ai"><div class="ai-card"><div class="ai-card__text">' +
-              escHtml(aiText) +
+              renderAiContentHtml(aiText) +
               "</div></div></div>";
               "</div></div></div>";
           }
           }
         }
         }