WbwLookupController.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Models\UserDict;
  4. use App\Models\DictInfo;
  5. use App\Models\WbwTemplate;
  6. use App\Models\Channel;
  7. use App\Models\WbwAnalysis;
  8. use Illuminate\Http\Request;
  9. use App\Tools\CaseMan;
  10. use Illuminate\Support\Facades\Log;
  11. use Illuminate\Support\Facades\Cache;
  12. use App\Http\Api\DictApi;
  13. class WbwLookupController extends Controller
  14. {
  15. private $dictList = [
  16. '85dcc61c-c9e1-4ae0-9b44-cd6d9d9f0d01',//社区汇总
  17. '4d3a0d92-0adc-4052-80f5-512a2603d0e8',// system irregular
  18. 'ef620a93-a55d-4756-89c5-e188ab009e45',//社区字典
  19. '8359757e-9575-455b-a772-cc6f036caea0',// system sandhi
  20. 'c42980f0-5967-4833-b695-84183344f68f',// robot compound
  21. '61f23efb-b526-4a8e-999e-076965034e60',// pali myanmar grammar
  22. 'eae9fd6f-7bac-4940-b80d-ad6cd6f433bf',// Concise P-E Dict
  23. '2f93d0fe-3d68-46ee-a80b-11fa445a29c6',// unity
  24. 'beb45062-7c20-4047-bcd4-1f636ba443d1',// U Hau Sein
  25. '8833de18-0978-434c-b281-a2e7387f69be',// 巴汉增订
  26. '3acf0c0f-59a7-4d25-a3d9-bf394a266ebd',// 汉译パーリ语辞典-黃秉榮
  27. ];
  28. /**
  29. * Display a listing of the resource.
  30. * @param \Illuminate\Http\Request $request
  31. *
  32. * @return \Illuminate\Http\Response
  33. */
  34. public function index(Request $request)
  35. {
  36. // system regular
  37. $dict_id = DictApi::getSysDict('system_regular');
  38. $this->dictList[] = $dict_id;
  39. //
  40. $startAt = microtime(true)*1000;
  41. $words = \explode(',',$request->get("word"));
  42. $bases = \explode(',',$request->get("base"));
  43. # 查询深度
  44. $deep = $request->get("deep",2);
  45. $result = $this->lookup($words,$bases,$deep);
  46. $endAt = microtime(true)*1000;
  47. return $this->ok(["rows"=>$result,
  48. "count"=>count($result),
  49. "time"=>(int)($endAt-$startAt)]);
  50. }
  51. public function lookup($words,$bases,$deep){
  52. $wordPool = array();
  53. $output = array();
  54. foreach ($words as $word) {
  55. $wordPool[$word] = ['base' => false,'done' => false,'apply' => false];
  56. }
  57. foreach ($bases as $base) {
  58. $wordPool[$base] = ['base' => true,'done' => false,'apply' => false];
  59. }
  60. /**
  61. * 先查询字典名称
  62. */
  63. $dict_info = DictInfo::whereIn('id',$this->dictList)->select('id','shortname')->get();
  64. $dict_name = [];
  65. foreach ($dict_info as $key => $value) {
  66. # code...
  67. $dict_name[$value->id] = $value->shortname;
  68. }
  69. $caseman = new CaseMan();
  70. for ($i=0; $i < $deep; $i++) {
  71. $newBase = array();
  72. $newWords = [];
  73. foreach ($wordPool as $word => $info) {
  74. # code...
  75. if($info['done'] === false){
  76. $newWords[] = $word;
  77. $wordPool[$word]['done'] = true;
  78. }
  79. }
  80. $data = UserDict::whereIn('word',$newWords)
  81. ->whereIn('dict_id',$this->dictList)
  82. ->leftJoin('dict_infos', 'user_dicts.dict_id', '=', 'dict_infos.id')
  83. ->orderBy('confidence','desc')
  84. ->get();
  85. foreach ($data as $row) {
  86. # code...
  87. array_push($output,$row);
  88. if(!empty($row->parent) && !isset($wordPool[$row->parent]) ){
  89. //将parent 插入待查询列表
  90. $wordPool[$row->parent] = ['base' => true,'done' => false,'apply' => false];
  91. }
  92. }
  93. //处理查询结果中的拆分信息
  94. $newWordPart = array();
  95. foreach ($wordPool as $word => $info) {
  96. if(!empty($info['factors'])){
  97. $factors = \explode('+',$info['factors']);
  98. foreach ($factors as $factor) {
  99. # 将没有的拆分放入单词查询列表
  100. if(!isset($wordPool[$factor])){
  101. $wordPool[$factor] = ['base' => true,'done' => false,'apply' => false];
  102. }
  103. }
  104. }
  105. }
  106. }
  107. return $output;
  108. }
  109. /**
  110. * 自动查词
  111. *
  112. * @param \Illuminate\Http\Request $request
  113. * @return \Illuminate\Http\Response
  114. */
  115. public function store(Request $request)
  116. {
  117. //
  118. $startAt = microtime(true)*1000;
  119. // system regular
  120. $dict_id = DictApi::getSysDict('system_regular');
  121. $this->dictList[] = $dict_id;
  122. $channel = Channel::find($request->get('channel_id'));
  123. $orgData = $request->get('data');
  124. //句子中的单词
  125. $words = [];
  126. foreach ($orgData as $word) {
  127. # code...
  128. if($word['type']['value'] !== '.ctl.' && !empty($word['real']['value'])){
  129. $words[] = $word['real']['value'];
  130. }
  131. }
  132. $result = $this->lookup($words,[],2);
  133. $indexed = $this->toIndexed($result);
  134. foreach ($orgData as $key => $word) {
  135. if($word['type']['value'] !== '.ctl.' && !empty($word['real']['value'])){
  136. $data = $word;
  137. if(isset($indexed[$word['real']['value']])){
  138. //parent
  139. $case = [];
  140. $parent = [];
  141. $factors = [];
  142. $factorMeaning = [];
  143. $meaning = [];
  144. $parent2 = [];
  145. $case2 = [];
  146. foreach ($indexed[$word['real']['value']] as $value) {
  147. //非base优先
  148. if(strstr($value->type,'base') === FALSE){
  149. $increment = 10;
  150. }else{
  151. $increment = 1;
  152. }
  153. //将全部结果加上得分放入数组
  154. $parent = $this->insertValue([$value->parent],$parent,$increment);
  155. if(!empty($value->type) && $value->type !== ".cp."){
  156. $case = $this->insertValue([$value->type."#".$value->grammar],$case,$increment);
  157. }
  158. $factors = $this->insertValue([$value->factors],$factors,$increment);
  159. $factorMeaning = $this->insertValue([$value->factormean],$factorMeaning,$increment);
  160. $meaning = $this->insertValue(explode('$',$value->mean),$meaning,$increment,false);
  161. }
  162. if(count($case)>0){
  163. arsort($case);
  164. $first = array_keys($case)[0];
  165. $data['case'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
  166. }
  167. if(count($parent)>0){
  168. arsort($parent);
  169. $first = array_keys($parent)[0];
  170. $data['parent'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
  171. }
  172. if(count($factors)>0){
  173. arsort($factors);
  174. $first = array_keys($factors)[0];
  175. $data['factors'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
  176. }
  177. //拆分意思
  178. if(count($factorMeaning)>0){
  179. arsort($factorMeaning);
  180. $first = array_keys($factorMeaning)[0];
  181. $data['factorMeaning'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
  182. }
  183. $wbwFactorMeaning = [];
  184. if(!empty($data['factors']['value'])){
  185. foreach (explode("+",$data['factors']['value']) as $factor) {
  186. # code...
  187. $wbwAnalyses = WbwAnalysis::where('wbw_word',$factor)
  188. ->where('type',7)
  189. ->selectRaw('data,count(*)')
  190. ->groupBy("data")
  191. ->orderBy("count", "desc")
  192. ->first();
  193. if($wbwAnalyses){
  194. $wbwFactorMeaning[]=$wbwAnalyses->data;
  195. }else{
  196. $wbwFactorMeaning[]="";
  197. }
  198. }
  199. }
  200. $data['factorMeaning'] = ['value'=>implode('+',$wbwFactorMeaning),'status'=>3];
  201. if(!empty($data['parent'])){
  202. if(isset($indexed[$data['parent']['value']])){
  203. foreach ($indexed[$data['parent']['value']] as $value) {
  204. //根据base 查找词意
  205. //非base优先
  206. $increment = 10;
  207. $meaning = $this->insertValue(explode('$',$value->mean),$meaning,$increment,false);
  208. //查找词源
  209. if(!empty($value->parent) && $value->parent !== $value->word && strstr($value->type,"base") !== FALSE ){
  210. $parent2 = $this->insertValue([$value->grammar."$".$value->parent],$parent2,1,false);
  211. }
  212. }
  213. }
  214. }
  215. if(count($meaning)>0){
  216. arsort($meaning);
  217. $first = array_keys($meaning)[0];
  218. $data['meaning'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
  219. }
  220. if(count($parent2)>0){
  221. arsort($parent2);
  222. $first = explode("$",array_keys($parent2)[0]);
  223. $data['parent2'] = ['value'=>$first[1],'status'=>3];
  224. $data['grammar2'] = ['value'=>$first[0],'status'=>3];
  225. }
  226. }
  227. $orgData[$key] = $data;
  228. }
  229. }
  230. return $this->ok($orgData);
  231. }
  232. /**
  233. * 自动查词
  234. *
  235. * @param string $sentId
  236. * @return \Illuminate\Http\Response
  237. */
  238. public function show(Request $request,string $sentId)
  239. {
  240. $startAt = microtime(true)*1000;
  241. $channel = Channel::find($request->get('channel_id'));
  242. //查询句子中的单词
  243. $sent = \explode('-',$sentId);
  244. $wbw = WbwTemplate::where('book',$sent[0])
  245. ->where('paragraph',$sent[1])
  246. ->whereBetween('wid',[$sent[2],$sent[3]])
  247. ->orderBy('wid')
  248. ->get();
  249. $words = [];
  250. foreach ($wbw as $row) {
  251. if($row->type !== '.ctl.' && !empty($row->real)){
  252. $words[] = $row->real;
  253. }
  254. }
  255. $result = $this->lookup($words,[],2);
  256. $indexed = $this->toIndexed($result);
  257. //生成自动填充结果
  258. $wbwContent = [];
  259. foreach ($wbw as $row) {
  260. $type = $row->type=='?'? '':$row->type;
  261. $grammar = $row->gramma=='?'? '':$row->gramma;
  262. $part = $row->part=='?'? '':$row->part;
  263. if(!empty($type) || !empty($grammar)){
  264. $case = "{$type}#$grammar";
  265. }else{
  266. $case = "";
  267. }
  268. $data = [
  269. 'sn'=>[$row->wid],
  270. 'word'=>['value'=>$row->word,'status'=>3],
  271. 'real'=> ['value'=>$row->real,'status'=>3],
  272. 'meaning'=> ['value'=>[],'status'=>3],
  273. 'type'=> ['value'=>$type,'status'=>3],
  274. 'grammar'=> ['value'=>$grammar,'status'=>3],
  275. 'case'=> ['value'=>$case,'status'=>3],
  276. 'style'=> ['value'=>$row->style,'status'=>3],
  277. 'factors'=> ['value'=>$part,'status'=>3],
  278. 'factorMeaning'=> ['value'=>'','status'=>3],
  279. 'confidence'=> 0.5
  280. ];
  281. if($row->type !== '.ctl.' && !empty($row->real)){
  282. if(isset($indexed[$row->real])){
  283. //parent
  284. $case = [];
  285. $parent = [];
  286. $factors = [];
  287. $factorMeaning = [];
  288. $meaning = [];
  289. $parent2 = [];
  290. $case2 = [];
  291. foreach ($indexed[$row->real] as $value) {
  292. //非base优先
  293. if(strstr($value->type,'base') === FALSE){
  294. $increment = 10;
  295. }else{
  296. $increment = 1;
  297. }
  298. //将全部结果加上得分放入数组
  299. $parent = $this->insertValue([$value->parent],$parent,$increment);
  300. $case = $this->insertValue([$value->type."#".$value->grammar],$case,$increment);
  301. $factors = $this->insertValue([$value->factors],$factors,$increment);
  302. $factorMeaning = $this->insertValue([$value->factormean],$factorMeaning,$increment);
  303. $meaning = $this->insertValue(explode('$',$value->mean),$meaning,$increment,false);
  304. }
  305. if(count($case)>0){
  306. arsort($case);
  307. $first = array_keys($case)[0];
  308. $data['case'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
  309. }
  310. if(count($parent)>0){
  311. arsort($parent);
  312. $first = array_keys($parent)[0];
  313. $data['parent'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
  314. }
  315. if(count($factors)>0){
  316. arsort($factors);
  317. $first = array_keys($factors)[0];
  318. $data['factors'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
  319. }
  320. if(count($factorMeaning)>0){
  321. arsort($factorMeaning);
  322. $first = array_keys($factorMeaning)[0];
  323. $data['factorMeaning'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
  324. }
  325. //根据base 查找词意
  326. if(!empty($data['parent'])){
  327. if(isset($indexed[$data['parent']['value']])){
  328. Log::info($data['parent']['value']."=".count($indexed[$data['parent']['value']]));
  329. foreach ($indexed[$data['parent']['value']] as $value) {
  330. //非base优先
  331. $increment = 10;
  332. $meaning = $this->insertValue(explode('$',$value->mean),$meaning,$increment,false);
  333. }
  334. }else{
  335. Log::error("no set parent".$data['parent']['value']);
  336. }
  337. }
  338. if(count($meaning)>0){
  339. arsort($meaning);
  340. Log::info('meanings=');
  341. Log::info(array_keys($meaning));
  342. $first = array_keys($meaning)[0];
  343. $data['meaning'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
  344. }
  345. }
  346. }
  347. $wbwContent[] = $data;
  348. }
  349. $endAt = microtime(true)*1000;
  350. return $this->ok(["rows"=>$wbwContent,
  351. "count"=>count($wbwContent),
  352. "time"=>(int)($endAt-$startAt)]);
  353. }
  354. private function toIndexed($words){
  355. //转成索引数组
  356. $indexed = [];
  357. foreach ($words as $key => $value) {
  358. # code...
  359. $indexed[$value->word][] = $value;
  360. }
  361. return $indexed;
  362. }
  363. private function insertValue($value,$container,$increment,$empty=true){
  364. foreach ($value as $one) {
  365. if($empty === false){
  366. if(empty($one)){
  367. break;
  368. }
  369. }
  370. $one=trim($one);
  371. $key = $one;
  372. if(empty($key)){
  373. $key = '_null';
  374. }
  375. if(isset($container[$key])){
  376. $container[$key] += $increment;
  377. }else{
  378. $container[$key] = $increment;
  379. }
  380. }
  381. return $container;
  382. }
  383. /**
  384. * Update the specified resource in storage.
  385. *
  386. * @param \Illuminate\Http\Request $request
  387. * @param \App\Models\UserDict $userDict
  388. * @return \Illuminate\Http\Response
  389. */
  390. public function update(Request $request, UserDict $userDict)
  391. {
  392. //
  393. }
  394. /**
  395. * Remove the specified resource from storage.
  396. *
  397. * @param \App\Models\UserDict $userDict
  398. * @return \Illuminate\Http\Response
  399. */
  400. public function destroy(UserDict $userDict)
  401. {
  402. //
  403. }
  404. }