AiController.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  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->save();
  181. return Response::success($complete);
  182. } catch (\Exception $exception) {
  183. LogHelper::exceptionLog($exception, $this->code);
  184. return Response::fail($exception->getMessage());
  185. }
  186. }
  187. // /**
  188. // * 获取图生文
  189. // *
  190. // * @param $imageUrl
  191. // * @return string
  192. // * @throws \Exception
  193. // */
  194. // public function setImageToText($imageUrl = 'http://zhengda.oss-cn-chengdu.aliyuncs.com/hb/images/AeP5fMFqeutOOcyMsfCaSnMmMFMqW6GRO2ZOOzSW.jpg'){
  195. // $url = 'https://api.zhishuyun.com/midjourney/describe?token=04c7db50869a476883183510db23011a&version=2.0';
  196. // $result = Curl::requestCurl($url,'POST',[ "accept:application/json","content-type:application/json"],json_encode([
  197. // 'image_url' => $imageUrl
  198. // ]));
  199. // $result = json_decode($result,true);
  200. // return $result['descriptions'][0] ?? '';
  201. // }
  202. // /**
  203. // * 生成故事.
  204. // */
  205. // public function buildStory(Request $request): \Illuminate\Http\JsonResponse
  206. // {
  207. // try {
  208. // $task = TaskList::query()->with('role')->where('state', 0)->inRandomOrder()->first();
  209. // if (!$task) {
  210. // return Response::fail('暂无任务');
  211. // }
  212. // $key = [];
  213. // // $keyword = Keyword::query()->pluck('keyword');
  214. // // foreach ($keyword as $value) {
  215. // // $key[] = $value;
  216. // // }
  217. // // $keyword = implode(',', $key);
  218. // $keyword = Config::query()->where('key', 'prompt_gushi')->value('value');
  219. // $task->state = 1;
  220. // $task->save();
  221. // Log::warning('这个是当前的次数:' . $this->getBuildCountString($task->level));
  222. // $imageToText = $this->setImageToText($task->image);
  223. // $prompt = "一个{$task->role->sex},叫{$task->role->name},{$task->role->age}岁。".$imageToText."{$keyword},要求不低于{$this->getBuildCountString($task->role->level)}字。备注:不要加什么特殊符号只需要正常的逗号句号叹号这些。";
  224. // $messages[] = ['role' => 'user', 'content' => $prompt];
  225. // $data = [
  226. // 'messages' => $messages,
  227. // ];
  228. // $postData = json_encode($data);
  229. // $complete = $this->host($postData);
  230. // $task->init_content = $complete['result'];
  231. // $task->save();
  232. // return Response::success($complete);
  233. // } catch (\Exception $exception) {
  234. // LogHelper::exceptionLog($exception, $this->code);
  235. // return Response::fail($exception->getMessage());
  236. // }
  237. // }
  238. /**
  239. * 生成标题.
  240. *
  241. * @return \Illuminate\Http\JsonResponse
  242. */
  243. public function buildTitle(Request $request)
  244. {
  245. try {
  246. $task = TaskList::query()->with('role')->where('state', 1)->inRandomOrder()->first();
  247. if (!$task) {
  248. return Response::fail('暂无任务');
  249. }
  250. $task->state = 2;
  251. $task->save();
  252. $prompt = $task->init_content . '。将这段童话故事生成一个标题,标题不能有特殊符号,只需要纯文字标题即可,不需要其他任何文字,标题文字控制在10个字以内。不能超过10个字';
  253. $messages[] = ['role' => 'user', 'content' => $prompt];
  254. $data = [
  255. 'messages' => $messages,
  256. ];
  257. $postData = json_encode($data);
  258. $complete = $this->host($postData);
  259. // $task->state = 2;
  260. $task->title = $complete['result'];
  261. $task->save();
  262. return Response::success($complete);
  263. } catch (\Exception $exception) {
  264. LogHelper::exceptionLog($exception, $this->code);
  265. return Response::fail($exception->getMessage());
  266. }
  267. }
  268. /**
  269. * 生成关键词.
  270. *
  271. * @return \Illuminate\Http\JsonResponse
  272. */
  273. public function buildKeyword(Request $request)
  274. {
  275. try {
  276. $task = TaskList::query()->with('role')->where('state', 2)->inRandomOrder()->first();
  277. if (!$task) {
  278. return Response::fail('暂无任务');
  279. }
  280. $keyword = Config::query()->where('key','prompt_keyword')->value('value');
  281. $prompt = $task->init_content . $keyword;
  282. $messages[] = ['role' => 'user', 'content' => $prompt];
  283. $data = [
  284. 'messages' => $messages,
  285. ];
  286. $task->state = 3;
  287. $task->save();
  288. $postData = json_encode($data);
  289. $complete = $this->host($postData);
  290. // $task->state = 3;
  291. $task->keyword = $complete['result'];
  292. $task->save();
  293. return Response::success($complete);
  294. } catch (\Exception $exception) {
  295. LogHelper::exceptionLog($exception, $this->code);
  296. return Response::fail($exception->getMessage());
  297. }
  298. }
  299. /**
  300. * 翻译英文.
  301. */
  302. private function toEnglish($prompt)
  303. {
  304. $keyword = Config::query()->where('key','prompt_style')->value('value');
  305. $prompt = $prompt . $keyword;
  306. $promptTo = '我希望你能担任英语翻译、拼写校对和修辞改进的角色。我会将翻译的结果用于如stable diffusion、midjourney等绘画场景生成图片,语言要求尽量优美。我会用任何语言和你交流,你会识别语言,将其翻译为英语并仅回答翻译的最终结果,不要写解释。我的第一句话是:' . $prompt . '。请立刻翻译,不要回复其它内容。';
  307. $messages[] = ['role' => 'user', 'content' => $promptTo];
  308. $data = [
  309. 'messages' => $messages,
  310. ];
  311. $postData = json_encode($data);
  312. $complete = $this->host($postData);
  313. return $complete['result'];
  314. }
  315. /**
  316. * 提交sd生成插图.
  317. *
  318. * @return \Illuminate\Http\JsonResponse
  319. */
  320. public function buildSd(Request $request)
  321. {
  322. try {
  323. $task = TaskList::query()->with('role')->where('state', 3)->inRandomOrder()->first();
  324. if (!$task) {
  325. return Response::fail('暂无任务');
  326. }
  327. $task->state = 4;
  328. $task->save();
  329. $keyword = $this->toEnglish($task->keyword);
  330. $param = ['name' => '甜瓜(动漫风格)',
  331. 'init_image' => '',
  332. 'prompt' => $keyword,
  333. 'width' => '512',
  334. 'height' => '512',
  335. 'guidance_scale' => '7',
  336. 'samples' => '1',
  337. 'model_id' => '3',
  338. 'scheduler' => 'DDPMScheduler',
  339. 'type' => 'text2img',
  340. 'num_inference_steps' => '30',
  341. 'keywords' => $keyword,
  342. ];
  343. $result = (new Helper())->opensd($param);
  344. $result = json_decode($result, true);
  345. Log::warning('这个是SD回调信息:'.json_encode($result,256));
  346. if(isset($result['data']['id'])){
  347. $task->sd_id = $result['data']['id'];
  348. }else{
  349. $task->state = 3;
  350. }
  351. $task->save();
  352. return Response::success($result['data']);
  353. } catch (\Exception $exception) {
  354. LogHelper::exceptionLog($exception, $this->code);
  355. return Response::fail($exception->getMessage());
  356. }
  357. }
  358. /**
  359. * 查询生成进度.
  360. *
  361. * @return \Illuminate\Http\JsonResponse
  362. */
  363. public function getOpensdDetail(Request $request)
  364. {
  365. $task = TaskList::query()->where('state', 4)->inRandomOrder()->first();
  366. if (!$task) {
  367. return $this->error('暂无任务');
  368. }
  369. $res = (new Helper())->opensdDetail($task->sd_id);
  370. $res = @json_decode($res, true);
  371. if (200 != $res['code']) {
  372. return Response::fail($res['msg']);
  373. }
  374. if ('fail' == $res['data']['state']) {
  375. $task->state = 3;
  376. $task->desc = $res['data']['fail_reason'];
  377. }
  378. $task->save();
  379. if ('success' == $res['data']['state']) {
  380. $path = $this->saveImage($res['data']['gen_img']);
  381. $task->sd_image = $path;
  382. $task->state = 5;
  383. $task->save();
  384. }
  385. return $this->success('操作成功', $res['data']);
  386. }
  387. /**
  388. * 获取品牌排版.
  389. *
  390. * @return \Illuminate\Http\JsonResponse
  391. */
  392. public function buildPinyin(Request $request)
  393. {
  394. try {
  395. $task = TaskList::query()->where('state', 5)->inRandomOrder()->first();
  396. if (!$task) {
  397. return $this->error('暂无任务');
  398. }
  399. if (empty($file_name)) {
  400. $file_name = md5(time()) . '.jpeg';
  401. }
  402. $date = date('Ymd');
  403. $path = public_path() . '/file/images/'.$date.'/' . $file_name;
  404. $imageDir = public_path() . '/file/images/'.$date.'/';
  405. if (!is_dir($imageDir)) {
  406. mkdir($imageDir, 0755, true);
  407. }
  408. $shell = 'wkhtmltoimage --quality 50 https://hb.swdz.com/api/ai/Pinyin?id=' . $task->id . ' ' . $path;
  409. exec($shell, $result, $status);
  410. if ($status) {
  411. $this->exit_out('生成图片失败', ['生成图片失败' => [$shell, $result, $status]]);
  412. }
  413. $domain = request()->getScheme() . '://' . request()->getHost();
  414. $pdfPath = $domain . '/file/pdf/' . $date.'/'.$file_name;
  415. $task->image_path = $pdfPath;
  416. $result = $this->extracted($task);
  417. $task->pinyin_content = $result;
  418. $task->state = 6;
  419. $task->save();
  420. return Response::success($result);
  421. } catch (\Exception $exception) {
  422. LogHelper::exceptionLog($exception, $this->code);
  423. return Response::fail($exception->getMessage());
  424. }
  425. }
  426. /**
  427. * 下载PDF.
  428. *
  429. * @return \Illuminate\Http\JsonResponse
  430. */
  431. public function downloadPdf(Request $request)
  432. {
  433. try {
  434. $id = $request->input('id', 0);
  435. $task = TaskList::query()->find($id);
  436. if (!$task) {
  437. return Response::fail('没有该任务');
  438. }
  439. if (!empty($task->pdf_path)) {
  440. return Response::success(['url' => $task->pdf_path]);
  441. }
  442. if (empty($file_name)) {
  443. $file_name = md5(time()) . '.pdf';
  444. }
  445. $date = date('Ymd');
  446. $path = public_path() . '/file/pdf/' . $date.'/'.$file_name;
  447. $imageDir = public_path() . '/file/pdf/'.$date.'/';
  448. if (!is_dir($imageDir)) {
  449. mkdir($imageDir, 0755, true);
  450. }
  451. $shell = 'wkhtmltopdf https://hb.swdz.com/api/ai/Pinyin?id=' . $task->id . ' ' . $path;
  452. exec($shell, $result, $status);
  453. if ($status) {
  454. $this->exit_out('生成PDF失败', ['生成PDF失败' => [$shell, $result, $status]]);
  455. }
  456. $domain = request()->getScheme() . '://' . request()->getHost();
  457. $pdfPath = $domain . '/file/pdf/' . $date.'/'.$file_name;
  458. $task->pdf_path = $pdfPath;
  459. $task->save();
  460. return Response::success(['url' => $pdfPath]);
  461. } catch (\Exception $exception) {
  462. LogHelper::exceptionLog($exception, $this->code);
  463. return Response::fail($exception->getMessage());
  464. }
  465. }
  466. private function splitChineseCharacters($inputString, $type = 0)
  467. {
  468. if (0 == $type) {
  469. $inputString = str_replace("\n", '', $inputString);
  470. }
  471. $inputString = str_replace('“', '', $inputString);
  472. $inputString = str_replace('”', '', $inputString);
  473. // $inputString = preg_replace('/[^\w\s-]+/u', '', $inputString);
  474. $length = mb_strlen($inputString, 'utf-8');
  475. $result = [];
  476. for ($i = 0; $i < $length; $i++) {
  477. $result[] = mb_substr($inputString, $i, 1, 'utf-8');
  478. }
  479. return $result;
  480. // return $inputString;
  481. }
  482. public function Pinyin(Request $request)
  483. {
  484. try {
  485. $id = $request->input('id');
  486. $task = TaskList::query()->find($id);
  487. $result = $this->extracted($task);
  488. return view('pdf', ['data' => $result, 'img' => $task->image,'title' => $task->title]);
  489. } catch (\Exception $exception) {
  490. LogHelper::exceptionLog($exception, $this->code);
  491. return Response::fail($exception->getMessage());
  492. }
  493. }
  494. public function containsPunctuation($str)
  495. {
  496. // 定义要检测的符号
  497. $punctuation = '/[,。!、.1234567890:]/u'; // 中文逗号、中文句号、中文感叹号
  498. // 使用 preg_match 函数进行匹配
  499. return 1 === preg_match($punctuation, $str);
  500. }
  501. public function generate_pdf($html_path = '', $file_name = '')
  502. {
  503. if (empty($file_name)) {
  504. $file_name = md5(time()) . '.pdf';
  505. }
  506. $path = public_path() . '/file/pdf/' . $file_name;
  507. var_dump($path);
  508. exit;
  509. $shell = 'wkhtmltopdf --outline --minimum-font-size 9 ' . $html_path . ' ' . $path;
  510. exec($shell, $result, $status);
  511. if ($status) {
  512. $this->exit_out('生成PDF失败', ['生成PDF失败' => [$shell, $result, $status]]);
  513. }
  514. $domain = request()->getScheme() . '://' . request()->getHost();
  515. return $domain . '/file/pdf/' . $file_name;
  516. }
  517. public function exit_out($msg, $exceptionData = false, $code = 1, $data = [])
  518. {
  519. $out = ['code' => $code, 'msg' => $msg, 'data' => $data];
  520. if (false !== $exceptionData) {
  521. $this->trace([$msg => $exceptionData], 'error');
  522. }
  523. $json = json_encode($out, JSON_UNESCAPED_UNICODE);
  524. throw new ApiException($json);
  525. }
  526. public function trace($log = '', $level = 'info')
  527. {
  528. Log::log($level, $log);
  529. }
  530. /**
  531. * 保存图片.
  532. *
  533. * @return \Illuminate\Http\JsonResponse|string
  534. */
  535. private function saveImage($image_url)
  536. {
  537. $imageContent = file_get_contents($image_url);
  538. $imageDir = $_SERVER['DOCUMENT_ROOT'] . '/file/sd/' . date('Ymd') . '/';
  539. $imageName = uniqid() . time() . '_image.png';
  540. $imagePath = $imageDir . $imageName;
  541. if (!is_dir($imageDir)) {
  542. mkdir($imageDir, 0777, true);
  543. }
  544. if (false !== $imageContent) {
  545. $savedImages = file_put_contents($imagePath, $imageContent);
  546. if (false !== $savedImages) {
  547. return $_SERVER['HTTP_HOST'] . '/file/sd/' . date('Ymd') . '/' . $imageName;
  548. }
  549. return false;
  550. }
  551. return false;
  552. }
  553. /**
  554. * 执行请求
  555. */
  556. private function host($postData)
  557. {
  558. $ch = curl_init();
  559. curl_setopt_array($ch, [
  560. CURLOPT_URL => 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=' . Helper::getAccessToken(),
  561. CURLOPT_RETURNTRANSFER => true,
  562. CURLOPT_POST => true,
  563. CURLOPT_POSTFIELDS => $postData,
  564. ]);
  565. $res = curl_exec($ch);
  566. curl_close($ch);
  567. return json_decode(trim($res), true);
  568. }
  569. public function extracted($result,$type = 0,$sdImage = ''): string
  570. {
  571. if ($type == 0){
  572. $inputString = $result->init_content;
  573. $sdImage = $result->sd_image;
  574. }else{
  575. $inputString = $result;
  576. }
  577. $inputString = str_replace('“', '', $inputString);
  578. $inputString = str_replace('”', '', $inputString);
  579. $inputString = str_replace('——', '', $inputString);
  580. $inputString = str_replace('—', '', $inputString);
  581. $inputStringFor = $this->splitChineseCharacters($inputString, 1);
  582. $arr = [];
  583. $i = 0;
  584. foreach ($inputStringFor as $key => $value) {
  585. if ("\n" == $value) {
  586. $arr[] = $key - $i;
  587. $i++;
  588. }
  589. }
  590. $splitCharacters = $this->splitChineseCharacters($inputString);
  591. $pinyin = Pinyin::Sentence($inputString)->toArray();
  592. $string = '';
  593. $count = 0;
  594. foreach ($pinyin as $value) {
  595. $count += mb_strlen($value);
  596. }
  597. $img = '<img style="width: 100%;height:auto;float: right;margin-right: 10px;margin-top: 10px; margin-bottom: 5px" src="https://' . $sdImage . '"/>';
  598. $stringCount = 0;
  599. foreach ($pinyin as $key => $value) {
  600. if ($this->containsPunctuation($value)) {
  601. $value = '&nbsp;';
  602. }
  603. $stringCount += mb_strlen($value);
  604. if (in_array($count - $stringCount, [158, 159, 160, 161, 162, 163]) && !strstr($string, '<img')) {
  605. $string = $string . $img;
  606. }
  607. if (in_array($key + 1, $arr)) {
  608. $string = $string . "<span><sup>{$value}</sup>{$splitCharacters[$key]}</span><br style='clear: both'><br style='clear: both'>";
  609. } else {
  610. $style = '';
  611. if (in_array($key, $arr) || 0 == $key) {
  612. $style = 'style="margin-left: 5rem"';
  613. }
  614. $string = $string . '<span ' . $style . "><sup>{$value}</sup>{$splitCharacters[$key]}</span>";
  615. }
  616. }
  617. return $string;
  618. }
  619. }