国内流行的内容管理系统(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.

569 lines
26KB

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
  6. <title>修改栏目</title>
  7. <link rel="stylesheet" href="/static/web/css/font-awesome.min.css">
  8. <link rel="stylesheet" href="/static/web/css/bootstrap.min.css">
  9. <link rel="stylesheet" href="/static/web/css/admin.css">
  10. <script src="/static/web/js/jquery.min.js"></script>
  11. <script src="/static/web/js/bootstrap.min.js"></script>
  12. <script src="/static/web/js/admin.main.js"></script>
  13. </head>
  14. <body>
  15. <div class="container-fluid">
  16. <ol class="breadcrumb">
  17. <li class="breadcrumb-item"><a href="index_body.php">后台面板</a></li>
  18. <li class="breadcrumb-item"><a href="catalog_main.php">网站栏目管理</a></li>
  19. <li class="breadcrumb-item active">修改栏目</li>
  20. </ol>
  21. <div class="card shadow-sm">
  22. <div class="card-header d-flex justify-content-between align-items-center"><span>修改栏目</span><?php if ($cfg_ai_enabled == 'Y'){;?><button type="button" id="btnAI" onclick="showAI();" class="btn btn-success btn-sm">小德AI助手</button><?php };?></div>
  23. <div class="card-body">
  24. <form name="form1" action="catalog_edit.php" method="post">
  25. <input type="hidden" name="dopost" value="save">
  26. <input type="hidden" name="id" value="<?php echo $id;?>">
  27. <input type="hidden" name="topid" value="<?php echo $myrow['topid'];?>">
  28. <div class="table-responsive">
  29. <table class="table table-borderless">
  30. <tbody>
  31. <tr>
  32. <td width="10%">是否支持投稿</td>
  33. <td width="40%">
  34. <label><input type="radio" name="issend" value="1" <?php if ($myrow['issend']=="1") echo 'checked';?>> 支持</label>
  35. <label><input type="radio" name="issend" value="0" <?php if ($myrow['issend']=="0") echo 'checked';?>> 不支持</label>
  36. </td>
  37. <td width="10%">是否隐藏栏目</td>
  38. <td width="40%">
  39. <label><input type="radio" name="ishidden" value="0" <?php if ($myrow['ishidden']=="0") echo 'checked';?>> 显示</label>
  40. <label><input type="radio" name="ishidden" value="1" <?php if ($myrow['ishidden']=="1") echo 'checked';?>> 隐藏</label>
  41. </td>
  42. </tr>
  43. <tr>
  44. <td>文档模型</td>
  45. <td>
  46. <input type="hidden" value="{style}" name="dfstyle">
  47. <select name="channeltype" id="channeltype" onChange="ParTemplet(this);" class="admin-input-sm">
  48. <?php
  49. foreach($channelArray as $k=>$arr)
  50. {
  51. if ($k==$channelid) echo " <option value='{$k}' selected>{$arr['typename']} {$arr['nid']}</option>";
  52. else echo " <option value='{$k}'>{$arr['typename']} {$arr['nid']}</option>";
  53. }
  54. ?>
  55. </select>
  56. <div id="smclass" class="mt-2" style="<?php echo ($channelid<0 ? '' : 'display:none');?>">
  57. <select name="smalltype[]" multiple="yes" class="admin-input-lg">
  58. <?php
  59. $smtypes = explode(',',trim($myrow['smalltypes']));
  60. $sql = "SELECT * FROM `#@__sys_enum` WHERE egroup LIKE 'infotype' ORDER BY disorder ASC,evalue ASC ";
  61. $dsql->Execute('s',$sql);
  62. while($arr = $dsql->GetArray('s'))
  63. {
  64. if (in_array($arr['evalue'],$smtypes)) {
  65. $selstr = " selected='1' ";
  66. } else {
  67. $selstr = '';
  68. }
  69. if ($arr['evalue']%500==0) {
  70. echo "<option value='{$arr['evalue']}'{$selstr}>{$arr['ename']}</option>";
  71. } else if (preg_match("#\.#", $arr['evalue'])) {
  72. echo "<option value='{$arr['evalue']}'{$selstr}>└── {$arr['ename']}</option>";
  73. } else {
  74. echo "<option value='{$arr['evalue']}'{$selstr}>└─ {$arr['ename']}</option>";
  75. }
  76. }
  77. ?>
  78. </select>
  79. <span>(请选栏目的信息联动类型支持多选)</span>
  80. </div>
  81. </td>
  82. <td>上级目录</td>
  83. <td>
  84. <?php
  85. $pardir = '{cmspath}'.$cfg_arcdir;
  86. if (!empty($typedir)) $pardir = $typedir.'/';
  87. $pardir = preg_replace("#\/{1,}#", '/', $pardir);
  88. echo $pardir;
  89. ?>
  90. <input type="hidden" name="nextdir" id="nextdir" value="<?php echo $pardir?>">
  91. </td>
  92. </tr>
  93. <tr>
  94. <td>中文名称</td>
  95. <td><input type="text" name="typename" value="<?php echo $myrow['typename']?>" class="admin-input-lg" required></td>
  96. <td>中文概述</td>
  97. <td><input type="text" name="cnoverview" value="<?php echo $myrow['cnoverview']?>" class="admin-input-lg"></td>
  98. </tr>
  99. <tr>
  100. <td>英文名称</td>
  101. <td><input type="text" name="enname" value="<?php echo $myrow['enname']?>" class="admin-input-lg"></td>
  102. <td>英文概述</td>
  103. <td><input type="text" name="enoverview" value="<?php echo $myrow['enoverview']?>" class="admin-input-lg"></td>
  104. </tr>
  105. <tr>
  106. <td>栏目大图</td>
  107. <td>
  108. <input type="text" name="bigpic" value="<?php echo $myrow['bigpic']?>" class="admin-input-lg">
  109. <button type="button" class="btn btn-success btn-sm" onclick="SelectImage('form1.bigpic');">选择</button>
  110. </td>
  111. <td>栏目小图</td>
  112. <td>
  113. <input type="text" name="litimg" value="<?php echo $myrow['litimg']?>" class="admin-input-lg">
  114. <button type="button" class="btn btn-success btn-sm" onclick="SelectImage('form1.litimg');">选择</button>
  115. </td>
  116. </tr>
  117. <tr>
  118. <td>排列顺序</td>
  119. <td><input type="text" name="sortrank" value="<?php echo $myrow['sortrank']?>" class="admin-input-sm">(由低到高)</td>
  120. <td>浏览权限</td>
  121. <td>
  122. <select name="corank" id="corank" class="admin-input-sm">
  123. <?php
  124. $dsql->SetQuery("SELECT * FROM `#@__arcrank` WHERE `rank` >= 0 ORDER BY `rank` ASC");
  125. $dsql->Execute('cc');
  126. while($row = $dsql->GetObject('cc'))
  127. {
  128. if ($myrow['corank']==$row->rank)
  129. echo "<option value='".$row->rank."' selected>".$row->membername."</option>";
  130. else
  131. echo "<option value='".$row->rank."'>".$row->membername."</option>";
  132. }
  133. ?>
  134. </select>
  135. <span>(暂不支持静态)</span>
  136. </td>
  137. </tr>
  138. <tr>
  139. <td>栏目生成目录</td>
  140. <td><input type="text" name="typedir" id="typedir" value="<?php echo $myrow['typedir']?>" class="admin-input-lg"></td>
  141. <td>是否继承选项</td>
  142. <td><label><input type="checkbox" name="upnext" id="upnext" value="1"> 子类栏目继承顶级栏目的浏览权限、文档类型、模板风格等属性</label></td>
  143. </tr>
  144. <tr>
  145. <td>栏目列表选项</td>
  146. <td>
  147. <label><input type="radio" name="isdefault" value="1" <?php if ($myrow['isdefault']==1) echo 'checked';?>> 静态浏览</label>
  148. <label><input type="radio" name="isdefault" value="-1" <?php if ($myrow['isdefault']==-1) echo 'checked';?>> 动态浏览</label>
  149. <label><input type="radio" name="isdefault" value="0" <?php if ($myrow['isdefault']==0) echo 'checked';?>> 列表第一页浏览</label>
  150. </td>
  151. <td>默认页的名称</td>
  152. <td><input type="text" name="defaultname" value="<?php echo $myrow['defaultname']?>" class="admin-input-lg"></td>
  153. </tr>
  154. <tr>
  155. <td>栏目属性</td>
  156. <td>
  157. <label><input type="radio" name="ispart" value="0" <?php if ($myrow['ispart']==0) echo 'checked';?>> 列表栏目(允许发布)</label>
  158. <label><input type="radio" name="ispart" value="1" <?php if ($myrow['ispart']==1) echo 'checked';?>> 封面栏目(不允许发布)</label>
  159. <label><input type="radio" name="ispart" value="2" <?php if ($myrow['ispart']==2) echo 'checked';?>> 外部栏目(栏目生成目录填写链接)</label>
  160. </td>
  161. <td>栏目交叉</td>
  162. <td>
  163. <label><input type="radio" name="cross" id="cross0" value="0" onclick="CheckCross();" <?php if ($myrow['cross']==0) echo 'checked';?>> 不交叉</label>
  164. <label><input type="radio" name="cross" id="cross1" value="1" onclick="CheckCross();" <?php if ($myrow['cross']==1) echo 'checked';?>> 自动获取同名栏目</label>
  165. <label><input type="radio" name="cross" id="cross2" value="2" onclick="CheckCross();" <?php if ($myrow['cross']==2) echo 'checked';?>> 指定交叉栏目id(英文逗号隔开)</label>
  166. <a href="javascript:ShowHide('helpvarco');" class="btn btn-success btn-sm">说明</a>
  167. <div id="crossid" style="<?php if ($myrow['cross']!=2) echo'display:none';?>"><textarea name="crossid" class="admin-textarea-sm"><?php echo $myrow['crossid'];?></textarea></div>
  168. <div id="helpvarco" class="alert alert-secondary my-2" style="display:none">交叉栏目该栏目与另一个非子栏目交叉的情况,相当于副栏目功能</div>
  169. </td>
  170. </tr>
  171. <tr>
  172. <td width="260">多站点支持</td>
  173. <td>
  174. <label><input type="radio" name="moresite" value="1" <?php if ($myrow['moresite']==1) echo 'checked';?>> 启用</label>
  175. <label><input type="radio" name="moresite" value="0" <?php if ($myrow['moresite']==0) echo 'checked';?>> 不启用</label>
  176. <span>(仅顶级栏目启用,子类栏目无效)</span>
  177. </td>
  178. <td>绑定域名</td>
  179. <td><input type="text" name="siteurl" id="siteurl" value="<?php echo $myrow['siteurl']?>" class="admin-input-lg">(请输入绑定域名http开头)</td>
  180. </tr>
  181. <tr>
  182. <td>列表模板</td>
  183. <td>
  184. <input type="text" name="templist" value="<?php echo $myrow['templist']?>" class="admin-input-lg">
  185. <button type="button" class="btn btn-success btn-sm" onclick="SelectTemplets('form1.templist')">选择</button>
  186. </td>
  187. <td>封面模板</td>
  188. <td>
  189. <input type="text" name="tempindex" value="<?php echo $myrow['tempindex']?>" class="admin-input-lg">
  190. <button type="button" class="btn btn-success btn-sm" onclick="SelectTemplets('form1.tempindex')">选择</button>
  191. <a href="javascript:ShowHide('helpvar1');" class="btn btn-success btn-sm">说明</a>
  192. <div id="helpvar1" class="alert alert-secondary my-2" style="display:none">
  193. <p>{tid} 栏目id</p>
  194. <p>{cid} 栏目模型名字id</p>
  195. </div>
  196. </td>
  197. </tr>
  198. <tr>
  199. <td>文档模板</td>
  200. <td>
  201. <input type="text" name="temparticle" value="<?php echo $myrow['temparticle']?>" class="admin-input-lg">
  202. <button type="button" class="btn btn-success btn-sm" onclick="SelectTemplets('form1.temparticle')">选择</button>
  203. </td>
  204. <td>列表命名规则</td>
  205. <td>
  206. <input type="text" name="namerule2" id="namerule2" value="<?php echo $myrow['namerule2']?>" class="admin-input-lg">
  207. <a href="javascript:ShowHide('helpvar2');" class="btn btn-success btn-sm">说明</a>
  208. <div id="helpvar2" class="alert alert-secondary my-2" style="display:none">
  209. <p>静态规则</p>
  210. <p>{tid} 栏目id</p>
  211. <p>{page} 栏目页码数</p>
  212. <p>伪静态规则(Nginx)</p>
  213. <p>rewrite ^/list/([0-9]+)$ /apps/list.php?tid=$1;</p>
  214. <p>rewrite ^/list/([0-9]+)-([0-9]+)$ /apps/list.php?tid=$1&PageNo=$2;</p>
  215. </div>
  216. </td>
  217. </tr>
  218. <tr>
  219. <td>文档命名规则</td>
  220. <td>
  221. <input type="text" name="namerule" id="namerule" value="<?php echo $myrow['namerule']?>" class="admin-input-lg">
  222. <a href="javascript:ShowHide('helpvar3');" class="btn btn-success btn-sm">说明</a>
  223. <div id="helpvar3" class="alert alert-secondary my-2" style="display:none">
  224. <p>静态规则</p>
  225. <p>{Y}{M}{D} 年月日</p>
  226. <p>{timestamp} INT类型的UNIX时间戳</p>
  227. <p>{aid} 文档id</p>
  228. <p>{pinyin} 拼音加文档id</p>
  229. <p>{py} 拼音部首加文档id</p>
  230. <p>{typedir} 栏目保存目录</p>
  231. <p>{cc} 日期加混编id后用转换为适合字母</p>
  232. <p>伪静态规则(Nginx)</p>
  233. <p>rewrite ^/article/([0-9]+).html$ /apps/view.php?aid=$1;</p>
  234. <p>rewrite ^/article/([0-9]+)-([0-9]+).html$ /apps/view.php?aid=$1&PageNo=$2;</p>
  235. </div>
  236. </td>
  237. <td>SEO标题</td>
  238. <td><input type="text" name="seotitle" id="seotitle" value="<?php echo $myrow['seotitle']?>" class="admin-input-lg">(标签{dede:field.seotitle/}调用)</td>
  239. </tr>
  240. <tr>
  241. <td>关键词</td>
  242. <td>
  243. <textarea name="keywords" cid="keywords" class="admin-textarea-sm"><?php echo $myrow['keywords']?></textarea>
  244. <span>(标签{dede:field.keywords/}调用)</span>
  245. </td>
  246. <td>描述</td>
  247. <td>
  248. <textarea name="description" id="description" class="admin-textarea-sm"><?php echo $myrow['description']?></textarea>
  249. <span>(标签{dede:field.description/}调用)</span>
  250. </td>
  251. </tr>
  252. <tr>
  253. <td>栏目文档</td>
  254. <td>(标签{dede:field.content/}调用)</td>
  255. <td>是否支持跨站调用</td>
  256. <td>
  257. <input value="<?php echo $myrow['apikey']?>" type="text" name="apikey" id="apikey" class="admin-input-lg" placeholder="请输入跨站调用秘钥">
  258. <label><input type="radio" name="apienabled" value="1" <?php if ($myrow['apienabled']=="1") echo 'checked';?>> 支持</label>
  259. <label><input type="radio" name="apienabled" value="0" <?php if ($myrow['apienabled']=="0") echo 'checked';?>> 不支持</label>
  260. <a href="javascript:makeAPIKey();" class="btn btn-success btn-sm">更新</i></a>
  261. <a href="javascript:showAPI(<?php echo $id;?>);" class="btn btn-success btn-sm">说明</a>
  262. </td>
  263. </tr>
  264. <tr>
  265. <td colspan="4"><?php GetEditor("content",$myrow['content'],"400","Default","print","false");?></td>
  266. </tr>
  267. <tr>
  268. <td align="center" colspan="4">
  269. <button type="submit" class="btn btn-success btn-sm">保存</button>
  270. <a href="catalog_main.php" class="btn btn-outline-success btn-sm">返回</a>
  271. </td>
  272. </tr>
  273. </tbody>
  274. </table>
  275. </div>
  276. </form>
  277. </div>
  278. </div>
  279. </div>
  280. <div id="mdlViewAPI" class="modal fade" tabindex="-1" aria-hidden="true">
  281. <div class="modal-dialog modal-xl">
  282. <div class="modal-content">
  283. <div class="modal-header">
  284. <h5 class="modal-title">跨站调用</h5>
  285. <button type="button" class="update-close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times"></i></button>
  286. </div>
  287. <div class="modal-body">
  288. <form>
  289. <div class="form-group">
  290. <span>跨站调用功能用于同后台管理或其他网站之间调用栏目文档数据</span>
  291. </div>
  292. <div class="form-group">
  293. <label for="iptAPICode" class="mb-3">代码示例</label>
  294. <div class="nav nav-pills mb-3" id="data-tab" role="tablist">
  295. <button type="button" class="nav-link active" id="php-tab" data-toggle="tab" data-target="#nav-php" role="tab" aria-controls="nav-php" aria-selected="true">PHP</button>
  296. <button type="button" class="nav-link" id="js-tab" data-toggle="tab" data-target="#nav-js" role="tab" aria-controls="nav-js" aria-selected="true">Javasctipt</button>
  297. <button type="button" class="nav-link" id="go-tab" data-toggle="tab" data-target="#nav-go" role="tab" aria-controls="nav-go" aria-selected="false">Go</button>
  298. <button type="button" class="nav-link" id="python-tab" data-toggle="tab" data-target="#nav-python" role="tab" aria-controls="nav-python" aria-selected="false">Python3</button>
  299. </div>
  300. <div class="tab-content" id="data-tabContent">
  301. <div class="tab-pane fade show active" id="nav-php" role="tabpanel" aria-labelledby="php-tab">
  302. <pre><code id="codephp"></code></pre></div>
  303. <div class="tab-pane fade" id="nav-js" role="tabpanel" aria-labelledby="js-tab">
  304. <pre><code id="codejs"></code></pre>
  305. </div>
  306. <div class="tab-pane fade" id="nav-go" role="tabpanel" aria-labelledby="go-tab">
  307. <pre><code id="codego"></code></pre>
  308. </div>
  309. <div class="tab-pane fade" id="nav-python" role="tabpanel" aria-labelledby="python-tab">
  310. <pre><code id="codepython"></code></pre>
  311. </div>
  312. </div>
  313. </div>
  314. <div class="form-group">
  315. <label for="iptAPITag" class="mb-3">标签示例</label>
  316. <pre><code id="codetag"></code></pre>
  317. </div>
  318. </form>
  319. </div>
  320. <div class="modal-footer">
  321. <div class="btnStep"><button id="btnGoStep4" type="button" class="btn btn-success btn-sm" data-dismiss="modal">关闭</button></div>
  322. </div>
  323. </div>
  324. </div>
  325. </div>
  326. <div id="mdlAI" class="modal fade" tabindex="-1" aria-hidden="true">
  327. <div class="modal-dialog modal-xl">
  328. <div class="modal-content">
  329. <div class="modal-header">
  330. <h5 class="modal-title">小德AI助手:修改栏目</h5>
  331. <button type="button" class="update-close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times"></i></button>
  332. </div>
  333. <div class="modal-body">
  334. <form>
  335. <div class="form-group">
  336. <textarea id="prompt" class="form-control" style="height:160px" placeholder="请输入修改栏目要求,例如:我需要栏目信息内容更丰富一些"></textarea>
  337. </div>
  338. <div class="form-group">
  339. <label for="modelid" class="form-label">选择模型</label>
  340. <select id="modelid" class="form-control">
  341. <?php
  342. $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");
  343. $dsql->Execute();
  344. while ($row = $dsql->GetObject()) {
  345. ?>
  346. <option value="<?php echo $row->id;?>" <?php echo $row->isdefault==1?' selected' : '';?>><?php echo $row->model;?> <?php echo $row->aititle;?></option>
  347. <?php
  348. }
  349. ?>
  350. </select>
  351. </div>
  352. </form>
  353. </div>
  354. <div class="modal-footer">
  355. <button id="btnAIAction" class="btn btn-success btn-sm">确定</button>
  356. </div>
  357. </div>
  358. </div>
  359. </div>
  360. <script>
  361. var channelArray = new Array();
  362. <?php
  363. $i = 0;
  364. foreach($channelArray as $k=> $arr)
  365. {
  366. echo "channelArray[$k] = \"{$arr['nid']}\";";
  367. }
  368. ?>
  369. function Nav() {
  370. if (window.navigator.userAgent.indexOf("MSIE") >= 1) return 'IE';
  371. else if (window.navigator.userAgent.indexOf("Firefox") >= 1) return 'FF';
  372. else return "OT";
  373. }
  374. function SelectTemplets(fname) {
  375. var pos = GetWinPos(800,600);
  376. window.open("./dialog/select_templets.php?f=" + fname, "poptempWin", "scrollbars=yes,resizable=yes,statebar=no,width=800,height=600,left=" + pos.left + ", top=" + pos.top);
  377. }
  378. function ShowHide(objname) {
  379. var obj = document.getElementById(objname);
  380. if (obj.style.display != "none")
  381. obj.style.display = "none";
  382. else {
  383. if (Nav() == 'IE') obj.style.display = "block";
  384. else obj.style.display = "block";
  385. }
  386. }
  387. function ShowObj(objname) {
  388. var obj = document.getElementById(objname);
  389. if (Nav() == 'IE') obj.style.display = "block";
  390. else obj.style.display = "block";
  391. }
  392. function HideObj(objname) {
  393. var obj = document.getElementById(objname);
  394. obj.style.display = "none";
  395. }
  396. function CheckTypeDir() {
  397. var upinyin = document.getElementById('upinyin');
  398. var tpobj = document.getElementById('typedir');
  399. if (upinyin.checked) tpobj.style.display = "none";
  400. else tpobj.style.display = "inline-block";
  401. }
  402. function ParTemplet(obj) {
  403. var sevvalue = channelArray[obj.value];
  404. var tobj = document.getElementById('smclass');
  405. var tempindex = document.getElementsByName('tempindex');
  406. var templist = document.getElementsByName('templist');
  407. var temparticle = document.getElementsByName('temparticle');
  408. var dfstyle = document.getElementsByName('dfstyle');
  409. var dfstyleValue = dfstyle[0].value;
  410. tempindex[0].value = dfstyleValue + "/index_" + sevvalue + ".htm";
  411. templist[0].value = dfstyleValue + "/list_" + sevvalue + ".htm";
  412. temparticle[0].value = dfstyleValue + "/article_" + sevvalue + ".htm";
  413. if (obj.value < 0) {
  414. if (Nav() == 'IE') tobj.style.display = "block";
  415. else tobj.style.display = "block";
  416. } else {
  417. tobj.style.display = "none";
  418. }
  419. }
  420. function CheckCross() {
  421. var cross2 = document.getElementById('cross2');
  422. var crossid = document.getElementById('crossid');
  423. if (cross2.checked) crossid.style.display = 'block';
  424. else crossid.style.display = 'none';
  425. }
  426. function makeAPIKey(){
  427. var apikey = document.getElementById('apikey');
  428. jQuery.get("sys_info.php?dopost=make_encode", function(data) {
  429. jQuery("#apikey").val(data);
  430. });
  431. }
  432. function showAPI(tid) {
  433. fetch('catalog_do.php?dopost=viewAPI&typeid=' + tid).then(resp => resp.text()).then((d) => {
  434. let data = JSON.parse(d);
  435. if (data.code == 0) {
  436. $("#codephp").html(data.data.phpcode);
  437. $("#codego").html(data.data.gocode);
  438. $("#codepython").html(data.data.pythoncode);
  439. $("#codejs").html(data.data.jscode);
  440. $("#codetag").html(data.data.tagcode);
  441. $("#mdlViewAPI").modal('show');
  442. }
  443. });
  444. }
  445. function showAI() {
  446. $("#mdlAI").modal('show');
  447. }
  448. let bodyHtml = "";
  449. $("#btnAIAction").click(async function() {
  450. let prompt = document.getElementById("prompt").value;
  451. let modelid = document.getElementById("modelid").value;
  452. let req = await fetch(`api.php?action=get_ai_server&pname=catalog_edit&tid=<?php echo $id?>&modelid=${modelid}&prompt=${prompt}`);
  453. let resp = await req.json();
  454. if (resp.code !== 0) {
  455. ShowMsg("获取服务器地址失败");
  456. return
  457. }
  458. let eventSource = new EventSource(resp.data);
  459. //新增状态跟踪变量
  460. let currentKey = null;
  461. let tagBuffer = "";
  462. let isClosingTag = false;
  463. $("#mdlAI").modal('hide');
  464. $("#btnAI").attr("disabled", "disabled");
  465. prompt = "";
  466. let lastChar = "";
  467. eventSource.onmessage = (event) => {
  468. const chars = event.data.split('');
  469. chars.forEach(char => {
  470. if (lastChar === '\\' && char === 'r') {
  471. char = '<br>'; //替换为br标签
  472. lastChar = ""; //清空追踪字符
  473. } else {
  474. lastChar = char; //记录当前字符
  475. }
  476. if (char === '\\') {
  477. return; //如果是反斜杠,跳过处理
  478. }
  479. if (currentKey) {
  480. if (char === '{') {
  481. isClosingTag = true;
  482. tagBuffer = '{';
  483. return;
  484. }
  485. if (isClosingTag) {
  486. tagBuffer += char;
  487. if (tagBuffer === `{/${currentKey}}`) {
  488. if (currentKey == "content") {
  489. CKEDITOR.instances["content"].setReadOnly(false);
  490. bodyHtml = "";
  491. } else {
  492. const input = document.querySelector(`[name="${currentKey}"]`);
  493. if (input) $(input).prop("disabled", false).removeClass("disabled"); //恢复输入状态
  494. }
  495. currentKey = null;
  496. isClosingTag = false;
  497. tagBuffer = "";
  498. return;
  499. }
  500. if (!`{/${currentKey}}`.startsWith(tagBuffer)) {
  501. if (currentKey == "content") {
  502. bodyHtml += tagBuffer;
  503. console.log(bodyHtml);
  504. CKEDITOR.instances["content"].setData(bodyHtml)
  505. } else {
  506. const input = document.querySelector(`[name="${currentKey}"]`);
  507. if (input) input.value += tagBuffer;
  508. }
  509. isClosingTag = false;
  510. tagBuffer = "";
  511. }
  512. } else {
  513. if (currentKey == "content") {
  514. bodyHtml += char;
  515. CKEDITOR.instances["content"].setData(bodyHtml)
  516. } else {
  517. const input = document.querySelector(`[name="${currentKey}"]`);
  518. if (input) {
  519. input.value += char;
  520. input.scrollTop = input.scrollHeight; //滚动到底部
  521. }
  522. }
  523. }
  524. } else {
  525. if (char === '{') {
  526. tagBuffer = '{';
  527. } else if (tagBuffer.startsWith('{')) {
  528. tagBuffer += char;
  529. if (char === '}') {
  530. const match = tagBuffer.match(/{([^>]+)}/);
  531. if (match) {
  532. currentKey = match[1];
  533. if (currentKey == "content") {
  534. CKEDITOR.instances["content"].setReadOnly(true);
  535. } else {
  536. const input = document.querySelector(`[name="${currentKey}"]`);
  537. if (input) {
  538. $(input).prop("disabled", true).addClass("disabled"); //仅禁用当前输入框
  539. input.value = "";
  540. }
  541. }
  542. }
  543. tagBuffer = "";
  544. }
  545. }
  546. }
  547. });
  548. };
  549. eventSource.onerror = (error) => {
  550. if (error.target.readyState === EventSource.CONNECTING) {
  551. ShowMsg("连接失败,请确保您已开启并正确配置了DedeBIZ小德AI助手。 <a class='text-success' href='https://www.dedebiz.com/ai?from=dedebiz' target='_blank'>如何配置?</a>");
  552. } else if (typeof error.data!=="undefined" && error.data !== "" && error.target.readyState !== EventSource.CLOSED) {
  553. ShowMsg(error.data);
  554. }
  555. $("#btnAI").prop("disabled", false);
  556. eventSource.close();
  557. };
  558. //监听特定事件close
  559. eventSource.addEventListener('close', (event) => {
  560. console.log('SSE connection closed:', event.data);
  561. $("#btnAI").prop("disabled", false);
  562. eventSource.close(); //关闭连接
  563. });
  564. });
  565. </script>
  566. </body>
  567. </html>