control.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <?php
  2. /**
  3. * The control file of aiapp module of ZenTaoPMS.
  4. *
  5. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
  6. * @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  7. * @author Wenrui LI <liwenrui@easycorp.ltd>
  8. * @package ai
  9. * @link https://www.zentao.net
  10. */
  11. class aiapp extends control
  12. {
  13. /**
  14. * aiapp model.
  15. *
  16. * @var aiappModel
  17. * @access public
  18. */
  19. public $aiapp;
  20. /**
  21. * ai model.
  22. *
  23. * @var aiModel
  24. * @access public
  25. */
  26. public $ai;
  27. public function __construct($module = '', $method = '')
  28. {
  29. parent::__construct($module, $method);
  30. $this->loadModel('ai');
  31. }
  32. public function view($id)
  33. {
  34. echo $this->fetch('aiapp', 'browseMiniProgram', "id=$id");
  35. }
  36. /**
  37. * Browse mini program by id from square.
  38. *
  39. * @param string $id
  40. * @access public
  41. * @return void
  42. */
  43. public function browseMiniProgram($id)
  44. {
  45. $miniProgram = $this->ai->getMiniProgramByID($id);
  46. if(empty($miniProgram)) return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->aiapp->noMiniProgram, 'locate' => $this->createLink('aiapp', 'square'))));
  47. $this->view->miniProgram = $miniProgram;
  48. $this->view->messages = $this->aiapp->getHistoryMessages($id);
  49. $this->view->fields = $this->ai->getMiniProgramFields($id);
  50. $this->view->collectedIDs = $this->aiapp->getCollectedMiniProgramIDs($this->app->user->id);
  51. $this->view->title = "{$this->lang->aiapp->title}#{$miniProgram->id} $miniProgram->name";
  52. $this->display();
  53. }
  54. /**
  55. * Mini program chat.
  56. *
  57. * @param string $id
  58. * @access public
  59. * @return void
  60. */
  61. public function miniProgramChat($id)
  62. {
  63. if(empty($_POST)) return $this->locate($this->createLink('ai', 'browseMiniProgram', "id=$id"));
  64. $miniProgram = $this->ai->getMiniProgramByID($id);
  65. if(empty($miniProgram)) return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->aiapp->noMiniProgram, 'locate' => $this->createLink('aiapp', 'square'))));
  66. if($miniProgram->published == '0' && $this->post->test !== '1') return $this->send(array('result' => 'fail', 'message' => $this->lang->aiapp->unpublishedTip, 'reason' => 'unpublished'));
  67. $history = $this->post->history;
  68. $message = $this->post->message;
  69. $isRetry = $this->post->retry == 'true';
  70. $messages = json_decode($history);
  71. if(!$isRetry)
  72. {
  73. $messages[] = (object)array('role' => 'user', 'content' => $message);
  74. if($this->post->test !== '1') $this->aiapp->saveMiniProgramMessage($id, 'req', $message);
  75. }
  76. if($this->ai->hasModelsAvailable())
  77. {
  78. if(!empty($miniProgram->model))
  79. {
  80. /* Check if model required by miniProgram is available, fallback to default (first enabled) model if not. */
  81. $model = $this->ai->getLanguageModel($miniProgram->model);
  82. if(empty($model) || !$model->enabled)
  83. {
  84. $defaultModel = $this->getDefaultLanguageModel();
  85. if(empty($defaultModel)) return $this->send(array('result' => 'fail', 'message' => $this->lang->aiapp->noModelError, 'reason' => 'no model'));
  86. $miniProgram->model = $defaultModel->id;
  87. }
  88. }
  89. $response = $this->ai->converse($miniProgram->model, $messages);
  90. if(empty($response)) return $this->send(array('result' => 'fail', 'message' => $this->lang->aiapp->chatNoResponse, 'reason' => 'no response'));
  91. if($this->post->test !== '1') $this->aiapp->saveMiniProgramMessage($id, 'res', is_array($response) ? current($response) : $response);
  92. return $this->send(array('result' => 'success', 'message' => array('time' => date("Y/n/j G:i"), 'role' => 'assistant', 'content' => is_array($response) ? current($response) : $response)));
  93. }
  94. return $this->send(array('result' => 'fail', 'message' => $this->lang->aiapp->noModelError, 'reason' => 'no model'));
  95. }
  96. /**
  97. * Mini program square.
  98. *
  99. * @param string $category
  100. * @param int $recTotal
  101. * @param int $recPerPage
  102. * @param int $pageID
  103. * @access public
  104. * @return void
  105. */
  106. public function square($category = '', $recTotal = 0, $recPerPage = 15, $pageID = 1)
  107. {
  108. $this->app->loadClass('pager', true);
  109. $pager = new pager($recTotal, $recPerPage, $pageID);
  110. $collectedIDs = null;
  111. if($category === '')
  112. {
  113. $collectedIDs = $this->aiapp->getCollectedMiniProgramIDs($this->app->user->id);
  114. $category = empty($collectedIDs) ? 'discovery' : 'collection';
  115. }
  116. if($category === 'collection') $collectedIDs = $this->aiapp->getCollectedMiniProgramIDs($this->app->user->id, $pager);
  117. elseif($collectedIDs === null) $collectedIDs = $this->aiapp->getCollectedMiniProgramIDs($this->app->user->id);
  118. if($category === 'collection') $miniPrograms = $this->ai->getMiniProgramsByID($collectedIDs, true);
  119. else if($category === 'discovery') $miniPrograms = $this->ai->getMiniPrograms('', 'active', 'createdDate_desc', $pager);
  120. else if($category === 'latest') $miniPrograms = $this->aiapp->getLatestMiniPrograms($pager);
  121. else $miniPrograms = $this->ai->getMiniPrograms($category, 'active', 'createdDate_desc', $pager);
  122. $squareCategoryArray = $this->aiapp->getSquareCategoryArray();
  123. $usedCategoryArray = $this->aiapp->getUsedCategoryArray();
  124. $this->view->collectedIDs = $collectedIDs;
  125. $this->view->category = $category;
  126. $this->view->categoryList = array_merge($squareCategoryArray, $usedCategoryArray);
  127. $this->view->pager = $pager;
  128. $this->view->miniPrograms = $miniPrograms ?: array();
  129. $this->view->title = $this->lang->aiapp->generalAgent;
  130. $this->display();
  131. }
  132. /**
  133. * Collect mini program by appid.
  134. *
  135. * @param string $appID
  136. * @param string $delete
  137. * @access public
  138. * @return void
  139. */
  140. public function collectMiniProgram($appID, $delete = 'false')
  141. {
  142. $this->ai->collectMiniProgram($this->app->user->id, $appID, $delete);
  143. return $this->send(array('status' => ($delete === 'true' ? '0' : '1')));
  144. }
  145. /**
  146. * 模型列表。
  147. * Models page.
  148. *
  149. * @access public
  150. * @return void
  151. */
  152. public function models()
  153. {
  154. $this->view->title = $this->lang->aiapp->models;
  155. $this->display();
  156. }
  157. /**
  158. * 智能会话页面。
  159. * Conversation page.
  160. *
  161. * @param string $chat 要打开的会话 ID,ID 中的 _ 会被替换为 -,如果设置为 NEW,则打开新会话。 The chat ID to open, _ will be replaced with -, if set to NEW, open a new chat. The default is an empty string.
  162. * @param string $params 会话参数,JSON 字符串,使用 base64 编码。 The chat parameters, JSON string, using base64 encoding.
  163. * @access public
  164. * @return void
  165. */
  166. public function conversation($chat = '', $params = '')
  167. {
  168. $this->view->title = $this->lang->aiapp->conversation;
  169. $this->view->currentChatID = empty($chat) ? '' : str_replace('_', '-', $chat);
  170. $this->view->params = empty($params) ? '' : helper::safe64Decode($params);
  171. $this->display();
  172. }
  173. }