inputinject.html.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <?php
  2. /**
  3. * The ai input inject view file of ai module of ZenTaoPMS.
  4. *
  5. * This view file is used to inject ai generated result into
  6. * input fields. Include this view file in the target forms.
  7. *
  8. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
  9. * @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  10. * @author Wenrui LI <liwenrui@easycorp.ltd>
  11. * @package ai
  12. * @link https://www.zentao.net
  13. */
  14. ?>
  15. <?php
  16. $this->app->loadConfig('ai');
  17. $this->app->loadLang('ai');
  18. $module = $this->app->getModuleName();
  19. $method = $this->app->getMethodName();
  20. if(isset($config->ai->availableForms[$module]) && in_array($method, $config->ai->availableForms[$module])):
  21. ?>
  22. <?php
  23. if(isset($_SESSION['aiInjectData']) && isset($_SESSION['aiInjectData'][$module]) && isset($_SESSION['aiInjectData'][$module][$method])) $injectData = $_SESSION['aiInjectData'][$module][$method];
  24. if(!empty($injectData)):
  25. ?>
  26. <?php
  27. js::set('injectData', $injectData);
  28. unset($_SESSION['aiInjectData'][$module]);
  29. $this->app->loadLang('ai');
  30. ?>
  31. <script>
  32. (function()
  33. {
  34. function injectToInputElement(inputName, data, index)
  35. {
  36. if(typeof index !== 'undefined')
  37. {
  38. inputName = inputName + '[' + index + ']';
  39. }
  40. const $input = $('[name="' + inputName + '"]');
  41. if(!$input.length) return;
  42. const inputType = $input.prop('nodeName');
  43. switch(inputType) // Contains case fallthroughs, on purpose.
  44. {
  45. case 'TEXTAREA':
  46. /* Textareas might be controlled by KindEditors. */
  47. if(typeof KindEditor !== 'undefined' && KindEditor.instances.length)
  48. {
  49. const editorInstance = KindEditor.instances.find(function(e)
  50. {
  51. return e.srcElement.attr('name') == inputName;
  52. });
  53. if(editorInstance)
  54. {
  55. if(data === null) data = '';
  56. /* Remove placeholder. */
  57. if(data !== '') editorInstance.$placeholder.each(function(_idx, ph) {ph.style.display = 'none';});
  58. /* Set editor content and sync with textarea. */
  59. editorInstance.html(data);
  60. editorInstance.sync();
  61. break;
  62. }
  63. }
  64. default:
  65. /* For normal inputs, just set the value is enough. */
  66. $input.val(data);
  67. break;
  68. }
  69. }
  70. function inject(obj)
  71. {
  72. for(const key in obj)
  73. {
  74. duelWithSpecialInputType(key, obj[key]);
  75. if(Array.isArray(obj[key]))
  76. {
  77. const isStartWith0 = $('[name="' + key + '[0]' + '"]').length;
  78. const arr = obj[key];
  79. for(let i = 0; i < arr.length; i++)
  80. {
  81. for(const key in arr[i])
  82. {
  83. injectToInputElement(key, arr[i][key], isStartWith0 ? i : i + 1);
  84. }
  85. }
  86. }
  87. else if(typeof obj[key] === 'Object')
  88. {
  89. inject(obj[key]);
  90. }
  91. else
  92. {
  93. injectToInputElement(key, obj[key])
  94. }
  95. }
  96. }
  97. function duelWithSpecialInputType(key, value)
  98. {
  99. if(key === 'steps')
  100. {
  101. const steps = document.getElementById('steps');
  102. if(!steps) return;
  103. if(value.length > steps.children.length)
  104. {
  105. const gap = value.length - steps.children.length;
  106. for(let i = 0; i < gap; i++)
  107. {
  108. const addButton = document.querySelector('#steps > tr:last-child > .step-actions button:first-child');
  109. if(!addButton) return;
  110. addButton.click();
  111. }
  112. }
  113. }
  114. }
  115. document.addEventListener("DOMContentLoaded", function()
  116. {
  117. try
  118. {
  119. const data = JSON.parse(injectData);
  120. if(!data) return;
  121. inject(data);
  122. $.zui.messager.success('<?php echo $lang->ai->dataInject->success;?>');
  123. }
  124. catch(e)
  125. {
  126. $.zui.messager.danger('<?php echo $lang->ai->dataInject->fail;?>');
  127. console.error(e);
  128. }
  129. finally
  130. {
  131. /* Set injected in oreder to cancel loading class on object view (see promptmenu.html.php). */
  132. sessionStorage.setItem('ai-prompt-data-injected', true);
  133. const container = window.frameElement?.closest('.load-indicator');
  134. if(container && container.dataset.loading)
  135. {
  136. sessionStorage.removeItem('ai-prompt-data-injected');
  137. delete container.dataset.loading;
  138. container.classList.remove('loading');
  139. container.classList.remove('no-delay');
  140. }
  141. }
  142. });
  143. })();
  144. </script>
  145. <?php endif;?>
  146. <?php if(isset($_SESSION['aiPrompt']['prompt']) && $_SESSION['aiPrompt']['objectId']):
  147. $prompt = $_SESSION['aiPrompt']['prompt'];
  148. $objectId = $_SESSION['aiPrompt']['objectId'];
  149. $isAudit = isset($_SESSION['auditPrompt']) && time() - $_SESSION['auditPrompt']['time'] < 10 * 60;
  150. ?>
  151. <script>
  152. (function() {
  153. const isAudit = <?php echo $isAudit ? 'true' : 'false';?>;
  154. const promptId = '<?php echo $prompt->id;?>';
  155. <?php if(isset($config->ai->injectAuditButton->locations[$module][$method])) :?>
  156. function injectAuditAction()
  157. {
  158. <?php
  159. $htmlStr = html::commonButton($lang->ai->promptPublish, "id='promptPublish' data-promptId=$prompt->id", 'btn btn-primary btn-wide');
  160. $targetContainer = $config->ai->injectAuditButton->locations[$module][$method]['action']->targetContainer;
  161. $injectMethod = $config->ai->injectAuditButton->locations[$module][$method]['action']->injectMethod;
  162. if($module == 'doc'):
  163. $containerStyles = empty($config->ai->injectAuditButton->locations[$module][$method]['action']->containerStyles) ? '{}' : $config->ai->injectAuditButton->locations[$module][$method]['action']->containerStyles;
  164. $exitAuditButton = html::commonButton($lang->ai->audit->exit, "id='promptAuditExit'", 'btn');
  165. ?>
  166. const containerStyles = JSON.parse('<?php echo $containerStyles;?>');
  167. const htmlStr = `<?php echo $htmlStr;?>`;
  168. $('<?php echo $targetContainer;?>')['<?php echo $injectMethod;?>'](htmlStr);
  169. $('<?php echo $targetContainer;?>').css(containerStyles);
  170. $('#mainContent #headerBox td:first-child').html(`<?php echo $exitAuditButton;?>`);
  171. <?php else:
  172. $htmlStr = $htmlStr . html::commonButton($lang->ai->audit->exit, "id='promptAuditExit'", 'btn btn-wide');
  173. ?>
  174. const htmlStr = `<?php echo $htmlStr;?>`;
  175. $('<?php echo $targetContainer;?>')['<?php echo $injectMethod;?>'](htmlStr);
  176. <?php endif;?>
  177. }
  178. function injectAuditToolbar()
  179. {
  180. <?php
  181. $htmlStr = html::a(helper::createLink('ai', 'promptexecute', "promptId=$prompt->id&objectId=$objectId"), '<i class="icon icon-refresh muted"></i> ' . $lang->ai->audit->regenerate, '', 'id="promptRegenerate" class="btn btn-link"');
  182. if($isAudit)
  183. {
  184. $htmlStr = $htmlStr . html::a(helper::createLink('ai', 'promptaudit', "promptId=$prompt->id&objectId=$objectId"), $lang->ai->audit->designPrompt, '', 'id="promptAudit" class="btn btn-info iframe"');
  185. }
  186. $targetContainer = $config->ai->injectAuditButton->locations[$module][$method]['toolbar']->targetContainer;
  187. $injectMethod = $config->ai->injectAuditButton->locations[$module][$method]['toolbar']->injectMethod;
  188. if(!empty($config->ai->injectAuditButton->locations[$module][$method]['toolbar']->class)) $htmlStr = '<div class="' . $config->ai->injectAuditButton->locations[$module][$method]['toolbar']->class . '">' . $htmlStr . '</div>';
  189. ?>
  190. const targetContainer = `<?php echo $targetContainer;?>`;
  191. const injectMethod = `<?php echo $injectMethod;?>`;
  192. const htmlStr = `<?php echo $htmlStr;?>`;
  193. $(targetContainer)[injectMethod](htmlStr);
  194. }
  195. if(isAudit)
  196. {
  197. injectAuditAction();
  198. }
  199. if(typeof injectData !== 'undefined')
  200. {
  201. injectAuditToolbar();
  202. }
  203. <?php endif;?>
  204. const publishButton = document.getElementById('promptPublish');
  205. if(publishButton)
  206. {
  207. publishButton.addEventListener('click', function(e)
  208. {
  209. e.preventDefault();
  210. const promptId = publishButton.dataset.promptid;
  211. const aTag = document.createElement('a');
  212. aTag.href = createLink('ai', 'promptPublish', 'promptId=' + promptId + '&backToTestingLocation=true') + '#app=admin';
  213. aTag.style.display = 'none';
  214. document.body.appendChild(aTag);
  215. aTag.click();
  216. if($.appCode !== 'admin') $.apps.close($.appCode);
  217. });
  218. }
  219. const auditExitButton = document.getElementById('promptAuditExit');
  220. if(auditExitButton)
  221. {
  222. auditExitButton.addEventListener('click', function(e)
  223. {
  224. e.preventDefault();
  225. const aTag = document.createElement('a');
  226. aTag.href = createLink('ai', 'promptAudit', 'promptId=' + promptId + '&objectId=0' + '&exit=true') + '#app=admin';
  227. aTag.style.display = 'none';
  228. document.body.appendChild(aTag);
  229. aTag.click();
  230. if($.appCode !== 'admin') $.apps.close($.appCode);
  231. });
  232. }
  233. const regenerateButton = document.getElementById('promptRegenerate');
  234. if(regenerateButton)
  235. {
  236. regenerateButton.addEventListener('click', function()
  237. {
  238. $('body').attr('data-loading', '<?php echo $lang->ai->execute->loading;?>');
  239. $('body').addClass('load-indicator loading');
  240. });
  241. }
  242. })();
  243. </script>
  244. <?php endif;?>
  245. <?php endif;?>