AiController.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  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. $shell = 'wkhtmltoimage --quality 50 https://hb.swdz.com/api/ai/Pinyin?id=' . $task->id . ' ' . $path;
  405. exec($shell, $result, $status);
  406. if ($status) {
  407. $this->exit_out('生成图片失败', ['生成图片失败' => [$shell, $result, $status]]);
  408. }
  409. $domain = request()->getScheme() . '://' . request()->getHost();
  410. $pdfPath = $domain . '/file/images/' . $file_name;
  411. $task->image_path = $pdfPath;
  412. $result = $this->extracted($task);
  413. $task->pinyin_content = $result;
  414. $task->state = 6;
  415. $task->save();
  416. return Response::success($result);
  417. } catch (\Exception $exception) {
  418. LogHelper::exceptionLog($exception, $this->code);
  419. return Response::fail($exception->getMessage());
  420. }
  421. }
  422. /**
  423. * 下载PDF.
  424. *
  425. * @return \Illuminate\Http\JsonResponse
  426. */
  427. public function downloadPdf(Request $request)
  428. {
  429. try {
  430. $id = $request->input('id', 0);
  431. $task = TaskList::query()->find($id);
  432. if (!$task) {
  433. return Response::fail('没有该任务');
  434. }
  435. if (!empty($task->pdf_path)) {
  436. return Response::success(['url' => $task->pdf_path]);
  437. }
  438. if (empty($file_name)) {
  439. $file_name = md5(time()) . '.pdf';
  440. }
  441. $path = public_path() . '/file/pdf/' . $file_name;
  442. $shell = 'wkhtmltopdf https://hb.swdz.com/api/ai/Pinyin?id=' . $task->id . ' ' . $path;
  443. exec($shell, $result, $status);
  444. if ($status) {
  445. $this->exit_out('生成PDF失败', ['生成PDF失败' => [$shell, $result, $status]]);
  446. }
  447. $domain = request()->getScheme() . '://' . request()->getHost();
  448. $pdfPath = $domain . '/file/pdf/' . $file_name;
  449. $task->pdf_path = $pdfPath;
  450. $task->save();
  451. return Response::success(['url' => $pdfPath]);
  452. } catch (\Exception $exception) {
  453. LogHelper::exceptionLog($exception, $this->code);
  454. return Response::fail($exception->getMessage());
  455. }
  456. }
  457. private function splitChineseCharacters($inputString, $type = 0)
  458. {
  459. if (0 == $type) {
  460. $inputString = str_replace("\n", '', $inputString);
  461. }
  462. $inputString = str_replace('“', '', $inputString);
  463. $inputString = str_replace('”', '', $inputString);
  464. // $inputString = preg_replace('/[^\w\s-]+/u', '', $inputString);
  465. $length = mb_strlen($inputString, 'utf-8');
  466. $result = [];
  467. for ($i = 0; $i < $length; $i++) {
  468. $result[] = mb_substr($inputString, $i, 1, 'utf-8');
  469. }
  470. return $result;
  471. // return $inputString;
  472. }
  473. public function Pinyin(Request $request)
  474. {
  475. try {
  476. $id = $request->input('id');
  477. $task = TaskList::query()->find($id);
  478. $result = $this->extracted($task);
  479. return view('pdf', ['data' => $result, 'img' => $task->image,'title' => $task->title]);
  480. } catch (\Exception $exception) {
  481. LogHelper::exceptionLog($exception, $this->code);
  482. return Response::fail($exception->getMessage());
  483. }
  484. }
  485. public function containsPunctuation($str)
  486. {
  487. // 定义要检测的符号
  488. $punctuation = '/[,。!、.1234567890:]/u'; // 中文逗号、中文句号、中文感叹号
  489. // 使用 preg_match 函数进行匹配
  490. return 1 === preg_match($punctuation, $str);
  491. }
  492. public function generate_pdf($html_path = '', $file_name = '')
  493. {
  494. if (empty($file_name)) {
  495. $file_name = md5(time()) . '.pdf';
  496. }
  497. $path = public_path() . '/file/pdf/' . $file_name;
  498. var_dump($path);
  499. exit;
  500. $shell = 'wkhtmltopdf --outline --minimum-font-size 9 ' . $html_path . ' ' . $path;
  501. exec($shell, $result, $status);
  502. if ($status) {
  503. $this->exit_out('生成PDF失败', ['生成PDF失败' => [$shell, $result, $status]]);
  504. }
  505. $domain = request()->getScheme() . '://' . request()->getHost();
  506. return $domain . '/file/pdf/' . $file_name;
  507. }
  508. public function exit_out($msg, $exceptionData = false, $code = 1, $data = [])
  509. {
  510. $out = ['code' => $code, 'msg' => $msg, 'data' => $data];
  511. if (false !== $exceptionData) {
  512. $this->trace([$msg => $exceptionData], 'error');
  513. }
  514. $json = json_encode($out, JSON_UNESCAPED_UNICODE);
  515. throw new ApiException($json);
  516. }
  517. public function trace($log = '', $level = 'info')
  518. {
  519. Log::log($level, $log);
  520. }
  521. /**
  522. * 保存图片.
  523. *
  524. * @return \Illuminate\Http\JsonResponse|string
  525. */
  526. private function saveImage($image_url)
  527. {
  528. $imageContent = file_get_contents($image_url);
  529. $imageDir = $_SERVER['DOCUMENT_ROOT'] . '/file/sd/' . date('Ymd') . '/';
  530. $imageName = uniqid() . time() . '_image.png';
  531. $imagePath = $imageDir . $imageName;
  532. if (!is_dir($imageDir)) {
  533. mkdir($imageDir, 0777, true);
  534. }
  535. if (false !== $imageContent) {
  536. $savedImages = file_put_contents($imagePath, $imageContent);
  537. if (false !== $savedImages) {
  538. return $_SERVER['HTTP_HOST'] . '/file/sd/' . date('Ymd') . '/' . $imageName;
  539. }
  540. return false;
  541. }
  542. return false;
  543. }
  544. /**
  545. * 执行请求
  546. */
  547. private function host($postData)
  548. {
  549. $ch = curl_init();
  550. curl_setopt_array($ch, [
  551. CURLOPT_URL => 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=' . Helper::getAccessToken(),
  552. CURLOPT_RETURNTRANSFER => true,
  553. CURLOPT_POST => true,
  554. CURLOPT_POSTFIELDS => $postData,
  555. ]);
  556. $res = curl_exec($ch);
  557. curl_close($ch);
  558. return json_decode(trim($res), true);
  559. }
  560. public function extracted($result,$type = 0,$sdImage = ''): string
  561. {
  562. if ($type == 0){
  563. $inputString = $result->init_content;
  564. $sdImage = $result->sd_image;
  565. }else{
  566. $inputString = $result;
  567. }
  568. $inputString = str_replace('“', '', $inputString);
  569. $inputString = str_replace('”', '', $inputString);
  570. $inputString = str_replace('——', '', $inputString);
  571. $inputString = str_replace('—', '', $inputString);
  572. $inputStringFor = $this->splitChineseCharacters($inputString, 1);
  573. $arr = [];
  574. $i = 0;
  575. foreach ($inputStringFor as $key => $value) {
  576. if ("\n" == $value) {
  577. $arr[] = $key - $i;
  578. $i++;
  579. }
  580. }
  581. $splitCharacters = $this->splitChineseCharacters($inputString);
  582. $pinyin = Pinyin::Sentence($inputString)->toArray();
  583. $string = '';
  584. $count = 0;
  585. foreach ($pinyin as $value) {
  586. $count += mb_strlen($value);
  587. }
  588. $img = '<img style="width: 100%;height:auto;float: right;margin-right: 10px;margin-top: 10px; margin-bottom: 5px" src="https://' . $sdImage . '"/>';
  589. $stringCount = 0;
  590. foreach ($pinyin as $key => $value) {
  591. if ($this->containsPunctuation($value)) {
  592. $value = '&nbsp;';
  593. }
  594. $stringCount += mb_strlen($value);
  595. if (in_array($count - $stringCount, [158, 159, 160, 161, 162, 163]) && !strstr($string, '<img')) {
  596. $string = $string . $img;
  597. }
  598. if (in_array($key + 1, $arr)) {
  599. $string = $string . "<span><sup>{$value}</sup>{$splitCharacters[$key]}</span><br style='clear: both'><br style='clear: both'>";
  600. } else {
  601. $style = '';
  602. if (in_array($key, $arr) || 0 == $key) {
  603. $style = 'style="margin-left: 5rem"';
  604. }
  605. $string = $string . '<span ' . $style . "><sup>{$value}</sup>{$splitCharacters[$key]}</span>";
  606. }
  607. }
  608. return $string;
  609. }
  610. }