ArticleController.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. use Illuminate\Support\Str;
  5. use Illuminate\Support\Facades\DB;
  6. use Illuminate\Support\Facades\Log;
  7. use App\Models\Article;
  8. use App\Models\ArticleCollection;
  9. use App\Models\Collection;
  10. use App\Models\CustomBook;
  11. use App\Models\CustomBookId;
  12. use App\Models\Sentence;
  13. use App\Http\Resources\ArticleResource;
  14. use App\Http\Api\AuthApi;
  15. use App\Http\Api\ShareApi;
  16. use App\Http\Api\StudioApi;
  17. use App\Http\Api\ChannelApi;
  18. use App\Http\Api\SentenceApi;
  19. use App\Tools\OpsLog;
  20. class ArticleController extends Controller
  21. {
  22. public static function userCanRead($user_uid,Article $article){
  23. if($article->status === 30 ){
  24. return true;
  25. }
  26. if(empty($user_uid)){
  27. return false;
  28. }
  29. //私有文章,判断是否为所有者
  30. if($user_uid === $article->owner){
  31. return true;
  32. }
  33. //非所有者
  34. //判断是否为文章协作者
  35. $power = ShareApi::getResPower($user_uid,$article->uid);
  36. if($power >= 10 ){
  37. return true;
  38. }
  39. //无读取权限
  40. //判断文集是否有读取权限
  41. $inCollection = ArticleCollection::where('article_id',$article->uid)
  42. ->select('collect_id')
  43. ->groupBy('collect_id')->get();
  44. if(!$inCollection){
  45. return false;
  46. }
  47. //查找与文章同主人的文集
  48. $collections = Collection::whereIn('uid',$inCollection)
  49. ->where('owner',$article->owner)
  50. ->select('uid')
  51. ->get();
  52. if(!$collections){
  53. return false;
  54. }
  55. //查找与文章同主人的文集是否是共享的
  56. $power = 0;
  57. foreach ($collections as $collection) {
  58. # code...
  59. $currPower = ShareApi::getResPower($user_uid,$collection->uid);
  60. if($currPower >= 10){
  61. return true;
  62. }
  63. }
  64. return false;
  65. }
  66. public static function userCanEditId($user_uid,$articleId){
  67. $article = Article::find($articleId);
  68. if($article){
  69. return ArticleController::userCanEdit($user_uid,$article);
  70. }else{
  71. return false;
  72. }
  73. }
  74. public static function userCanEdit($user_uid,$article){
  75. if(empty($user_uid)){
  76. return false;
  77. }
  78. //私有文章,判断是否为所有者
  79. if($user_uid === $article->owner){
  80. return true;
  81. }
  82. //非所有者
  83. //判断是否为文章协作者
  84. $power = ShareApi::getResPower($user_uid,$article->uid);
  85. if($power >= 20 ){
  86. return true;
  87. }
  88. //无读取权限
  89. //判断文集是否有读取权限
  90. $inCollection = ArticleCollection::where('article_id',$article->uid)
  91. ->select('collect_id')
  92. ->groupBy('collect_id')->get();
  93. if(!$inCollection){
  94. return false;
  95. }
  96. //查找与文章同主人的文集
  97. $collections = Collection::whereIn('uid',$inCollection)
  98. ->where('owner',$article->owner)
  99. ->select('uid')
  100. ->get();
  101. if(!$collections){
  102. return false;
  103. }
  104. //查找与文章同主人的文集是否是共享的
  105. $power = 0;
  106. foreach ($collections as $collection) {
  107. # code...
  108. $currPower = ShareApi::getResPower($user_uid,$collection->uid);
  109. if($currPower >= 20){
  110. return true;
  111. }
  112. }
  113. return false;
  114. }
  115. public static function userCanManage($user_uid,$studioName){
  116. if(empty($user_uid)){
  117. return false;
  118. }
  119. //判断是否为所有者
  120. if($user_uid === StudioApi::getIdByName($studioName)){
  121. return true;
  122. }else{
  123. return false;
  124. }
  125. }
  126. /**
  127. * Display a listing of the resource.
  128. *
  129. * @return \Illuminate\Http\Response
  130. */
  131. public function index(Request $request)
  132. {
  133. //
  134. $field = ['uid','title','subtitle',
  135. 'summary','owner','lang',
  136. 'status','editor_id','updated_at','created_at'];
  137. if($request->get('content')==="true"){
  138. $field[] = 'content';
  139. $field[] = 'content_type';
  140. }
  141. $table = Article::select($field);
  142. switch ($request->get('view')) {
  143. case 'template':
  144. $studioId = StudioApi::getIdByName($request->get('studio_name'));
  145. $table = $table->where('owner', $studioId);
  146. break;
  147. case 'studio':
  148. # 获取studio内所有 article
  149. $user = AuthApi::current($request);
  150. if(!$user){
  151. return $this->error(__('auth.failed'),[],401);
  152. }
  153. //判断当前用户是否有指定的studio的权限
  154. $studioId = StudioApi::getIdByName($request->get('name'));
  155. if($user['user_uid'] !== $studioId){
  156. return $this->error(__('auth.failed'),[],403);
  157. }
  158. if($request->get('view2','my')==='my'){
  159. $table = $table->where('owner', $studioId);
  160. }else{
  161. //协作
  162. $resList = ShareApi::getResList($studioId,3);
  163. $resId=[];
  164. foreach ($resList as $res) {
  165. $resId[] = $res['res_id'];
  166. }
  167. $table = $table->whereIn('uid', $resId)->where('owner','<>', $studioId);
  168. }
  169. //根据anthology过滤
  170. if($request->has('anthology')){
  171. switch ($request->get('anthology')) {
  172. case 'all':
  173. break;
  174. case 'none':
  175. # 我的文集
  176. $myCollection = Collection::where('owner',$studioId)->select('uid')->get();
  177. //收录在我的文集里面的文章
  178. $articles = ArticleCollection::whereIn('collect_id',$myCollection)
  179. ->select('article_id')->groupBy('article_id')->get();
  180. //不在这些范围之内的文章
  181. $table = $table->whereNotIn('uid',$articles);
  182. break;
  183. default:
  184. $articles = ArticleCollection::where('collect_id',$request->get('anthology'))
  185. ->select('article_id')->get();
  186. $table = $table->whereIn('uid',$articles);
  187. break;
  188. }
  189. }
  190. break;
  191. case 'public':
  192. $table = $table->where('status',30);
  193. break;
  194. default:
  195. $this->error("view error");
  196. break;
  197. }
  198. //处理搜索
  199. if($request->has("search") && !empty($request->get("search"))){
  200. $table = $table->where('title', 'like', "%".$request->get("search")."%");
  201. }
  202. if($request->has("subtitle") && !empty($request->get("subtitle"))){
  203. $table = $table->where('subtitle', 'like', $request->get("subtitle"));
  204. }
  205. //获取记录总条数
  206. $count = $table->count();
  207. //处理排序
  208. $table = $table->orderBy($request->get("order",'updated_at'),
  209. $request->get("dir",'desc'));
  210. //处理分页
  211. $table = $table->skip($request->get("offset",0))
  212. ->take($request->get("limit",1000));
  213. //获取数据
  214. $result = $table->get();
  215. return $this->ok(["rows"=>ArticleResource::collection($result),"count"=>$count]);
  216. }
  217. /**
  218. * Display a listing of the resource.
  219. *
  220. * @return \Illuminate\Http\Response
  221. */
  222. public function showMyNumber(Request $request){
  223. $user = AuthApi::current($request);
  224. if(!$user){
  225. return $this->error(__('auth.failed'));
  226. }
  227. //判断当前用户是否有指定的studio的权限
  228. $studioId = StudioApi::getIdByName($request->get('studio'));
  229. if($user['user_uid'] !== $studioId){
  230. return $this->error(__('auth.failed'));
  231. }
  232. //我的
  233. $my = Article::where('owner', $studioId)->count();
  234. //协作
  235. $resList = ShareApi::getResList($studioId,3);
  236. $resId=[];
  237. foreach ($resList as $res) {
  238. $resId[] = $res['res_id'];
  239. }
  240. $collaboration = Article::whereIn('uid', $resId)->where('owner','<>', $studioId)->count();
  241. return $this->ok(['my'=>$my,'collaboration'=>$collaboration]);
  242. }
  243. /**
  244. * Store a newly created resource in storage.
  245. *
  246. * @param \Illuminate\Http\Request $request
  247. * @return \Illuminate\Http\Response
  248. */
  249. public function store(Request $request)
  250. {
  251. //判断权限
  252. $user = AuthApi::current($request);
  253. if(!$user){
  254. Log::error('未登录');
  255. return $this->error(__('auth.failed'),[],401);
  256. }else{
  257. $user_uid=$user['user_uid'];
  258. }
  259. $canManage = ArticleController::userCanManage($user_uid,$request->get('studio'));
  260. if(!$canManage){
  261. Log::error('userCanManage 失败');
  262. //判断是否有文集权限
  263. if($request->has('anthologyId')){
  264. $currPower = ShareApi::getResPower($user_uid,$request->get('anthologyId'));
  265. if($currPower <= 10){
  266. Log::error('没有文集编辑权限');
  267. return $this->error(__('auth.failed'),[],403);
  268. }
  269. }else{
  270. Log::error('没有文集id');
  271. return $this->error(__('auth.failed'),[],403);
  272. }
  273. }
  274. //权限判断结束
  275. //查询标题是否重复
  276. /*
  277. if(Article::where('title',$request->get('title'))->where('owner',$studioUuid)->exists()){
  278. return $this->error(__('validation.exists'));
  279. }*/
  280. Log::debug('开始新建'.$request->get('title'));
  281. $newArticle = new Article;
  282. DB::transaction(function() use($user,$request,$newArticle){
  283. $studioUuid = StudioApi::getIdByName($request->get('studio'));
  284. //新建文章,加入文集必须都成功。否则回滚
  285. $newArticle->id = app('snowflake')->id();
  286. $newArticle->uid = Str::uuid();
  287. $newArticle->title = mb_substr($request->get('title'),0,128,'UTF-8');
  288. $newArticle->lang = $request->get('lang');
  289. if(!empty($request->get('status'))){
  290. $newArticle->status = $request->get('status');
  291. }
  292. $newArticle->owner = $studioUuid;
  293. $newArticle->owner_id = $user['user_id'];
  294. $newArticle->editor_id = $user['user_id'];
  295. $newArticle->parent = $request->get('parentId');
  296. $newArticle->create_time = time()*1000;
  297. $newArticle->modify_time = time()*1000;
  298. $newArticle->save();
  299. OpsLog::debug($user['user_uid'],$newArticle);
  300. Log::debug('开始挂接 id='.$newArticle->uid);
  301. $anthologyId = $request->get('anthologyId');
  302. if(Str::isUuid($anthologyId)){
  303. $parentNode = $request->get('parentNode');
  304. if(Str::isUuid($parentNode)){
  305. Log::debug('有挂接点'.$parentNode);
  306. $map = ArticleCollection::where('collect_id',$anthologyId)
  307. ->orderBy('id')->get();
  308. Log::debug('查询到原map数据'.count($map));
  309. $newMap = array();
  310. $parentNodeLevel = -1;
  311. $appended = false;
  312. foreach ($map as $key => $row) {
  313. $orgNode = $row;
  314. if(!$appended){
  315. if($parentNodeLevel>0){
  316. if($row->level <= $parentNodeLevel ){
  317. //parent node 末尾
  318. $newNode = array();
  319. $newNode['collect_id'] = $anthologyId;
  320. $newNode['article_id'] = $newArticle->uid;
  321. $newNode['level'] = $parentNodeLevel+1;
  322. $newNode['title'] = $newArticle->title;
  323. $newNode['children'] = 0;
  324. $newMap[] = $newNode;
  325. Log::debug('新增节点',['node'=>$newNode]);
  326. $appended = true;
  327. }
  328. }else{
  329. if($row->article_id === $parentNode){
  330. $parentNodeLevel = $row->level;
  331. $orgNode['children'] = $orgNode['children']+1;
  332. }
  333. }
  334. }
  335. $newMap[] = $orgNode;
  336. }
  337. if($parentNodeLevel>0){
  338. if($appended===false){
  339. //
  340. Log::debug('没挂上 挂到结尾');
  341. $newNode = array();
  342. $newNode['collect_id'] = $anthologyId;
  343. $newNode['article_id'] = $newArticle->uid;
  344. $newNode['level'] = $parentNodeLevel+1;
  345. $newNode['title'] = $newArticle->title;
  346. $newNode['children'] = 0;
  347. $newMap[] = $newNode;
  348. }
  349. }else{
  350. Log::error('没找到挂接点'.$parentNode);
  351. }
  352. Log::debug('新map数据'.count($newMap));
  353. $delete = ArticleCollection::where('collect_id',$anthologyId)->delete();
  354. Log::debug('删除旧map数据'.$delete);
  355. $count=0;
  356. foreach ($newMap as $key => $row) {
  357. $new = new ArticleCollection;
  358. $new->id = app('snowflake')->id();
  359. $new->article_id = $row["article_id"];
  360. $new->collect_id = $row["collect_id"];
  361. $new->title = $row["title"];
  362. $new->level = $row["level"];
  363. $new->children = $row["children"];
  364. $new->editor_id = $user["user_id"];
  365. if(isset($row["deleted_at"])){
  366. $new->deleted_at = $row["deleted_at"];
  367. }
  368. $new->save();
  369. $count++;
  370. }
  371. Log::debug('新map数据'.$count);
  372. ArticleMapController::updateCollection($anthologyId);
  373. }else{
  374. $articleMap = new ArticleCollection();
  375. $articleMap->id = app('snowflake')->id();
  376. $articleMap->article_id = $newArticle->uid;
  377. $articleMap->collect_id = $request->get('anthologyId');
  378. $articleMap->title = Article::find($newArticle->uid)->title;
  379. $articleMap->level = 1;
  380. $articleMap->save();
  381. }
  382. }
  383. });
  384. if(Str::isUuid($newArticle->uid)){
  385. return $this->ok(new ArticleResource($newArticle));
  386. }else{
  387. return $this->error('fail');
  388. }
  389. }
  390. /**
  391. * Display the specified resource.
  392. * @param \Illuminate\Http\Request $request
  393. * @param \App\Models\Article $article
  394. * @return \Illuminate\Http\Response
  395. */
  396. public function show(Request $request,Article $article)
  397. {
  398. //
  399. if(!$article){
  400. return $this->error("no recorder");
  401. }
  402. //判断权限
  403. $user = AuthApi::current($request);
  404. if(!$user){
  405. $user_uid="";
  406. }else{
  407. $user_uid=$user['user_uid'];
  408. }
  409. $canRead = ArticleController::userCanRead($user_uid,$article);
  410. if(!$canRead){
  411. return $this->error(__('auth.failed'),403,403);
  412. }
  413. return $this->ok(new ArticleResource($article));
  414. }
  415. /**
  416. * Display the specified resource.
  417. * @param \Illuminate\Http\Request $request
  418. * @param string $article
  419. * @return \Illuminate\Http\Response
  420. */
  421. public function preview(Request $request,string $articleId)
  422. {
  423. //
  424. $article = Article::find($articleId);
  425. if(!$article){
  426. return $this->error("no recorder");
  427. }
  428. //判断权限
  429. $user = AuthApi::current($request);
  430. if(!$user){
  431. $user_uid="";
  432. }else{
  433. $user_uid=$user['user_uid'];
  434. }
  435. $canRead = ArticleController::userCanRead($user_uid,$article);
  436. if(!$canRead){
  437. return $this->error(__('auth.failed'),[],401);
  438. }
  439. if($request->has('content')){
  440. $article->content = $request->get('content');
  441. return $this->ok(new ArticleResource($article));
  442. }else{
  443. return $this->error('no content',[],200);
  444. }
  445. }
  446. /**
  447. * Update the specified resource in storage.
  448. *
  449. * @param \Illuminate\Http\Request $request
  450. * @param \App\Models\Article $article
  451. * @return \Illuminate\Http\Response
  452. */
  453. public function update(Request $request, Article $article)
  454. {
  455. //
  456. if(!$article){
  457. return $this->error("no recorder");
  458. }
  459. //鉴权
  460. $user = AuthApi::current($request);
  461. if(!$user){
  462. return $this->error(__('auth.failed'),401,401);
  463. }else{
  464. $user_uid=$user['user_uid'];
  465. }
  466. $canEdit = ArticleController::userCanEdit($user_uid,$article);
  467. if(!$canEdit){
  468. return $this->error(__('auth.failed'),401,401);
  469. }
  470. /*
  471. //查询标题是否重复
  472. if(Article::where('title',$request->get('title'))
  473. ->where('owner',$article->owner)
  474. ->where('uid',"<>",$article->uid)
  475. ->exists()){
  476. return $this->error(__('validation.exists'));
  477. }*/
  478. $content = $request->get('content');
  479. if($request->get('to_tpl')===true){
  480. /**
  481. * 转化为模版
  482. */
  483. $tplContent = $this->toTpl($content,
  484. $request->get('anthology_id'),
  485. $user);
  486. $content = $tplContent;
  487. }
  488. $article->title = mb_substr($request->get('title'),0,128,'UTF-8') ;
  489. $article->subtitle = mb_substr($request->get('subtitle'),0,128,'UTF-8') ;
  490. $article->summary = mb_substr($request->get('summary'),0,1024,'UTF-8') ;
  491. $article->content = $content;
  492. $article->lang = $request->get('lang');
  493. $article->status = $request->get('status',10);
  494. $article->editor_id = $user['user_id'];
  495. $article->modify_time = time()*1000;
  496. $article->save();
  497. OpsLog::debug($user_uid,$article);
  498. return $this->ok(new ArticleResource($article));
  499. }
  500. /**
  501. * Remove the specified resource from storage.
  502. * @param \Illuminate\Http\Request $request
  503. * @param \App\Models\Article $article
  504. * @return \Illuminate\Http\Response
  505. */
  506. public function destroy(Request $request,Article $article)
  507. {
  508. //
  509. $user = AuthApi::current($request);
  510. if(!$user){
  511. return $this->error(__('auth.failed'));
  512. }
  513. //判断当前用户是否有指定的studio的权限
  514. if($user['user_uid'] !== $article->owner){
  515. return $this->error(__('auth.failed'));
  516. }
  517. $delete = 0;
  518. DB::transaction(function() use($article,$delete){
  519. //TODO 删除文集中的文章
  520. $delete = $article->delete();
  521. ArticleMapController::deleteArticle($article->uid);
  522. });
  523. return $this->ok($delete);
  524. }
  525. public function toTpl($content,$anthologyId,$user){
  526. //查询书号
  527. if(!Str::isUuid($anthologyId)){
  528. throw new \Exception('anthology Id not uuid');
  529. }
  530. $bookId = $this->getBookId($anthologyId,$user);
  531. $tpl = $this->convertToTpl($content,$bookId['book'],$bookId['paragraph']);
  532. //保存原文到句子表
  533. $customBook = $this->getCustomBookByBookId($bookId['book']);
  534. $sentenceSave = new SentenceApi;
  535. $auth = $sentenceSave->auth($customBook->channel_id,$user['user_uid']);
  536. if(!$auth){
  537. throw new \Exception('auth fail');
  538. }
  539. foreach ($tpl['sentences'] as $key => $sentence) {
  540. $sentenceSave->store($sentence,$user);
  541. }
  542. return $tpl['content'];
  543. }
  544. private function getCustomBookByBookId($bookId){
  545. return CustomBook::where('book_id',$bookId)->first();
  546. }
  547. private function getBookId($anthologyId,$user){
  548. $anthology = Collection::where('uid',$anthologyId)->first();
  549. if(!$anthology){
  550. throw new \Exception('anthology not exists id='.$anthologyId);
  551. }
  552. $bookId = $anthology->book_id;
  553. if(empty($bookId)){
  554. //生成 book id
  555. $newBookId = CustomBook::max('book_id') + 1;
  556. $newBook = new CustomBook;
  557. $newBook->id = app('snowflake')->id();
  558. $newBook->book_id = $newBookId;
  559. $newBook->title = $anthology->title;
  560. $newBook->owner = $anthology->owner;
  561. $newBook->editor_id = $user['user_id'];
  562. $newBook->lang = $anthology->lang;
  563. $newBook->status = $anthology->status;
  564. //查询anthology所在的studio有没有符合要求的channel 没有的话,建立
  565. $channelId = ChannelApi::userBookGetOrCreate($anthology->owner,$anthology->lang,$anthology->status);
  566. if($channelId === false){
  567. throw new \Exception('user book get fail studio='.$anthology->owner.' language='.$anthology->lang);
  568. }
  569. $newBook->channel_id = $channelId;
  570. $ok = $newBook->save();
  571. if(!$ok){
  572. throw new \Exception('user book create fail studio='.$anthology->owner.' language='.$anthology->lang);
  573. }
  574. CustomBookId::where('key','max_book_number')->update(['value'=>$newBookId]);
  575. $bookId = $newBookId;
  576. $anthology->book_id = $newBookId;
  577. $anthology->save();
  578. }else{
  579. $channelId = CustomBook::where('book_id',$bookId)->value('channel_id');
  580. }
  581. $maxPara = Sentence::where('channel_uid',$channelId)
  582. ->where('book_id',$bookId)->max('paragraph');
  583. if(!$maxPara){
  584. $maxPara = 0;
  585. }
  586. return ['book'=>$bookId,'paragraph'=>$maxPara+1];
  587. }
  588. public function convertToTpl($content,$bookId,$paraStart){
  589. $newSentence = array();
  590. $para = $paraStart;
  591. $sentNum = 1;
  592. $newText = "";
  593. $isTable=false;
  594. $isList=false;
  595. $newSent="";
  596. $sentences = explode("\n",$content);
  597. foreach ($sentences as $row) {
  598. //$data 为一行文本
  599. $listHead= "";
  600. $isList = false;
  601. $heading = false;
  602. $title = false;
  603. $trimData = trim($row);
  604. # 判断是否为list
  605. $listLeft =strstr($row,"- ",true);
  606. if($listLeft !== FALSE){
  607. if(ctype_space($listLeft) || empty($listLeft)){
  608. # - 左侧是空,判定为list
  609. $isList=true;
  610. $iListPos = mb_strpos($row,'- ',0,"UTF-8");
  611. $listHead = mb_substr($row,0,$iListPos+2,"UTF-8");
  612. $listBody = mb_substr($row,$iListPos+2,mb_strlen($row,"UTF-8")-$iListPos+2,"UTF-8");
  613. }
  614. }
  615. # TODO 判断是否为标题
  616. $headingStart =mb_strpos($row,"# ",0,'UTF-8');
  617. if($headingStart !== false){
  618. $headingLeft = mb_substr($row,0,$headingStart+2,'UTF-8');
  619. $title = mb_substr($row,$headingStart+2,null,'UTF-8');
  620. if(str_replace('#','', trim($headingLeft)) === ''){
  621. # 除了#没有其他东西,那么是标题
  622. $heading = $headingLeft;
  623. $newText .= $headingLeft;
  624. $newText .='{{'."{$bookId}-{$para}-{$sentNum}-{$sentNum}"."}}\n";
  625. $newSentence[] = $this->newSent($bookId,$para,$sentNum,$sentNum,$title);
  626. $newSent="";
  627. $para++;
  628. $sentNum = 1;
  629. continue;
  630. }
  631. }
  632. //判断是否为表格开始
  633. if(mb_substr($trimData,0,1,"UTF-8") == "|"){
  634. $isTable=true;
  635. }
  636. if($trimData!="" && $isTable == true){
  637. //如果是表格 不新增句子
  638. $newSent .= "{$row}\n";
  639. continue;
  640. }
  641. if($isList == true){
  642. $newSent .= $listBody;
  643. }else{
  644. $newSent .= $trimData;
  645. }
  646. #生成句子编号
  647. if($trimData==""){
  648. #空行
  649. if(strlen($newSent)>0){
  650. //之前有内容
  651. $newText .='{{'."{$bookId}-{$para}-{$sentNum}-{$sentNum}"."}}\n";
  652. $newSentence[] = $this->newSent($bookId,$para,$sentNum,$sentNum,$newSent);
  653. $newSent="";
  654. }
  655. #新的段落 不插入数据库
  656. $para++;
  657. $sentNum = 1;
  658. $newText .="\n";
  659. $isTable = false; //表格开始标记
  660. $isList = false;
  661. continue;
  662. }else{
  663. $sentNum=$sentNum+10;
  664. }
  665. if(mb_substr($trimData,0,2,"UTF-8")=="{{"){
  666. #已经有的句子链接不处理
  667. $newText .= $trimData."\n";
  668. }else{
  669. $newText .= $listHead;
  670. $newText .='{{'."{$bookId}-{$para}-{$sentNum}-{$sentNum}"."}}\n";
  671. $newSentence[] = $this->newSent($bookId,$para,$sentNum,$sentNum,$newSent);
  672. $newSent="";
  673. }
  674. }
  675. return [
  676. 'content' =>$newText,
  677. 'sentences' =>$newSentence,
  678. ];
  679. }
  680. private function newSent($book,$para,$start,$end,$content){
  681. return array(
  682. 'book_id'=>$book,
  683. 'paragraph'=>$para,
  684. 'word_start'=>$start,
  685. 'word_end'=>$end,
  686. 'content'=>$content,
  687. );
  688. }
  689. }