AiController.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. <?php
  2. namespace App\Http\Controllers\V1\Ai;
  3. use App\Auth;
  4. use App\libs\helpers\Curl;
  5. use App\Http\Controllers\V1\Controller;
  6. use App\libs\helpers\Helper;
  7. use App\libs\helpers\LogHelper;
  8. use App\libs\helpers\Response;
  9. use App\Models\Config;
  10. use App\Models\Keyword;
  11. use App\Models\TaskList;
  12. use App\Models\User;
  13. use App\Models\UserRole;
  14. use Illuminate\Http\Request;
  15. use Illuminate\Support\Facades\Log;
  16. use App\Exceptions\ApiException;
  17. use Overtrue\Pinyin\Pinyin;
  18. class AiController extends Controller
  19. {
  20. public $code = '_Ai';
  21. /**
  22. * 用户提交任务
  23. */
  24. public function submitTask(Request $request): \Illuminate\Http\JsonResponse
  25. {
  26. try {
  27. (int) $plot = Config::query()->where('key', 'plot')->value('value');
  28. if (!$plot) {
  29. return Response::fail('系统错误,请联系管理员#');
  30. }
  31. if (Auth::$user->diamond < $plot) {
  32. return Response::fail('钻石不够了,请先充值');
  33. }
  34. $roleId = $request->post('roleId', 0);
  35. if ($roleId) {
  36. $role = UserRole::query()->find($roleId);
  37. if (!$role) {
  38. return Response::fail('没有该角色');
  39. }
  40. } else {
  41. $role = UserRole::query()->create([
  42. 'user_id' => Auth::$userId,
  43. 'name' => $request->post('name', ''),
  44. 'sex' => $request->post('sex', ''),
  45. 'age' => $request->post('age', ''),
  46. 'star' => $request->post('star', ''),
  47. 'level' => $request->post('level', ''),
  48. ]);
  49. if (!$role) {
  50. return Response::fail('提交失败,请稍后再试!');
  51. }
  52. }
  53. User::query()->where('id', Auth::$userId)->decrement('diamond', $plot);
  54. $task = TaskList::query()->create([
  55. 'user_id' => Auth::$userId,
  56. 'role_id' => $role->id,
  57. 'image' => $request->post('image', ''),
  58. 'surplus_diamond' => Auth::$user->diamond - $plot,
  59. 'nickname' => 'AI绘本生成',
  60. 'plot' => $plot,
  61. ]);
  62. if (!$task) {
  63. return Response::fail('任务提交失败');
  64. }
  65. return Response::success(['id' => $task->id], '提交成功,请稍等');
  66. } catch (\Exception $exception) {
  67. LogHelper::exceptionLog($exception, $this->code);
  68. return Response::fail($exception->getMessage());
  69. }
  70. }
  71. /**
  72. * 获取任务详情.
  73. *
  74. * @return \Illuminate\Http\JsonResponse
  75. */
  76. public function getTaskDetail(Request $request)
  77. {
  78. try {
  79. $id = $request->get('id', 0);
  80. return Response::success(TaskList::query()->where('user_id', Auth::$userId)->find($id));
  81. } catch (\Exception $exception) {
  82. LogHelper::exceptionLog($exception, $this->code);
  83. return Response::fail($exception->getMessage());
  84. }
  85. }
  86. /**
  87. * 获取字数
  88. *
  89. * @param $level
  90. * @return int|mixed
  91. */
  92. private function getBuildCountString($level = 1){
  93. $string = Config::query()->where('key','class_count')->first()->toArray();
  94. foreach ($string['value'] ?? [] as $value){
  95. if ($level == $value['lv']){
  96. return $value['count'];
  97. }
  98. }
  99. return 200;
  100. }
  101. // /**
  102. // * 生成故事.
  103. // */
  104. // public function buildStory(Request $request): \Illuminate\Http\JsonResponse
  105. // {
  106. // try {
  107. // $task = TaskList::query()->with('role')->where('state', 0)->inRandomOrder()->first();
  108. // if (!$task) {
  109. // return Response::fail('暂无任务');
  110. // }
  111. // $key = [];
  112. // // $keyword = Keyword::query()->pluck('keyword');
  113. // // foreach ($keyword as $value) {
  114. // // $key[] = $value;
  115. // // }
  116. // // $keyword = implode(',', $key);
  117. // $keyword = Config::query()->where('key','prompt_gushi')->value('value');
  118. // $task->state = 1;
  119. // $task->save();
  120. // Log::warning('这个是当前的次数:'.$this->getBuildCountString($task->level));
  121. // $prompt = "一个{$task->role->sex},叫{$task->role->name},{$task->role->age}岁。{$keyword},要求不低于{$this->getBuildCountString($task->role->level)}字。备注:不要加什么特殊符号只需要正常的逗号句号叹号这些。如果有英语的地方翻译为中文";
  122. // $messages[] = ['role' => 'user', 'content' => $prompt];
  123. // $data = [
  124. // 'messages' => $messages,
  125. // ];
  126. // $postData = json_encode($data);
  127. // $complete = $this->host($postData);
  128. // $task->init_content = $complete['result'];
  129. // $task->save();
  130. // return Response::success($complete);
  131. // } catch (\Exception $exception) {
  132. // LogHelper::exceptionLog($exception, $this->code);
  133. // return Response::fail($exception->getMessage());
  134. // }
  135. // }
  136. /**
  137. * 获取图生文
  138. *
  139. * @param $imageUrl
  140. * @return string
  141. * @throws \Exception
  142. */
  143. public function setImageToText($imageUrl = 'http://zhengda.oss-cn-chengdu.aliyuncs.com/hb/images/AeP5fMFqeutOOcyMsfCaSnMmMFMqW6GRO2ZOOzSW.jpg'){
  144. $url = 'https://api.zhishuyun.com/midjourney/describe?token=9f4df24de4004f1a9a0c88e5e0989503&version=2.0';
  145. $result = Curl::requestCurl($url,'POST',[ "accept:application/json","content-type:application/json"],json_encode([
  146. 'image_url' => $imageUrl
  147. ]));
  148. $result = json_decode($result,true);
  149. return $result['descriptions'][0] ?? '';
  150. }
  151. /**
  152. * 生成故事.
  153. */
  154. public function buildStory(Request $request): \Illuminate\Http\JsonResponse
  155. {
  156. try {
  157. $task = TaskList::query()->with('role')->where('state', 0)->inRandomOrder()->first();
  158. if (!$task) {
  159. return Response::fail('暂无任务');
  160. }
  161. $key = [];
  162. // $keyword = Keyword::query()->pluck('keyword');
  163. // foreach ($keyword as $value) {
  164. // $key[] = $value;
  165. // }
  166. // $keyword = implode(',', $key);
  167. $keyword = Config::query()->where('key', 'prompt_gushi')->value('value');
  168. $task->state = 1;
  169. $task->save();
  170. Log::warning('这个是当前的次数:' . $this->getBuildCountString($task->level));
  171. $imageToText = $this->setImageToText($task->image);
  172. $prompt = "一个{$task->role->sex},叫{$task->role->name},{$task->role->age}岁。".$imageToText."{$keyword},要求不低于{$this->getBuildCountString($task->role->level)}字。备注:不要加什么特殊符号与英文之类的任何非中文字符串,包括不能出现数字与拼音字母这些。只需要正常的逗号句号叹号这些。如果有英语的地方翻译为中文";
  173. $messages[] = ['role' => 'user', 'content' => $prompt];
  174. $data = [
  175. 'messages' => $messages,
  176. ];
  177. $postData = json_encode($data);
  178. $complete = $this->host($postData);
  179. $task->init_content = $complete['result'];
  180. $task->image_to_text = $imageToText;
  181. $task->save();
  182. return Response::success($complete);
  183. } catch (\Exception $exception) {
  184. LogHelper::exceptionLog($exception, $this->code);
  185. return Response::fail($exception->getMessage());
  186. }
  187. }
  188. // /**
  189. // * 获取图生文
  190. // *
  191. // * @param $imageUrl
  192. // * @return string
  193. // * @throws \Exception
  194. // */
  195. // public function setImageToText($imageUrl = 'http://zhengda.oss-cn-chengdu.aliyuncs.com/hb/images/AeP5fMFqeutOOcyMsfCaSnMmMFMqW6GRO2ZOOzSW.jpg'){
  196. // $url = 'https://api.zhishuyun.com/midjourney/describe?token=04c7db50869a476883183510db23011a&version=2.0';
  197. // $result = Curl::requestCurl($url,'POST',[ "accept:application/json","content-type:application/json"],json_encode([
  198. // 'image_url' => $imageUrl
  199. // ]));
  200. // $result = json_decode($result,true);
  201. // return $result['descriptions'][0] ?? '';
  202. // }
  203. // /**
  204. // * 生成故事.
  205. // */
  206. // public function buildStory(Request $request): \Illuminate\Http\JsonResponse
  207. // {
  208. // try {
  209. // $task = TaskList::query()->with('role')->where('state', 0)->inRandomOrder()->first();
  210. // if (!$task) {
  211. // return Response::fail('暂无任务');
  212. // }
  213. // $key = [];
  214. // // $keyword = Keyword::query()->pluck('keyword');
  215. // // foreach ($keyword as $value) {
  216. // // $key[] = $value;
  217. // // }
  218. // // $keyword = implode(',', $key);
  219. // $keyword = Config::query()->where('key', 'prompt_gushi')->value('value');
  220. // $task->state = 1;
  221. // $task->save();
  222. // Log::warning('这个是当前的次数:' . $this->getBuildCountString($task->level));
  223. // $imageToText = $this->setImageToText($task->image);
  224. // $prompt = "一个{$task->role->sex},叫{$task->role->name},{$task->role->age}岁。".$imageToText."{$keyword},要求不低于{$this->getBuildCountString($task->role->level)}字。备注:不要加什么特殊符号只需要正常的逗号句号叹号这些。";
  225. // $messages[] = ['role' => 'user', 'content' => $prompt];
  226. // $data = [
  227. // 'messages' => $messages,
  228. // ];
  229. // $postData = json_encode($data);
  230. // $complete = $this->host($postData);
  231. // $task->init_content = $complete['result'];
  232. // $task->save();
  233. // return Response::success($complete);
  234. // } catch (\Exception $exception) {
  235. // LogHelper::exceptionLog($exception, $this->code);
  236. // return Response::fail($exception->getMessage());
  237. // }
  238. // }
  239. /**
  240. * 生成标题.
  241. *
  242. * @return \Illuminate\Http\JsonResponse
  243. */
  244. public function buildTitle(Request $request)
  245. {
  246. try {
  247. $task = TaskList::query()->with('role')->where('state', 1)->inRandomOrder()->first();
  248. if (!$task) {
  249. return Response::fail('暂无任务');
  250. }
  251. $task->state = 2;
  252. $task->save();
  253. $prompt = $task->init_content . '。将这段童话故事生成一个标题,标题不能有特殊符号,只需要纯文字标题即可,不需要其他任何文字,标题文字控制在10个字以内。不能超过10个字';
  254. $messages[] = ['role' => 'user', 'content' => $prompt];
  255. $data = [
  256. 'messages' => $messages,
  257. ];
  258. $postData = json_encode($data);
  259. $complete = $this->host($postData);
  260. // $task->state = 2;
  261. $task->title = $complete['result'];
  262. $task->save();
  263. return Response::success($complete);
  264. } catch (\Exception $exception) {
  265. LogHelper::exceptionLog($exception, $this->code);
  266. return Response::fail($exception->getMessage());
  267. }
  268. }
  269. /**
  270. * 生成关键词.
  271. *
  272. * @return \Illuminate\Http\JsonResponse
  273. */
  274. public function buildKeyword(Request $request)
  275. {
  276. try {
  277. $task = TaskList::query()->with('role')->where('state', 2)->inRandomOrder()->first();
  278. if (!$task) {
  279. return Response::fail('暂无任务');
  280. }
  281. $keyword = Config::query()->where('key','prompt_keyword')->value('value');
  282. $prompt = $task->init_content . $keyword;
  283. $messages[] = ['role' => 'user', 'content' => $prompt];
  284. $data = [
  285. 'messages' => $messages,
  286. ];
  287. $task->state = 3;
  288. $task->save();
  289. $postData = json_encode($data);
  290. $complete = $this->host($postData);
  291. // $task->state = 3;
  292. $task->keyword = $complete['result'];
  293. $task->save();
  294. return Response::success($complete);
  295. } catch (\Exception $exception) {
  296. LogHelper::exceptionLog($exception, $this->code);
  297. return Response::fail($exception->getMessage());
  298. }
  299. }
  300. /**
  301. * 翻译英文.
  302. */
  303. private function toEnglish($prompt)
  304. {
  305. $keyword = Config::query()->where('key','prompt_style')->value('value');
  306. $prompt = $prompt . $keyword;
  307. $promptTo = '我希望你能担任英语翻译、拼写校对和修辞改进的角色。我会将翻译的结果用于如stable diffusion、midjourney等绘画场景生成图片,语言要求尽量优美。我会用任何语言和你交流,你会识别语言,将其翻译为英语并仅回答翻译的最终结果,不要写解释。我的第一句话是:' . $prompt . '。请立刻翻译,不要回复其它内容。';
  308. $messages[] = ['role' => 'user', 'content' => $promptTo];
  309. $data = [
  310. 'messages' => $messages,
  311. ];
  312. $postData = json_encode($data);
  313. $complete = $this->host($postData);
  314. return $complete['result'];
  315. }
  316. /**
  317. * 提交sd生成插图.
  318. *
  319. * @return \Illuminate\Http\JsonResponse
  320. */
  321. public function buildSd(Request $request)
  322. {
  323. try {
  324. $task = TaskList::query()->with('role')->where('state', 3)->inRandomOrder()->first();
  325. if (!$task) {
  326. return Response::fail('暂无任务');
  327. }
  328. $task->state = 4;
  329. $task->save();
  330. $keyword = $this->toEnglish($task->keyword);
  331. $param = ['name' => '甜瓜(动漫风格)',
  332. 'init_image' => '',
  333. 'prompt' => $keyword,
  334. 'width' => '512',
  335. 'height' => '512',
  336. 'guidance_scale' => '7',
  337. 'samples' => '1',
  338. 'model_id' => '3',
  339. 'scheduler' => 'DDPMScheduler',
  340. 'type' => 'text2img',
  341. 'num_inference_steps' => '30',
  342. 'keywords' => $keyword,
  343. ];
  344. $result = (new Helper())->opensd($param);
  345. $result = json_decode($result, true);
  346. Log::warning('这个是SD回调信息:'.json_encode($result,256));
  347. if(isset($result['data']['id'])){
  348. $task->sd_id = $result['data']['id'];
  349. }else{
  350. $task->state = 3;
  351. }
  352. $task->save();
  353. return Response::success($result['data']);
  354. } catch (\Exception $exception) {
  355. LogHelper::exceptionLog($exception, $this->code);
  356. return Response::fail($exception->getMessage());
  357. }
  358. }
  359. /**
  360. * 查询生成进度.
  361. *
  362. * @return \Illuminate\Http\JsonResponse
  363. */
  364. public function getOpensdDetail(Request $request)
  365. {
  366. $task = TaskList::query()->where('state', 4)->inRandomOrder()->first();
  367. if (!$task) {
  368. return $this->error('暂无任务');
  369. }
  370. $res = (new Helper())->opensdDetail($task->sd_id);
  371. $res = @json_decode($res, true);
  372. if (200 != $res['code']) {
  373. return Response::fail($res['msg']);
  374. }
  375. if ('fail' == $res['data']['state']) {
  376. $task->state = 3;
  377. $task->desc = $res['data']['fail_reason'];
  378. }
  379. $task->save();
  380. if ('success' == $res['data']['state']) {
  381. $path = $this->saveImage($res['data']['gen_img']);
  382. $task->sd_image = $path;
  383. $task->state = 5;
  384. $task->save();
  385. }
  386. return $this->success('操作成功', $res['data']);
  387. }
  388. /**
  389. * 获取拼音排版.
  390. *
  391. * @return \Illuminate\Http\JsonResponse
  392. */
  393. public function buildPinyin(Request $request)
  394. {
  395. try {
  396. $task = TaskList::query()->where('state', 5)->inRandomOrder()->first();
  397. if (!$task) {
  398. return $this->error('暂无任务');
  399. }
  400. if (empty($file_name)) {
  401. $file_name = md5(time()) . '.jpeg';
  402. }
  403. $date = date('Ymd');
  404. $path = public_path() . '/file/images/'.$date.'/' . $file_name;
  405. $imageDir = public_path() . '/file/images/'.$date.'/';
  406. if (!is_dir($imageDir)) {
  407. mkdir($imageDir, 0755, true);
  408. }
  409. $shell = 'wkhtmltoimage --quality 50 https://hb.swdz.com/api/ai/Pinyin?id=' . $task->id . ' ' . $path;
  410. exec($shell, $result, $status);
  411. if ($status) {
  412. $this->exit_out('生成图片失败', ['生成图片失败' => [$shell, $result, $status]]);
  413. }
  414. $domain = request()->getScheme() . '://' . request()->getHost();
  415. $pdfPath = $domain . '/file/images/' . $date.'/'.$file_name;
  416. $task->image_path = $pdfPath;
  417. $result = $this->extracted($task);
  418. $task->pinyin_content = $result;
  419. $task->state = 6;
  420. $task->save();
  421. return Response::success($result);
  422. } catch (\Exception $exception) {
  423. LogHelper::exceptionLog($exception, $this->code);
  424. return Response::fail($exception->getMessage());
  425. }
  426. }
  427. /**
  428. * 下载PDF.
  429. *
  430. * @return \Illuminate\Http\JsonResponse
  431. */
  432. public function downloadPdf(Request $request)
  433. {
  434. try {
  435. $id = $request->input('id', 0);
  436. $task = TaskList::query()->find($id);
  437. if (!$task) {
  438. return Response::fail('没有该任务');
  439. }
  440. if (!empty($task->pdf_path)) {
  441. return Response::success(['url' => $task->pdf_path]);
  442. }
  443. if (empty($file_name)) {
  444. $file_name = md5(time()) . '.pdf';
  445. }
  446. $date = date('Ymd');
  447. $path = public_path() . '/file/pdf/' . $date.'/'.$file_name;
  448. $imageDir = public_path() . '/file/pdf/'.$date.'/';
  449. if (!is_dir($imageDir)) {
  450. mkdir($imageDir, 0755, true);
  451. }
  452. $shell = 'wkhtmltopdf https://hb.swdz.com/api/ai/Pinyin?id=' . $task->id . ' ' . $path;
  453. exec($shell, $result, $status);
  454. if ($status) {
  455. $this->exit_out('生成PDF失败', ['生成PDF失败' => [$shell, $result, $status]]);
  456. }
  457. $domain = request()->getScheme() . '://' . request()->getHost();
  458. $pdfPath = $domain . '/file/pdf/' . $date.'/'.$file_name;
  459. $task->pdf_path = $pdfPath;
  460. $task->save();
  461. return Response::success(['url' => $pdfPath]);
  462. } catch (\Exception $exception) {
  463. LogHelper::exceptionLog($exception, $this->code);
  464. return Response::fail($exception->getMessage());
  465. }
  466. }
  467. private function splitChineseCharacters($inputString, $type = 0)
  468. {
  469. if (0 == $type) {
  470. $inputString = str_replace("\n", '', $inputString);
  471. }
  472. $inputString = str_replace('“', '', $inputString);
  473. $inputString = str_replace('”', '', $inputString);
  474. // $inputString = preg_replace('/[^\w\s-]+/u', '', $inputString);
  475. $length = mb_strlen($inputString, 'utf-8');
  476. $result = [];
  477. for ($i = 0; $i < $length; $i++) {
  478. $result[] = mb_substr($inputString, $i, 1, 'utf-8');
  479. }
  480. return $result;
  481. // return $inputString;
  482. }
  483. public function Pinyin(Request $request)
  484. {
  485. try {
  486. $id = $request->input('id');
  487. $task = TaskList::query()->find($id);
  488. $result = $this->extracted($task);
  489. return view('pdf', ['data' => $result, 'img' => $task->image,'title' => $task->title]);
  490. } catch (\Exception $exception) {
  491. LogHelper::exceptionLog($exception, $this->code);
  492. return Response::fail($exception->getMessage());
  493. }
  494. }
  495. public function containsPunctuation($str)
  496. {
  497. // 定义要检测的符号
  498. $punctuation = '/[,。!、.1234567890:]/u'; // 中文逗号、中文句号、中文感叹号
  499. // 使用 preg_match 函数进行匹配
  500. return 1 === preg_match($punctuation, $str);
  501. }
  502. public function generate_pdf($html_path = '', $file_name = '')
  503. {
  504. if (empty($file_name)) {
  505. $file_name = md5(time()) . '.pdf';
  506. }
  507. $path = public_path() . '/file/pdf/' . $file_name;
  508. var_dump($path);
  509. exit;
  510. $shell = 'wkhtmltopdf --outline --minimum-font-size 9 ' . $html_path . ' ' . $path;
  511. exec($shell, $result, $status);
  512. if ($status) {
  513. $this->exit_out('生成PDF失败', ['生成PDF失败' => [$shell, $result, $status]]);
  514. }
  515. $domain = request()->getScheme() . '://' . request()->getHost();
  516. return $domain . '/file/pdf/' . $file_name;
  517. }
  518. public function exit_out($msg, $exceptionData = false, $code = 1, $data = [])
  519. {
  520. $out = ['code' => $code, 'msg' => $msg, 'data' => $data];
  521. if (false !== $exceptionData) {
  522. $this->trace([$msg => $exceptionData], 'error');
  523. }
  524. $json = json_encode($out, JSON_UNESCAPED_UNICODE);
  525. throw new ApiException($json);
  526. }
  527. public function trace($log = '', $level = 'info')
  528. {
  529. Log::log($level, $log);
  530. }
  531. /**
  532. * 保存图片.
  533. *
  534. * @return \Illuminate\Http\JsonResponse|string
  535. */
  536. private function saveImage($image_url)
  537. {
  538. $imageContent = file_get_contents($image_url);
  539. $imageDir = $_SERVER['DOCUMENT_ROOT'] . '/file/sd/' . date('Ymd') . '/';
  540. $imageName = uniqid() . time() . '_image.png';
  541. $imagePath = $imageDir . $imageName;
  542. if (!is_dir($imageDir)) {
  543. mkdir($imageDir, 0777, true);
  544. }
  545. if (false !== $imageContent) {
  546. $savedImages = file_put_contents($imagePath, $imageContent);
  547. if (false !== $savedImages) {
  548. return $_SERVER['HTTP_HOST'] . '/file/sd/' . date('Ymd') . '/' . $imageName;
  549. }
  550. return false;
  551. }
  552. return false;
  553. }
  554. /**
  555. * 执行请求
  556. */
  557. private function host($postData)
  558. {
  559. $ch = curl_init();
  560. curl_setopt_array($ch, [
  561. CURLOPT_URL => 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=' . Helper::getAccessToken(),
  562. CURLOPT_RETURNTRANSFER => true,
  563. CURLOPT_POST => true,
  564. CURLOPT_POSTFIELDS => $postData,
  565. ]);
  566. $res = curl_exec($ch);
  567. curl_close($ch);
  568. return json_decode(trim($res), true);
  569. }
  570. public function extracted($result,$type = 0,$sdImage = ''): string
  571. {
  572. if ($type == 0){
  573. $inputString = $result->init_content;
  574. $sdImage = $result->sd_image;
  575. }else{
  576. $inputString = $result;
  577. }
  578. $inputString = str_replace('“', '', $inputString);
  579. $inputString = str_replace('”', '', $inputString);
  580. $inputString = str_replace('——', '', $inputString);
  581. $inputString = str_replace('—', '', $inputString);
  582. $inputStringFor = $this->splitChineseCharacters($inputString, 1);
  583. $arr = [];
  584. $i = 0;
  585. foreach ($inputStringFor as $key => $value) {
  586. if ("\n" == $value) {
  587. $arr[] = $key - $i;
  588. $i++;
  589. }
  590. }
  591. $splitCharacters = $this->splitChineseCharacters($inputString);
  592. $pinyin = Pinyin::Sentence($inputString)->toArray();
  593. $string = '';
  594. $count = 0;
  595. foreach ($pinyin as $value) {
  596. $count += mb_strlen($value);
  597. }
  598. $img = '<img style="width: 100%;height:auto;float: right;margin-right: 10px;margin-top: 10px; margin-bottom: 5px" src="https://' . $sdImage . '"/>';
  599. $stringCount = 0;
  600. foreach ($pinyin as $key => $value) {
  601. if ($this->containsPunctuation($value)) {
  602. $value = '&nbsp;';
  603. }
  604. $stringCount += mb_strlen($value);
  605. if (in_array($count - $stringCount, [158, 159, 160, 161, 162, 163]) && !strstr($string, '<img')) {
  606. $string = $string . $img;
  607. }
  608. if (in_array($key + 1, $arr)) {
  609. $string = $string . "<span><sup>{$value}</sup>{$splitCharacters[$key]}</span><br style='clear: both'><br style='clear: both'>";
  610. } else {
  611. $style = '';
  612. if (in_array($key, $arr) || 0 == $key) {
  613. $style = 'style="margin-left: 5rem"';
  614. }
  615. $string = $string . '<span ' . $style . "><sup>{$value}</sup>{$splitCharacters[$key]}</span>";
  616. }
  617. }
  618. return $string;
  619. }
  620. }