| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581 |
- <?php
- namespace App\Http\Controllers;
- use App\Models\UserDict;
- use App\Models\DictInfo;
- use App\Models\WbwTemplate;
- use App\Models\Channel;
- use Illuminate\Http\Request;
- use App\Tools\CaseMan;
- use Illuminate\Support\Facades\Log;
- use Illuminate\Support\Facades\Cache;
- use App\Tools\RedisClusters;
- use App\Http\Api\DictApi;
- use App\Http\Api\AuthApi;
- class WbwLookupController extends Controller
- {
- private $dictList = [
- '85dcc61c-c9e1-4ae0-9b44-cd6d9d9f0d01',//社区汇总
- '4d3a0d92-0adc-4052-80f5-512a2603d0e8',// system irregular
- '8359757e-9575-455b-a772-cc6f036caea0',// system sandhi
- '61f23efb-b526-4a8e-999e-076965034e60',// pali myanmar grammar
- 'eae9fd6f-7bac-4940-b80d-ad6cd6f433bf',// Concise P-E Dict
- '2f93d0fe-3d68-46ee-a80b-11fa445a29c6',// unity
- 'beb45062-7c20-4047-bcd4-1f636ba443d1',// U Hau Sein
- '8833de18-0978-434c-b281-a2e7387f69be',// 巴汉增订
- '3acf0c0f-59a7-4d25-a3d9-bf394a266ebd',// 汉译パーリ语辞典-黃秉榮
- '9ce6a53b-e28f-4fb7-b69d-b35fd5d76a24',//缅英字典
- ];
- /**
- * Create a new command instance.
- *
- * @return void
- */
- private function initSysDict()
- {
- // system regular
- $this->dictList[] = DictApi::getSysDict('system_regular');
- $this->dictList[] = DictApi::getSysDict('robot_compound');
- $this->dictList[] = DictApi::getSysDict('community');
- $this->dictList[] = DictApi::getSysDict('community_extract');
- }
- /**
- * Display a listing of the resource.
- * @param \Illuminate\Http\Request $request
- *
- * @return \Illuminate\Http\Response
- */
- public function index(Request $request)
- {
- //
- $startAt = microtime(true)*1000;
- $this->initSysDict();
- $words = \explode(',',$request->get("word"));
- $bases = \explode(',',$request->get("base"));
- # 查询深度
- $deep = $request->get("deep",2);
- $result = $this->lookup($words,$bases,$deep);
- $endAt = microtime(true)*1000;
- return $this->ok(["rows"=>$result,
- "count"=>count($result),
- "time"=>(int)($endAt-$startAt)]);
- }
- //查用户字典获取全部结果
- public function lookup($words,$bases,$deep){
- $wordPool = array();
- $output = array();
- foreach ($words as $word) {
- $wordPool[$word] = ['base' => false,'done' => false,'apply' => false];
- }
- foreach ($bases as $base) {
- $wordPool[$base] = ['base' => true,'done' => false,'apply' => false];
- }
- /**
- * 先查询字典名称
- */
- $dict_info = DictInfo::whereIn('id',$this->dictList)->select('id','shortname')->get();
- $dict_name = [];
- foreach ($dict_info as $key => $value) {
- # code...
- $dict_name[$value->id] = $value->shortname;
- }
- $caseman = new CaseMan();
- for ($i=0; $i < $deep; $i++) {
- $newBase = array();
- $newWords = [];
- foreach ($wordPool as $word => $info) {
- # code...
- if($info['done'] === false){
- $newWords[] = $word;
- $wordPool[$word]['done'] = true;
- }
- }
- $data = UserDict::whereIn('word',$newWords)
- ->whereIn('dict_id',$this->dictList)
- ->leftJoin('dict_infos', 'user_dicts.dict_id', '=', 'dict_infos.id')
- ->orderBy('confidence','desc')
- ->get();
- foreach ($data as $row) {
- # code...
- array_push($output,$row);
- if(!empty($row->parent) && !isset($wordPool[$row->parent]) ){
- //将parent 插入待查询列表
- $wordPool[$row->parent] = ['base' => true,'done' => false,'apply' => false];
- }
- }
- //处理查询结果中的拆分信息
- $newWordPart = array();
- foreach ($wordPool as $word => $info) {
- if(!empty($info['factors'])){
- $factors = \explode('+',$info['factors']);
- foreach ($factors as $factor) {
- # 将没有的拆分放入单词查询列表
- if(!isset($wordPool[$factor])){
- $wordPool[$factor] = ['base' => true,'done' => false,'apply' => false];
- }
- }
- }
- }
- }
- return $output;
- }
- /**
- *
- */
- private function langCheck($query,$lang){
- if($query===[]){
- return true;
- }else{
- if(in_array(strtolower($lang),$query)){
- return true;
- }else{
- $langFamily = explode('-',$lang)[0];
- foreach ($query as $value) {
- if(strpos($value,$langFamily) !== false){
- return true;
- }
- }
- }
- }
- return false;
- }
- private function wbwPreference($word,$field,$userId){
- $prefix = 'wbw-preference';
- $fieldMap = [
- 'type'=>1,
- 'grammar'=>2,
- 'meaning'=>3,
- 'factors'=>4,
- 'factorMeaning'=>5,
- 'parent'=>6,
- 'part'=>7,
- 'case'=>8,
- ];
- $fieldId = $fieldMap[$field];
- $myPreference = RedisClusters::get("{$prefix}/{$word}/{$fieldId}/{$userId}");
- if(!empty($myPreference)){
- Log::debug($word.'命中我的wbw-'.$field,['data'=>$myPreference]);
- return ['value'=>$myPreference,'status'=>5];
- }else{
- $myPreference = RedisClusters::get("{$prefix}/{$word}/3/0");
- if(!empty($myPreference)){
- Log::debug($word.'命中社区wbw-'.$field,['data'=>$myPreference]);
- return ['value'=>$myPreference,'status'=>5];
- }
- }
- //Log::debug($word.'未命中'.$field);
- return false;
- }
- /**
- * 自动查词
- *
- * @param \Illuminate\Http\Request $request
- * @return \Illuminate\Http\Response
- */
- public function store(Request $request)
- {
- //
- $user = AuthApi::current($request);
- if(!$user ){
- //未登录用户
- return $this->error(__('auth.failed'),401,401);
- }
- $startAt = microtime(true)*1000;
- // system regular
- $this->initSysDict();
- $channel = Channel::find($request->get('channel_id'));
- $orgData = $request->get('data');
- $lang = [];
- foreach ($request->get('lang',[]) as $value) {
- $lang[] = strtolower($value);
- }
- //句子中的单词
- $words = [];
- foreach ($orgData as $word) {
- # code...
- if( isset($word['type']) && $word['type']['value'] === '.ctl.'){
- continue;
- }
- if(!empty($word['real']['value'])){
- $words[] = $word['real']['value'];
- }
- }
- $result = $this->lookup($words,[],2);
- $indexed = $this->toIndexed($result);
- foreach ($orgData as $key => $word) {
- if( isset($word['type']) && $word['type']['value'] === '.ctl.'){
- continue;
- }
- if(empty($word['real']['value'])){
- continue;
- }
- $data = $word;
- $preference = $this->wbwPreference($word['real']['value'],'meaning',$user['user_id']);
- if($preference!==false){
- $data['meaning'] = $preference;
- }
- $preference = $this->wbwPreference($word['real']['value'],'factors',$user['user_id']);
- if($preference!==false){
- $data['factors'] = $preference;
- }
- $preference = $this->wbwPreference($word['real']['value'],'factorMeaning',$user['user_id']);
- if($preference!==false){
- $data['factorMeaning'] = $preference;
- }
- $preference = $this->wbwPreference($word['real']['value'],'case',$user['user_id']);
- if($preference!==false){
- $data['case'] = $preference;
- }
- if(isset($indexed[$word['real']['value']])){
- //parent
- $case = [];
- $parent = [];
- $factors = [];
- $factorMeaning = [];
- $meaning = [];
- $parent2 = [];
- $case2 = [];
- foreach ($indexed[$word['real']['value']] as $value) {
- //非base优先
- if(strstr($value->type,'base') === FALSE){
- $increment = 10;
- }else{
- $increment = 1;
- }
- //将全部结果加上得分放入数组
- if($value->type !== '.cp.'){
- $parent = $this->insertValue([$value->parent],$parent,$increment);
- }
- if(isset($data['case']) && $data['case']['status']<5){
- if(!empty($value->type) && $value->type !== ".cp."){
- $case = $this->insertValue([$value->type."#".$value->grammar],$case,$increment);
- }
- }
- if($data['factors']['status'] < 50){
- $factors = $this->insertValue([$value->factors],$factors,$increment);
- }
- if(isset($data['factorMeaning']) && $data['factorMeaning']['status'] < 50){
- $factorMeaning = $this->insertValue([$value->factormean],$factorMeaning,$increment,false);
- }
- if($data['meaning']['status'] < 50){
- if($this->langCheck($lang,$value->language)){
- $meaning = $this->insertValue(explode('$',$value->mean),$meaning,$increment,false);
- }
- }
- }
- if(count($case)>0){
- arsort($case);
- $first = array_keys($case)[0];
- $data['case'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
- }
- if(count($parent)>0){
- arsort($parent);
- $first = array_keys($parent)[0];
- $data['parent'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
- }
- if(count($factors)>0 && empty($data['factors']['value'])){
- arsort($factors);
- $first = array_keys($factors)[0];
- $data['factors'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
- }
- if(count($factorMeaning)>0){
- arsort($factorMeaning);
- $first = array_keys($factorMeaning)[0];
- $data['factorMeaning'] = ['value'=>$first==="_null"?"":$first,'status'=>5];
- }
- if(isset($data['factorMeaning']) && $data['factorMeaning']['status']<5){
- $wbwFactorMeaning = [];
- if(!empty($data['factors']['value'])){
- foreach (explode("+",$data['factors']['value']) as $factor) {
- $preference = $this->wbwPreference($factor,'meaning',$user['user_id']);
- if($preference!==false){
- $wbwFactorMeaning[] = $preference['value'];
- }else{
- $wbwFactorMeaning[] = $factor;
- }
- }
- }
- $data['factorMeaning'] = ['value'=>implode('+',$wbwFactorMeaning),'status'=>3];
- }
- if(empty($data['meaning']['value']) && !empty($data['parent']['value'])){
- if(isset($indexed[$data['parent']['value']])){
- foreach ($indexed[$data['parent']['value']] as $value) {
- //根据base 查找词意
- //非base优先
- $increment = 10;
- if($this->langCheck($lang,$value->language)){
- $meaning = $this->insertValue(explode('$',$value->mean),$meaning,$increment,false);
- }
- //查找词源
- if(!empty($value->parent) && $value->parent !== $value->word && strstr($value->type,"base") !== FALSE ){
- $parent2 = $this->insertValue([$value->grammar."$".$value->parent],$parent2,1,false);
- }
- }
- }
- }
- if(count($meaning)>0){
- arsort($meaning);
- $first = array_keys($meaning)[0];
- $data['meaning'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
- }
- if(count($parent2)>0){
- arsort($parent2);
- $first = explode("$",array_keys($parent2)[0]);
- $data['parent2'] = ['value'=>$first[1],'status'=>3];
- $data['grammar2'] = ['value'=>$first[0],'status'=>3];
- }
- }
- if(!isset($data['factorMeaning']['value']) ||
- $this->fmEmpty($data['factorMeaning']['value'])){
- $factorMeaning = [];
- //生成自动的拆分意思
- $autoMeaning = '';
- $currFactors = explode('+',$data['factors']['value']) ;
- $autoFM = [];
- foreach ($currFactors as $factor) {
- $subFactors = explode('-',$factor) ;
- $autoSubFM = [];
- foreach ($subFactors as $subFactor) {
- $preference = $this->wbwPreference($subFactor,'factorMeaning',$user['user_id']);
- if($preference !== false){
- $autoSubFM[] = $preference['value'];
- }else{
- $preference = $this->wbwPreference($subFactor,'meaning',$user['user_id']);
- if($preference !== false){
- $autoSubFM[] = $preference['value'];
- }else{
- $autoSubFM[] = '';
- }
- }
- }
- $autoFM[] = implode('-',$autoSubFM);
- $autoMeaning .= implode('',$autoSubFM);
- }
- $autoMeaning .= implode('',$autoFM);
- if(count($autoFM) > 0){
- $data['factorMeaning'] = ['value'=>implode('+',$autoFM),'status'=>3];
- if(empty($data['meaning']['value']) && !empty($autoMeaning)){
- $data['meaning'] = ['value'=>$autoMeaning,'status'=>3];
- }
- }
- }
- $orgData[$key] = $data;
- }
- return $this->ok($orgData);
- }
- private function fmEmpty($value){
- if(str_replace(['+','-',' '],'',$value) === ''){
- return true;
- }else{
- return false;
- }
- }
- /**
- * 自动查词
- *
- * @param string $sentId
- * @return \Illuminate\Http\Response
- */
- public function show(Request $request,string $sentId)
- {
- $startAt = microtime(true)*1000;
- $channel = Channel::find($request->get('channel_id'));
- //查询句子中的单词
- $sent = \explode('-',$sentId);
- $wbw = WbwTemplate::where('book',$sent[0])
- ->where('paragraph',$sent[1])
- ->whereBetween('wid',[$sent[2],$sent[3]])
- ->orderBy('wid')
- ->get();
- $words = [];
- foreach ($wbw as $row) {
- if($row->type !== '.ctl.' && !empty($row->real)){
- $words[] = $row->real;
- }
- }
- $result = $this->lookup($words,[],2);
- $indexed = $this->toIndexed($result);
- //生成自动填充结果
- $wbwContent = [];
- foreach ($wbw as $row) {
- $type = $row->type=='?'? '':$row->type;
- $grammar = $row->gramma=='?'? '':$row->gramma;
- $part = $row->part=='?'? '':$row->part;
- if(!empty($type) || !empty($grammar)){
- $case = "{$type}#$grammar";
- }else{
- $case = "";
- }
- $data = [
- 'sn'=>[$row->wid],
- 'word'=>['value'=>$row->word,'status'=>3],
- 'real'=> ['value'=>$row->real,'status'=>3],
- 'meaning'=> ['value'=>[],'status'=>3],
- 'type'=> ['value'=>$type,'status'=>3],
- 'grammar'=> ['value'=>$grammar,'status'=>3],
- 'case'=> ['value'=>$case,'status'=>3],
- 'style'=> ['value'=>$row->style,'status'=>3],
- 'factors'=> ['value'=>$part,'status'=>3],
- 'factorMeaning'=> ['value'=>'','status'=>3],
- 'confidence'=> 0.5
- ];
- if($row->type !== '.ctl.' && !empty($row->real)){
- if(isset($indexed[$row->real])){
- //parent
- $case = [];
- $parent = [];
- $factors = [];
- $factorMeaning = [];
- $meaning = [];
- $parent2 = [];
- $case2 = [];
- foreach ($indexed[$row->real] as $value) {
- //非base优先
- if(strstr($value->type,'base') === FALSE){
- $increment = 10;
- }else{
- $increment = 1;
- }
- //将全部结果加上得分放入数组
- $parent = $this->insertValue([$value->parent],$parent,$increment);
- $case = $this->insertValue([$value->type."#".$value->grammar],$case,$increment);
- $factors = $this->insertValue([$value->factors],$factors,$increment);
- $factorMeaning = $this->insertValue([$value->factormean],$factorMeaning,$increment);
- $meaning = $this->insertValue(explode('$',$value->mean),$meaning,$increment,false);
- }
- if(count($case)>0){
- arsort($case);
- $first = array_keys($case)[0];
- $data['case'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
- }
- if(count($parent)>0){
- arsort($parent);
- $first = array_keys($parent)[0];
- $data['parent'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
- }
- if(count($factors)>0){
- arsort($factors);
- $first = array_keys($factors)[0];
- $data['factors'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
- }
- if(count($factorMeaning)>0){
- arsort($factorMeaning);
- $first = array_keys($factorMeaning)[0];
- $data['factorMeaning'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
- }
- //根据base 查找词意
- if(!empty($data['parent'])){
- if(isset($indexed[$data['parent']['value']])){
- foreach ($indexed[$data['parent']['value']] as $value) {
- //非base优先
- $increment = 10;
- $meaning = $this->insertValue(explode('$',$value->mean),$meaning,$increment,false);
- }
- }else{
- //Log::error("no set parent".$data['parent']['value']);
- }
- }
- if(count($meaning)>0){
- arsort($meaning);
- $first = array_keys($meaning)[0];
- $data['meaning'] = ['value'=>$first==="_null"?"":$first,'status'=>3];
- }
- }
- }
- $wbwContent[] = $data;
- }
- $endAt = microtime(true)*1000;
- return $this->ok(["rows"=>$wbwContent,
- "count"=>count($wbwContent),
- "time"=>(int)($endAt-$startAt)]);
- }
- private function toIndexed($words){
- //转成索引数组
- $indexed = [];
- foreach ($words as $key => $value) {
- # code...
- $indexed[$value->word][] = $value;
- }
- return $indexed;
- }
- /**
- * $empty:是否允许空值
- */
- private function insertValue($value,$container,$increment,$empty=true){
- foreach ($value as $one) {
- if($empty === false){
- if($this->fmEmpty($one)){
- break;
- }
- }
- $one=trim($one);
- $key = $one;
- if(empty($key)){
- $key = '_null';
- }
- if(isset($container[$key])){
- $container[$key] += $increment;
- }else{
- $container[$key] = $increment;
- }
- }
- return $container;
- }
- /**
- * Update the specified resource in storage.
- *
- * @param \Illuminate\Http\Request $request
- * @param \App\Models\UserDict $userDict
- * @return \Illuminate\Http\Response
- */
- public function update(Request $request, UserDict $userDict)
- {
- //
- }
- /**
- * Remove the specified resource from storage.
- *
- * @param \App\Models\UserDict $userDict
- * @return \Illuminate\Http\Response
- */
- public function destroy(UserDict $userDict)
- {
- //
- }
- }
|