国内流行的内容管理系统(CMS)多端全媒体解决方案 https://www.dedebiz.com
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

221 řádky
11KB

  1. <?php
  2. /**
  3. * 小德AI助手对话框
  4. *
  5. * @version $id:ai_dialog.php 2025 tianya $
  6. * @package DedeBIZ.Dialog
  7. * @copyright Copyright (c) 2022 DedeBIZ.COM
  8. * @license GNU GPL v2 (https://www.dedebiz.com/license)
  9. * @link https://www.dedebiz.com
  10. */
  11. require_once(dirname(__FILE__) . "/config.php");
  12. if (empty($f)) {
  13. $f = 'form1.enclosure';
  14. }
  15. if (empty($comeback)) {
  16. $comeback = '';
  17. }
  18. $addparm = '';
  19. if (!empty($CKEditor)) {
  20. $addparm = '&CKEditor=' . $CKEditor;
  21. }
  22. if (!empty($CKEditorFuncNum)) {
  23. $addparm .= '&CKEditorFuncNum=' . $CKEditorFuncNum;
  24. }
  25. if (!empty($noeditor)) {
  26. $addparm .= '&noeditor=yes';
  27. }
  28. ?>
  29. <!DOCTYPE html>
  30. <html>
  31. <head>
  32. <meta charset="utf-8">
  33. <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
  34. <title>小德AI助手对话框</title>
  35. <link rel="stylesheet" href="/static/web/css/font-awesome.min.css">
  36. <link rel="stylesheet" href="/static/web/css/bootstrap.min.css">
  37. <link rel="stylesheet" href="/static/web/css/admin.css">
  38. <script src="/static/web/js/jquery.min.js"></script>
  39. <script src="/static/web/js/bootstrap.min.js"></script>
  40. <script src="/static/web/js/admin.main.js"></script>
  41. </head>
  42. <body class="p-3">
  43. <div class="card shadow-sm">
  44. <div class="card-header">小德AI助手:智能处理</div>
  45. <div class="card-body">
  46. <div class="form-group">
  47. <div class="alert alert-warning mb-0">处理过程中请勿关闭小德AI助手对话框</div>
  48. </div>
  49. <div class="form-group">
  50. <textarea id="prompt" class="form-control" style="height:160px" placeholder="请输入内容处理要求,例如:我需要将内容润色下,希望更专业"></textarea>
  51. </div>
  52. <div class="form-group">
  53. <label for="modelid" class="form-label">选择模型</label>
  54. <select id="modelid" class="form-control">
  55. <?php
  56. $dsql->SetQuery("SELECT AM.*,A.title as aititle FROM `#@__ai_model` AM LEFT JOIN `#@__ai` A ON A.id = AM.aiid ORDER BY AM.sortrank ASC,AM.id DESC");
  57. $dsql->Execute();
  58. while ($row = $dsql->GetObject()) {
  59. ?>
  60. <option value="<?php echo $row->id; ?>" <?php echo $row->isdefault == 1 ? ' selected' : ''; ?>><?php echo $row->model; ?> <?php echo $row->aititle; ?></option>
  61. <?php
  62. }
  63. ?>
  64. </select>
  65. </div>
  66. <button type="button" id="btnAIAction" class="btn btn-success btn-sm">确定</button>
  67. </div>
  68. </div>
  69. <script>
  70. $("#btnAIAction").click(async function() {
  71. let body = window.opener.CKEDITOR.instances["<?php echo $f ?>"].getData();
  72. let prompt = document.getElementById("prompt").value;
  73. let modelid = document.getElementById("modelid").value;
  74. let req = await fetch(`api.php?action=get_ai_server&pname=body_edit&modelid=${modelid}&prompt=${prompt}`);
  75. let resp = await req.json();
  76. if (resp.code !== 0) {
  77. ShowMsg("获取服务器地址失败");
  78. return
  79. }
  80. let req2 = await fetch(`api.php?action=get_setbody_url`);
  81. let resp2 = await req2.json();
  82. if (resp2.code !== 0) {
  83. ShowMsg("获取服务器地址失败");
  84. return
  85. }
  86. let req3 = await fetch(resp2.data, {
  87. method: 'POST',
  88. headers: {
  89. 'Content-Type': 'application/x-www-form-urlencoded'
  90. },
  91. body: new URLSearchParams({
  92. body: body
  93. })
  94. });
  95. let resp3 = await req3.json();
  96. if (resp3.code !== 0) {
  97. ShowMsg("提交原始内容失败");
  98. return
  99. }
  100. let eventSource = new EventSource(resp.data);
  101. //新增状态跟踪变量
  102. let currentKey = null;
  103. let tagBuffer = "";
  104. let isClosingTag = false;
  105. $("#mdlAI").modal('hide');
  106. window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').disable();
  107. $("#btnAIAction").attr("disabled", "disabled");
  108. $("#prompt").attr("disabled", "disabled");
  109. $("#modelid").attr("disabled", "disabled");
  110. prompt = "";
  111. let bodyHtml = "";
  112. let lastChar = "";
  113. eventSource.onmessage = (event) => {
  114. const chars = event.data.split('');
  115. chars.forEach(char => {
  116. if (lastChar === '\\' && char === 'r') {
  117. char = '<br>'; //替换为br标签
  118. lastChar = ""; //清空追踪字符
  119. } else {
  120. lastChar = char; //记录当前字符
  121. }
  122. if (char === '\\') {
  123. return; //如果是反斜杠,跳过处理
  124. }
  125. if (currentKey) {
  126. if (char === '{') {
  127. isClosingTag = true;
  128. tagBuffer = '{';
  129. return;
  130. }
  131. if (isClosingTag) {
  132. tagBuffer += char;
  133. if (tagBuffer === `{/${currentKey}}`) {
  134. if (currentKey == "content") {
  135. window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(false);
  136. bodyHtml = "";
  137. } else {
  138. const input = document.querySelector(`[name="${currentKey}"]`);
  139. if (input) $(input).prop("disabled", false).removeClass("disabled"); //恢复输入状态
  140. }
  141. currentKey = null;
  142. isClosingTag = false;
  143. tagBuffer = "";
  144. return;
  145. }
  146. if (!`{/${currentKey}}`.startsWith(tagBuffer)) {
  147. if (currentKey == "content") {
  148. bodyHtml += tagBuffer;
  149. console.log(bodyHtml);
  150. window.opener.CKEDITOR.instances["<?php echo $f ?>"].setData(bodyHtml)
  151. } else {
  152. const input = document.querySelector(`[name="${currentKey}"]`);
  153. if (input) input.value += tagBuffer;
  154. }
  155. isClosingTag = false;
  156. tagBuffer = "";
  157. }
  158. } else {
  159. if (currentKey == "content") {
  160. bodyHtml += char;
  161. window.opener.CKEDITOR.instances["<?php echo $f ?>"].setData(bodyHtml)
  162. } else {
  163. const input = document.querySelector(`[name="${currentKey}"]`);
  164. if (input) {
  165. input.value += char;
  166. input.scrollTop = input.scrollHeight; //滚动到底部
  167. }
  168. }
  169. }
  170. } else {
  171. if (char === '{') {
  172. tagBuffer = '{';
  173. } else if (tagBuffer.startsWith('{')) {
  174. tagBuffer += char;
  175. if (char === '}') {
  176. const match = tagBuffer.match(/{([^>]+)}/);
  177. if (match) {
  178. currentKey = match[1];
  179. if (currentKey == "content") {
  180. window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(true);
  181. } else {
  182. const input = document.querySelector(`[name="${currentKey}"]`);
  183. if (input) {
  184. $(input).prop("disabled", true).addClass("disabled"); //仅禁用当前输入框
  185. input.value = "";
  186. }
  187. }
  188. }
  189. tagBuffer = "";
  190. }
  191. }
  192. }
  193. });
  194. };
  195. eventSource.onerror = (error) => {
  196. if (error.target.readyState === EventSource.CONNECTING) {
  197. ShowMsg("连接失败,请确保您已开启并正确配置了DedeBIZ小德AI助手。 <a class='text-success' href='https://www.dedebiz.com/ai?from=dedebiz' target='_blank'>如何配置?</a>");
  198. } else if (typeof error.data !== "undefined" && error.data !== "" && error.target.readyState !== EventSource.CLOSED) {
  199. ShowMsg(error.data);
  200. }
  201. window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').enable();
  202. $("#btnAI").prop("disabled", false);
  203. $("#btnAIAction").prop("disabled", false);
  204. $("#prompt").prop("disabled", false);
  205. $("#modelid").prop("disabled", false);
  206. eventSource.close();
  207. };
  208. //监听特定事件close
  209. eventSource.addEventListener('close', (event) => {
  210. // console.log('SSE connection closed:', event.data);
  211. window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').enable();
  212. $("#btnAIAction").prop("disabled", false);
  213. $("#prompt").prop("disabled", false);
  214. $("#modelid").prop("disabled", false);
  215. eventSource.close(); //关闭连接
  216. window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(false);
  217. });
  218. });
  219. </script>
  220. </body>
  221. </html>