visuddhinanda пре 5 година
родитељ
комит
a31dbb50ff

+ 18 - 8
app/channal/function.php

@@ -1,5 +1,6 @@
 <?php
 require_once "../path.php";
+require_once "../share/function.php";
 
 function channel_get_title($id)
 {
@@ -19,11 +20,10 @@ function channel_get_title($id)
 
 class Channal
 {
-    public $dbh;
+    private $dbh;
     public function __construct() {
-        $dns = ""._FILE_DB_CHANNAL_;
-        $this->dbh = new PDO($dns, "", "",array(PDO::ATTR_PERSISTENT=>true));
-        $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);  
+        $this->dbh = new PDO(_FILE_DB_CHANNAL_, "", "",array(PDO::ATTR_PERSISTENT=>true));
+        $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
     }
 
     public function getChannal($id){
@@ -41,15 +41,25 @@ class Channal
 	
 	public function getPower($id){
 		#查询用户对此channel是否有权限		
-		if(!isset($_COOKIE["userid"])){
-			return 0;
-		}
+
 		$channelPower = 0;
 		$query = "SELECT owner,status FROM channal WHERE id=? and status>0 ";
 		$stmt = $this->dbh->prepare($query);
 		$stmt->execute(array($id));
 		$channel = $stmt->fetch(PDO::FETCH_ASSOC);
 		if($channel){
+			if(!isset($_COOKIE["userid"])  ){
+				#未登录用户
+				if($channel["status"]==30){
+					#全网公开有建议权限
+					return 10;
+				}
+				else{
+					#其他状态没有任何权限
+					return 0;
+				}
+				
+			}
 			if($channel["owner"]==$_COOKIE["userid"]){
 				return 30;
 			}
@@ -58,7 +68,7 @@ class Channal
 				$channelPower = 10;
 			}
 		}
-
+		#查询共享权限,如果共享权限更大,覆盖上面的的
 		$sharePower = share_get_res_power($_COOKIE["userid"],$id);
 		if($sharePower>$channelPower){
 			$channelPower=$sharePower;

+ 1 - 0
app/dict/comp_csv.php

@@ -59,6 +59,7 @@ while($word = $redis->hGet("pali://wordindex.hash",$start))
         foreach ($arrword as $oneword) {
 			$result = array(); //全局变量,递归程序的输出容器
 			$min_result = 1;
+			
 			if(mb_strlen($oneword)>35){
 				mySplit2($oneword, 0, true, 0.8, 0.9, 0, true, false);
 			}

+ 1 - 1
app/install/db_insert_sentence.php

@@ -43,7 +43,7 @@ function wordStyle($word, $style)
 
         case 'note':
             # vir note...
-            return "<note>" . $word . "</note>";
+            return "<n>" . $word . "</n>";
             break;
         case 'paranum':
             # vir note...

+ 18 - 8
app/install/step5.php

@@ -150,24 +150,29 @@ $db = $dbfile[5];
 echo '<div style="padding:10px;margin:5px;border-bottom: 1px solid gray;display:flex;">';
 echo '<div style="flex:5;">' . $db[0] . '</div>';
 echo '<div style="flex:3;">';
+/*
 if (!file_exists($db[0])) {
     echo "<span style='color:red;'>数据库不存在</span>";
     echo "</div>";
     echo '<div style="flex:2;"><a href="step5.php?index=5">建立</a></div>';
-} else {
+} else 
+*/
+{
     echo "<span style='color:green;'>已存在</span>";
     echo "</div>";
     echo '<div style="flex:2;"><a href="step5.php?index=5">清空</a><span style="color:red;">注意!此操作将删除原数据库中所有数据!</span></div>';
 }
 echo "</div>";
 
-if (file_exists(_FILE_DB_PALI_SENTENCE_)) {
+//if (file_exists(_FILE_DB_PALI_SENTENCE_)) 
+{
     echo "Pali句子数据库已经存在<br>";
     echo '<a href="db_insert_sentence.php">重新生成</a>';
-} else {
-    echo "Pali句子数据库不存在<br>";
-    echo '<a href="db_insert_sentence.php">生成</a>';
-}
+} 
+//else {
+//    echo "Pali句子数据库不存在<br>";
+//    echo '<a href="db_insert_sentence.php">生成</a>';
+//}
 ?>
 </div>
 
@@ -222,13 +227,18 @@ if (!file_exists($db[0])) {
 }
 echo "</div>";
 
-if (file_exists(_FILE_DB_PALITEXT_)) {
+//if (file_exists(_FILE_DB_PALITEXT_)) 
+{
     echo "标题索引数据库已经存在<br>";
     echo '<a href="db_update_toc.php" target="_blank">更新</a><br>';
-} else {
+} 
+/*
+else 
+{
     echo "标题索引数据库不存在<br>";
     echo '<div style="flex:2;"><a href="step5.php?index=' . $i . '">建立</a></div>';
 }
+*/
 echo "<a href = '" . _DIR_LOG_ . "/db_update_title.log" . "' target='_blank'>view Log</a>"
 ?>
 </div>

+ 44 - 41
app/pcdl/css/color_day.css

@@ -1,42 +1,45 @@
 :root {
-    --bg-color: #FFFFFF;
-    --main-color: #1E1E1E;
-    --main-color1: #626262;
-    --main-color1: #626262;
-    --btn-color: #DFDFDF;
-    --btn-bg-color: #DFDFDF;
-    --btn-border-color: #7D7D7D;
-    --btn-hover-color: #FFFFFF;
-    --btn-hover-bg-color: #494949;
-    --btn-border-line-color: #7D7D7D --input-bg-color: #424242;
-    --select-bg-color: #424242;
-    --drop-bg-color: #EBEBEB;
-    --link-color: #6baaff;
-    --link-hover-color: #1F7DF5;
-    --border-line-color: #C5C7CB;
-    --border: 1px solid var(--border-line-color);
-    --border-shadow: #D2D2D2;
-    --shadow-color: rgba(0, 0, 0, 0.28);
-    --mean-user-color: #F9468F;
-    --tool-bg-color: #333333;
-    --tool-color: #FFFFFF;
-    --tool-bt-bg-color: #222222;
-    --tool-bt-color: #FFFFFF;
-    --tool-bt-bg-hover-color: #545454;
-    --tool-bt-hover-color: #FFFFFF;
-    --tool-bt-border-line-color: #C5C7CB;
-    --tool-bg-color1: #ebebeb;
-    --tool-color1: rgb(49, 49, 49);
-    --tool-bt-bg-color1: #222222;
-    --tool-bt-color1: #FFFFFF;
-    --tool-bt-bg-hover-color1: #545454;
-    --tool-bt-hover-color1: #FFFFFF;
-    --tool-bt-border-line-color1: #C5C7CB;
-    --tool-title-color: #1B1C1C;
-    --tool-line-color: #A4A4A4;
-    --tool-link-hover-color: #A1C9FF;
-    --nocolor: rgba(255, 255, 255, 0);
-    --box-bg-color1: #545454;
-    --box-bg-color2: #545454;
-    --info-bg-color: rgba(255, 255, 255, 0.8);
-}
+	--bg-color: #ffffff;
+	--main-color: #1e1e1e;
+	--main-color1: #626262;
+	--main-color1: #626262;
+	--btn-color: #dfdfdf;
+	--btn-bg-color: #dfdfdf;
+	--btn-border-color: #7d7d7d;
+	--btn-hover-color: #ffffff;
+	--btn-hover-bg-color: #494949;
+	--btn-border-line-color: #7d7d7d;
+	--input-bg-color: #424242;
+	--select-bg-color: #424242;
+	--drop-bg-color: #ebebeb;
+	--link-color: #6baaff;
+	--link-hover-color: #1f7df5;
+	--border-line-color: #c5c7cb;
+	--border: 1px solid var(--border-line-color);
+	--border-shadow: #d2d2d2;
+	--shadow-color: rgba(0, 0, 0, 0.28);
+	--mean-user-color: #f9468f;
+	--tool-bg-color: #333333;
+	--tool-color: #ffffff;
+	--tool-bt-bg-color: #222222;
+	--tool-bt-color: #ffffff;
+	--tool-bt-bg-hover-color: #545454;
+	--tool-bt-hover-color: #ffffff;
+	--tool-bt-border-line-color: #c5c7cb;
+	--tool-bg-color1: #ebebeb;
+	--tool-color1: rgb(49, 49, 49);
+	--tool-bt-bg-color1: #222222;
+	--tool-bt-color1: #ffffff;
+	--tool-bt-bg-hover-color1: #545454;
+	--tool-bt-hover-color1: #ffffff;
+	--tool-bt-border-line-color1: #c5c7cb;
+	--tool-title-color: #1b1c1c;
+	--tool-line-color: #a4a4a4;
+	--tool-link-hover-color: #a1c9ff;
+	--nocolor: rgba(255, 255, 255, 0);
+	--box-bg-color1: #545454;
+	--box-bg-color2: #545454;
+	--info-bg-color: rgba(255, 255, 255, 0.8);
+	--booka: #ddddff;
+	--bookx: #e4e4e4;
+}

+ 21 - 8
app/pcdl/css/style.css

@@ -2685,13 +2685,12 @@ th {
 .tooltip {
 	position: relative;
 	display: inline;
-	cursor: help;
 }
 
 .tooltip .tooltiptext {
 	visibility: hidden;
 	position: absolute;
-	width: 100px;
+	min-width: 80px;
 	background-color: #555;
 	color: #fff;
 	text-align: center;
@@ -2699,18 +2698,32 @@ th {
 	border-radius: 6px;
 	z-index: 1;
 	opacity: 0;
-	transition: opacity 0.6s;
-}
-
-.tooltip:hover {
-	color: red;
+	transition: all 0.6s;
 }
 
 .tooltip:hover .tooltiptext {
 	visibility: visible;
 	opacity: 1;
 }
-
+.tooltip-top {
+	top: -120%;
+	left: 50%;
+	margin-left: -40px;
+	transition: all 0.6s;
+}
+.tooltip:hover .tooltip-top {
+	top: -150%;
+}
+.tooltip .tooltip-top::after {
+	content: " ";
+	position: absolute;
+	top: 100%; /* 提示工具底部 */
+	left: 50%;
+	margin-left: -5px;
+	border-width: 5px;
+	border-style: solid;
+	border-color: #555 transparent transparent transparent;
+}
 .tooltip-bottom {
 	top: 100%;
 	left: 50%;

+ 29 - 0
app/public/js/comm.js

@@ -156,5 +156,34 @@ function copy_to_clipboard(strInput) {
 	document.body.removeChild(input);
 }
 
+function getPassDataTime(time) {
+	let currDate = new Date();
+
+	let pass = currDate.getTime() - time;
+	let strPassTime = "";
+	if (pass < 60 * 1000) {
+		//一分钟内
+		strPassTime = Math.floor(pass / 1000) + "秒前";
+	} else if (pass < 3600 * 1000) {
+		//一小时内
+		strPassTime = Math.floor(pass / 1000 / 60) + "分钟前";
+	} else if (pass < 3600 * 24 * 1000) {
+		//一天内
+		strPassTime = Math.floor(pass / 1000 / 3600) + "小时前";
+	} else if (pass < 3600 * 24 * 7 * 1000) {
+		//一周内
+		strPassTime = Math.floor(pass / 1000 / 3600 / 24) + "天前";
+	} else if (pass < 3600 * 24 * 30 * 1000) {
+		//一个月内
+		strPassTime = Math.floor(pass / 1000 / 3600 / 24 / 7) + "周前";
+	} else if (pass < 3600 * 24 * 365 * 1000) {
+		//一年内
+		strPassTime = Math.floor(pass / 1000 / 3600 / 24 / 30) + "月前";
+	} else {
+		//超过一年
+		strPassTime = Math.floor(pass / 1000 / 3600 / 24 / 365) + "年前";
+	}
+	return strPassTime;
+}
 //所有页面都需要在加载的的时候设置浏览器时区
 setTimeZone();

+ 1 - 0
app/redis/redis.json

@@ -2,4 +2,5 @@
 	{ "key": "ref_dict_idx", "type": "hash", "valid": true, "description": "参考字典索引" },
 	{ "key": "pali_sent_*", "type": "string", "valid": false, "description": "巴利句子列表" },
 	{ "key": "pali://sent/*", "type": "hash", "valid": true, "description": "巴利句子列表" }
+	{ "key": "sent://*/*", "type": "hash", "valid": true, "description": "译文句子列表 第一个星号channel 第二个是句子id book-para-start-end" }
 ]

+ 22 - 12
app/studio/css/style.css

@@ -3042,13 +3042,13 @@ th {
 .tooltip {
 	position: relative;
 	display: inline;
-	zcursor: help;
+	cursor: help;
 }
 
 .tooltip .tooltiptext {
 	visibility: hidden;
 	position: absolute;
-	width: 100px;
+	min-width: 80px;
 	background-color: #555;
 	color: #fff;
 	text-align: center;
@@ -3056,18 +3056,32 @@ th {
 	border-radius: 6px;
 	z-index: 1;
 	opacity: 0;
-	transition: opacity 0.6s;
-}
-
-.tooltip:hover {
-	color: red;
+	transition: all 0.6s;
 }
 
 .tooltip:hover .tooltiptext {
 	visibility: visible;
 	opacity: 1;
 }
-
+.tooltip-top {
+	top: -150%;
+	left: 50%;
+	margin-left: -40px;
+	transition: all 0.6s;
+}
+.tooltip:hover .tooltip-top {
+	top: -180%;
+}
+.tooltip .tooltip-top::after {
+	content: " ";
+	position: absolute;
+	top: 100%; /* 提示工具底部 */
+	left: 50%;
+	margin-left: -5px;
+	border-width: 5px;
+	border-style: solid;
+	border-color: #555 transparent transparent transparent;
+}
 .tooltip-bottom {
 	top: 100%;
 	left: 50%;
@@ -3115,10 +3129,6 @@ th {
 	color: #555;
 }
 
-.tooltip_menu:hover {
-	color: red;
-}
-
 .tooltip_menu:hover .tooltiptext {
 	visibility: visible;
 	opacity: 1;

+ 493 - 53
app/term/note.js

@@ -346,13 +346,26 @@ function render_channal_list(channalinfo) {
 
 	//  output += "<a href='../wiki/wiki.php?word=" + _word;
 	//  output += "&channal=" + channalinfo.id + "' >";
+	switch (parseInt(channalinfo.status)) {
+		case 10:
+			output += "🔐";
+			break;
+		case 20:
+			output += "🌐";
+			break;
+		case 30:
+			output += "🌐";
+			break;
+		default:
+			break;
+	}
 	if (parseInt(channalinfo.power) >= 20) {
-		if (parseInt(channalinfo.power) != 30) {
-			output += "[写]";
+		//if (parseInt(channalinfo.power) != 30)
+		{
+			output += "✏️";
 		}
-	} else {
-		output += "[读]";
 	}
+	//✋
 	output += "<a onclick=\"set_channal('" + channalinfo.id + "')\">";
 
 	output += channalinfo["name"];
@@ -521,7 +534,8 @@ function note_json_html(in_json) {
 
 	//output += "<div id='translation_div'>";
 	for (const iterator of in_json.translation) {
-		output += render_one_sent_tran(in_json.book, in_json.para, in_json.begin, in_json.end, iterator);
+		output += render_one_sent_tran_a(iterator);
+		//output += render_one_sent_tran(in_json.book, in_json.para, in_json.begin, in_json.end, iterator);
 	}
 	//所选全部译文结束
 	//output += "</div>";
@@ -581,6 +595,259 @@ function note_json_html(in_json) {
 	//出处路径结束
 	return output;
 }
+function sent_tran_edit(obj) {
+	let jqObj = $(obj);
+	while (!jqObj.hasClass("sent_tran")) {
+		jqObj = jqObj.parent();
+		if (!jqObj) {
+			return;
+		}
+	}
+	if (jqObj.hasClass("edit_mode")) {
+		jqObj.removeClass("edit_mode");
+	} else {
+		$(".sent_tran").removeClass("edit_mode");
+		jqObj.addClass("edit_mode");
+	}
+}
+
+function sent_pr_merge(id) {
+	$.post(
+		"../usent/sent_pr_merge.php",
+		{
+			id: id,
+		},
+		function (data) {
+			let result = JSON.parse(data);
+			if (result.status > 0) {
+				alert("error" + result.message);
+			} else {
+				ntf_show("成功采纳");
+			}
+		}
+	);
+}
+function render_one_sent_tran_a(iterator) {
+	let mChannel = get_channel_by_id(iterator.channal);
+
+	let tranText;
+	let sid = iterator.book + "-" + iterator.para + "-" + iterator.begin + "-" + iterator.end;
+	if (iterator.text == "") {
+		tranText =
+			"<span style='color:var(--border-line-color);'>" +
+			iterator.channalinfo.name +
+			"-" +
+			iterator.channalinfo.lang +
+			"</span>";
+	} else {
+		//note_init处理句子链接
+		tranText = note_init(term_std_str_to_tran(iterator.text, iterator.channal, iterator.editor, iterator.lang));
+	}
+	let html = "";
+	html += "<div class='sent_tran ";
+	if (typeof iterator.is_pr != "undefined" && iterator.is_pr == true) {
+		html += " pr ";
+	}
+	html += "' channel='" + iterator.channal + "' sid='" + sid + "'>";
+	html += "<div class='sent_tran_inner'>";
+	html += '<div class="tool_bar">';
+	html += '	<div class="right">';
+	//句子菜单
+	html += '<div class="pop_menu">';
+
+	if (typeof iterator.is_pr != "undefined" && iterator.is_pr == true) {
+		//在pr 列表中的译文
+		if (typeof iterator.is_pr_editor != "undefined" && iterator.is_pr_editor == true) {
+			//提交人
+			//修改按钮
+			html += "<button class='icon_btn tooltip' onclick='sent_pr_edit(this)'>";
+			html += '<svg class="icon" >';
+			html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#ic_mode_edit"></use>';
+			html += "</svg>";
+			html += "<span class='tooltiptext tooltip-top'>";
+			html += gLocal.gui.modify;
+			html += "</span>";
+			html += "</button>";
+
+			//删除按钮
+			html += "<button class='icon_btn tooltip' onclick='sent_pr_del(this)'>";
+			html += '<svg class="icon" >';
+			html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#ic_delete"></use>';
+			html += "</svg>";
+			html += "<span class='tooltiptext tooltip-top'>";
+			html += gLocal.gui.delete;
+			html += "</span>";
+			html += "</button>";
+		} else {
+			//非提交人
+			//采纳按钮
+			html += "<button class='icon_btn tooltip' onclick=\"sent_pr_merge('" + iterator.id + "')\">";
+			html += '<svg class="icon" >';
+			html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#ic_mode_edit"></use>';
+			html += "</svg>";
+			html += "<span class='tooltiptext tooltip-top'>";
+			html += gLocal.gui.accept_copy;
+			html += "</span>";
+			html += "</button>";
+
+			//点赞按钮
+			html += "<button class='icon_btn tooltip' onclick='sent_pr_like(this)'>";
+			html += '<svg class="icon" >';
+			html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#like"></use>';
+			html += "</svg>";
+			html += "<span class='tooltiptext tooltip-top'>";
+			html += gLocal.gui.like;
+			html += "</span>";
+			html += "</button>";
+		}
+	} else {
+		//非pr列表里的句子
+		//编辑按钮
+		html += "<button class='icon_btn tooltip' onclick='sent_tran_edit(this)'>";
+		html += '<svg class="icon" >';
+		html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#ic_mode_edit"></use>';
+		html += "</svg>";
+		html += "<span class='tooltiptext tooltip-top'>";
+		if (parseInt(iterator.mypower) < 20) {
+			html += "建议";
+		} else {
+			html += gLocal.gui.edit;
+		}
+
+		html += "</span>";
+		html += "</button>";
+
+		//推送按钮
+		if (parseInt(iterator.mypower) >= 20) {
+			html += "<button class='icon_btn tooltip' onclick='sent_tran_edit(this)'>";
+			html += '<svg class="icon" >';
+			html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#ic_mode_edit"></use>';
+			html += "</svg>";
+			html += "<span class='tooltiptext tooltip-top'>";
+			html += "推送";
+			html += "</span>";
+			html += "</button>";
+		}
+
+		//更多按钮
+		html += '<div class="case_dropdown">';
+		html += "<button class='icon_btn'>";
+		html += '<svg class="icon" >';
+		html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#ic_more"></use>';
+		html += "</svg>";
+		html += "</button>";
+		html += '<div class="case_dropdown-content menu_space_between" style="right:0;">';
+		//时间线
+		html += "<a onclick=\"history_show('" + iterator.id + "')\">";
+		html += "<span>" + gLocal.gui.timeline + "</span>";
+		html += '<svg class="icon" >';
+		html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#recent_scan"></use>';
+		html += "</svg>";
+		html += "</a>";
+		//复制
+		html += "<a onclick=\"history_show('" + iterator.id + "')\">";
+		html += "<span>" + gLocal.gui.copy + "</span>";
+		html += '<svg class="icon" >';
+		html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#copy"></use>';
+		html += "</svg>";
+		html += "</a>";
+		//点赞
+		html += "<a onclick=\"history_show('" + iterator.id + "')\">";
+		html += "<span>" + gLocal.gui.like + "</span>";
+		html += '<svg class="icon" >';
+		html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#like"></use>';
+		html += "</svg>";
+		html += "</a>";
+		//分享
+		html += "<a onclick=\"history_show('" + iterator.id + "')\">";
+		html += "<span>" + gLocal.gui.share_to + "</span>";
+		html += '<svg class="icon" >';
+		html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#share_to"></use>';
+		html += "</svg>";
+		html += "</a>";
+
+		html += "</div>";
+		html += "</div>";
+		//更多按钮结束
+	}
+
+	html += "</div>";
+	//句子菜单结束
+	html += "</div>";
+	html += "</div>";
+	//tool_bar 结束
+	html += '<div class="left_bar">';
+	html += '	<div class="face">';
+	if (iterator.id != "") {
+		html += '<span class="head_img">' + iterator.editor_name.nickname.slice(0, 1) + "</span>";
+	}
+	html += "</div>";
+	html += '<div class="date">' + getPassDataTime(iterator.update_time) + "</div>";
+	html += "</div>";
+	html += '<div class="body">';
+	html += '<div class="head_bar">';
+	html += '<div class="info">';
+	html += '<span class="name">' + iterator.editor_name.nickname + "</span>";
+	html += '<span class="date">' + getPassDataTime(iterator.update_time) + "</span>";
+	html += "</div>";
+	html += "<div class='preview'>" + tranText + "</div>";
+	html += "</div>";
+
+	html += '<div class="edit">';
+	html += '<div class="input">';
+	html += "<textarea dbid='" + iterator.id + "' ";
+	html += "sid='" + sid + "' ";
+	html += "channel='" + iterator.channal + "' ";
+	html += 'onchange="note_sent_save_a(this)">' + iterator.text + "</textarea>";
+	html += "</div>";
+	html += '<div class="edit_tool">';
+	if (parseInt(iterator.mypower) < 20) {
+		html += "<b>提交修改建议</b> ";
+	}
+	html += "点击输入框外面自动<a onclick='sent_tran_edit(this)'>保存</a> 支持markdown语法";
+	html += "</div>";
+	html += "</div>";
+
+	html += '<div class="foot_bar">';
+
+	html += '<div class="info">';
+	if (iterator.id != "") {
+		html += '<span class="name">' + iterator.editor_name.nickname + "</span>";
+	}
+	if (iterator.id != "") {
+		html += '<span class="date"> 于' + getPassDataTime(iterator.update_time) + "</span>";
+	}
+	if (iterator.id != "") {
+		html += '<span class="channel">更新了 @' + iterator.channalinfo.name + "</span>";
+	} else {
+		html += '<span class="channel">无人更新 @' + iterator.channalinfo.name + "</span>";
+	}
+
+	html += '<ul class="tag_list">';
+	if (iterator.pr_all && parseInt(iterator.pr_all) > 0) {
+		html +=
+			"			<li onclick=\"note_pr_show('" +
+			iterator.channal +
+			"','" +
+			sid +
+			"')\"><span class='icon'>✋</span><span class='num'>" +
+			iterator.pr_new +
+			"/" +
+			iterator.pr_all +
+			"</span></li>";
+	}
+	html += "</ul>";
+	html += "</div>"; //end of info
+
+	html += "</div>"; //end of foot bar
+
+	html += "</div>";
+	html += "</div>";
+	//sent_tran_inner结束
+	html += '<div class="pr_content"></div>';
+	html += "</div>";
+	return html;
+}
 
 function render_one_sent_tran(book, para, begin, end, iterator) {
 	let output = "";
@@ -609,9 +876,8 @@ function render_one_sent_tran(book, para, begin, end, iterator) {
 		'<svg class="icon" ><use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#ic_mode_edit"></use></svg>';
 	output += gLocal.gui.edit + "</li>";
 	output += "<li class = 'tip_buttom' ";
-	output += " onclick=\"history_show('" + iterator.id + "')\"";
+	output += " onclick=\"history_show('" + iterator.id + "')\" >";
 	output +=
-		">" +
 		'<svg class="icon" ><use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#recent_scan"></use></svg>';
 	output += gLocal.gui.timeline + "</li>";
 	output +=
@@ -777,12 +1043,14 @@ function set_more_button_display() {
 							},
 							function (data, status) {
 								let arrSent = JSON.parse(data);
-								let html = "";
+								let html = "<div class='compact'>";
 								for (const iterator of arrSent) {
 									if (_channal.indexOf(iterator.channal) == -1) {
-										html += "<div>" + marked(iterator.text) + "</div>";
+										html += render_one_sent_tran_a(iterator);
+										//html += "<div>" + marked(iterator.text) + "</div>";
 									}
 								}
+								html += "</div>";
 								let sentId =
 									arrSent[0].book +
 									"-" +
@@ -854,7 +1122,87 @@ function note_edit_sentence(book, para, begin, end, channal) {
 
 	alert("未找到句子");
 }
+function update_note_sent_tran(obj) {}
+//保存译文句子 新
+function note_sent_save_a(obj) {
+	let id = $(obj).attr("dbid");
+	let sid = $(obj).attr("sid").split("-");
+	let book = sid[0];
+	let para = sid[1];
+	let begin = sid[2];
+	let end = sid[3];
+	let channal = $(obj).attr("channel");
+	let text = $(obj).val();
+	let sent_tran_div = find_sent_tran_div(obj);
+	$.post(
+		"../usent/sent_post.php",
+		{
+			id: id,
+			book: book,
+			para: para,
+			begin: begin,
+			end: end,
+			channal: channal,
+			text: text,
+			lang: "zh",
+		},
+		function (data) {
+			let result = JSON.parse(data);
+			if (result.status > 0) {
+				alert("error" + result.message);
+			} else {
+				if (result.commit_type == 1 || result.commit_type == 2) {
+					ntf_show("成功修改");
+					if (sent_tran_div) {
+						let divPreview = $(sent_tran_div).find(".preview").first();
+						if (result.text == "") {
+							let channel_info = "Empty";
+							let thisChannel = find_channal(result.channal);
+							if (thisChannel) {
+								channel_info = thisChannel.name + "-" + thisChannel.nickname;
+							}
+							divPreview.html(
+								"<span style='color:var(--border-line-color);'>" + channel_info + "</span>"
+							);
+						} else {
+							divPreview.html(
+								marked(term_std_str_to_tran(result.text, result.channal, result.editor, result.lang))
+							);
+							term_updata_translation();
+							popup_init();
+							for (const iterator of _arrData) {
+								if (
+									iterator.book == result.book &&
+									iterator.para == result.para &&
+									iterator.begin == result.begin &&
+									iterator.end == result.end
+								) {
+									for (const tran of iterator.translation) {
+										if (tran.channal == result.channal) {
+											tran.text = result.text;
+											break;
+										}
+									}
+								}
+							}
+						}
+						$(sent_tran_div).find(".preview").removeClass("loading");
+					}
+				} else if (result.commit_type == 3) {
+					ntf_show("已经提交修改建议");
+				} else {
+					ntf_show("未提交");
+				}
+			}
+		}
+	);
+
+	if (sent_tran_div) {
+		$(sent_tran_div).find(".preview").addClass("loading");
+	}
+}
 
+//保存译文句子
 function note_sent_save() {
 	let id = $("#edit_dialog_text").attr("sent_id");
 	let book = $("#edit_dialog_text").attr("book");
@@ -881,54 +1229,60 @@ function note_sent_save() {
 			if (result.status > 0) {
 				alert("error" + result.message);
 			} else {
-				ntf_show("success");
-				if (result.text == "") {
-					let channel_info = "Empty";
-					let thisChannel = find_channal(result.channal);
-					if (thisChannel) {
-						channel_info = thisChannel.name + "-" + thisChannel.nickname;
-					}
-					$(
-						"#tran_text_" +
-							result.book +
-							"_" +
-							result.para +
-							"_" +
-							result.begin +
-							"_" +
-							result.end +
-							"_" +
-							result.channal
-					).html("<span style='color:var(--border-line-color);'>" + channel_info + "</span>");
-				} else {
-					$(
-						"#tran_text_" +
-							result.book +
-							"_" +
-							result.para +
-							"_" +
-							result.begin +
-							"_" +
-							result.end +
-							"_" +
-							result.channal
-					).html(marked(term_std_str_to_tran(result.text, result.channal, result.editor, result.lang)));
-					term_updata_translation();
-					for (const iterator of _arrData) {
-						if (
-							iterator.book == result.book &&
-							iterator.para == result.para &&
-							iterator.begin == result.begin &&
-							iterator.end == result.end
-						) {
-							for (const tran of iterator.translation) {
-								if (tran.channal == result.channal) {
-									tran.text = result.text;
-									break;
+				if (result.commit_type == 1 || result.commit_type == 2) {
+					ntf_show("成功修改");
+					if (result.text == "") {
+						let channel_info = "Empty";
+						let thisChannel = find_channal(result.channal);
+						if (thisChannel) {
+							channel_info = thisChannel.name + "-" + thisChannel.nickname;
+						}
+						$(
+							"#tran_text_" +
+								result.book +
+								"_" +
+								result.para +
+								"_" +
+								result.begin +
+								"_" +
+								result.end +
+								"_" +
+								result.channal
+						).html("<span style='color:var(--border-line-color);'>" + channel_info + "</span>");
+					} else {
+						$(
+							"#tran_text_" +
+								result.book +
+								"_" +
+								result.para +
+								"_" +
+								result.begin +
+								"_" +
+								result.end +
+								"_" +
+								result.channal
+						).html(marked(term_std_str_to_tran(result.text, result.channal, result.editor, result.lang)));
+						term_updata_translation();
+						for (const iterator of _arrData) {
+							if (
+								iterator.book == result.book &&
+								iterator.para == result.para &&
+								iterator.begin == result.begin &&
+								iterator.end == result.end
+							) {
+								for (const tran of iterator.translation) {
+									if (tran.channal == result.channal) {
+										tran.text = result.text;
+										break;
+									}
 								}
 							}
 						}
 					}
+				} else if (result.commit_type == 3) {
+					ntf_show("已经提交修改建议");
+				} else {
+					ntf_show("未提交");
 				}
 			}
 		}
@@ -968,6 +1322,7 @@ function tool_bar_show(element) {
 	}
 }
 
+//显示和隐藏某个内容 如 巴利文
 function setVisibility(key, value) {
 	switch (key) {
 		case "palitext":
@@ -1053,3 +1408,88 @@ function set_second_scrip(value) {
 function slider_show(obj) {
 	$(obj).parent().parent().parent().parent().parent().toggleClass("slider_show_shell");
 }
+
+function find_sent_tran_div(obj) {
+	let parent = obj.parentNode;
+	while (parent.nodeType == 1) {
+		if ($(parent).hasClass("sent_tran")) {
+			return parent;
+		} else if (parent.nodeName == "BODY") {
+			return false;
+		}
+		parent = parent.parentNode;
+	}
+
+	return false;
+}
+//显示或隐藏pr数据
+function note_pr_show(channel, id) {
+	let obj = $(".sent_tran[channel='" + channel + "'][sid='" + id + "']").find(".pr_content");
+	let prHtml = obj.first().html();
+	if (prHtml == "") {
+		note_get_pr(channel, id);
+	} else {
+		obj.slideUp();
+		obj.html("");
+	}
+}
+
+//获取pr数据并显示
+function note_get_pr(channel, id) {
+	let sid = id.split("-");
+	let book = sid[0];
+	let para = sid[1];
+	let begin = sid[2];
+	let end = sid[3];
+	$.post(
+		"../usent/get_pr.php",
+		{
+			book: book,
+			para: para,
+			begin: begin,
+			end: end,
+			channel: channel,
+		},
+		function (data) {
+			let result = JSON.parse(data);
+			if (result.length > 0) {
+				let html = "<div class='compact'>";
+				for (const iterator of result) {
+					html += render_one_sent_tran_a(iterator);
+				}
+				html += "</div>";
+				$(".sent_tran[channel='" + channel + "'][sid='" + id + "']")
+					.find(".pr_content")
+					.html(html);
+				$(".sent_tran[channel='" + channel + "'][sid='" + id + "']")
+					.find(".pr_content")
+					.slideDown();
+			} else {
+			}
+		}
+	);
+	$(".sent_tran[channel='" + channel + "'][sid='" + id + "']")
+		.find(".pr_content")
+		.html("loading");
+	$(".sent_tran[channel='" + channel + "'][sid='" + id + "']")
+		.find(".pr_content")
+		.show();
+}
+
+function get_channel_by_id(id) {
+	if (typeof _channalData != "undefined") {
+		for (const iterator of _channalData) {
+			if (iterator.id == id) {
+				return iterator;
+			}
+		}
+	}
+	if (typeof _my_channal != "undefined") {
+		for (const iterator of _my_channal) {
+			if (iterator.id == id) {
+				return iterator;
+			}
+		}
+	}
+	return false;
+}

+ 58 - 4
app/term/note.php

@@ -3,11 +3,15 @@ require_once "../path.php";
 require_once "../public/_pdo.php";
 require_once "../public/function.php";
 require_once "../channal/function.php";
+require_once "../ucenter/function.php";
+require_once "../usent/function.php";
 require_once "../redis/function.php";
 
 $redis = redis_connect();
 
 $_channal = new Channal();
+$_userinfo = new UserInfo();
+$_sentPr = new SentPr($redis);
 
 $_data = array();
 if (isset($_POST["data"])) {
@@ -165,7 +169,18 @@ foreach ($_data as $key => $value) {
                 $Fetch = $stmt->fetch(PDO::FETCH_ASSOC);
                 if ($Fetch) {
                     $tran = $Fetch["text"];
-                    $translation[] = array("id" => $Fetch["id"], "text" => $Fetch["text"], "lang" => $Fetch["language"], "channal" => $Fetch["channal"], "editor" => $Fetch["editor"]);
+                    $translation[] = array("id" => $Fetch["id"], 
+										   "book"=>$bookId,
+										   "para"=>$para,
+										   "begin"=>$begin,
+										   "end"=>$end,
+										   "text" => $Fetch["text"], 
+										   "lang" => $Fetch["language"], 
+										   "channal" => $Fetch["channal"], 
+										   "editor" => $Fetch["editor"],
+										   "editor_name"=>$_userinfo->getName($Fetch["editor"]),
+										   "update_time"=>$Fetch["modify_time"]
+										);
                     if (!empty($Fetch["channal"])) {
                         $tran_channal[$Fetch["channal"]] = $Fetch["channal"];
                     }
@@ -177,7 +192,18 @@ foreach ($_data as $key => $value) {
                 $Fetch = $stmt->fetch(PDO::FETCH_ASSOC);
                 if ($Fetch) {
                     $tran = $Fetch["text"];
-                    $translation[] = array("id" => $Fetch["id"], "text" => $Fetch["text"], "lang" => $Fetch["language"], "channal" => $Fetch["channal"], "editor" => $Fetch["editor"]);
+                    $translation[] = array("id" => $Fetch["id"], 
+											"book"=>$bookId,
+											"para"=>$para,
+											"begin"=>$begin,
+											"end"=>$end,
+										   "text" => $Fetch["text"], 
+										   "lang" => $Fetch["language"], 
+										   "channal" => $Fetch["channal"], 
+										   "editor" => $Fetch["editor"],
+										   "editor_name"=>$_userinfo->getName($Fetch["editor"]),
+										   "update_time"=>$Fetch["modify_time"]
+										);
                     $tran_channal[$Fetch["channal"]] = $Fetch["channal"];
                 }
             }
@@ -189,10 +215,32 @@ foreach ($_data as $key => $value) {
                 $stmt->execute(array($bookId, $para, $begin, $end, $value));
                 $Fetch = $stmt->fetch(PDO::FETCH_ASSOC);
                 if ($Fetch) {
-                    $translation[] = array("id" => $Fetch["id"], "text" => $Fetch["text"], "lang" => $Fetch["language"], "channal" => $value, "editor" => $Fetch["editor"],"update_time"=>$Fetch["modify_time"]);
+                    $translation[] = array("id" => $Fetch["id"],
+										   "book"=>$bookId,
+										   "para"=>$para,
+										   "begin"=>$begin,
+										   "end"=>$end,
+										   "text" => $Fetch["text"], 
+										   "lang" => $Fetch["language"], 
+										   "channal" => $value, 
+										   "editor" => $Fetch["editor"],
+										   "editor_name"=>$_userinfo->getName($Fetch["editor"]),
+										   "update_time"=>$Fetch["modify_time"]
+										);
 
                 } else {
-                    $translation[] = array("id" => "", "text" => "", "lang" => "", "channal" => $value);
+                    $translation[] = array("id" => "", 
+											"book"=>$bookId,
+											"para"=>$para,
+											"begin"=>$begin,
+											"end"=>$end,
+										   "text" => "", 
+										   "lang" => "", 
+										   "channal" => $value,
+										   "editor" => false,
+										   "editor_name"=>false,
+										   "update_time"=>false
+										);
                 }
                 $tran_channal[$value] = $value;
             }
@@ -206,14 +254,20 @@ foreach ($_data as $key => $value) {
     foreach ($tran_channal as $key => $value) {
         # code...
         $tran_channal[$key] = $_channal->getChannal($key);
+		$tran_channal[$key]["mypower"] = $_channal->getPower($key);
     }
     foreach ($translation as $key => $value) {
         # code...
         if ($value["channal"]) {
             $translation[$key]["channalinfo"] = $tran_channal[$value["channal"]];
+            $translation[$key]["mypower"] = $tran_channal[$value["channal"]]["mypower"];
+			#查询句子pr
+			$translation[$key]["pr_new"]=$_sentPr->getNewPrNumber($value["book"],$value["para"],$value["begin"],$value["end"],$value["channal"]);
+			$translation[$key]["pr_all"]=$_sentPr->getAllPrNumber($value["book"],$value["para"],$value["begin"],$value["end"],$value["channal"]);
         } else {
             $translation[$key]["channalinfo"] = false;
         }
+
     }
 
     //查询路径

+ 149 - 5
app/term/term.css

@@ -265,13 +265,9 @@ note > .palitext,
 	font-weight: 500;
 	margin-bottom: 10px;
 }
-note > .palitext > note {
+note n {
 	display: inline;
 	color: blue;
-	background-color: unset;
-	padding: unset;
-	margin-bottom: unset;
-	border-radius: unset;
 }
 
 .term_word_head_pali {
@@ -547,3 +543,151 @@ pw {
 .slider_show_shell .bg_color_1 {
 	background-color: unset;
 }
+
+/*编辑框*/
+.sent_tran {
+	padding: 5px;
+	margin-bottom: 2px;
+}
+.sent_tran_inner {
+	display: flex;
+}
+.sent_tran:hover {
+	background-color: #fafafa;
+}
+.left_bar {
+	width: 40px;
+}
+.sent_tran .left_bar > .face {
+	display: block;
+}
+.compact .left_bar > .face {
+	display: none;
+}
+.left_bar > .date {
+	display: none;
+}
+.compact .left_bar > .date {
+	display: block;
+}
+
+.sent_tran_inner > .body {
+	width: 100%;
+	display: block;
+}
+.preview {
+	font-size: 110%;
+}
+.compact .body > .head_bar {
+	display: flex;
+}
+.compact .body > .head_bar > .date {
+	display: none;
+}
+.head_bar > .info {
+	display: none;
+}
+.head_bar > .info > .name {
+	font-weight: 700;
+}
+.head_bar > .info > .date {
+	font-size: 0.8em;
+	color: gray;
+}
+.compact .head_bar > .info {
+	display: block;
+}
+.compact .head_bar > .info > .date {
+	display: none;
+}
+.foot_bar .info {
+	color: gray;
+}
+.tool_bar > .right {
+	position: absolute;
+	right: 0;
+	margin-top: -18px;
+	display: none;
+	width: auto;
+	background-color: var(--bg-color);
+	border: 1px solid var(--border-line-color);
+	border-radius: 6px;
+	padding: 3px;
+	margin-right: 20px;
+}
+.sent_tran_inner:hover .tool_bar > .right {
+	display: block;
+}
+
+.body > .edit {
+	display: none;
+}
+.body > .edit textarea {
+	color: var(--main-color);
+	width: 100%;
+	background-color: var(--drop-bg-color);
+	border: unset;
+	border-radius: 8px;
+	padding: 5px;
+	line-height: 1.5em;
+	height: 90px;
+	font-size: 120%;
+}
+.foot_bar {
+	font-size: 90%;
+}
+.foot_bar > .info {
+	display: flex;
+}
+.foot_bar > .info span {
+	margin-right: 4px;
+}
+.compact .foot_bar {
+	display: none;
+}
+.edit_mode {
+	background-color: #fafafa;
+}
+.edit_mode > .sent_tran_inner > .body > .head_bar > .preview {
+	display: none;
+}
+.edit_mode > .sent_tran_inner > .body > .edit {
+	display: block;
+}
+.pop_menu {
+	display: flex;
+}
+.tag_list {
+	display: flex;
+	list-style-type: none;
+}
+.tag_list li {
+	border-radius: 6px;
+	margin-right: 5px;
+	background-color: var(--bookx);
+	padding: 2px 5px;
+	cursor: pointer;
+}
+li.active {
+	background-color: var(--booka);
+}
+.tag_list li:hover {
+	background-color: var(--booka);
+}
+.sent_tran .preview p {
+	margin: 0;
+}
+.pop_menu .icon {
+	fill: var(--main-color);
+}
+.pr_content {
+	margin-left: 3em;
+	border-left: 3px solid var(--border-line-color);
+}
+.menu_space_between a {
+	display: flex;
+	justify-content: space-between;
+}
+.body > .head_bar > .loading {
+	color: gray;
+}

+ 247 - 0
app/term/test.php

@@ -0,0 +1,247 @@
+<?php
+require_once '../studio/index_head.php';
+?>
+
+<body>
+
+<style>
+
+</style>
+
+<div class="sent_tran">
+	<div class="tool_bar">
+		<div class="right">
+				<div class="pop_menu">
+					<a>🔐</a>
+					<a>🔐</a>
+					<a>🔐</a>
+				</div>
+		</div>
+	</div>
+	<div class="left_bar">
+		<div class="face">K</div>
+		<div class="date">2/25</div>
+	</div>
+	<div class="body">
+		<div class="head_bar">
+			<div class="info"><span class="name">Kosalla</span><span class="date">2-25</span></div>
+			<div class="preview">这是正文的<span class='tooltip'>预览<span class="tooltiptext tooltip_menu-bottom">编辑</span></span></div>
+		</div>
+
+		<div class="edit">
+			<div class="input">
+				<textarea>这是正文的修改</textarea>
+			</div>
+			<div class="edit_tool">
+				ESC键取消 回车键保存
+			</div>
+		</div>
+
+		<div class="foot_bar">
+			<ul class="tag_list">
+				<li class="active"><span class="icon">🔐</span><span class="num">3</span></li>
+			</ul>
+		</div>
+	</div>
+</div>
+
+<div class="sent_tran">
+	<div class="tool_bar">
+		<div class="right">
+				<div class="pop_menu">
+					<button>🔐</button>
+					<button>🔐</button>
+					<div class="case_dropdown">
+						<svg class="edit_icon">
+							<use xlink:href="../studio/svg/icon.svg#ic_more"></use>
+						</svg>
+						<div class="case_dropdown-content" style="right:0;">
+							<a onclick="">时间线</a>
+							<a onclick="">时间线</a>
+							<a onclick="">时间线</a>
+							<a onclick="">时间线</a>
+						</div>
+					</div>
+				</div>
+		</div>
+	</div>
+	<div class="left_bar">
+		<div class="face">K</div>
+		<div class="date">2/25</div>
+	</div>
+	<div class="body">
+		<div class="head_bar">
+			<div class="info"><span class="name">Kosalla</span><span class="date">2-25</span></div>
+			<div class="preview">这是正文的<span class='tooltip'>预览<span class="tooltiptext tooltip-top">Edit</span></span></div>
+		</div>
+
+		<div class="edit">
+			<div class="input">
+				<textarea>这是正文的修改</textarea>
+			</div>
+			<div class="edit_tool">
+				ESC键<a>取消</a> 回车键<a>保存</a>
+			</div>
+		</div>
+
+		<div class="foot_bar">
+			<ul class="tag_list">
+				<li><span class="icon">🔐</span><span class="num">3</span></li>
+				<li><span class="icon">✋</span><span class="num">3/10</span></li>
+			</ul>
+			<div class="content">
+			</div>
+		</div>
+	</div>
+</div>
+
+<div class="sent_tran compact">
+	<div class="tool_bar">
+		<div class="right">
+				<div class="pop_menu">
+					<button>🔐</button>
+					<button>🔐</button>
+					<button>🔐</button>
+				</div>
+		</div>
+	</div>
+	<div class="left_bar">
+		<div class="face">K</div>
+		<div class="date">2/25</div>
+	</div>
+	<div class="body">
+		<div class="head_bar">
+			<div class="info"><span class="name">Kosalla</span><span class="date">2-25</span></div>
+			<div class="preview">这是正文的预览</div>
+		</div>
+
+		<div class="edit">
+			<div class="input">
+				<textarea>这是正文的修改</textarea>
+			</div>
+			<div class="edit_tool">
+				ESC键取消 回车键保存
+			</div>
+		</div>
+
+		<div class="foot_bar">
+			<ul>
+				<li>🔐<span>3</span></li>
+			</ul>
+		</div>
+	</div>
+</div>
+
+<div class="sent_tran compact">
+	<div class="tool_bar">
+		<div class="right">
+				<div class="pop_menu">
+					<button>🔐</button>
+					<button>🔐</button>
+					<button>🔐</button>
+				</div>
+		</div>
+	</div>
+	<div class="left_bar">
+		<div class="face">K</div>
+		<div class="date">2/25</div>
+	</div>
+	<div class="body">
+		<div class="head_bar">
+			<div class="info"><span class="name">Kosalla</span><span class="date">2-25</span></div>
+			<div class="preview">这是正文的预览</div>
+		</div>
+
+		<div class="edit">
+			<div class="input">
+				<textarea>这是正文的修改</textarea>
+			</div>
+			<div class="edit_tool">
+				ESC键取消 回车键保存
+			</div>
+		</div>
+
+		<div class="foot_bar">
+			<ul>
+				<li>🔐<span>3</span></li>
+			</ul>
+		</div>
+	</div>
+</div>
+
+<div class="sent_tran compact">
+	<div class="tool_bar">
+		<div class="right">
+				<div class="pop_menu">
+					<button>🔐</button>
+					<button>🔐</button>
+					<button>🔐</button>
+				</div>
+		</div>
+	</div>
+	<div class="left_bar">
+		<div class="face">K</div>
+		<div class="date">2/25</div>
+	</div>
+	<div class="body">
+		<div class="head_bar">
+			<div class="info"><span class="name">Kosalla</span><span class="date">2-25</span></div>
+			<div class="preview">这是正文的预览</div>
+		</div>
+
+		<div class="edit">
+			<div class="input">
+				<textarea>这是正文的修改</textarea>
+			</div>
+			<div class="edit_tool">
+				ESC键取消 回车键保存
+			</div>
+		</div>
+
+		<div class="foot_bar">
+			<ul>
+				<li>🔐<span>3</span></li>
+			</ul>
+		</div>
+	</div>
+</div>
+
+<div class="sent_tran compact edit_mode">
+	<div class="tool_bar">
+		<div class="right">
+				<div class="pop_menu">
+					<button>🔐</button>
+					<button>🔐</button>
+					<button>🔐</button>
+				</div>
+		</div>
+	</div>
+	<div class="left_bar">
+		<div class="face">K</div>
+		<div class="date">2/25</div>
+	</div>
+	<div class="body">
+		<div class="head_bar">
+			<div class="info"><span class="name">Kosalla</span><span class="date">2-25</span></div>
+			<div class="preview">这是正文的预览</div>
+		</div>
+
+		<div class="edit">
+			<div class="input">
+				<textarea>这是正文的修改</textarea>
+			</div>
+			<div class="edit_tool">
+				ESC键取消 回车键保存
+			</div>
+		</div>
+
+		<div class="foot_bar">
+			<ul>
+				<li>🔐<span>3</span></li>
+			</ul>
+		</div>
+	</div>
+</div>
+
+</body>
+</html>

+ 92 - 0
app/usent/function.php

@@ -21,6 +21,85 @@ function update_historay($sent_id, $user_id, $text, $landmark)
     }
 }
 
+class SentPr{
+	private $dbh_sent;
+	private $redis;
+	public function __construct($redis=false) {
+        $this->dbh_sent = new PDO(_FILE_DB_SENTENCE_, "", "",array(PDO::ATTR_PERSISTENT=>true));
+		$this->dbh_sent->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);  
+		$this->redis=$redis;
+	}
+	public function getNewPrNumber($book,$para,$begin,$end,$channel){
+		if ($this->dbh_sent) {
+            $query = "SELECT count(*) as ct FROM sent_pr WHERE book = ? and paragraph= ? and begin=? and end=? and channel=? and status=1 ";
+            $stmt = $this->dbh_sent->prepare($query);
+            $stmt->execute(array($book,$para,$begin,$end,$channel));
+            $result = $stmt->fetch(PDO::FETCH_ASSOC);
+			if($result){
+				return $result["ct"];
+			}
+			else{
+				return false;
+			}
+		}
+		else{
+			return false;
+		}
+	}
+	public function getAllPrNumber($book,$para,$begin,$end,$channel){
+		if ($this->dbh_sent) {
+            $query = "SELECT count(*) as ct FROM sent_pr WHERE book = ? and paragraph= ? and begin=? and end=? and channel=?  ";
+            $stmt = $this->dbh_sent->prepare($query);
+            $stmt->execute(array($book,$para,$begin,$end,$channel));
+            $result = $stmt->fetch(PDO::FETCH_ASSOC);
+			if($result){
+				return $result["ct"];
+			}
+			else{
+				return false;
+			}
+		}
+		else{
+			return false;
+		}
+	}
+
+	public function getPrData($book,$para,$begin,$end,$channel){
+		if ($this->dbh_sent) {
+            $query = "SELECT id,book,paragraph,begin,end,text,editor,modify_time FROM sent_pr WHERE book = ? and paragraph= ? and begin=? and end=? and channel=? and status=1 limit 0,100";
+            $stmt = $this->dbh_sent->prepare($query);
+            $stmt->execute(array($book,$para,$begin,$end,$channel));
+            $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
+			if($result){
+				return $result;
+			}
+			else{
+				return false;
+			}
+		}
+		else{
+			return false;
+		}
+	}
+	public function getPrDataById($id){
+		if ($this->dbh_sent) {
+            $query = "SELECT id,book,paragraph,begin,end,channel,text,editor,modify_time FROM sent_pr WHERE id = ? ";
+            $stmt = $this->dbh_sent->prepare($query);
+            $stmt->execute(array($id));
+            $result = $stmt->fetch(PDO::FETCH_ASSOC);
+			if($result){
+				return $result;
+			}
+			else{
+				return false;
+			}
+		}
+		else{
+			return false;
+		}
+	}
+}
+
 class Sent_DB
 {
     private $dbh_sent;
@@ -36,6 +115,19 @@ class Sent_DB
 	public function getError(){
 		return $errorMsg;
 	}
+	public function getSent($book,$para,$begin,$end,$channel){
+		$query = "SELECT * FROM sentence WHERE book= ? AND paragraph= ? AND begin= ? AND end= ?  AND channal = ?  ";
+		$stmt = $this->dbh_sent->prepare($query);
+		if($stmt){
+			$stmt->execute(array($book,$para,$begin,$end,$channel));
+			$fetchDest = $stmt->fetch(PDO::FETCH_ASSOC);
+			return $fetchDest;
+		}
+		else{
+			return false;
+		}
+		
+	}
 	public function update($arrData){
 		/* 修改现有数据 */
 	

+ 4 - 0
app/usent/get.php

@@ -76,7 +76,11 @@ foreach ($Fetch as $key => $value) {
     if ($channel) {
         $Fetch[$key]["c_name"] = $channel["name"];
         $Fetch[$key]["c_owner"] = $user_info->getName($channel["owner"]);
+        $Fetch[$key]["channalinfo"] = $channel;
     }
+	$Fetch[$key]["editor_name"]=$user_info->getName($value["editor"]);
+	$Fetch[$key]["update_time"]=$value["modify_time"];
+
 }
 
 echo json_encode($Fetch, JSON_UNESCAPED_UNICODE);

+ 32 - 0
app/usent/get_pr.php

@@ -0,0 +1,32 @@
+<?php
+
+require_once "../usent/function.php";
+require_once "../channal/function.php";
+require_once "../ucenter/function.php";
+require_once "../redis/function.php";
+
+$redis = redis_connect();
+
+$channel_info = new Channal();
+$user_info = new UserInfo();
+$pr = new SentPr($redis);
+$result = $pr->getPrData($_POST["book"],$_POST["para"],$_POST["begin"],$_POST["end"],$_POST["channel"]);
+foreach ($result as $key => $value) {
+	# code...
+	$result[$key]["editor_name"]=$user_info->getName($value["editor"]);
+	$result[$key]["update_time"]=$value["modify_time"];
+	$result[$key]["channalinfo"] = $channel_info->getChannal($value["channal"]);
+	if(isset($_COOKIE["userid"])){
+		if($value["editor"]==$_COOKIE["userid"]){
+			$result[$key]["is_pr_editor"] =true;
+		}
+		else{
+			$result[$key]["is_pr_editor"] =false;
+		}
+	}
+	else{
+		$result[$key]["is_pr_editor"] =false;
+	}
+	$result[$key]["is_pr"] =true;
+}
+echo json_encode($result, JSON_UNESCAPED_UNICODE);

+ 70 - 0
app/usent/sent_pr_merge.php

@@ -0,0 +1,70 @@
+<?php
+#更新一个句子
+require_once "../path.php";
+require_once "../public/function.php";
+require_once "../usent/function.php";
+require_once "../ucenter/active.php";
+require_once "../share/function.php";
+require_once "../redis/function.php";
+require_once "../channal/function.php";
+
+$db_pr = new SentPr();
+$db_sent = new Sent_DB();
+$channel = new Channal();
+
+$updateDate=array();
+$insertData=array();
+$insertHistoray=array();
+
+$respond["error"]=0;
+$respond["message"]="";
+$prData = $db_pr->getPrDataById($_POST["id"]);
+if($prData){
+	$channelPower = $channel->getPower($prData["channel"]);
+	if($channelPower>=20){
+		$dest = $db_sent->getSent($prData["book"],$prData["paragraph"],$prData["begin"],$prData["end"],$prData["channel"]);
+		$newData = $prData;
+		if($dest){
+			#更新
+			$newData["id"]=$dest["id"];
+			$newData["modify_time"]=mTime();
+			$newData["landmark"]="";
+			$updateDate[] = $newData;
+			$insertHistoray[] = $newData;
+		}
+		else{
+			#插入
+			$newData["id"]=UUID::v4();;
+			$newData["modify_time"]=mTime();
+			$newData["landmark"]="";
+			$insertData[] = $newData;
+			$insertHistoray[] = $newData;
+		}
+		if($db_sent->update($updateDate)){
+			$respond['update'] = count($updateDate);
+		}
+		else{
+			$respond['message'] = $db_sent->getError();
+			$respond['status'] = 1;
+		}
+		if($db_sent->insert($insertData)){
+			$respond['insert'] = count($insertData);
+	
+		}else{
+			$respond['message'] = $db_sent->getError();
+			$respond['status'] = 1;
+		}
+		if($db_sent->historay($insertHistoray)){
+			$respond['historay'] = count($insertHistoray);
+	
+		}else{
+			$respond['message'] = $db_sent->getError();
+			$respond['status'] = 1;
+		}
+	}
+	else{
+		$output["error"]=1;
+		$output["message"]="没有写入权限";
+	}
+}
+?>

Разлика између датотеке није приказан због своје велике величине
+ 4 - 5
pali_title/217_title.csv


Неке датотеке нису приказане због велике количине промена