Apis.php 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976
  1. <?php
  2. namespace app\index\controller;
  3. use think\Request;
  4. use think\Db;
  5. header("Access-Control-Allow-Origin: *"); // 允许所有来源
  6. header("Access-Control-Allow-Headers: Content-Type"); // 允许的请求头
  7. //sm4
  8. use Evit\PhpGmCrypto\Encryption\EvitSM4Encryption;
  9. class Apis extends \think\Controller
  10. {
  11. //对传入的信息进行存储并获取短令牌
  12. public function getToken(){
  13. //通过入参构建准备存入数据库的内容
  14. $information = request() -> param('information');
  15. // $information = 'eyJlbmNyeXB0ZWRCYXNlNjQiOiJibjk2UzZxQXBlanhVTHZLSExkdDJuWEtKSnUwZit1YlVYanl1a29HU2JYdEk5bGV4RVZZUDFHNkVJcnZld3ZtZTZDUDlKaGZZSjZyR1wvUyttdGd6cHlTQzVLM1JkUWZUYzdRNndsTG5XbGludEhqdFM0RTJqdHVSWlFPeXNZQmZQU0x4anE0SG13MEI2WkE4bTRLK2xVTHJIRXdlMVUyUkFuWkYzbDBqblZmZVZ0clwvaEloKzZ6VzRVeHBHRzllWll5ZGNIVVBGOCtldGRxdEJ5aHB1TWtEYXEwRmlXckRVXC9BVkJZYXdtTmt3aTZiRFdrdWtZS1JKRWhIa0Z3SDdYZVh1REdFdmFBNEs5VktiRENQQXY4cXJoT21abGFOMVNcLzhXZG5VczBaaEVKSXk4WEVmREcxZ0oxOVJuQTUzbENVTGgrZVFnbWVQXC9DYTd2MisxRmpjZUhlVERPaGRNamVWeXlhXC81VzJ1OVI0bnFcLzBxZ3R5WVkwMDBxeEZMaWVncHNReFlCMzh0bEh5M1hVeVdOMFBVbkNcL2FNV29ncGMrNTZleEtwU0liYkJGQXN4b2tsY2xZWkkwREVDaExFZzIiLCJzbUlWIjoiNXlVYjhGY0xGd1FFN0NpNyIsInB1YmxpY0tleSI6IlhsZTZMUjVvT1pKdU84Y3lYODFqbDNRdmZCeGg1ZmxzIn0';
  16. $askInfo['encryption'] = $information;
  17. $informationCut = substr($information, 0, 20);
  18. $time = time();
  19. $token = md5($informationCut.$time.rand(10000,99999));
  20. $askInfo['token'] = $token;
  21. $askInfo['time'] = $time;
  22. $information = base64UrlDecode($information);
  23. $information = json_decode($information);
  24. $information = stdClassObjToArray($information);
  25. if(!$information){
  26. $error['code'] = 6;
  27. $error['message'] = '非法请求,已拒绝。';
  28. return json_encode($error,JSON_UNESCAPED_UNICODE);
  29. }
  30. //通过sm4进行解密
  31. $smIV = $information['smIV'];
  32. $publicKey = $information['publicKey'];
  33. $encryptedBase64 = $information['encryptedBase64'];
  34. $mapProject['public_key'] = array('eq',$publicKey);
  35. $privateKey = db('Project') -> where($mapProject) -> value('private_key');
  36. $config = [
  37. 'mode' => 'cbc',
  38. 'key' => $privateKey, // 16 字节二进制密钥
  39. 'iv' => $smIV, // 16 字节二进制 IV
  40. 'hash' => false
  41. ];
  42. $sm4 = new EvitSM4Encryption($config);
  43. $pass = base64_decode($encryptedBase64);
  44. $decrypted = $sm4->decrypt($pass);
  45. $decrypted = base64_decode($decrypted);
  46. $information = json_decode($decrypted);
  47. $information = stdClassObjToArray($information);
  48. if(!$information){
  49. $error['code'] = 0;
  50. $error['message'] = '解密错误,请核对仔细核对参数!';
  51. return json_encode($error,JSON_UNESCAPED_UNICODE);
  52. }
  53. //请求信息整理
  54. $dataInsert['smIV'] = $smIV;
  55. $dataInsert['publicKey'] = $publicKey;
  56. $dataInsert['model'] = $information['model'];
  57. $dataInsert['network'] = $information['network'];
  58. $dataInsert['input'] = $information['input'];
  59. //构建数据库记录
  60. $askInfo['decrypt'] = json_encode($dataInsert,JSON_UNESCAPED_UNICODE);
  61. //将请求记录存储至数据库
  62. db('askinfo') -> insert($askInfo);
  63. //将token返回给请求端
  64. $success['code'] = 1;
  65. $success['token'] = $token;
  66. return json_encode($success,JSON_UNESCAPED_UNICODE);
  67. }
  68. //对传入的参数进行校验
  69. public function check(){
  70. $token = request() -> param('token');
  71. $ragId = request() -> param('ragId');
  72. //通过获取的token获取对应的encryption
  73. $mapAskInfo['token'] = array('eq',$token);
  74. $information = db('askinfo') -> where($mapAskInfo) -> value('encryption');
  75. $information = base64UrlDecode($information);
  76. $information = json_decode($information);
  77. $information = stdClassObjToArray($information);
  78. if(!$information){
  79. $error['code'] = 6;
  80. $error['message'] = '非法请求,已拒绝。';
  81. return json_encode($error,JSON_UNESCAPED_UNICODE);
  82. }
  83. //通过sm4进行解密
  84. $smIV = $information['smIV'];
  85. $publicKey = $information['publicKey'];
  86. $encryptedBase64 = $information['encryptedBase64'];
  87. $mapProject['public_key'] = array('eq',$publicKey);
  88. $privateKey = db('Project') -> where($mapProject) -> value('private_key');
  89. $config = [
  90. 'mode' => 'cbc',
  91. 'key' => $privateKey, // 16 字节二进制密钥
  92. 'iv' => $smIV, // 16 字节二进制 IV
  93. 'hash' => false
  94. ];
  95. $sm4 = new EvitSM4Encryption($config);
  96. $pass = base64_decode($encryptedBase64);
  97. $decrypted = $sm4->decrypt($pass);
  98. $decrypted = base64_decode($decrypted);
  99. $information = json_decode($decrypted);
  100. $information = stdClassObjToArray($information);
  101. if(!$information){
  102. $error['code'] = 0;
  103. $error['message'] = '解密错误,请核对仔细核对参数!';
  104. return json_encode($error,JSON_UNESCAPED_UNICODE);
  105. }
  106. //获取接口请求信息
  107. $model = $information['model'];
  108. $network = $information['network'];
  109. $input = $information['input'];
  110. if(!is_array($input)){
  111. $error['code'] = 7;
  112. $error['message'] = '输入内容必须为数组格式!';
  113. return json_encode($error,JSON_UNESCAPED_UNICODE);
  114. }
  115. //判断模型是否存在
  116. $mapModel['model'] = array('eq',$model);
  117. $modelId = db('Model') -> where($mapModel) -> value('id');
  118. if($modelId){
  119. $mapModel['network'] = array('eq',$network);
  120. $modelId = db('Model') -> where($mapModel) -> value('id');
  121. //判断network参数是否正确
  122. if($modelId){
  123. //判断publicKey参数是否正确
  124. $mapProject['public_key'] = array('eq',$publicKey);
  125. $modelList = db('Project') -> where($mapProject) -> value('models');
  126. if($modelList){
  127. //判断publicKey是否具备模型权限
  128. $modelList = json_decode($modelList);
  129. if(in_array($modelId,$modelList)){
  130. $success['code'] = 5;
  131. $success['input'] = $input;
  132. $success['modelId'] = $modelId;
  133. if($ragId == 'empty'){
  134. $success['ragId'] = '';
  135. }
  136. else{
  137. //判断ragId和public是否存在关联关系
  138. $ragList = db('Project') -> where($mapProject) -> value('rags');
  139. $ragList = json_decode($ragList);
  140. $mapRag['ragid'] = array('eq',$ragId);
  141. $ragIdIncrement = db('Rag') -> where($mapRag) -> value('id');
  142. if(in_array($ragIdIncrement,$ragList)){
  143. $success['ragId'] = $ragId;
  144. }
  145. else{
  146. $error['code'] = 8;
  147. $error['message'] = '该公钥不具备该知识库权限,请联系管理员添加!';
  148. return json_encode($error,JSON_UNESCAPED_UNICODE);
  149. }
  150. }
  151. return json_encode($success,JSON_UNESCAPED_UNICODE);
  152. }
  153. else{
  154. $error['code'] = 4;
  155. $error['message'] = '该公钥不具备该模型权限,请联系管理员添加!';
  156. return json_encode($error,JSON_UNESCAPED_UNICODE);
  157. }
  158. }
  159. else{
  160. $error['code'] = 3;
  161. $error['message'] = '该公钥不正确,请核对参数“publicKey”的值!';
  162. return json_encode($error,JSON_UNESCAPED_UNICODE);
  163. }
  164. }
  165. else{
  166. $error['code'] = 2;
  167. $error['message'] = '该模型不支持该网络状态,请核对参数“network”的值!';
  168. return json_encode($error,JSON_UNESCAPED_UNICODE);
  169. }
  170. }
  171. else{
  172. $error['code'] = 1;
  173. $error['message'] = '模型不存在,请核对参数“model”的值!';
  174. return json_encode($error,JSON_UNESCAPED_UNICODE);
  175. }
  176. }
  177. //存储对应的回复记录
  178. public function reply(){
  179. $token = request() -> param('token');
  180. $reply = request() -> param('reply');
  181. $mapAskInfo['token'] = array('eq',$token);
  182. $data['reply'] = $reply;
  183. db('askinfo') -> where($mapAskInfo) -> update($data);
  184. }
  185. //供三方系统所支持的模型信息
  186. public function search(){
  187. //根据公钥查询模型列表
  188. $publicKey = request() -> param('publicKey');
  189. $mapProject['public_key'] = array('eq',$publicKey);
  190. $models = db('Project') -> where($mapProject) -> find();
  191. if($models){
  192. $modelList = json_decode($models['models']);
  193. //根据模型列表查询模型信息
  194. $mapModel['id'] = array('in',$modelList);
  195. $modelList = db('Model') -> where($mapModel) -> order('sort') -> select();
  196. $data['code'] = 1;
  197. $data['models'] = $modelList;
  198. return json($data,JSON_UNESCAPED_UNICODE) -> code(200);
  199. }
  200. else{
  201. $data['code'] = 0;
  202. $data['models'] = '该公钥并未配置模型权限,请联系管理员添加!';
  203. return json($data,JSON_UNESCAPED_UNICODE);
  204. }
  205. }
  206. //
  207. function handleChatTest() {
  208. if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  209. http_response_code(405); // 405 Method Not Allowed
  210. echo json_encode(['error' => 'Only POST requests are allowed']);
  211. return;
  212. }
  213. $expectedToken = 'sk-d5f7c8b1a37c4a9ba24f905927a7b3f9';
  214. $targetUrl = 'http://60.164.133.40:9997/v1/chat/completions';
  215. // 获取请求体和头信息
  216. $requestBody = file_get_contents('php://input');
  217. $headers = getallheaders();
  218. $authorizationHeader = isset($headers['Authorization']) ? $headers['Authorization'] : '';
  219. // 校验 Authorization
  220. if ($authorizationHeader !== 'Bearer ' . $expectedToken) {
  221. http_response_code(403);
  222. echo json_encode(['error' => 'Authorization header']);
  223. return;
  224. }
  225. // 发起代理请求
  226. $ch = curl_init($targetUrl);
  227. curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
  228. curl_setopt($ch, CURLOPT_POST, true);
  229. curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
  230. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  231. 'Content-Type: application/json',
  232. 'Authorization: ' . $authorizationHeader
  233. ]);
  234. // 设置回调,边接收边输出
  235. curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) {
  236. echo $data;
  237. // 立即刷新输出缓冲
  238. @ob_flush();
  239. @flush();
  240. return strlen($data);
  241. });
  242. // 返回响应
  243. header('Content-Type: application/json');
  244. $res = curl_exec($ch);
  245. if (curl_errno($ch)) {
  246. http_response_code(500);
  247. echo json_encode(['error' => 'cURL Error: ' . curl_error($ch)]);
  248. }
  249. curl_close($ch);
  250. }
  251. function handleChatapi() {
  252. if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  253. http_response_code(405);
  254. echo json_encode(['error' => 'Only POST requests are allowed']);
  255. return;
  256. }
  257. // 关闭所有缓冲,强制流式输出
  258. @ini_set('output_buffering', 'off');
  259. @ini_set('zlib.output_compression', false);
  260. while (ob_get_level() > 0) {
  261. ob_end_flush();
  262. }
  263. ob_implicit_flush(true);
  264. // 设置流式响应头
  265. header('Content-Type: application/json; charset=utf-8');
  266. header('Cache-Control: no-cache');
  267. header('X-Accel-Buffering: no'); // 对 Nginx 有效,关闭缓冲
  268. $expectedToken = 'sk-d5f7c8b1a37c4a9ba24f905927a7b3f9';
  269. $targetUrl = 'http://60.164.133.40:19997/v1/chat/completions';
  270. $requestBody = file_get_contents('php://input');
  271. $headers = getallheaders();
  272. $authorizationHeader = isset($headers['Authorization']) ? $headers['Authorization'] : '';
  273. if ($authorizationHeader !== 'Bearer ' . $expectedToken) {
  274. http_response_code(403);
  275. echo json_encode(['error' => 'Invalid Authorization header']);
  276. return;
  277. }
  278. $ch = curl_init($targetUrl);
  279. curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
  280. curl_setopt($ch, CURLOPT_POST, true);
  281. curl_setopt($ch, CURLOPT_TIMEOUT, 0);
  282. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
  283. curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
  284. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  285. 'Content-Type: application/json',
  286. 'Authorization: ' . $authorizationHeader
  287. ]);
  288. curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) {
  289. echo $data;
  290. @ob_flush();
  291. @flush();
  292. return strlen($data);
  293. });
  294. $logFile = __DIR__ . '/handleChat.log';
  295. $timestamp = date('[Y-m-d H:i:s]');
  296. file_put_contents($logFile, $timestamp . ' ' .$requestBody .PHP_EOL, FILE_APPEND);
  297. $res = curl_exec($ch);
  298. if (curl_errno($ch)) {
  299. http_response_code(500);
  300. echo json_encode(['error' => 'cURL Error: ' . curl_error($ch)]);
  301. }
  302. curl_close($ch);
  303. $timestamp = date('[Y-m-d H:i:s]');
  304. file_put_contents($logFile, $timestamp . ' ' .PHP_EOL, FILE_APPEND);
  305. }
  306. function handleEmbedding() {
  307. if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  308. http_response_code(405);
  309. echo json_encode(['error' => 'Only POST requests are allowed']);
  310. return;
  311. }
  312. $expectedToken = 'sk-a9de61b8b354442a98e842d9ecf2a204';
  313. $targetUrl = 'http://60.164.133.40:19997/v1/embeddings';
  314. $headers = array_change_key_case(getallheaders(), CASE_LOWER);
  315. if (!isset($headers['authorization'])) {
  316. http_response_code(401);
  317. echo json_encode(['error' => 'Missing Authorization header']);
  318. return;
  319. }
  320. $authHeader = $headers['authorization'];
  321. if ($authHeader !== 'Bearer ' . $expectedToken) {
  322. http_response_code(403);
  323. echo json_encode(['error' => 'Invalid API token']);
  324. return;
  325. }
  326. $requestBody = file_get_contents('php://input');
  327. $ch = curl_init($targetUrl);
  328. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  329. curl_setopt($ch, CURLOPT_POST, true);
  330. curl_setopt($ch, CURLOPT_TIMEOUT, 0);
  331. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
  332. curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
  333. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  334. 'Content-Type: application/json',
  335. 'accept: application/json',
  336. 'Authorization: ' . $authHeader,
  337. ]);
  338. curl_setopt($ch, CURLOPT_HEADER, true);
  339. curl_setopt($ch, CURLOPT_ENCODING, ''); // 支持所有编码,防止自动解压影响
  340. $response = curl_exec($ch);
  341. if (curl_errno($ch)) {
  342. http_response_code(500);
  343. echo json_encode(['error' => 'cURL Error: ' . curl_error($ch)]);
  344. curl_close($ch);
  345. return;
  346. }
  347. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  348. $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  349. curl_close($ch);
  350. $responseHeaders = substr($response, 0, $headerSize);
  351. $responseBody = substr($response, $headerSize);
  352. // 关闭所有输出缓冲区,防止格式被修改
  353. while (ob_get_level()) {
  354. ob_end_clean();
  355. }
  356. // 只转发 Content-Type,避免冲突
  357. foreach (explode("\r\n", $responseHeaders) as $headerLine) {
  358. if (stripos($headerLine, 'Content-Type:') === 0) {
  359. header($headerLine);
  360. }
  361. }
  362. http_response_code($httpCode);
  363. // 直接原样输出响应体,不做任何json_encode或修改
  364. echo $responseBody;
  365. }
  366. //查询RAG列表
  367. public function searchRag(){
  368. //根据公钥查询模型列表
  369. $publicKey = request() -> param('publicKey');
  370. $mapProject['public_key'] = array('eq',$publicKey);
  371. $rags = db('Project') -> where($mapProject) -> find();
  372. if($rags){
  373. $ragList = json_decode($rags['rags']);
  374. //根据模型列表查询模型信息
  375. $mapRag['id'] = array('in',$ragList);
  376. $ragList = db('Rag') -> where($mapRag) -> select();
  377. $data['code'] = 1;
  378. $data['rags'] = $ragList;
  379. return json($data, JSON_UNESCAPED_UNICODE) -> code(200);
  380. }
  381. else{
  382. $data['code'] = 0;
  383. $data['models'] = '该公钥并未配置知识库权限,请联系管理员添加!';
  384. return json($data,JSON_UNESCAPED_UNICODE);
  385. }
  386. }
  387. //查询RAG列表
  388. public function searchagents(){
  389. //根据公钥查询模型列表
  390. $publicKey = request() -> param('publicKey');
  391. $mapProject['public_key'] = array('eq',$publicKey);
  392. $agents = db('Project') -> where($mapProject) -> find();
  393. if($agents){
  394. $agentsList = json_decode($agents['agents']);
  395. //根据模型列表查询模型信息
  396. $mapRag['id'] = array('in',$agentsList);
  397. $agentsList = db('agent') -> where($mapRag) -> select();
  398. $data['code'] = 1;
  399. $data['agents'] = $agentsList;
  400. return json($data,JSON_UNESCAPED_UNICODE) -> code(200);
  401. }
  402. else{
  403. $data['code'] = 0;
  404. $data['models'] = '该公钥并未配置智能体权限,请联系管理员添加!';
  405. return json($data,JSON_UNESCAPED_UNICODE);
  406. }
  407. }
  408. //检索增强接口
  409. public function ragData(){
  410. $input = request() -> param('input');
  411. $kid = request() -> param('kid');
  412. $RAGdata = [
  413. "username" => "test",
  414. "password" => "test123"
  415. ];
  416. // 调用时只需传递非 Content-Type/Accept 的 Header
  417. $headers = [
  418. 'Cache-Control: no-cache',
  419. 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
  420. ];
  421. $urlRAG = "http://192.168.1.8:6039/auth/login"; // 替换为实际 URL
  422. $id = curlPostRAG($urlRAG, $RAGdata, $headers);
  423. $token = $id; // 默认启用 JSON 模式
  424. $token = json_decode($token);
  425. $token = stdClassObjToArray($token);
  426. $token = $token['data']['token'];
  427. $url = "http://192.168.1.8:6039/rag/schema"; // 替换成实际接口地址
  428. $data = [
  429. "messages" => $input, // 替换成实际用户输入
  430. "model" => "123", // 替换成实际模型名称
  431. "maxDistance" => 0.7, // 替换成实际分数(浮点数)
  432. "kid" => $kid // 替换成实际知识库 ID
  433. ];
  434. // 初始化 cURL
  435. $ch = curl_init();
  436. // 设置 cURL 选项
  437. curl_setopt($ch, CURLOPT_URL, $url);
  438. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回响应数据
  439. curl_setopt($ch, CURLOPT_POST, true); // 使用 POST 方法
  440. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); // 发送 JSON 数据
  441. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  442. "Authorization: Bearer " . $token,
  443. "Content-Type: application/json" // 声明请求体是 JSON
  444. ]);
  445. // 执行请求并获取响应
  446. $response = curl_exec($ch);
  447. // 检查是否有错误
  448. if (curl_errno($ch)) {
  449. echo "cURL 请求失败: " . curl_error($ch);
  450. } else {
  451. // 解析 JSON 响应
  452. //$result = json_decode($response, true);
  453. return $response; // 输出返回数据(prompt, vector, nearest)
  454. }
  455. // 关闭 cURL 资源
  456. curl_close($ch);
  457. }
  458. //查询生命体征数据
  459. public function vitalSignsData(){
  460. $number = request() -> param('number');
  461. $data["number"] = request() -> param('number');
  462. if(!isset($number) || $number == "" ){
  463. return ("未输入患者编号,请输入。");
  464. }
  465. $data["lowerBloodPressure"] = request() -> param('lowerBloodPressure');
  466. $data["upperBloodPressure"] = request() -> param('upperBloodPressure');
  467. $data["heartRate"] = request() -> param('heartRate');
  468. $data["temperature"] = request() -> param('temperature');
  469. $data["bloodOxygen"] = request() -> param('bloodOxygen');
  470. $data["breatheRate"] = request() -> param('breatheRate');
  471. $data["name"] = request() -> param('name');
  472. $data["sex"] = request() -> param('sex');
  473. $data["age"] = request() -> param('age');
  474. $data["deptName"] = request() -> param('deptName');
  475. $data["doctor"] = request() -> param('doctor');
  476. $alarmType = request() -> param('alarmType');
  477. $data["alarmType"] = request() -> param('alarmType');
  478. if(!isset($alarmType) || trim($alarmType) === "" || $alarmType == "" ){
  479. return ("未输入异常类型,请输入。");
  480. }
  481. $data = json_encode($data,JSON_UNESCAPED_UNICODE);
  482. $urlvitalsigns = "http://192.168.1.8:6039/patient/vitalSigns";
  483. $headers = [
  484. 'Content-Type: application/json'
  485. ];
  486. $response = curlPost($urlvitalsigns,$data,$headers);
  487. return $response;
  488. }
  489. public function test123(){
  490. $data["input"] = "?";
  491. $data["kid"] = '1947484295610253313';
  492. // $data = json_encode($data, JSON_UNESCAPED_UNICODE);
  493. // dump($data);
  494. // exit;
  495. $url = "http://192.168.1.8:3338/apis/knowledgeMessage";
  496. $a = curlPost($url,$data);
  497. return $a;
  498. }
  499. public function testhttp(){
  500. $data["token"] = "c9fce85232e25a803f3b0e17714a674b";
  501. $data["ragId"] = '1947484295610253313';
  502. // $data = json_encode($data, JSON_UNESCAPED_UNICODE);
  503. // dump($data);
  504. // exit;
  505. $url = "http://192.168.1.8:3340";
  506. $a = curlPost($url,$data);
  507. return $a;
  508. }
  509. //供三方系统的检索增强接口
  510. public function knowledgeMessage(){
  511. // $input = request() -> param('input');
  512. // $kid = request() -> param('kid');
  513. $json = file_get_contents('php://input');
  514. $json = json_decode($json);
  515. $json = stdClassObjToArray($json);
  516. if($json){
  517. $input = $json['input'];
  518. $kid = $json['kid'];
  519. }
  520. $count = request() -> param('count');
  521. // $input = $_POST['input'];
  522. // $kid = $_POST['kid'];
  523. $count = json_decode($count);
  524. $count = stdClassObjToArray($count);
  525. // echo($input);
  526. // exit;
  527. if($count){
  528. $input = $count['input'];
  529. $kid = $count['kid'];
  530. }
  531. if(!$input){
  532. echo '{"code":500,"msg":"cURL 请求失败: 请检查参数。","data":null}';
  533. exit;
  534. }
  535. if(!$kid){
  536. echo '{"code":500,"msg":"cURL 请求失败: 请检查参数。","data":null}';
  537. exit;
  538. }
  539. $RAGdata = [
  540. "username" => "test",
  541. "password" => "test123"
  542. ];
  543. // 调用时只需传递非 Content-Type/Accept 的 Header
  544. $headers = [
  545. 'Cache-Control: no-cache',
  546. 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
  547. ];
  548. $urlRAG = "http://192.168.1.8:6039/auth/login"; // 替换为实际 URL
  549. $id = curlPostRAG($urlRAG, $RAGdata, $headers);
  550. $token = $id; // 默认启用 JSON 模式
  551. $token = json_decode($token);
  552. $token = stdClassObjToArray($token);
  553. $token = $token['data']['token'];
  554. $url = "http://192.168.1.8:6039/rag/schema"; // 替换成实际接口地址
  555. $data = [
  556. "messages" => $input, // 替换成实际用户输入
  557. "model" => "123", // 替换成实际模型名称
  558. "maxDistance" => 0.7, // 替换成实际分数(浮点数)
  559. "kid" => $kid // 替换成实际知识库 ID
  560. ];
  561. // 初始化 cURL
  562. $ch = curl_init();
  563. // 设置 cURL 选项
  564. curl_setopt($ch, CURLOPT_URL, $url);
  565. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回响应数据
  566. curl_setopt($ch, CURLOPT_POST, true); // 使用 POST 方法
  567. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); // 发送 JSON 数据
  568. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  569. "Authorization: Bearer " . $token,
  570. "Content-Type: application/json" // 声明请求体是 JSON
  571. ]);
  572. // 执行请求并获取响应
  573. $response = curl_exec($ch);
  574. // 检查是否有错误
  575. if (strpos($response, "code") !== false) {
  576. $response = json_decode($response);
  577. echo '{"code":'.$response ->code.',"msg":"cURL 请求失败: 请检查参数。","data":null}';
  578. exit;
  579. } else {
  580. // 解析 JSON 响应
  581. $response = json_decode($response, true);
  582. $response["code"] = 200;
  583. $response = json_encode($response, JSON_UNESCAPED_UNICODE);
  584. return $response; // 输出返回数据(prompt, vector, nearest)
  585. }
  586. // 关闭 cURL 资源
  587. curl_close($ch);
  588. }
  589. public function MCPData(){
  590. $input = [ [
  591. "content" => "你好",
  592. "role" => "user"
  593. ],
  594. [
  595. "content" => "你好!我是EMOON AI助手,有什么可以帮助你的吗?",
  596. "role" => "assistant"
  597. ],
  598. [
  599. "content" => "查询2025年6月1日到2025年6月2的医院数据 并计算这三天外科的平均住院人数是多少?",
  600. "role" => "user"
  601. ],
  602. ];
  603. $kid = "";
  604. $RAGdata = [
  605. "username" => "test",
  606. "password" => "test123"
  607. ];
  608. // 调用时只需传递非 Content-Type/Accept 的 Header
  609. $headers = [
  610. 'Cache-Control: no-cache',
  611. 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
  612. ];
  613. $urlRAG = "http://192.168.1.8:6039/auth/login"; // 替换为实际 URL
  614. $id = curlPostRAG($urlRAG, $RAGdata, $headers);
  615. $token = $id; // 默认启用 JSON 模式
  616. $token = json_decode($token);
  617. $token = stdClassObjToArray($token);
  618. $token = $token['data']['token'];
  619. $url = "http://192.168.1.8:6039/chat/send"; // 替换成实际接口地址
  620. $data = [
  621. "messages" => $input,
  622. "model" => "qwen3-8B", //X
  623. "temperature" => 0.5,
  624. "top_p" => 1,
  625. "presence_penalty" => 0,
  626. "frequency_penalty" => 0,
  627. "kid" => $kid,
  628. "chat_type" => 0,
  629. "appId" => "",
  630. "stream" => true
  631. ];
  632. // 初始化 cURL
  633. $ch = curl_init();
  634. // 设置 cURL 选项
  635. curl_setopt($ch, CURLOPT_URL, $url);
  636. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回响应数据
  637. curl_setopt($ch, CURLOPT_POST, true); // 使用 POST 方法
  638. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); // 发送 JSON 数据
  639. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  640. "Authorization: Bearer " . $token,
  641. "Content-Type: application/json" // 声明请求体是 JSON
  642. ]);
  643. curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
  644. // 执行请求并获取响应
  645. $response = curl_exec($ch);
  646. $lines = explode("\n", $response);
  647. $output = '';
  648. foreach ($lines as $line) {
  649. if (strpos($line, 'event:chat_completion') !== false) {
  650. // 提取data部分
  651. $content = str_replace('event:chat_completion data:', '', $line);
  652. $output .= trim($content);
  653. } elseif (trim($line) === '[DONE]') {
  654. // 处理结束标志
  655. $output .= "\n[传输结束]";
  656. }
  657. }
  658. // 现在$output包含所有提取的内容
  659. echo $output;
  660. // 关闭 cURL 资源
  661. curl_close($ch);
  662. }
  663. public function handleChat() {
  664. // 关闭所有缓冲,强制流式输出
  665. @ini_set('output_buffering', 'off');
  666. @ini_set('zlib.output_compression', false);
  667. while (ob_get_level() > 0) {
  668. ob_end_flush();
  669. }
  670. ob_implicit_flush(true);
  671. // 设置流式响应头
  672. header('Content-Type: text/event-stream; charset=utf-8');
  673. header('Cache-Control: no-cache');
  674. header('X-Accel-Buffering: no'); // 对 Nginx 有效,关闭缓冲
  675. $requestBody = file_get_contents('php://input');
  676. $headers = getallheaders();
  677. $authorizationHeader = isset($headers['Authorization']) ? $headers['Authorization'] : '';
  678. $input = [ [
  679. "content" => "你好",
  680. "role" => "user"
  681. ],
  682. [
  683. "content" => "你好!我是EMOON AI助手,有什么可以帮助你的吗?",
  684. "role" => "assistant"
  685. ],
  686. [
  687. "content" => "查询2025年6月1日到2025年6月2的医院数据 并计算这三天外科的平均住院人数是多少?",
  688. "role" => "user"
  689. ],
  690. ];
  691. $kid = "";
  692. $RAGdata = [
  693. "username" => "test",
  694. "password" => "test123"
  695. ];
  696. // 调用时只需传递非 Content-Type/Accept 的 Header
  697. $headers = [
  698. 'Cache-Control: no-cache',
  699. 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
  700. ];
  701. $urlRAG = "http://192.168.1.8:6039/auth/login"; // 替换为实际 URL
  702. $id = curlPostRAG($urlRAG, $RAGdata, $headers);
  703. $token = $id; // 默认启用 JSON 模式
  704. $token = json_decode($token);
  705. $token = stdClassObjToArray($token);
  706. $token = $token['data']['token'];
  707. $url = "http://192.168.1.8:6039/chat/send"; // 替换成实际接口地址
  708. $data = [
  709. "messages" => $input,
  710. "model" => "qwen3-32B", //X
  711. "temperature" => 0.5,
  712. "top_p" => 1,
  713. "presence_penalty" => 0,
  714. "frequency_penalty" => 0,
  715. "kid" => $kid,
  716. "chat_type" => 0,
  717. "appId" => "",
  718. "stream" => true
  719. ];
  720. // 初始化 cURL
  721. $ch = curl_init();
  722. // 设置 cURL 选项
  723. curl_setopt($ch, CURLOPT_URL, $url);
  724. curl_setopt($ch, CURLOPT_RETURNTRANSFER, false); // 返回响应数据
  725. curl_setopt($ch, CURLOPT_POST, true); // 使用 POST 方法
  726. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); // 发送 JSON 数据
  727. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  728. "Authorization: Bearer " . $token,
  729. "Content-Type: application/json" // 声明请求体是 JSON
  730. ]);
  731. curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($url, $data) {
  732. echo $data;
  733. @ob_flush();
  734. @flush();
  735. return strlen($data);
  736. });
  737. $res = curl_exec($ch);
  738. curl_close($ch);
  739. }
  740. // public function MCPData() {
  741. // // 1. 强制设置SSE头并关闭缓冲
  742. // header('Content-Type: text/event-stream');
  743. // header('Cache-Control: no-cache');
  744. // ob_end_flush();
  745. // // 2. 模拟流式输出
  746. // for ($i = 1; $i <= 5; $i++) {
  747. // echo "event: test\n";
  748. // echo "data: " . json_encode(['count' => $i, 'time' => date('H:i:s')]) . "\n\n";
  749. // ob_flush();
  750. // flush();
  751. // sleep(1); // 模拟延迟
  752. // }
  753. // // 3. 结束标记
  754. // echo "event: end\n";
  755. // echo "data: {\"status\": \"complete\"}\n\n";
  756. // ob_flush();
  757. // flush();
  758. // }
  759. //生成随机key
  760. public function getKey() {
  761. $count = request() -> param('count');
  762. $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  763. $randomString = '';
  764. for ($i = 0; $i < $count; $i++) {
  765. $index = rand(0, strlen($characters) - 1);
  766. $randomString .= $characters[$index];
  767. }
  768. return $randomString;
  769. }
  770. //创建一个测试用例
  771. public function demo(){
  772. dump('-----------------------------');
  773. dump('【参数处理对照DEMO】');
  774. $information['model'] = 'emoon-E1-13B';
  775. $information['network'] = '1';
  776. $messages = [
  777. [
  778. 'role' => 'user',
  779. 'content' => "What is the highest mountain in the world?"
  780. ],
  781. [
  782. 'role' => 'assistant',
  783. 'content' => 'The highest mountain in the world is Mount Everest.'
  784. ],
  785. [
  786. 'role' => 'user',
  787. 'content' => 'What is the second?'
  788. ]
  789. ];
  790. $information['input'] = $messages;
  791. dump('-----------------------------');
  792. dump('1.数组');
  793. dump($information);
  794. //从后端生成是这种格式
  795. $data = json_encode($information, JSON_UNESCAPED_UNICODE);
  796. //从前端直接取值是这种格式
  797. //$data = '{"model":"emoon-E1-13B","network":"1","input":"[{\"role\":\"assistant\",\"content\":\"你好,我是医疗大语言模型「EMOON E1」,请问有什么可以帮您?\"},{\"role\":\"user\",\"content\":\"请问你是什么模型?\"},{\"role\":\"assistant\",\"content\":\"您好!我是EMOON E1 13B模型,一个专注于医疗领域的大语言模型。我由回车网络(EnterLO)训练研发,专门设计来提供医疗专业知识的解读和分析。如果您有任何医疗相关的问题或需要专业建议,我会尽力提供准确和有用的信息。请问有什么具体的医疗问题我可以帮您解答吗?\"},{\"role\":\"user\",\"content\":\"常见的脑科疾病以及对应的预防办法有哪些?\"}]"}';
  798. dump('-----------------------------');
  799. dump('2.数组转 json');
  800. dump($data);
  801. $data = base64_encode($data);
  802. dump('-----------------------------');
  803. dump('3.将 json 转换为 base64');
  804. dump($data);
  805. $config = [
  806. 'mode' => 'cbc',
  807. 'key' => 'VKc17yt2QiNZO8Ci', // 16 字节二进制密钥
  808. 'iv' => '1234567891478523', // 16 字节二进制 IV
  809. 'hash' => false
  810. ];
  811. dump('-----------------------------');
  812. dump('4.构建 sm4 参数,参数为:');
  813. dump($config);
  814. $sm4 = new EvitSM4Encryption($config);
  815. $encryptedBinary = $sm4->encrypt($data);
  816. dump('-----------------------------');
  817. dump('5.将 base64 进行 sm4 加密,此时为二进制文件');
  818. dump($encryptedBinary);
  819. $encryptedBase64 = base64_encode($encryptedBinary);
  820. dump('-----------------------------');
  821. dump('6.将二进制 转换为 Base64');
  822. dump($encryptedBase64);
  823. $modifiedData['encryptedBase64'] = $encryptedBase64;
  824. $modifiedData['smIV'] = '1234567891478523';
  825. $modifiedData['publicKey'] = 'tHJZp9mJQPJ4CJAu19F6vhIVa1cyZhP8';
  826. dump('-----------------------------');
  827. dump('7.构造最终的请求体数组');
  828. dump($modifiedData);
  829. $modifiedData = json_encode($modifiedData,JSON_UNESCAPED_UNICODE);
  830. dump('-----------------------------');
  831. dump('8.将请求体数组转换为 json');
  832. dump($modifiedData);
  833. $modifiedData = base64_encode($modifiedData);
  834. dump('-----------------------------');
  835. dump('9.将请求体 json 转换为 Base64');
  836. dump($modifiedData);
  837. $modifiedData = strtr($modifiedData, '+/', '-_');
  838. dump('-----------------------------');
  839. dump('10.// 将 + 替换为 -,/ 替换为 _');
  840. dump($modifiedData);
  841. dump('-----------------------------');
  842. dump('END.完成构建,将该字符串请求 https://open.emoon.com/apiSSE.php?information=XXXX');
  843. dump('-----------------------------');
  844. exit;
  845. }
  846. //sm4加密
  847. public function password() {
  848. $config = [
  849. 'mode' => 'cbc',
  850. 'key' => 'jdujuujhjuiki987', // 16 字节二进制密钥
  851. 'iv' => 'jdujuujhjuiki988', // 16 字节二进制 IV
  852. 'hash' => false
  853. ];
  854. $sm4 = new EvitSM4Encryption($config);
  855. // 加密
  856. $plaintext = 'nihao';
  857. $encryptedBinary = $sm4->encrypt($plaintext);
  858. // 将二进制结果转换为 Base64
  859. $encryptedBase64 = base64_encode($encryptedBinary);
  860. var_dump("Cipher text (Base64): " . $encryptedBase64);
  861. }
  862. //sm4解密
  863. public function unpassword(){
  864. $config = [
  865. 'mode' => 'cbc',
  866. 'key' => 'jdujuujhjuiki987', // 16 字节二进制密钥
  867. 'iv' => 'jdujuujhjuiki988', // 16 字节二进制 IV
  868. 'hash' => false
  869. ];
  870. $sm4 = new EvitSM4Encryption($config);
  871. // Decrypt
  872. $pass = 'fI7Cs/lAmFzG7EIuMKAyPQ==';
  873. $pass = base64_decode($pass);
  874. $decrypted = $sm4->decrypt($pass);
  875. var_dump("Plain text(Base64): " . $decrypted);
  876. }
  877. }