2
0

ArticleController.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  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. $newArticle->owner = $studioUuid;
  290. $newArticle->owner_id = $user['user_id'];
  291. $newArticle->editor_id = $user['user_id'];
  292. $newArticle->parent = $request->get('parentId');
  293. $newArticle->create_time = time()*1000;
  294. $newArticle->modify_time = time()*1000;
  295. $newArticle->save();
  296. OpsLog::debug($user['user_uid'],$newArticle);
  297. Log::debug('开始挂接 id='.$newArticle->uid);
  298. $anthologyId = $request->get('anthologyId');
  299. if(Str::isUuid($anthologyId)){
  300. $parentNode = $request->get('parentNode');
  301. if(Str::isUuid($parentNode)){
  302. Log::debug('有挂接点'.$parentNode);
  303. $map = ArticleCollection::where('collect_id',$anthologyId)
  304. ->orderBy('id')->get();
  305. Log::debug('查询到原map数据'.count($map));
  306. $newMap = array();
  307. $parentNodeLevel = -1;
  308. $appended = false;
  309. foreach ($map as $key => $row) {
  310. $orgNode = $row;
  311. if(!$appended){
  312. if($parentNodeLevel>0){
  313. if($row->level <= $parentNodeLevel ){
  314. //parent node 末尾
  315. $newNode = array();
  316. $newNode['collect_id'] = $anthologyId;
  317. $newNode['article_id'] = $newArticle->uid;
  318. $newNode['level'] = $parentNodeLevel+1;
  319. $newNode['title'] = $newArticle->title;
  320. $newNode['children'] = 0;
  321. $newMap[] = $newNode;
  322. Log::debug('新增节点',['node'=>$newNode]);
  323. $appended = true;
  324. }
  325. }else{
  326. if($row->article_id === $parentNode){
  327. $parentNodeLevel = $row->level;
  328. $orgNode['children'] = $orgNode['children']+1;
  329. }
  330. }
  331. }
  332. $newMap[] = $orgNode;
  333. }
  334. if($parentNodeLevel>0){
  335. if($appended===false){
  336. //
  337. Log::debug('没挂上 挂到结尾');
  338. $newNode = array();
  339. $newNode['collect_id'] = $anthologyId;
  340. $newNode['article_id'] = $newArticle->uid;
  341. $newNode['level'] = $parentNodeLevel+1;
  342. $newNode['title'] = $newArticle->title;
  343. $newNode['children'] = 0;
  344. $newMap[] = $newNode;
  345. }
  346. }else{
  347. Log::error('没找到挂接点'.$parentNode);
  348. }
  349. Log::debug('新map数据'.count($newMap));
  350. $delete = ArticleCollection::where('collect_id',$anthologyId)->delete();
  351. Log::debug('删除旧map数据'.$delete);
  352. $count=0;
  353. foreach ($newMap as $key => $row) {
  354. $new = new ArticleCollection;
  355. $new->id = app('snowflake')->id();
  356. $new->article_id = $row["article_id"];
  357. $new->collect_id = $row["collect_id"];
  358. $new->title = $row["title"];
  359. $new->level = $row["level"];
  360. $new->children = $row["children"];
  361. $new->editor_id = $user["user_id"];
  362. if(isset($row["deleted_at"])){
  363. $new->deleted_at = $row["deleted_at"];
  364. }
  365. $new->save();
  366. $count++;
  367. }
  368. Log::debug('新map数据'.$count);
  369. ArticleMapController::updateCollection($anthologyId);
  370. }else{
  371. $articleMap = new ArticleCollection();
  372. $articleMap->id = app('snowflake')->id();
  373. $articleMap->article_id = $newArticle->uid;
  374. $articleMap->collect_id = $request->get('anthologyId');
  375. $articleMap->title = Article::find($newArticle->uid)->title;
  376. $articleMap->level = 1;
  377. $articleMap->save();
  378. }
  379. }
  380. });
  381. if(Str::isUuid($newArticle->uid)){
  382. return $this->ok($newArticle);
  383. }else{
  384. return $this->error('fail');
  385. }
  386. }
  387. /**
  388. * Display the specified resource.
  389. * @param \Illuminate\Http\Request $request
  390. * @param \App\Models\Article $article
  391. * @return \Illuminate\Http\Response
  392. */
  393. public function show(Request $request,Article $article)
  394. {
  395. //
  396. if(!$article){
  397. return $this->error("no recorder");
  398. }
  399. //判断权限
  400. $user = AuthApi::current($request);
  401. if(!$user){
  402. $user_uid="";
  403. }else{
  404. $user_uid=$user['user_uid'];
  405. }
  406. $canRead = ArticleController::userCanRead($user_uid,$article);
  407. if(!$canRead){
  408. return $this->error(__('auth.failed'),403,403);
  409. }
  410. return $this->ok(new ArticleResource($article));
  411. }
  412. /**
  413. * Display the specified resource.
  414. * @param \Illuminate\Http\Request $request
  415. * @param string $article
  416. * @return \Illuminate\Http\Response
  417. */
  418. public function preview(Request $request,string $articleId)
  419. {
  420. //
  421. $article = Article::find($articleId);
  422. if(!$article){
  423. return $this->error("no recorder");
  424. }
  425. //判断权限
  426. $user = AuthApi::current($request);
  427. if(!$user){
  428. $user_uid="";
  429. }else{
  430. $user_uid=$user['user_uid'];
  431. }
  432. $canRead = ArticleController::userCanRead($user_uid,$article);
  433. if(!$canRead){
  434. return $this->error(__('auth.failed'),[],401);
  435. }
  436. if($request->has('content')){
  437. $article->content = $request->get('content');
  438. return $this->ok(new ArticleResource($article));
  439. }else{
  440. return $this->error('no content',[],200);
  441. }
  442. }
  443. /**
  444. * Update the specified resource in storage.
  445. *
  446. * @param \Illuminate\Http\Request $request
  447. * @param \App\Models\Article $article
  448. * @return \Illuminate\Http\Response
  449. */
  450. public function update(Request $request, Article $article)
  451. {
  452. //
  453. if(!$article){
  454. return $this->error("no recorder");
  455. }
  456. //鉴权
  457. $user = AuthApi::current($request);
  458. if(!$user){
  459. return $this->error(__('auth.failed'),401,401);
  460. }else{
  461. $user_uid=$user['user_uid'];
  462. }
  463. $canEdit = ArticleController::userCanEdit($user_uid,$article);
  464. if(!$canEdit){
  465. return $this->error(__('auth.failed'),401,401);
  466. }
  467. /*
  468. //查询标题是否重复
  469. if(Article::where('title',$request->get('title'))
  470. ->where('owner',$article->owner)
  471. ->where('uid',"<>",$article->uid)
  472. ->exists()){
  473. return $this->error(__('validation.exists'));
  474. }*/
  475. $content = $request->get('content');
  476. if($request->get('to_tpl')===true){
  477. /**
  478. * 转化为模版
  479. */
  480. $tplContent = $this->toTpl($content,
  481. $request->get('anthology_id'),
  482. $user);
  483. $content = $tplContent;
  484. }
  485. $article->title = mb_substr($request->get('title'),0,128,'UTF-8') ;
  486. $article->subtitle = mb_substr($request->get('subtitle'),0,128,'UTF-8') ;
  487. $article->summary = mb_substr($request->get('summary'),0,1024,'UTF-8') ;
  488. $article->content = $content;
  489. $article->lang = $request->get('lang');
  490. $article->status = $request->get('status',10);
  491. $article->editor_id = $user['user_id'];
  492. $article->modify_time = time()*1000;
  493. $article->save();
  494. OpsLog::debug($user_uid,$article);
  495. return $this->ok($article);
  496. }
  497. /**
  498. * Remove the specified resource from storage.
  499. * @param \Illuminate\Http\Request $request
  500. * @param \App\Models\Article $article
  501. * @return \Illuminate\Http\Response
  502. */
  503. public function destroy(Request $request,Article $article)
  504. {
  505. //
  506. $user = AuthApi::current($request);
  507. if(!$user){
  508. return $this->error(__('auth.failed'));
  509. }
  510. //判断当前用户是否有指定的studio的权限
  511. if($user['user_uid'] !== $article->owner){
  512. return $this->error(__('auth.failed'));
  513. }
  514. $delete = 0;
  515. DB::transaction(function() use($article,$delete){
  516. //TODO 删除文集中的文章
  517. $delete = $article->delete();
  518. ArticleMapController::deleteArticle($article->uid);
  519. });
  520. return $this->ok($delete);
  521. }
  522. public function toTpl($content,$anthologyId,$user){
  523. //查询书号
  524. if(!Str::isUuid($anthologyId)){
  525. throw new \Exception('anthology Id not uuid');
  526. }
  527. $bookId = $this->getBookId($anthologyId,$user);
  528. $tpl = $this->convertToTpl($content,$bookId['book'],$bookId['paragraph']);
  529. //保存原文到句子表
  530. $customBook = $this->getCustomBookByBookId($bookId['book']);
  531. $sentenceSave = new SentenceApi;
  532. $auth = $sentenceSave->auth($customBook->channel_id,$user['user_uid']);
  533. if(!$auth){
  534. throw new \Exception('auth fail');
  535. }
  536. foreach ($tpl['sentences'] as $key => $sentence) {
  537. $sentenceSave->store($sentence,$user);
  538. }
  539. return $tpl['content'];
  540. }
  541. private function getCustomBookByBookId($bookId){
  542. return CustomBook::where('book_id',$bookId)->first();
  543. }
  544. private function getBookId($anthologyId,$user){
  545. $anthology = Collection::where('uid',$anthologyId)->first();
  546. if(!$anthology){
  547. throw new \Exception('anthology not exists id='.$anthologyId);
  548. }
  549. $bookId = $anthology->book_id;
  550. if(empty($bookId)){
  551. //生成 book id
  552. $newBookId = CustomBook::max('book_id') + 1;
  553. $newBook = new CustomBook;
  554. $newBook->id = app('snowflake')->id();
  555. $newBook->book_id = $newBookId;
  556. $newBook->title = $anthology->title;
  557. $newBook->owner = $anthology->owner;
  558. $newBook->editor_id = $user['user_id'];
  559. $newBook->lang = $anthology->lang;
  560. $newBook->status = $anthology->status;
  561. //查询anthology所在的studio有没有符合要求的channel 没有的话,建立
  562. $channelId = ChannelApi::userBookGetOrCreate($anthology->owner,$anthology->lang,$anthology->status);
  563. if($channelId === false){
  564. throw new \Exception('user book get fail studio='.$anthology->owner.' language='.$anthology->lang);
  565. }
  566. $newBook->channel_id = $channelId;
  567. $ok = $newBook->save();
  568. if(!$ok){
  569. throw new \Exception('user book create fail studio='.$anthology->owner.' language='.$anthology->lang);
  570. }
  571. CustomBookId::where('key','max_book_number')->update(['value'=>$newBookId]);
  572. $bookId = $newBookId;
  573. $anthology->book_id = $newBookId;
  574. $anthology->save();
  575. }else{
  576. $channelId = CustomBook::where('book_id',$bookId)->value('channel_id');
  577. }
  578. $maxPara = Sentence::where('channel_uid',$channelId)
  579. ->where('book_id',$bookId)->max('paragraph');
  580. if(!$maxPara){
  581. $maxPara = 0;
  582. }
  583. return ['book'=>$bookId,'paragraph'=>$maxPara+1];
  584. }
  585. public function convertToTpl($content,$bookId,$paraStart){
  586. $newSentence = array();
  587. $para = $paraStart;
  588. $sentNum = 1;
  589. $newText = "";
  590. $isTable=false;
  591. $isList=false;
  592. $newSent="";
  593. $sentences = explode("\n",$content);
  594. foreach ($sentences as $row) {
  595. //$data 为一行文本
  596. $listHead= "";
  597. $isList = false;
  598. $heading = false;
  599. $title = false;
  600. $trimData = trim($row);
  601. # 判断是否为list
  602. $listLeft =strstr($row,"- ",true);
  603. if($listLeft !== FALSE){
  604. if(ctype_space($listLeft) || empty($listLeft)){
  605. # - 左侧是空,判定为list
  606. $isList=true;
  607. $iListPos = mb_strpos($row,'- ',0,"UTF-8");
  608. $listHead = mb_substr($row,0,$iListPos+2,"UTF-8");
  609. $listBody = mb_substr($row,$iListPos+2,mb_strlen($row,"UTF-8")-$iListPos+2,"UTF-8");
  610. }
  611. }
  612. # TODO 判断是否为标题
  613. $headingStart =mb_strpos($row,"# ",0,'UTF-8');
  614. if($headingStart !== false){
  615. $headingLeft = mb_substr($row,0,$headingStart+2,'UTF-8');
  616. $title = mb_substr($row,$headingStart+2,null,'UTF-8');
  617. if(str_replace('#','', trim($headingLeft)) === ''){
  618. # 除了#没有其他东西,那么是标题
  619. $heading = $headingLeft;
  620. $newText .= $headingLeft;
  621. $newText .='{{'."{$bookId}-{$para}-{$sentNum}-{$sentNum}"."}}\n";
  622. $newSentence[] = $this->newSent($bookId,$para,$sentNum,$sentNum,$title);
  623. $newSent="";
  624. $para++;
  625. $sentNum = 1;
  626. continue;
  627. }
  628. }
  629. //判断是否为表格开始
  630. if(mb_substr($trimData,0,1,"UTF-8") == "|"){
  631. $isTable=true;
  632. }
  633. if($trimData!="" && $isTable == true){
  634. //如果是表格 不新增句子
  635. $newSent .= "{$row}\n";
  636. continue;
  637. }
  638. if($isList == true){
  639. $newSent .= $listBody;
  640. }else{
  641. $newSent .= $trimData;
  642. }
  643. #生成句子编号
  644. if($trimData==""){
  645. #空行
  646. if(strlen($newSent)>0){
  647. //之前有内容
  648. $newText .='{{'."{$bookId}-{$para}-{$sentNum}-{$sentNum}"."}}\n";
  649. $newSentence[] = $this->newSent($bookId,$para,$sentNum,$sentNum,$newSent);
  650. $newSent="";
  651. }
  652. #新的段落 不插入数据库
  653. $para++;
  654. $sentNum = 1;
  655. $newText .="\n";
  656. $isTable = false; //表格开始标记
  657. $isList = false;
  658. continue;
  659. }else{
  660. $sentNum=$sentNum+10;
  661. }
  662. if(mb_substr($trimData,0,2,"UTF-8")=="{{"){
  663. #已经有的句子链接不处理
  664. $newText .= $trimData."\n";
  665. }else{
  666. $newText .= $listHead;
  667. $newText .='{{'."{$bookId}-{$para}-{$sentNum}-{$sentNum}"."}}\n";
  668. $newSentence[] = $this->newSent($bookId,$para,$sentNum,$sentNum,$newSent);
  669. $newSent="";
  670. }
  671. }
  672. return [
  673. 'content' =>$newText,
  674. 'sentences' =>$newSentence,
  675. ];
  676. }
  677. private function newSent($book,$para,$start,$end,$content){
  678. return array(
  679. 'book_id'=>$book,
  680. 'paragraph'=>$para,
  681. 'word_start'=>$start,
  682. 'word_end'=>$end,
  683. 'content'=>$content,
  684. );
  685. }
  686. }