robot.class.php 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. <?php
  2. if (!defined('IN_ONLINE')) {
  3. exit('Access Denied');
  4. }
  5. /**
  6. * Description of robot
  7. *
  8. * @author Administrator
  9. */
  10. class robot{
  11. private static $_robot;
  12. function __construct() {
  13. }
  14. public static function getInstance() {
  15. global $memory_limit;
  16. $memory_limit = ini_get("memory_limit");
  17. ini_set("memory_limit", '2048M');
  18. if (!self::$_robot) {
  19. $c = __CLASS__;
  20. self::$_robot = new $c;
  21. }
  22. return self::$_robot;
  23. }
  24. public function robot_chat_log() {
  25. $operate = utils::_get('operate');
  26. $operate = strtolower($operate);
  27. if (empty($operate)) {
  28. $column = column::getInstance()->getDisplayColumn('Robot_Chat_Search');
  29. $OperationTableColumns = column::getInstance()->tableColumns('Robot_Chat_Search',$column);
  30. $data['OperationTableColumns'] = $OperationTableColumns;
  31. common::echo_json_encode(200,$data);
  32. exit();
  33. }
  34. if ($operate == "search") {
  35. $cp = common::check_input($_POST ['cp']); //current_page
  36. $ps = common::check_input($_POST ['ps']); //ps
  37. if (empty($ps))
  38. $ps = 10;
  39. $sqlWhere = ' where 1=1';
  40. $text_search = common::check_input($_POST ['text_search']);
  41. $user_type = common::check_input($_POST ['user_type']);
  42. $question_type = common::check_input($_POST ['question_type']);
  43. $answer_type = common::check_input($_POST ['answer_type']);
  44. $answer_satisfication = common::check_input($_POST ['answer_satisfication']);
  45. $response_duration_type = common::check_input($_POST ['response_duration_type']);
  46. $response_duration_num = common::check_input($_POST ['response_duration_num']);
  47. if (!empty($text_search)){
  48. $sqlWhere .= " and (question_id ilike '%" . $text_search . "%' or user_name ilike '%" . $text_search . "%')";
  49. }
  50. if (isset($_POST['question_date_start']) && !empty($_POST['question_date_start'])){
  51. $sqlWhere .= " and question_date >= '" . common::usDate2sqlDate($_POST['question_date_start']) . " 00:00:00'";
  52. }
  53. if (isset($_POST['question_date_end']) && !empty($_POST['question_date_end'])){
  54. $sqlWhere .= " and question_date <= '" . common::usDate2sqlDate($_POST['question_date_end']) . " 23:59:59'";
  55. }
  56. if (!empty($user_type)){
  57. $sqlWhere .= " and user_type = '".strtolower($user_type)."'";
  58. }
  59. if (!empty($question_type)){
  60. //$question_type = $question_type == 'Free Text' ? "Free Question" : $question_type;
  61. $sqlWhere .= " and question_type = '$question_type'";
  62. }
  63. if (!empty($answer_type)){
  64. $sqlWhere .= " and answer_type = '$answer_type'";
  65. }
  66. if (!empty($answer_satisfication)){
  67. $answer_satisfication = $answer_satisfication == 'Null' ? '' : $answer_satisfication;
  68. $sqlWhere .= " and COALESCE(answer_satisfication,'') = '$answer_satisfication'";
  69. }
  70. if (!empty($response_duration_type) && !empty($response_duration_num)){
  71. if($response_duration_type == "thanOrEqual"){
  72. $sqlWhere .= " and response_duration >= '$response_duration_num'";
  73. } elseif ($response_duration_type == "equal"){
  74. $sqlWhere .= " and response_duration = '$response_duration_num'";
  75. } else {
  76. $sqlWhere .= " and response_duration <= '$response_duration_num'";
  77. }
  78. }
  79. $rc = $_POST ['rc'];
  80. if ($rc == - 1) {
  81. $sql = "SELECT count(1) from public.kln_robot_chat_log" . $sqlWhere;
  82. error_log($sql);
  83. $rc = common::excuteOneSql($sql);
  84. }
  85. $tp = ceil($rc / $ps);
  86. $order_by = " id desc";
  87. if ($rc > 0) {
  88. $sql = "SELECT ".column::getInstance()->getSearchSqlForDisplay('Robot_Chat_Search').",
  89. to_char(response_time, 'YYYY/MM/DD HH24:MI:SS') as _response_time,
  90. to_char(request_time, 'YYYY/MM/DD HH24:MI:SS') as _request_time,
  91. request_id
  92. from public.kln_robot_chat_log " . $sqlWhere .
  93. " order by $order_by limit " . $ps . " offset " . ($cp - 1) * $ps;
  94. $rs = common::excuteListSql($sql);
  95. foreach($rs as $key => $val){
  96. $rs[$key]["response_time"] = $val["_response_time"];
  97. $rs[$key]["request_time"] = $val["_request_time"];
  98. }
  99. $arrTmp = array('searchData' => $rs,
  100. 'tmp_search' => common::deCode($sql, 'E'),
  101. 'rc' => intval($rc),
  102. 'ps' => intval($ps),
  103. 'cp' => intval($cp),
  104. 'tp' => intval($tp));
  105. } else {
  106. $arrTmp = array('searchData' => array(),
  107. 'tmp_search' => common::deCode($sql, 'E'),
  108. 'rc' => intval($rc),
  109. 'ps' => intval($ps),
  110. 'cp' => intval($cp),
  111. 'tp' => intval($tp));
  112. }
  113. common::echo_json_encode(200,$arrTmp);
  114. exit();
  115. }
  116. if ($operate == "excel") {
  117. $sql = common::deCode($_POST ['tmp_search'], 'D');
  118. $sql = substr($sql, 0, strripos($sql, " limit"));
  119. if(!empty($sql)){
  120. $rss = common::excuteListSql($sql);
  121. }
  122. foreach($rss as $key =>$val){
  123. $rs[$key]["response_time"] = $val["_response_time"];
  124. $rs[$key]["request_time"] = $val["_request_time"];
  125. }
  126. common::echo_json_encode(200,array("msg"=>"success","Data" => $rss));
  127. exit;
  128. }
  129. if ($operate == "api_log") {
  130. $request_id = common::check_input($_POST['request_id']);
  131. $sql = "select question_content,ai_response_content from public.kln_robot_chat_log where request_id = '$request_id'";
  132. $data = common::excuteObjectSql($sql);
  133. $question_content = $data['question_content'];
  134. $ai_response_content = json_decode($data['ai_response_content']);
  135. common::echo_json_encode(200,array("msg"=>"success","Data" => array("request_content" =>$question_content, "ai_response_content"=>$ai_response_content)));
  136. //common::echo_json_encode(200,array("msg"=>"success","Data" => $data));
  137. exit;
  138. }
  139. }
  140. public function robot_api_log() {
  141. $operate = utils::_get('operate');
  142. $operate = strtolower($operate);
  143. if (empty($operate)) {
  144. $column = column::getInstance()->getDisplayColumn('Robot_API_Search');
  145. $OperationTableColumns = column::getInstance()->tableColumns('Robot_API_Search',$column);
  146. $data['OperationTableColumns'] = $OperationTableColumns;
  147. common::echo_json_encode(200,$data);
  148. exit();
  149. }
  150. if ($operate == "search") {
  151. $cp = common::check_input($_POST ['cp']); //current_page
  152. $ps = common::check_input($_POST ['ps']); //ps
  153. if (empty($ps))
  154. $ps = 10;
  155. //只查询自由问题
  156. $sqlWhere = " where 1=1 and question_type = 'Free Text' ";
  157. $text_search = common::check_input($_POST ['text_search']);
  158. $ai_model = common::check_input($_POST ['ai_model']);
  159. $response_duration_type = common::check_input($_POST ['response_duration_type']);
  160. $response_duration_num = common::check_input($_POST ['response_duration_num']);
  161. if (!empty($text_search)){
  162. $sqlWhere .= " and (question_id ilike '%" . $text_search . "%' or request_id ilike '%" . $text_search . "%')";
  163. }
  164. if (!empty($ai_model)){
  165. $sqlWhere .= " and lower(ai_model) = '".strtolower($ai_model)."'";
  166. }
  167. if (isset($_POST['request_date_start']) && !empty($_POST['request_date_start']))
  168. $sqlWhere .= " and request_time >= '" . common::usDate2sqlDate($_POST['request_date_start']) . " 00:00:00'";
  169. if (isset($_POST['request_date_end']) && !empty($_POST['request_date_end']))
  170. $sqlWhere .= " and request_time <= '" . common::usDate2sqlDate($_POST['request_date_end']) . " 23:59:59'";
  171. if (!empty($response_duration_type) && !empty($response_duration_num)){
  172. if($response_duration_type == "thanOrEqual"){
  173. $sqlWhere .= " and response_duration >= '$response_duration_num'";
  174. } elseif ($response_duration_type == "equal"){
  175. $sqlWhere .= " and response_duration = '$response_duration_num'";
  176. } else {
  177. $sqlWhere .= " and response_duration <= '$response_duration_num'";
  178. }
  179. }
  180. $rc = $_POST ['rc'];
  181. if ($rc == - 1) {
  182. $sql = "SELECT count(1) from public.kln_robot_chat_log" . $sqlWhere;
  183. $rc = common::excuteOneSql($sql);
  184. }
  185. $tp = ceil($rc / $ps);
  186. $order_by = " id desc";
  187. if ($rc > 0) {
  188. $sql = "SELECT ".column::getInstance()->getSearchSqlForDisplay('Robot_API_Search').",
  189. to_char(response_time, 'YYYY/MM/DD HH24:MI:SS') as _response_time,
  190. to_char(request_time, 'YYYY/MM/DD HH24:MI:SS') as _request_time
  191. from public.kln_robot_chat_log " . $sqlWhere .
  192. " order by $order_by limit " . $ps . " offset " . ($cp - 1) * $ps;
  193. $rs = common::excuteListSql($sql);
  194. foreach($rs as $key => $val){
  195. $rs[$key]["response_time"] = $val["_response_time"];
  196. $rs[$key]["request_time"] = $val["_request_time"];
  197. }
  198. $arrTmp = array('searchData' => $rs,
  199. 'tmp_search' => common::deCode($sql, 'E'),
  200. 'rc' => $rc,
  201. 'ps' => $ps,
  202. 'cp' => $cp,
  203. 'tp' => $tp);
  204. } else {
  205. $arrTmp = array('searchData' => array(),
  206. 'tmp_search' => common::deCode($sql, 'E'),
  207. 'rc' => $rc,
  208. 'ps' => $ps,
  209. 'cp' => $cp,
  210. 'tp' => $tp);
  211. }
  212. common::echo_json_encode(200,$arrTmp);
  213. exit();
  214. }
  215. if ($operate == "excel") {
  216. $sql = common::deCode($_POST ['tmp_search'], 'D');
  217. $sql = substr($sql, 0, strripos($sql, " limit"));
  218. if(!empty($sql)){
  219. $rss = common::excuteListSql($sql);
  220. }
  221. foreach($rss as $key =>$val){
  222. $rs[$key]["response_time"] = $val["_response_time"];
  223. $rs[$key]["request_time"] = $val["_request_time"];
  224. }
  225. common::echo_json_encode(200,array("msg"=>"success","Data" => $rss));
  226. exit;
  227. }
  228. if ($operate == "api_log") {
  229. $request_id = common::check_input($_POST['request_id']);
  230. $sql = "select request_content,ai_response_content from public.kln_robot_chat_log where request_id = '$request_id'";
  231. $data = common::excuteObjectSql($sql);
  232. common::echo_json_encode(200,array("msg"=>"success","Data" => $data));
  233. exit;
  234. }
  235. }
  236. public function robot_prompt_configuration() {
  237. $operate = utils::_get('operate');
  238. $operate = strtolower($operate);
  239. if (empty($operate)) {
  240. //查询所有配置信息 目前只有一个表一个数据
  241. $configuration = common::excuteObjectSql("select id, character_name,professional_field,main_tasks,table_name,table_description,
  242. table_structure_configuration,response_rule_configuration,output_format_configuration,fixed_problem_configuration
  243. from public.kln_robot_prompt_configuration where id = 1");
  244. $PromptAndVue = $this->dealPromptFormatAndVue($configuration);
  245. //tableDat-VUE
  246. $tableData = $PromptAndVue["vuedata"]["tableData"];
  247. //stepData -VUE
  248. $stepData = $PromptAndVue["vuedata"]["stepData"];
  249. //formatList -VUE
  250. $formatListType = $PromptAndVue["vuedata"]["formatListType"];
  251. $formatList = $PromptAndVue["vuedata"]["formatList"];
  252. //promptFormat
  253. $promptFormat =$PromptAndVue["promptFormat"];
  254. //获取历史变更记录
  255. $old_configuration = $this->getChangedLog($configuration["id"]);
  256. $id = $configuration['id'];
  257. $character_name = $configuration['character_name'];
  258. $professional_field = $configuration['professional_field'];
  259. $main_tasks = $configuration['main_tasks'];
  260. $table_name = $configuration['table_name'];
  261. $table_description = $configuration['table_description'];
  262. $prompt_summary = array("您是专門从事".$professional_field."的".$character_name."...",
  263. "表名:{".$table_name."}...",
  264. "响应规则,请按以下步骤处理...");
  265. $data = array(
  266. "id"=>$id,
  267. "character_name"=>$character_name,
  268. "professional_field"=>$professional_field,
  269. "main_tasks"=>$main_tasks,
  270. "table_name"=>$table_name,
  271. "table_description"=>$table_description,
  272. "tableData"=>$tableData,
  273. "stepData"=>$stepData,
  274. "formatList"=>$formatList,
  275. "formatListType"=>$formatListType,
  276. "complete_prompt"=>$promptFormat,
  277. "prompt_summary"=>$prompt_summary,
  278. "prompt_log_record"=>$old_configuration
  279. );
  280. $data = utils::arrayRemoveNull($data);
  281. common::echo_json_encode(200,$data);
  282. exit();
  283. }
  284. if ($operate == "save") {
  285. $id =common::check_input($_POST['id']);
  286. $character_name = common::check_input($_POST['role_name']);
  287. $professional_field = common::check_input($_POST['professional_field']);
  288. $main_tasks = common::check_input($_POST['main_tasks']);
  289. $table_name = common::check_input($_POST['table_name']);
  290. $table_description = common::check_input($_POST['table_description']);
  291. $outputvalue = common::check_input($_POST['outputvalue']);
  292. $tableDataList = $_POST['tableDataList'];
  293. $stepData = $_POST['stepData'];
  294. $formatList = $_POST['formatList'];
  295. $table_structure_configuration = common::check_input(json_encode($tableDataList));
  296. $response_rule_configuration = common::check_input(json_encode($stepData));
  297. $output_data = array("output_type"=>$outputvalue,"data"=>$formatList);
  298. $output_format_configuration = common::check_input(json_encode($output_data));
  299. if(empty($id)){
  300. $sql = "INSERT INTO public.kln_robot_prompt_configuration(
  301. character_name, professional_field, main_tasks, table_name,
  302. table_description, table_structure_configuration, response_rule_configuration,
  303. output_format_configuration, created_by, created_time)
  304. VALUES ('$character_name', '$professional_field', '$main_tasks', '$table_name',
  305. '$table_description', '$table_structure_configuration', '$response_rule_configuration',
  306. '$output_format_configuration', '"._getLoginName()."', now());";
  307. }else{
  308. $sql = "update public.kln_robot_prompt_configuration
  309. set character_name = '$character_name',professional_field ='$professional_field', main_tasks = '$main_tasks',
  310. table_name = '$table_name',table_description = '$table_description',
  311. table_structure_configuration = '$table_structure_configuration',
  312. response_rule_configuration = '$response_rule_configuration',
  313. output_format_configuration = '$output_format_configuration'
  314. where id = '$id';";
  315. //插入变更日志记录
  316. $sql .= "INSERT INTO public.kln_robot_prompt_configuration_log(ref_id, character_name, professional_field, main_tasks, table_name,
  317. table_description, table_structure_configuration, response_rule_configuration,
  318. output_format_configuration, created_by, created_time)
  319. VALUES ('$id','$character_name', '$professional_field', '$main_tasks', '$table_name',
  320. '$table_description', '$table_structure_configuration', '$response_rule_configuration',
  321. '$output_format_configuration', '"._getLoginName()."', now());";
  322. }
  323. error_log($sql);
  324. $rs = common::excuteUpdateSql($sql);
  325. if (!$rs) {
  326. $data = array("msg" => "save Error");
  327. } else {
  328. $data = array("msg" => "save Successful");
  329. }
  330. $data = array("msg" => "save Successful");
  331. common::echo_json_encode(200,$data);
  332. exit();
  333. }
  334. if($operate == "preview_propmpt_witout_save"){
  335. $character_name = common::check_input($_POST['role_name']);
  336. $professional_field = common::check_input($_POST['professional_field']);
  337. $main_tasks = common::check_input($_POST['main_tasks']);
  338. $table_name = common::check_input($_POST['table_name']);
  339. $table_description = common::check_input($_POST['table_description']);
  340. $outputvalue = common::check_input($_POST['outputvalue']);
  341. $tableDataList = $_POST['tableDataList'];
  342. $stepData = $_POST['stepData'];
  343. $formatList = $_POST['formatList'];
  344. $table_structure_configuration = common::check_input(json_encode($tableDataList));
  345. $response_rule_configuration = common::check_input(json_encode($stepData));
  346. $output_data = array("output_type"=>$outputvalue,"data"=>$formatList);
  347. $output_format_configuration = common::check_input(json_encode($output_data));
  348. //组合拼接需要的数据
  349. $configuration = array("character_name"=>$character_name,
  350. "professional_field"=>$professional_field,
  351. "main_tasks"=>$main_tasks,
  352. "table_name"=>$table_name,
  353. "table_description"=>$table_description,
  354. "professional_field"=>$professional_field,
  355. "table_structure_configuration"=>$table_structure_configuration,
  356. "response_rule_configuration" =>$response_rule_configuration,
  357. "output_format_configuration" =>$output_format_configuration
  358. );
  359. $PromptAndVue = $this->dealPromptFormatAndVue($configuration);
  360. //promptFormat
  361. $promptFormat =$PromptAndVue["promptFormat"];
  362. $character_name = empty($configuration['character_name']) ? "" :$configuration['character_name'];
  363. $professional_field = empty($configuration['professional_field']) ? "" :$configuration['professional_field'];
  364. $main_tasks = empty($configuration['main_tasks']) ? "" :$configuration['main_tasks'];
  365. $table_name = empty($configuration['table_name']) ? "" :$configuration['table_name'];
  366. $table_description = empty($configuration['table_description']) ? "" :$configuration['table_description'];
  367. $prompt_summary = array("您是专門从事".$professional_field."的".$character_name."...",
  368. "表名:{".$table_name."}...",
  369. "响应规则,请按以下步骤处理...");
  370. $data = array(
  371. "complete_prompt"=>$promptFormat,
  372. "prompt_summary"=>$prompt_summary
  373. );
  374. common::echo_json_encode(200,$data);
  375. exit();
  376. }
  377. if($operate == "test_with_ds_claude"){
  378. //$data = "### 查询结果\n\n- **总hbol数量**: 3581667\n\n- **前10票hbol信息**:\n\n | HBOL | MBOL | 运输方式 | 服务类型 | 发货人 | 收货人 | 数量 | 总重量(KG) | 预计离港时间 | 预计到港时间 |\n |------|------|----------|----------|--------|--------|------|------------|--------------|--------------|\n | E1205546127 | UASUCNNBO432262 | sea | CY/CY | HANGZHOU ZHONGSHEN BAGS & LUGGAGES CO.LTD. | C.Y IMPORT CORPORATION | 455 | 8689.000 | 2012-05-31 | 2012-07-09 |\n| E120537061 | HJSCFOC202818100 | sea | CY/DOOR | NANLIN(FUJIAN) INDUSTRIES CO.,LTD | CHICAGO STOOL & CHAIR INC | 1200 | 14400.000 | 2012-05-31 | 2012-06-18 |\n| E120537095 | MAEU602116826 | sea | CY/CY | LONG SHAN IMP & EXP CO LTD | COMPOSITE TECHNOLOGY INTERNATIONAL INC | 12 | 19900.000 | 2012-05-27 | 2012-07-02 |\n| E1205570012 | COSU6025917580 | sea | CY/DOOR | SHAANXI FUHUA CHEMICAL CO., LTD | CIMBAR PERFORMANCE MINERALS | 38 | 34396.000 | 2012-05-29 | 2012-07-06 |\n| E1205391561A | YMLUW230775660 | sea | CFS/CY | WISTRON NEWEB (KUNSHAN) CORPORATION | ARUBA NETWORKS | 30 | 391.000 | 2012-05-29 | 2012-06-16 |\n| A1208395110 | ZIMUSNH5455049 | sea | CFS/CFS | SHANGHAI EAST BEST INT'L BUSINESS DEV.CO | LUMINA GLOBAL, INC. | 2 | 2600.000 | 2012-08-25 | 2012-09-06 |\n| E1205391561 | YMLUW230775660 | sea | CY/CY | SERCOMM CORP. C/O SERNET | ARUBA NETWORKS | 354 | 2833.940 | 2012-05-29 | 2012-06-16 |\n| E1205395237 | YMLUW230777029 | sea | CY/CY | UNIPAK RESOURCES CO.,LTD. | PAN PACIFIC PLASTIC | 404 | 2424.000 | 2012-05-29 | 2012-06-16 |\n| X1205480323 | YMLUW241023500 | sea | CY/CY | SHANGHAI AUTOMOBILE IMPORT&EXPORT CO.,LTD. | AMERICAN CONDENSER | 1082 | 5178.000 | 2012-05-25 | 2012-06-12 |\n| E1205359270 | MAEU602108615 | sea | CY/CY | LZ CASKET MANUFACTURING CO.,LTD | BRICK ALLEY,LLC | 64 | 5901.700 | 2012-05-29 | 2012-07-06 |\n ";
  379. //$data = "### 查询结果\n\n- **总hbol数量**: 3581667\n\n- **前10票hbol信息**:\n\n| HBOL | MBOL | 运输方式 | 服务类型 | 发货人 | 收货人 | 数量 | 总重量(KG) | 预计离港时间 | 预计到港时间 |\n|------|------|----------|----------|--------|--------|------|------------|--------------|--------------|\n| E1205546127 | UASUCNNBO432262 | sea | CY/CY | HANGZHOU ZHONGSHEN BAGS & LUGGAGES CO.LTD. | C.Y IMPORT CORPORATION | 455 | 8689.000 | 2012-05-31 | 2012-07-09 |\n| E120537061 | HJSCFOC202818100 | sea | CY/DOOR | NANLIN(FUJIAN) INDUSTRIES CO.,LTD | CHICAGO STOOL & CHAIR INC | 1200 | 14400.000 | 2012-05-31 | 2012-06-18 |\n| E120537095 | MAEU602116826 | sea | CY/CY | LONG SHAN IMP & EXP CO LTD | COMPOSITE TECHNOLOGY INTERNATIONAL INC | 12 | 19900.000 | 2012-05-27 | 2012-07-02 |\n| E1205570012 | COSU6025917580 | sea | CY/DOOR | SHAANXI FUHUA CHEMICAL CO., LTD | CIMBAR PERFORMANCE MINERALS | 38 | 34396.000 | 2012-05-29 | 2012-07-06 |\n| E1205391561A | YMLUW230775660 | sea | CFS/CY | WISTRON NEWEB (KUNSHAN) CORPORATION | ARUBA NETWORKS | 30 | 391.000 | 2012-05-29 | 2012-06-16 |\n| A1208395110 | ZIMUSNH5455049 | sea | CFS/CFS | SHANGHAI EAST BEST INT'L BUSINESS DEV.CO | LUMINA GLOBAL, INC. | 2 | 2600.000 | 2012-08-25 | 2012-09-06 |\n| E1205391561 | YMLUW230775660 | sea | CY/CY | SERCOMM CORP. C/O SERNET | ARUBA NETWORKS | 354 | 2833.940 | 2012-05-29 | 2012-06-16 |\n| E1205395237 | YMLUW230777029 | sea | CY/CY | UNIPAK RESOURCES CO.,LTD. | PAN PACIFIC PLASTIC | 404 | 2424.000 | 2012-05-29 | 2012-06-16 |\n| X1205480323 | YMLUW241023500 | sea | CY/CY | SHANGHAI AUTOMOBILE IMPORT&EXPORT CO.,LTD. | AMERICAN CONDENSER | 1082 | 5178.000 | 2012-05-25 | 2012-06-12 |\n| E1205359270 | MAEU602108615 | sea | CY/CY | LZ CASKET MANUFACTURING CO.,LTD | BRICK ALLEY,LLC | 64 | 5901.700 | 2012-05-29 | 2012-07-06 |\n";
  380. //$return = array("type"=>"markdown","data" =>$data);
  381. //common::echo_json_encode(200,$return);
  382. //exit();
  383. //分担查询
  384. include ONLINE_ROOT . 'libs' . DS . 'map_config.ini.php';
  385. $ai_method = $_POST["test_ai_method"];
  386. $systemPrompt = $_POST["prompt"];
  387. $message = $_POST["test_question"];
  388. $model = $ai_method == 'DS' ? "deepseek" : "claude";
  389. //question_date request_time
  390. $request_question_time = date("Y-m-d H:i:s");
  391. $question_time = date("H:i:s");
  392. $item_value = common::excuteOneSql("select item_value from public.config where item = 'AIAPISetting'");
  393. $config = json_decode($item_value,true);
  394. $response = AIClientFactory::create($model, $config[$model], $systemPrompt, $message, $history = []);
  395. $response_time = date("Y-m-d H:i:s");
  396. $input_token = "";
  397. $output_token = "";
  398. $date1 = new DateTime($request_question_time);
  399. $date2 = new DateTime($response_time);
  400. $response_duration = $date2->getTimestamp() - $date1->getTimestamp();
  401. //回答问题类型,在没有超时的情况下,固定:AI回答
  402. $answer_type = "AI Answer";
  403. if ($response_duration > 120){
  404. $answer_type = "Timeout";
  405. }
  406. //获取自然序列
  407. $sequence = common::getChatAiSequence();
  408. $name = $ai_method == 'DS' ? "DS" : "CD";
  409. $request_id = "R".$name."".date("Ymd").$sequence;
  410. $question_id = "Q"."".date("Ymd").$sequence;
  411. //处理一下参数
  412. $user_name = common::check_input(_getLoginName());
  413. $user_type = _isApexLogin() ? "employee" : "customer";
  414. //这里的测试,固定写自由文本
  415. $question_type = 'Free Text';
  416. $question_id = common::check_input($question_id);
  417. $question_content = common::check_input($message);
  418. $answer_type = common::check_input($answer_type);
  419. //记录回答展示给客户的具体内容
  420. $answer = common::check_input(common::getChatAimessage($response['message']));
  421. $ai_model = common::check_input($model);
  422. $input_token = common::check_input($input_token);
  423. $request_content = common::check_input(json_encode($response['data']));
  424. $ai_response_content = common::check_input(json_encode($response['full_response']));
  425. $output_token = common::check_input($output_token);
  426. $answer_template = "";
  427. $message = json_decode(common::getChatAimessage($response['message']),true);
  428. if($message["can_query"] == "true" && !empty($message["sql"])){
  429. $reference = $message["reference"];
  430. $answer_template = common::check_input($message["reference"]);
  431. $sql = $message["sql"];
  432. //拆分sql 存在多条的情况
  433. $sqlArr = explode(";", $sql);
  434. //给所有sql 拼接用户权限
  435. $sqlWhere = ' ' . common::searchExtendHand_KLN("ocean", $_SESSION["ONLINE_USER"]);
  436. //先不考虑总数,处理有难度
  437. foreach($sqlArr as $_sql){
  438. error_log($_sql);
  439. if(empty($_sql)){
  440. continue;
  441. }
  442. //根据public.kln_ocean 和 WHERE 的位置关系,带入权限
  443. $new_sql = utils::modifyString($_sql,$sqlWhere);
  444. //处理limit 超过10 先限制10
  445. $new_sql = utils::processLimitClause($new_sql);
  446. //$rs = common::excuteListSql($new_sql);
  447. $rs = $mapdb->GetAll($new_sql) or ( (!$mapdb->ErrorMsg()) or error_log(common::dbLog($mapdb, $new_sql), 0));
  448. $reference = utils::replacementsMultiline($rs,$reference,$new_sql);
  449. }
  450. //有就去掉{{#each hbol_list}}\n {{/each}}
  451. $reference = preg_replace([
  452. '/\{\{[^}]+\}\}\n/', // 匹配开始标签及换行
  453. '/\{\{\/[^}]+\}\}/' // 匹配结束标签
  454. ], '', $reference);
  455. //$reference = $reference.$message["reference"];
  456. $answer = $reference;
  457. //$response['message'] = json_decode(common::getChatAimessage($response['message']),true);
  458. //$answer = $response;
  459. }else{
  460. $answer = $message["response"];
  461. }
  462. //最后插入数据
  463. $sql = "INSERT INTO public.kln_robot_chat_log( question_id, user_name, user_type, question_type, question_content,
  464. answer_type, answer, answer_satisfication, answer_duration,answer_template, question_date,
  465. question_time, request_id, ai_model, request_content, input_token,
  466. ai_response_content, output_token, request_time, response_time,
  467. response_duration)
  468. VALUES ('$question_id', '$user_name', '$user_type', '$question_type', '$question_content',
  469. '$answer_type', '".common::check_input($answer)."', '', '$response_duration','$answer_template','$request_question_time',
  470. '$question_time', '$request_id', '$ai_model','$request_content', '$input_token',
  471. '$ai_response_content', '$output_token', '$request_question_time', '$response_time',
  472. '$response_duration');";
  473. $rs = common::excuteUpdateSql($sql);
  474. if (!$rs) {
  475. $data = array("msg" => "AI Chat Save Error");
  476. common::echo_json_encode(200,$data);
  477. exit();
  478. }
  479. $return = array("type"=>"markdown","data" =>$answer);
  480. common::echo_json_encode(200,$return);
  481. exit();
  482. }
  483. if ($operate == "download"){
  484. $sql = common::deCode($_REQUEST['tmp_search'], 'D');
  485. if(!empty($sql)){
  486. $rs = common::excuteListSql($sql);
  487. }
  488. common::echo_json_encode(200,array("msg"=>"success","Data" => $rs));
  489. exit;
  490. }
  491. }
  492. public function ai_chat(){
  493. $operate = utils::_get('operate');
  494. $operate = strtolower($operate);
  495. if($operate == "ai_chat_prompt"){
  496. //查询所有配置信息 目前只有一个表一个数据
  497. $configuration = common::excuteObjectSql("select id, character_name,professional_field,main_tasks,table_name,table_description,
  498. table_structure_configuration,response_rule_configuration,output_format_configuration,fixed_problem_configuration
  499. from public.kln_robot_prompt_configuration where id = 1");
  500. $PromptAndVue = $this->dealPromptFormatAndVue($configuration);
  501. //promptFormat
  502. $promptFormat =$PromptAndVue["promptFormat"];
  503. $data = array("msg" => "succssful","prompt"=>$promptFormat);
  504. common::echo_json_encode(200,$data);
  505. exit();
  506. }
  507. if ($operate == "ai_chat_fixed_init"){
  508. $rs = common::excuteListSql("select fixed_faq,secondary_interaction_content from public.kln_robot_chat_fixed where active = true order by id");
  509. $data = array();
  510. foreach($rs as $v){
  511. $data[] = array("label" => $v['fixed_faq'],"value" =>$v['fixed_faq'],"isLong" => strlen($v['fixed_faq']) >80);
  512. }
  513. $data = array("msg" => "succssful","fixed_question"=>$data);
  514. common::echo_json_encode(200,$data);
  515. exit();
  516. }
  517. /**
  518. * ai 自由聊天
  519. */
  520. if($operate == "ai_chat"){
  521. try {
  522. //前端生成一个唯一的serial_no
  523. $serial_no = common::check_input($_POST["serial_no"]);
  524. //系统提示词
  525. $systemPrompt = common::check_input($_POST["prompt"]);
  526. $question_type = common::check_input($_POST['question_type']);
  527. $question_type = $question_type == 'Free Question' ? "Free Text" : $question_type;
  528. $question_content = common::check_input($_POST['question_content']);
  529. //固定问题的原始问题
  530. $fixed_faq = common::check_input($_POST['fixed_faq']);
  531. //claude deepseek 根據賬號信息判断
  532. $model = common::getUserCountry();
  533. //$model = "deepseek";
  534. //获取自然序列
  535. $sequence = common::getChatAiSequence();
  536. $name = $model == 'deepseek' ? "DS" : "CD";
  537. $request_id = "R".$name."".date("Ymd").$sequence;
  538. $question_id = "Q"."".date("Ymd").$sequence;
  539. //处理一下参数
  540. $user_name = common::check_input(_getLoginName());
  541. $user_type = _isApexLogin() ? "employee" : "customer";
  542. //首先生成基本记录数据 以便以后根据情况更新状态
  543. $sql = "INSERT INTO public.kln_robot_chat_log(serial_no, question_id, user_name, user_type, question_type, question_content,
  544. question_date, question_time, request_id, request_time,ai_model)
  545. VALUES ('$serial_no','$question_id', '$user_name', '$user_type', '$question_type', '$question_content',
  546. now(),to_char(CURRENT_TIME::time, 'HH24:MI:SS'), '$request_id',now(),'$model');";
  547. $rs = common::excuteUpdateSql($sql);
  548. if (!$rs) {
  549. $data = array("type"=>"markdown","data" => "AI Chat Save Error");
  550. common::echo_json_encode(200,$data);
  551. exit();
  552. }
  553. if ($question_type == 'Predefined Question'){
  554. $answer = $this->doFixedAnswerAndLog($serial_no,$fixed_faq,$question_content);
  555. //判断固定回答是否结束
  556. $is_fixedAnswer_end = false;
  557. $fixedChat = common::excuteObjectSql("select * from public.kln_robot_chat_fixed where fixed_faq = '$fixed_faq'");
  558. if (empty($fixedChat['secondary_interaction_content']) || $question_content != $fixedChat['fixed_faq'] ){
  559. $is_fixedAnswer_end = true;
  560. }
  561. } else {
  562. $answer = $this->doFreeAnswerAndLog($serial_no,$model,$systemPrompt, $question_content, $history = []);
  563. //自由问题固定为true
  564. $is_fixedAnswer_end = true;
  565. }
  566. $return = array("type"=>"markdown","is_fixedAnswer_end"=>$is_fixedAnswer_end,"data" =>$answer);
  567. common::echo_json_encode(200,$return);
  568. exit();
  569. } catch (Exception $e) {
  570. $return = array("type"=>"markdown","is_fixedAnswer_end"=>true,"data" =>$e->getMessage());
  571. common::echo_json_encode(200,$return);
  572. exit();
  573. }
  574. }
  575. if($operate == "ai_chat_stop"){
  576. $serial_no = common::check_input($_POST["serial_no"]);
  577. $updateSql = "update public.kln_robot_chat_log set answer_type = 'Suspend' where serial_no = '$serial_no'";
  578. $updateRs = common::excuteUpdateSql($updateSql);
  579. if (!$updateRs) {
  580. $data = array("msg" => "AI Chat Response Stop Error");
  581. }else{
  582. $data = array("msg" => "AI Chat Response Stop succssful");
  583. }
  584. common::echo_json_encode(200,$data);
  585. exit();
  586. }
  587. if($operate == "ai_chat_answer_mark"){
  588. $serial_no = common::check_input($_POST["serial_no"]);
  589. $answer_satisfication = common::check_input($_POST["feedback"]);
  590. $updateSql = "update public.kln_robot_chat_log set answer_satisfication = '$answer_satisfication' where serial_no = '$serial_no'";
  591. $updateRs = common::excuteUpdateSql($updateSql);
  592. if (!$updateRs) {
  593. $data = array("msg" => "AI Chat Response Mark Error");
  594. }else{
  595. $data = array("msg" => "AI Chat Response Mark succssful");
  596. }
  597. common::echo_json_encode(200,$data);
  598. exit();
  599. }
  600. if($operate == "download"){
  601. $faq = common::deCode($_GET['faq'], 'D');
  602. $sql = common::getFaqSql($faq);
  603. $columns = common::getFaqColumnSql($faq);
  604. //拼接用户权限
  605. $sqlWhere = ' ' . common::searchExtendHand_KLN("ocean", $_SESSION["ONLINE_USER"]);
  606. $sql = str_replace('<{ExtendHand_KLN}>', $sqlWhere, $sql);
  607. $rss = common::excuteListSql($sql);
  608. $rss = common::dealDataWithFaq($faq,$rss);
  609. //XLSXWriter输出
  610. $writer = new XLSXWriter();
  611. $sheetName = date('mdy');
  612. foreach ($rss as $k => $v) {
  613. $column = array();
  614. $value_temp = array();
  615. foreach($columns as $col){
  616. $value_temp[] = $v[$col['database_column_name']];
  617. if($k == 0){
  618. $column[] = $col['display_name'];
  619. }
  620. }
  621. if($k == 0){
  622. //输出column
  623. $writer->writeSheetRow($sheetName, $column);
  624. }
  625. $writer->writeSheetRow($sheetName, $value_temp, []);
  626. }
  627. $outfile = "Complete Data_" .date("Y-m-d H:i:s") . ".xlsx";
  628. if (file_exists($outfile)) {
  629. $outfile = "Complete Data_" .date("Y-m-d H:i:s") . "_". md5(uniqid(rand(), true)) . ".xlsx";
  630. }
  631. ob_end_clean();
  632. header('Content-Type: application/vnd.ms-excel');
  633. header("Expires: 0");
  634. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  635. header("Pragma: can-cache");
  636. header('Content-Disposition:attachment;filename="' . $outfile . '"');
  637. $writer->writetostdout();
  638. }
  639. }
  640. public function dealPromptFormatAndVue($configuration){
  641. //tableDat-VUE
  642. $tableData = array();
  643. $table_structure_text="[";
  644. $table_structure_configuration = json_decode($configuration['table_structure_configuration'],true);
  645. foreach($table_structure_configuration as $tk =>$tv){
  646. $tableData[] = $tv;
  647. $table_structure_text .='{
  648. "name": "'.$tv["name"].'",
  649. "type": "'.$tv["type"].'",
  650. "description": "'.$tv["description"].'",
  651. "exampledata": "'.$tv["exampledata"].'",
  652. }';
  653. if(count($table_structure_configuration)-1 > $tk){
  654. $table_structure_text .=",";
  655. }
  656. $table_structure_text .=common::splicedLlineBreaks();
  657. }
  658. $table_structure_text.="]";
  659. //stepData -VUE
  660. $stepData = array();
  661. $response_rule_text = "";
  662. $response_rule_configuration = json_decode($configuration['response_rule_configuration'],true);
  663. foreach($response_rule_configuration as $rk =>$rv){
  664. $tempTable = array();
  665. $tempTable["description"] = $rv["description"];
  666. $stepData[] = $tempTable;
  667. $response_rule_text .=($rk+1).'.'.$rv["description"];
  668. $response_rule_text .=common::splicedLlineBreaks();
  669. }
  670. //formatList -VUE
  671. $output_format_text = "{";
  672. $output_format_configuration = json_decode($configuration['output_format_configuration'],true);
  673. $formatListType = $output_format_configuration['output_type'];
  674. $formatList = empty($output_format_configuration['data']) ? array(): $output_format_configuration['data'];
  675. foreach($formatList as $ok =>$ov){
  676. $describe = $ov['describe'];
  677. if ($ov['selecttype'] == '必填字段') {
  678. $describe .= " . 必填要求:所有情况必填";
  679. } elseif ($ov['selecttype'] == '有条件必填'){
  680. $requirements = $ov['requirements'];
  681. $describe .= " . 必填要求:".$ov['selecttype']."(".$requirements.")";
  682. }
  683. $output_format_text .="\"".$ov['name']."\"".": "."\"".$describe."\"";
  684. $output_format_text .=common::splicedLlineBreaks();
  685. }
  686. $output_format_text .= "}";
  687. $output_format_text_two = "";
  688. foreach($formatList as $ok =>$ov){
  689. $describe = $ov['describe'];
  690. if ($ov['selecttype'] == '必填字段') {
  691. $describe .= " . 必填要求:所有情况必填";
  692. } elseif ($ov['selecttype'] == '有条件必填'){
  693. $requirements = $ov['requirements'];
  694. $describe .= " . 必填要求:".$ov['selecttype']."(".$requirements.")";
  695. }
  696. $output_format_text_two .="-".$ov['name'].": ".$describe;
  697. $output_format_text_two .=common::splicedLlineBreaks();
  698. }
  699. $promptFormat = $this->getCompletePromptFormat();
  700. $promptFormat = str_replace('<{professional_field}>', $configuration['character_name'], $promptFormat);
  701. $promptFormat = str_replace('<{character_name}>', $configuration['character_name'], $promptFormat);
  702. $promptFormat = str_replace('<{main_tasks}>', $configuration['main_tasks'], $promptFormat);
  703. $promptFormat = str_replace('<{table}>', $configuration['table_name'], $promptFormat);
  704. $promptFormat = str_replace('<{table_structure_configuration}>', $table_structure_text, $promptFormat);
  705. $promptFormat = str_replace('<{response_rule_configuration}>', $response_rule_text, $promptFormat);
  706. $promptFormat = str_replace('<{number}>', count($response_rule_configuration)+1, $promptFormat);
  707. $promptFormat = str_replace('<{output_type}>', $formatListType, $promptFormat);
  708. $promptFormat = str_replace('<{output_format_configuration}>', $output_format_text_two, $promptFormat);
  709. return array("vuedata"=>array("tableData"=>$tableData,"stepData"=>$stepData,"formatList"=>$formatList,"formatListType"=>$formatListType),
  710. "promptFormat" =>$promptFormat);
  711. }
  712. public function getChangedLog($id){
  713. $changeLogList = array();
  714. $configurationArr = common::excuteListSql("select id, character_name,professional_field,main_tasks,table_name,table_description,
  715. created_by,TO_CHAR(created_time, 'YYYY-mm-dd HH24:MI:SS') as created_time,
  716. table_structure_configuration,response_rule_configuration,output_format_configuration,fixed_problem_configuration
  717. from public.kln_robot_prompt_configuration_log where ref_id = '$id' order by id desc");
  718. foreach($configurationArr as $ca){
  719. $data = $this->dealPromptFormatAndVue($ca);
  720. $temp =array();
  721. $temp["time"] = $ca['created_time']." Prompt";
  722. $temp["person"] ="提交人:".$ca['created_by'];
  723. $temp["text"] = $data['promptFormat'];
  724. $changeLogList[] = $temp;
  725. }
  726. return $changeLogList;
  727. }
  728. public function getSystemPrompt(){
  729. //查询所有配置信息 目前只有一个表一个数据
  730. $configuration = common::excuteObjectSql("select id, character_name,professional_field,main_tasks,table_name,table_description,
  731. table_structure_configuration,response_rule_configuration,output_format_configuration,fixed_problem_configuration
  732. from public.kln_robot_prompt_configuration where id = 1");
  733. $PromptAndVue = $this->dealPromptFormatAndVue($configuration);
  734. //promptFormat
  735. $promptFormat =$PromptAndVue["promptFormat"];
  736. return $promptFormat;
  737. }
  738. public function getCompletePromptFormat() {
  739. $formatTpl = "
  740. 您是专门从<{professional_field}>的 <{character_name}>,请始终以<{output_type}>格式响应。您的主要任务是<{main_tasks}>
  741. 表名:<{table}>
  742. 表结构: \"columns\": <{table_structure_configuration}>
  743. 响应规则,请按以下步骤处理:
  744. <{response_rule_configuration}>
  745. <{number}>.请严格按照以下<{output_type}>格式返回,不要包含任何其他文字或说明:
  746. {
  747. \"can_query\": true,
  748. \"query_type\": \"货物跟踪\",
  749. \"reason\": \"分析原因\",
  750. \"sql\": \"生成的SQL語句\",
  751. \"reference\": \"Markdown格式的回复模板\",
  752. \"response\": \"直接回答內容或空字符串\"
  753. }
  754. 字段說明:
  755. <{output_format_configuration}>
  756. 重要:请只返回JSON对象,不要包含任何解释文字或代码块标记";
  757. return $formatTpl;
  758. }
  759. public function doFreeAnswerAndLog($serial_no,$model,$systemPrompt, $question_content, $history){
  760. //分担查询
  761. include ONLINE_ROOT . 'libs' . DS . 'map_config.ini.php';
  762. //Ai response
  763. $item_value = common::excuteOneSql("select item_value from public.config where item = 'AIAPISetting'");
  764. $config = json_decode($item_value,true);
  765. $response = AIClientFactory::create($model, $config[$model], $systemPrompt, $question_content, $history = []);
  766. $input_token = "";
  767. $output_token = "";
  768. $answer_template = "";
  769. $answer ="";
  770. $response_pram = common::excuteObjectSql("select to_char(now(), 'YYYY-mm-dd HH24:MI:SS') as response_time,
  771. CEIL(EXTRACT(EPOCH FROM (now() - question_date))) AS response_duration from public.kln_robot_chat_log where serial_no = '$serial_no'");
  772. $response_duration = $response_pram['response_duration'];
  773. //回答问题类型,在没有超时的情况下,固定:AI回答
  774. $answer_type = "AI Answer";
  775. if ($response_duration > 120){
  776. $answer_type = "Timeout";
  777. }
  778. $request_content = common::check_input(json_encode($response['data'],JSON_UNESCAPED_UNICODE));
  779. $ai_response_content = common::check_input(json_encode($response['full_response'],JSON_UNESCAPED_UNICODE));
  780. //提前记录AI 返回,如果sql异常掉了的话,可以查找原因
  781. $updateSql = "update public.kln_robot_chat_log set answer_duration = '$response_duration',answer_template='$answer_template',
  782. answer_type = case when COALESCE(answer_type,'') = 'Suspend' then 'Suspend' else '$answer_type' end,
  783. request_content='$request_content',
  784. input_token='$input_token',ai_response_content='$ai_response_content',
  785. output_token='$output_token',response_time=now(),response_duration='$response_duration'
  786. where serial_no = '$serial_no'";
  787. $updateRs = common::excuteUpdateSql($updateSql);
  788. if (!$updateRs) {
  789. $data = array("type"=>"markdown","data" => "AI Chat Response Save Error");
  790. common::echo_json_encode(200,$data);
  791. exit();
  792. }
  793. $message = json_decode(common::getChatAimessage($response['message']),true);
  794. if($message["can_query"] == "true" && !empty($message["sql"])){
  795. $reference = $message["reference"];
  796. $answer_template = common::check_input($message["reference"]);
  797. $sql = $message["sql"];
  798. //拆分sql 存在多条的情况
  799. $sqlArr = explode(";", $sql);
  800. //给所有sql 拼接用户权限
  801. $sqlWhere = ' ' . common::searchExtendHand_KLN("ocean", $_SESSION["ONLINE_USER"]);
  802. foreach($sqlArr as $_sql){
  803. if(empty($_sql)){
  804. continue;
  805. }
  806. //首先检查sql 是否有非法的字符和不规范查询
  807. $safe = common::checkSafeSql($_sql);
  808. if(!$safe){
  809. $reference = "The answer is incorrect. It has been filtered.";
  810. break;
  811. }
  812. //根据public.kln_ocean 和 WHERE 的位置关系,带入权限
  813. $new_sql = utils::modifyString($_sql,$sqlWhere);
  814. //处理limit 超过10 先限制10
  815. //$new_sql = utils::processLimitClause($new_sql);
  816. //$rs = common::excuteListSql($new_sql);
  817. $rs = $mapdb->GetAll($new_sql) or ( (!$mapdb->ErrorMsg()) or error_log(common::dbLog($mapdb, $new_sql), 0));
  818. $reference = utils::replacementsMultiline($rs,$reference,$new_sql);
  819. }
  820. //有就去掉{{#each hbol_list}}\n {{/each}}
  821. $reference = preg_replace([
  822. '/\{\{[^}]+\}\}\n/', // 匹配开始标签及换行
  823. '/\{\{\/[^}]+\}\}/' // 匹配结束标签
  824. ], '', $reference);
  825. $answer = $reference;
  826. }else{
  827. $answer = $message["response"];
  828. if(!$response['success']){
  829. $answer = $response["error"];
  830. }
  831. }
  832. //update 更新 answer
  833. $updateSql = "update public.kln_robot_chat_log set answer = '".common::check_input($answer)."'
  834. where serial_no = '$serial_no'";
  835. $updateRs = common::excuteUpdateSql($updateSql);
  836. if (!$updateRs) {
  837. $data = array("type"=>"markdown","data" => "AI Chat Response Save Error");
  838. common::echo_json_encode(200,$data);
  839. exit();
  840. }
  841. return $answer;
  842. }
  843. public function doFixedAnswerAndLog($serial_no,$fixed_faq,$question_content){
  844. $input_token = "";
  845. $output_token = "";
  846. $answer_template = "";
  847. $answer ="";
  848. $fixedChat = common::excuteObjectSql("select * from public.kln_robot_chat_fixed where fixed_faq = '$fixed_faq'");
  849. if (empty($fixedChat['secondary_interaction_content']) || $question_content != $fixedChat['fixed_faq'] ){
  850. $answer_template = common::check_input($fixedChat["answer_style"]);
  851. $answer = common::FixedAnswerAndLogData($fixedChat,$question_content);
  852. } else {
  853. $answer = $fixedChat['secondary_interaction_content'];
  854. }
  855. //回答完毕计时
  856. $response_pram = common::excuteObjectSql("select to_char(now(), 'YYYY-mm-dd HH24:MI:SS') as response_time,
  857. CEIL(EXTRACT(EPOCH FROM (now() - question_date))) AS response_duration from public.kln_robot_chat_log where serial_no = '$serial_no'");
  858. $response_duration = $response_pram['response_duration'];
  859. //回答问题类型,在没有超时的情况下,固定:AI回答
  860. $answer_type = "Predefined Template";
  861. if ($response_duration > 120){
  862. $answer_type = "Timeout";
  863. }
  864. $request_content = common::check_input($question_content);
  865. $ai_response_content = common::check_input($answer);
  866. //update 更新
  867. $updateSql = "update public.kln_robot_chat_log set answer_duration = '$response_duration',answer_template='$answer_template',answer = '".common::check_input($answer)."',
  868. answer_type = case when COALESCE(answer_type,'') = 'Suspend' then 'Suspend' else '$answer_type' end,
  869. request_content='$request_content',
  870. input_token='$input_token',ai_response_content='$ai_response_content',
  871. output_token='$output_token',response_time=now(),response_duration='$response_duration'
  872. where serial_no = '$serial_no'";
  873. $updateRs = common::excuteUpdateSql($updateSql);
  874. if (!$updateRs) {
  875. $data = array("type"=>"markdown","data" => "AI Chat Response Save Error");
  876. common::echo_json_encode(200,$data);
  877. exit();
  878. }
  879. return $answer;
  880. }
  881. }
  882. ?>