ArticleController.php 26 KB

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