国内流行的内容管理系统(CMS)多端全媒体解决方案 https://www.dedebiz.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ai_dialog.php 11KB

6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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" role="alert">
  48. <span>处理过程中请勿关闭当前对话框,否则富文本处理将终止</span>
  49. </div>
  50. </div>
  51. <div class="form-group">
  52. <textarea id="prompt" class="form-control" style="height:160px" placeholder="请输入内容处理要求,例如:我需要将内容润色下,希望更专业"></textarea>
  53. </div>
  54. <div class="form-group">
  55. <label for="modelid" class="form-label">选择模型</label>
  56. <select id="modelid" class="form-control">
  57. <?php
  58. $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");
  59. $dsql->Execute();
  60. while ($row = $dsql->GetObject()) {
  61. ?>
  62. <option value="<?php echo $row->id; ?>" <?php echo $row->isdefault == 1 ? ' selected' : ''; ?>><?php echo $row->model; ?> <?php echo $row->aititle; ?></option>
  63. <?php
  64. }
  65. ?>
  66. </select>
  67. </div>
  68. <div class="form-group">
  69. <button type="button" id="btnAIAction" class="btn btn-success btn-sm">确定</button>
  70. </div>
  71. </div>
  72. </div>
  73. <script>
  74. $("#btnAIAction").click(async function() {
  75. let body = window.opener.CKEDITOR.instances["<?php echo $f ?>"].getData();
  76. console.log(body);
  77. let prompt = document.getElementById("prompt").value;
  78. let modelid = document.getElementById("modelid").value;
  79. let req = await fetch(`api.php?action=get_ai_server&pname=body_edit&modelid=${modelid}&prompt=${prompt}`);
  80. let resp = await req.json();
  81. if (resp.code !== 0) {
  82. ShowMsg("获取服务器地址失败");
  83. return
  84. }
  85. let req2 = await fetch(`api.php?action=get_setbody_url`);
  86. let resp2 = await req2.json();
  87. if (resp2.code !== 0) {
  88. ShowMsg("获取服务器地址失败");
  89. return
  90. }
  91. let req3 = await fetch(resp2.data, {
  92. method: 'POST',
  93. headers: {
  94. 'Content-Type': 'application/x-www-form-urlencoded'
  95. },
  96. body: new URLSearchParams({
  97. body: body
  98. })
  99. });
  100. let resp3 = await req3.json();
  101. if (resp3.code !== 0) {
  102. ShowMsg("提交原始内容失败");
  103. return
  104. }
  105. let eventSource = new EventSource(resp.data);
  106. //新增状态跟踪变量
  107. let currentKey = null;
  108. let tagBuffer = "";
  109. let isClosingTag = false;
  110. $("#mdlAI").modal('hide');
  111. window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').disable();
  112. $("#btnAIAction").attr("disabled", "disabled");
  113. $("#prompt").attr("disabled", "disabled");
  114. $("#modelid").attr("disabled", "disabled");
  115. prompt = "";
  116. let bodyHtml = "";
  117. let lastChar = "";
  118. eventSource.onmessage = (event) => {
  119. const chars = event.data.split('');
  120. chars.forEach(char => {
  121. if (lastChar === '\\' && char === 'r') {
  122. char = '<br>'; //替换为br标签
  123. lastChar = ""; //清空追踪字符
  124. } else {
  125. lastChar = char; //记录当前字符
  126. }
  127. if (char === '\\') {
  128. return; //如果是反斜杠,跳过处理
  129. }
  130. if (currentKey) {
  131. if (char === '{') {
  132. isClosingTag = true;
  133. tagBuffer = '{';
  134. return;
  135. }
  136. if (isClosingTag) {
  137. tagBuffer += char;
  138. if (tagBuffer === `{/${currentKey}}`) {
  139. if (currentKey == "content") {
  140. window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(false);
  141. bodyHtml = "";
  142. } else {
  143. const input = document.querySelector(`[name="${currentKey}"]`);
  144. if (input) $(input).prop("disabled", false).removeClass("disabled"); //恢复输入状态
  145. }
  146. currentKey = null;
  147. isClosingTag = false;
  148. tagBuffer = "";
  149. return;
  150. }
  151. if (!`{/${currentKey}}`.startsWith(tagBuffer)) {
  152. if (currentKey == "content") {
  153. bodyHtml += tagBuffer;
  154. console.log(bodyHtml);
  155. window.opener.CKEDITOR.instances["<?php echo $f ?>"].setData(bodyHtml)
  156. } else {
  157. const input = document.querySelector(`[name="${currentKey}"]`);
  158. if (input) input.value += tagBuffer;
  159. }
  160. isClosingTag = false;
  161. tagBuffer = "";
  162. }
  163. } else {
  164. if (currentKey == "content") {
  165. bodyHtml += char;
  166. window.opener.CKEDITOR.instances["<?php echo $f ?>"].setData(bodyHtml)
  167. } else {
  168. const input = document.querySelector(`[name="${currentKey}"]`);
  169. if (input) {
  170. input.value += char;
  171. input.scrollTop = input.scrollHeight; //滚动到底部
  172. }
  173. }
  174. }
  175. } else {
  176. if (char === '{') {
  177. tagBuffer = '{';
  178. } else if (tagBuffer.startsWith('{')) {
  179. tagBuffer += char;
  180. if (char === '}') {
  181. const match = tagBuffer.match(/{([^>]+)}/);
  182. if (match) {
  183. currentKey = match[1];
  184. if (currentKey == "content") {
  185. window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(true);
  186. } else {
  187. const input = document.querySelector(`[name="${currentKey}"]`);
  188. if (input) {
  189. $(input).prop("disabled", true).addClass("disabled"); //仅禁用当前输入框
  190. input.value = "";
  191. }
  192. }
  193. }
  194. tagBuffer = "";
  195. }
  196. }
  197. }
  198. });
  199. };
  200. eventSource.onerror = (error) => {
  201. if (error.target.readyState === EventSource.CONNECTING) {
  202. ShowMsg("连接失败,请确保您已开启并正确配置了DedeBIZ小德AI助手。 <a class='text-success' href='https://www.dedebiz.com/ai?from=dedebiz' target='_blank'>如何配置?</a>");
  203. } else if (typeof error.data !== "undefined" && error.data !== "" && error.target.readyState !== EventSource.CLOSED) {
  204. ShowMsg(error.data);
  205. }
  206. window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').enable();
  207. $("#btnAI").prop("disabled", false);
  208. $("#btnAIAction").prop("disabled", false);
  209. $("#prompt").prop("disabled", false);
  210. $("#modelid").prop("disabled", false);
  211. eventSource.close();
  212. };
  213. //监听特定事件close
  214. eventSource.addEventListener('close', (event) => {
  215. console.log('SSE connection closed:', event.data);
  216. window.opener.CKEDITOR.instances["<?php echo $f ?>"].getCommand('openDedeBIZAi').enable();
  217. $("#btnAIAction").prop("disabled", false);
  218. $("#prompt").prop("disabled", false);
  219. $("#modelid").prop("disabled", false);
  220. eventSource.close(); //关闭连接
  221. window.opener.CKEDITOR.instances["<?php echo $f ?>"].setReadOnly(false);
  222. });
  223. });
  224. </script>
  225. </body>
  226. </html>