瀏覽代碼

Merge pull request #759 from visuddhinanda/laravel

✨ 译文搜索
visuddhinanda 4 年之前
父節點
當前提交
9c7cc6ce60

+ 6 - 2
app/Http/Controllers/DhammaTermController.php

@@ -116,6 +116,10 @@ class DhammaTermController extends Controller
             return $this->error($validator);
         } else {
             #查询重复的
+            /*
+            重复判定:
+            一个channel下面word+tag+language 唯一
+            */
             $table = DhammaTerm::where('owner', $_COOKIE["user_uid"])
                     ->where('word',$request->get("word"))
                     ->where('tag',$request->get("tag"));
@@ -130,7 +134,7 @@ class DhammaTermController extends Controller
             if($isDoesntExist){
                 #不存在插入数据
                 $term = new DhammaTerm;
-                $term->id=$snowflake->id();
+                $term->id=app('snowflake')->id();
                 $term->guid=Str::uuid();
                 $term->word=$request->get("word");
                 $term->meaning=$request->get("meaning");
@@ -143,7 +147,7 @@ class DhammaTermController extends Controller
             // store
             /*
             $data = $request->all();
-            $data['id'] = $snowflake->id();
+            $data['id'] = app('snowflake')->id();
             $data['guid'] = Str::uuid();
             DhammaTerm::create($data);
             */

+ 186 - 0
app/Http/Controllers/SentenceController.php

@@ -0,0 +1,186 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Models\Sentence;
+use Illuminate\Http\Request;
+
+class SentenceController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index(Request $request)
+    {
+        $result=false;
+		$indexCol = ['id','book_id','paragraph','word_start','word_end','content','channel_uid','updated_at'];
+
+		switch ($request->get('view')) {
+            case 'fulltext':
+                if(isset($_COOKIE['user_uid'])){
+                    $userUid = $_COOKIE['user_uid'];
+                }
+                $key = $request->get('key');
+                if(empty($key)){
+			        return $this->error("没有关键词");
+                }
+                $table = Sentence::select($indexCol)
+								  ->where('content','like', '%'.$key.'%')
+                                  ->where('editor_uid',$userUid);
+				if(!empty($request->get('order')) && !empty($request->get('dir'))){
+					$table->orderBy($request->get('order'),$request->get('dir'));
+				}else{
+					$table->orderBy('updated_at','desc');
+				}
+				$count = $table->count();
+				if(!empty($request->get('limit'))){
+					$offset = 0;
+					if(!empty($request->get("offset"))){
+						$offset = $request->get("offset");
+					}
+					$table->skip($offset)->take($request->get('limit'));
+				}
+				$result = $table->get();
+                break;
+			case 'user':
+				# code...
+                $userUid = $_COOKIE['user_uid'];
+                $search = $request->get('search');
+				$table = Sentence::select($indexCol)
+									->where('owner', $userUid);
+				if(!empty($search)){
+					$table->where('word', 'like', $search."%")
+                          ->orWhere('word_en', 'like', $search."%")
+                          ->orWhere('meaning', 'like', "%".$search."%");
+				}
+				if(!empty($request->get('order')) && !empty($request->get('dir'))){
+					$table->orderBy($request->get('order'),$request->get('dir'));
+				}else{
+					$table->orderBy('updated_at','desc');
+				}
+				$count = $table->count();
+				if(!empty($request->get('limit'))){
+					$offset = 0;
+					if(!empty($request->get("offset"))){
+						$offset = $request->get("offset");
+					}
+					$table->skip($offset)->take($request->get('limit'));
+				}
+				$result = $table->get();
+				break;
+			case 'word':
+				$result = Sentence::select($indexCol)
+									->where('word', $request->get("word"))
+									->orderBy('created_at','desc')
+									->get();
+				break;
+            case 'hot-meaning':
+                $key='term/hot_meaning';
+                $value = Cache::get($key, function()use($request) {
+                    $hotMeaning=[];
+                    $words = Sentence::select('word')
+                                ->where('language',$request->get("language"))
+                                ->groupby('word')
+                                ->get();
+                    
+                    foreach ($words as $key => $word) {
+                        # code...
+                        $result = Sentence::select(DB::raw('count(*) as word_count, meaning'))
+                                ->where('language',$request->get("language"))
+                                ->where('word',$word['word'])
+                                ->groupby('meaning')
+                                ->orderby('word_count','desc')
+                                ->first();
+                        if($result){
+                            $hotMeaning[]=[
+                                'word'=>$word['word'],
+                                'meaning'=>$result['meaning'],
+                                'language'=>$request->get("language"),
+                                'owner'=>'',
+                            ];
+                        }
+                    }
+                    Cache::put($key, $hotMeaning, 3600);
+                    return $hotMeaning;
+                });
+                return $this->ok(["rows"=>$value,"count"=>count($value)]);
+                break;
+			default:
+				# code...
+				break;
+		}
+		if($result){
+			return $this->ok(["rows"=>$result,"count"=>$count]);
+		}else{
+			return $this->error("没有查询到数据");
+		}
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function create()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return \Illuminate\Http\Response
+     */
+    public function store(Request $request)
+    {
+        //
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  \App\Models\Sentence  $sentence
+     * @return \Illuminate\Http\Response
+     */
+    public function show(Sentence $sentence)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  \App\Models\Sentence  $sentence
+     * @return \Illuminate\Http\Response
+     */
+    public function edit(Sentence $sentence)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\Models\Sentence  $sentence
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, Sentence $sentence)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\Models\Sentence  $sentence
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(Sentence $sentence)
+    {
+        //
+    }
+}

+ 112 - 0
public/app/search/sentence.js

@@ -0,0 +1,112 @@
+var dict_pre_searching = false;
+var dict_pre_search_curr_word = "";
+var dict_search_xml_http = null;
+var _key_word = "";
+var _page = 0;
+var _filter_word = new Array();
+var _bookId = new Array();
+
+$(document).ready(function () {
+	paliword_search(_key_word);
+});
+
+function paliword_search(keyword, words = new Array(), book = new Array()) {
+	$.getJSON(
+		"/api/v2/sentence",
+		{
+			view: "fulltext",
+			key: keyword,
+			page: _page,
+		},
+		function (data) {
+			let result = data;
+			console.log(result.time);
+			let html = "";
+			html += "<div>查询到 "+result.data.rows.length+" 条结果 "+"</div>";
+			for (const iterator of result.data.rows) {
+				html += render_word_result(iterator);
+			}
+			$("#contents").html(html);
+
+		}
+	);
+}
+
+
+function highlightWords(line, word) {
+	if (line && line.length > 0) {
+		let output = line;
+		for (const iterator of word) {
+			let regex = new RegExp("(" + iterator + ")", "gi");
+			output = output.replace(regex, "<highlight>$1</highlight>");
+		}
+		return output;
+	} else {
+		return "";
+	}
+}
+function render_word_result(worddata) {
+	let html = "";
+	html += "<div class='search_result'>";
+
+	html += "<div class='title'>";
+	html +=
+		"<a href='../article/index.php?view=sent&book=" +
+		worddata.book_id +
+		"&par=" +
+		worddata.paragraph +
+        "&start=" +
+		worddata.word_start +
+        "&end=" +
+		worddata.word_end +
+		"' target='_blank'>";
+	html += "Open" + "</a></div>";
+
+	let highlightStr;
+
+	highlightStr= highlightWords(worddata.content, _key_word);
+
+
+	html += "<div class='wizard_par_div'>" + highlightStr + "</div>";
+	html += "<div class='path'>" + worddata.book_id + "-" + worddata.paragraph + "-" + worddata.word_start + "-" + worddata.word_end + "</div>";
+	html += "</div>";
+	return html;
+}
+
+
+function gotoPage(index) {
+	_page = index;
+	paliword_search(_key_word, _filter_word, _bookId);
+}
+
+
+function dict_input_change(obj) {
+	search_pre_search(obj.value);
+}
+
+
+
+function search_input_onfocus() {
+	if ($("#dict_ref_search_input").val() == "") {
+		//search_show_history();
+	}
+}
+function search_input_keyup(e, obj) {
+	var keynum;
+	var keychar;
+	var numcheck;
+
+	if (window.event) {
+		// IE
+		keynum = e.keyCode;
+	} else if (e.which) {
+		// Netscape/Firefox/Opera
+		keynum = e.which;
+	}
+	var keychar = String.fromCharCode(keynum);
+	if (keynum == 13) {
+		//search_search(obj.value);
+		window.location.assign("../search/sentence.php?key=" + obj.value);
+	}
+}
+

+ 244 - 0
public/app/search/sentence.php

@@ -0,0 +1,244 @@
+<?PHP
+include "../pcdl/html_head.php";
+?>
+<body>
+<link type="text/css" rel="stylesheet" href="../search/search.css"/>
+
+<?php
+	require_once("../pcdl/head_bar.php");
+	require_once("../search/toobar.php");
+?>
+    <style>
+        #dt_pali , #dt_pali_1{
+            border-bottom: 2px solid var(--link-hover-color);
+        }
+        #index_list{
+			display:flex;
+		}
+
+		.main_view{
+		padding: 0 1em;
+		max-width: 1280px;
+		margin-left: auto;
+		margin-right: auto;
+	}
+
+	.fun_frame {
+		border-bottom: 1px solid gray;
+		margin-right: 10px;
+		margin-bottom: 10px;
+	}
+	.fun_frame .title{
+		padding:6px;
+		font-weight: 700;
+	}
+	.fun_frame>.content{
+		padding:6px;
+		overflow-y: scroll;
+	}
+	
+	.fixed{
+		position:fixed;
+		right: 0;
+    	top: 0;
+	}
+	.when_right_fixed{
+		padding-right:20em;
+	}
+
+
+	#contents_view{
+		display:flex;
+	}
+	#contents_div{
+		flex:7;
+		max-width: 70vw;
+	}
+	#contents{
+
+	}
+	#contents li{
+		white-space: normal;
+	}
+	#right_pannal{
+		flex:3;
+		max-width:20em;
+	}
+	#head_bar{
+		height:unset;
+	}
+	#contents_foot{
+		margin-bottom: 70vh;
+	}
+
+	#pre_search_word_content{
+		display:block;
+	}
+	@-webkit-keyframes spin {
+	from {
+		-webkit-transform: rotate(0deg);
+	}
+	to {
+		-webkit-transform: rotate(360deg);
+	}
+}
+
+@keyframes spin {
+	from {
+		transform: rotate(0deg);
+	}
+	to {
+		transform: rotate(360deg);
+	}
+}
+.icon_spin {
+	-webkit-animation: spin 2.5s linear infinite;
+	animation: spin 2.5s linear infinite;
+}
+
+    </style>
+    <style  media="screen and (max-width:800px)">
+		#index_list{
+			display:block;
+		}
+		#contents_view{
+		display:block;
+	}
+	#dict_ref_search_result{
+		display:none;
+	}
+	#footer_nav{
+    display: none;
+}
+#contents_foot {
+    margin-bottom: 70vh;
+    position: absolute;
+    left: 0;
+	width: 100vw;
+	margin-bottom: 10vh;
+}
+#contents_nav{
+	overflow-x: scroll;
+}
+.page_nav{
+	display:flex;
+}
+.foot_div{
+	margin-top:10vh;
+}
+	</style>
+	<script language="javascript" src="sentence.js"></script>
+	<script>
+		<?php
+		if(isset($_GET["key"])){
+			echo " _key_word = '{$_GET["key"]}';";
+		}
+		if(isset($_GET["page"])){
+			echo " _page = '{$_GET["page"]}';";
+		}		
+		?>
+	</script>
+
+	<div id="main_view" class="main_view">
+
+<div id="contents_view">
+	<div id="contents_div" style="padding: 0 1em 0 30px;">
+		<div id="contents" >
+			<div id="index_list">
+				<div style="flex:3;margin:12px;">
+					<div class="card" style="padding:10px;">
+						<div>最近搜索</div>
+						<div id="title_histray"></div>
+					</div>
+				</div>
+				<div style="flex:3;margin:12px;">
+					<div class="card" style="padding:10px;">
+						<div>热搜</div>
+						<div id="title_hot"></div>
+					</div>
+				</div>
+				<div style="flex:3;margin:12px;">
+					<div class="card" style="padding:10px;">
+						<div id="guide_title_search_index"></div>
+					</div>
+				</div>
+			</div>
+			<div style="text-align: center;display:none;">
+				<svg class='icon_spin' style='fill: saddlebrown;height: 4em;width: 4em; '>
+					<use xlink='http://www.w3.org/1999/xlink' href='../studio/svg/icon.svg#dhammacakkha'></use>
+				</svg>
+			</div>
+		</div>
+		<div id="contents_foot">
+			<div id="contents_nav" style="">
+			</div>
+		</div>
+	</div>
+
+	<div id="right_pannal">
+		<div class="fun_frame">
+			<div style="display:flex;justify-content: space-between;">
+				<div class="title"><?php echo $_local->gui->real_declension; ?></div>
+				<div id="case_tools" style="display:flex;">
+					<div class="select_button" style="margin:auto 0"  onclick="onWordFilterStart()"><?php echo $_local->gui->select; ?></div>
+					<div class="filter" >
+						<button onclick='word_search_filter()'><?php echo $_local->gui->filter; ?></button>
+						<button onclick='filter_cancel()'><?php echo $_local->gui->cancel; ?></button>
+					</div>
+				</div>
+			</div>
+			<div id = "case_content" class="content" style="max-height:20em;">
+			</div>
+		</div>
+		<div class="fun_frame">
+			<div style="display:flex;justify-content: space-between;">
+				<div class="title"><?php echo $_local->gui->book_name.$_local->gui->list; ?></div>
+				<div id="book_tools" style="display:flex;">
+					<div class="select_button" style="margin:auto 0" onclick="onBookFilterStart()"><?php echo $_local->gui->select; ?></div>
+					<div class="filter">
+						<button onclick='book_search_filter()'><?php echo $_local->gui->filter; ?></button>
+						<button onclick='book_filter_cancel()'><?php echo $_local->gui->cancel; ?></button>
+					</div>
+				</div>
+			</div>
+			<div id="book_list" class="content" >
+			</div>
+		</div>
+	</div>
+</div>
+
+</div>
+
+
+	<div id="dict_ref_search_result" style="background-color:white;color:black;display:none;">
+	</div>
+
+
+    <div id="index_list">
+			<div style="flex:3;margin:12px;">
+				<div class="card" style="padding:10px;">
+					<div><?php echo $_local->gui->search.$_local->gui->history; ?></div>
+                    <div id="search_histray"></div>
+				</div>
+			</div>
+			<div style="flex:3;margin:12px;">
+				<div class="card" style="padding:10px;">
+					<div><?php echo $_local->gui->top_search; ?></div>
+                    <div id="title_hot"></div>
+				</div>
+			</div>
+			<div style="flex:3;margin:12px;">
+				<div class="card" style="padding:10px;">
+                    <div id="guide_pali_search_index"></div>
+				</div>
+			</div>
+	</div>
+    <script>
+    search_show_history();
+    guide_get("pali_search_index");
+    </script>
+
+<?php
+include "../pcdl/html_foot.php";
+?>
+

+ 2 - 0
routes/api.php

@@ -4,6 +4,7 @@ use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Route;
 use App\Http\Controllers\WbwTemplateController;
 use App\Http\Controllers\DhammaTermController;
+use App\Http\Controllers\SentenceController;
 /*
 |--------------------------------------------------------------------------
 | API Routes
@@ -22,4 +23,5 @@ Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
 Route::group(['prefix' => 'v2'],function(){
 	Route::apiResource('wbw_templates',WbwTemplateController::class);
 	Route::apiResource('terms',DhammaTermController::class);
+	Route::apiResource('sentence',SentenceController::class);
 });