Browse Source

合并代码

Bhikkhu-Kosalla 5 years ago
parent
commit
2c24d0e292
80 changed files with 4749 additions and 880 deletions
  1. 32 0
      app/article/card.php
  2. 114 0
      app/article/function.php
  3. 24 0
      app/article/get.php
  4. 3 0
      app/article/index.php
  5. 1 1
      app/article/list_new.php
  6. 45 20
      app/article/my_article.js
  7. 3 1
      app/article/my_article_index.php
  8. 19 10
      app/article/my_article_post.php
  9. 6 3
      app/article/my_article_put.php
  10. 34 0
      app/channal/card.php
  11. 68 17
      app/channal/channal.js
  12. 77 8
      app/channal/function.php
  13. 27 21
      app/channal/get.php
  14. 3 0
      app/channal/my_channal_index.php
  15. 34 0
      app/collect/card.php
  16. 61 0
      app/commit/commit.css
  17. 356 0
      app/commit/commit.js
  18. 145 0
      app/commit/commit.php
  19. 1 0
      app/dict/comp_csv.php
  20. 0 1
      app/dict/css/style.css
  21. 1 12
      app/dict/css/style_mobile.css
  22. 72 13
      app/dict/dict_lookup.php
  23. 33 0
      app/doc/card.php
  24. 1 1
      app/doc/coop.php
  25. 20 0
      app/doc/function.php
  26. 27 0
      app/group/function.php
  27. 8 3
      app/group/get.php
  28. 65 17
      app/group/group.js
  29. 2 2
      app/group/group_del.php
  30. 2 1
      app/group/index.php
  31. 12 2
      app/group/list.php
  32. 3 3
      app/group/member_del.php
  33. 13 10
      app/group/my_group_put.php
  34. 5 1
      app/guide/guide.js
  35. 1 1
      app/install/db_insert_sentence.php
  36. 18 8
      app/install/step5.php
  37. 11 9
      app/pali_sent/redis_upgrade_pali_sent.php
  38. 1 0
      app/path.php
  39. 44 41
      app/pcdl/css/color_day.css
  40. 220 247
      app/pcdl/css/font.css
  41. 22 9
      app/pcdl/css/style.css
  42. 7 0
      app/pcdl/html_head.php
  43. 58 63
      app/pcdl/index.js
  44. 14 0
      app/public/images/svg.md
  45. 29 0
      app/public/js/comm.js
  46. 19 0
      app/redis/del.php
  47. 90 0
      app/redis/index.php
  48. 23 0
      app/redis/redis.json
  49. 44 0
      app/share/coop_del.php
  50. 44 0
      app/share/coop_get.php
  51. 45 0
      app/share/coop_post.php
  52. 52 0
      app/share/coop_put.php
  53. 160 0
      app/share/function.php
  54. 15 0
      app/share/readme.md
  55. 324 0
      app/share/share.js
  56. 138 0
      app/share/share.php
  57. 0 115
      app/statistics/index1.php
  58. 22 12
      app/studio/css/style.css
  59. 10 0
      app/studio/index_head.php
  60. 3 1
      app/studio/index_tool_bar.php
  61. 57 13
      app/studio/js/render.js
  62. 2 0
      app/studio/svg/icon.svg
  63. 3 1
      app/term/add.svg
  64. 25 16
      app/term/channal_list.php
  65. 3 4
      app/term/new.php
  66. 672 122
      app/term/note.js
  67. 68 4
      app/term/note.php
  68. 158 19
      app/term/term.css
  69. 247 0
      app/term/test.php
  70. 30 0
      app/ucenter/card.php
  71. 5 5
      app/ucenter/get.php
  72. 337 0
      app/usent/function.php
  73. 4 0
      app/usent/get.php
  74. 35 0
      app/usent/get_pr.php
  75. 30 0
      app/usent/pr_post.php
  76. 148 43
      app/usent/sent_post.php
  77. 73 0
      app/usent/sent_pr_merge.php
  78. 44 0
      app/widget/iframe_modal_win.css
  79. 77 0
      app/widget/iframe_modal_win.js
  80. BIN
      font/taitham/tai-tham-kh-new-v3.ttf

+ 32 - 0
app/article/card.php

@@ -0,0 +1,32 @@
+<?php
+//
+
+require_once "../path.php";
+require_once '../redis/function.php';
+require_once "../article/function.php";
+require_once '../ucenter/function.php';
+
+
+if (isset($_GET["id"])) {
+	$output["id"]=$_GET["id"];
+	$redis = redis_connect();
+	$article = new Article($redis); 
+	$result = $article->getInfo($_GET["id"]);
+	if ($result) {
+		$_userinfo = new UserInfo();
+		$name = $_userinfo->getName($result["owner"]);
+		$strData .= "<div>标题:".$result["title"]."</div>";
+		$strData .=  "<div>创建人:".$name["nickname"]."</div>";
+		$strData .=  "<div>创建时间:".date("Y/m/d",$result["create_time"]/1000)."</div>";
+		$strData .=  "<div>简介:".$result["summary"]."</div>";
+	} else {
+		$strData .=  "unkow";
+	}
+	$output["data"] = $strData;
+} else {
+	$output["id"]=0;
+	$output["data"] = "unkow";
+}
+echo json_encode($output, JSON_UNESCAPED_UNICODE);
+
+?>

+ 114 - 0
app/article/function.php

@@ -0,0 +1,114 @@
+<?php
+require_once "../path.php";
+require_once "../share/function.php";
+
+class Article
+{
+    private $dbh;
+	private $_redis;
+    public function __construct($redis=false) {
+        $this->dbh = new PDO(_FILE_DB_USER_ARTICLE_, "", "",array(PDO::ATTR_PERSISTENT=>true));
+        $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
+		$this->_redis=$redis;
+    }
+
+    public function getInfo($id){
+		$output = array();
+		if($this->_redis!==false){
+			if($this->_redis->exists("article://".$id)===1){
+				$output["id"]=$this->_redis->hGet("article://".$id,"id");
+				$output["title"]=$this->_redis->hGet("article://".$id,"title");
+				$output["subtitle"]=$this->_redis->hGet("article://".$id,"subtitle");
+				$output["owner"]=$this->_redis->hGet("article://".$id,"owner");
+				$output["summary"]=$this->_redis->hGet("article://".$id,"summary");
+				$output["tag"]=$this->_redis->hGet("article://".$id,"tag");
+				$output["status"]=$this->_redis->hGet("article://".$id,"status");
+				$output["create_time"]=$this->_redis->hGet("article://".$id,"create_time");
+				$output["modify_time"]=$this->_redis->hGet("article://".$id,"modify_time");
+				return $output;
+			}
+		}
+        $query = "SELECT id,title,owner,summary,tag,status,create_time,modify_time FROM article WHERE id= ? ";
+        $stmt = $this->dbh->prepare($query);
+        $stmt->execute(array($id));
+        $output = $stmt->fetch(PDO::FETCH_ASSOC);
+        if($output){
+			if($this->_redis!==false){
+				$this->_redis->hSet("article://".$id,"id",$output["id"]);
+				$this->_redis->hSet("article://".$id,"title",$output["title"]);
+				$this->_redis->hSet("article://".$id,"subtitle",$output["subtitle"]);
+				$this->_redis->hSet("article://".$id,"summary",$output["summary"]);
+				$this->_redis->hSet("article://".$id,"owner",$output["owner"]);
+				$this->_redis->hSet("article://".$id,"tag",$output["tag"]);
+				$this->_redis->hSet("article://".$id,"status",$output["status"]);
+				$this->_redis->hSet("article://".$id,"create_time",$output["create_time"]);
+				$this->_redis->hSet("article://".$id,"modify_time",$output["modify_time"]);
+			}
+            return $output;
+        }
+        else{
+            return false;
+        }
+	}
+    public function getContent($id){
+		$output = array();
+		if($this->_redis!==false){
+			if($this->_redis->hExists("article://".$id,"content")===TRUE){
+				$content=$this->_redis->hGet("article://".$id,"content");
+				return $content;
+			}
+		}
+        $query = "SELECT content FROM article WHERE id= ? ";
+        $stmt = $this->dbh->prepare($query);
+        $stmt->execute(array($id));
+        $output = $stmt->fetch(PDO::FETCH_ASSOC);
+        if($output){
+			if($this->_redis!==false){
+				$this->_redis->hSet("article://".$id,"content",$output["content"]);
+			}
+            return $output["content"];
+        }
+        else{
+            return false;
+        }
+	}
+	public function getPower($id){
+		#查询用户对此是否有权限		
+
+		$iPower = 0;
+		$query = "SELECT owner,status FROM article WHERE id=?  ";
+		$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;
+			}
+			else if($channel["status"]>=30){
+				#全网公开的 可以提交pr
+				$iPower = 10;
+			}
+		}
+		#查询共享权限,如果共享权限更大,覆盖上面的的
+		$sharePower = share_get_res_power($_COOKIE["userid"],$id);
+		if($sharePower>$iPower){
+			$iPower=$sharePower;
+		}
+		return $iPower;
+	}
+
+}
+
+?>

+ 24 - 0
app/article/get.php

@@ -5,14 +5,38 @@ require_once "../path.php";
 require_once "../public/_pdo.php";
 require_once '../public/function.php';
 require_once '../ucenter/function.php';
+require_once '../redis/function.php';
+require_once "../article/function.php";
+
 
 
 if(isset($_GET["id"])){
+	//查询权限
+	$redis = redis_connect();
+	$article = new Article($redis); 
+	$power = $article->getPower($_GET["id"]);
+	if($power<10){
+		$output = array();
+		$output["title"]="error";
+		$output["subtitle"]="No Power For Read";
+		$output["summary"]="";
+		$output["content"]="该资源不是公开资源。您**没有**阅读权限。";
+		$output["owner"]="";
+		$output["username"]=array("username"=>"","nickname"=>"");
+		$output["status"]="";
+		echo json_encode($output, JSON_UNESCAPED_UNICODE);
+		exit;
+	}
+	#查询权限结束
+	/*
     PDO_Connect(""._FILE_DB_USER_ARTICLE_);
     $id=$_GET["id"];
     $query = "SELECT * FROM article  WHERE id = ? ";
     $Fetch = PDO_FetchRow($query,array($id));
+	*/
+	$Fetch = $article->getInfo($_GET["id"]);
     if($Fetch){
+		$Fetch["content"] = $article->getContent($_GET["id"]);
         $userinfo = new UserInfo();
         $user = $userinfo->getName($Fetch["owner"]);
         $Fetch["username"] = $user;

+ 3 - 0
app/article/index.php

@@ -204,6 +204,9 @@ function GetPageScroll()
 }
 	</script>
 
+<div class="modal_win_bg">
+</div>
+<div id="model_win" class="model_win_container"></div>
 
 </body>
 </html>

+ 1 - 1
app/article/list_new.php

@@ -25,7 +25,7 @@ require_once '../collect/function.php';
         $begin = 0;
     }
     PDO_Connect(""._FILE_DB_USER_ARTICLE_);
-    $query = "SELECT id,title,subtitle,summary,owner,modify_time from article  where status <> 0 ";
+    $query = "SELECT id,title,subtitle,summary,owner,modify_time from article  where status >= 30 ";
     
     if(isset($_GET["orderby"])){
         switch ($_GET["orderby"]) {

+ 45 - 20
app/article/my_article.js

@@ -1,6 +1,8 @@
 var _display = "para";
+var share_win;
 function my_article_init() {
 	my_article_list();
+	share_win = iframe_win_init({ container: "share_win", name: "share", width: "500px" });
 	article_add_dlg_init("article_add_div");
 }
 function my_article_list() {
@@ -25,7 +27,7 @@ function my_article_list() {
 					html += "<div style='flex:1;'>" + gLocal.gui.copy_link + "</div>";
 					html += "<div style='flex:1;'>" + gLocal.gui.edit + "</a></div>";
 					html += "<div style='flex:1;'>" + gLocal.gui.preview + "</a></div>";
-					html += "<div style='flex:1;'>15</div>";
+					html += "<div style='flex:1;'></div>";
 					html += "</div>";
 					//列表
 					for (const iterator of result) {
@@ -47,7 +49,9 @@ function my_article_list() {
 							"' target='_blank'>" +
 							gLocal.gui.preview +
 							"</a></div>";
-						html += "<div style='flex:1;'>15</div>";
+						html += "<div style='flex:1;'>";
+						html += "<a onclick=\"article_share('" + iterator.id + "')\">share</a>";
+						html += "</div>";
 						html += "</div>";
 					}
 					$("#article_list").html(html);
@@ -60,32 +64,53 @@ function my_article_list() {
 		}
 	);
 }
-
-function render_status(status) {
+function article_share(id) {
+	share_win.show("../share/share.php?id=" + id + "&type=3");
+}
+function render_status(status, readonly = true) {
 	status = parseInt(status);
 	let html = "";
 	let objStatus = [
 		{
-			id: 1,
-			name:
-				"<svg class='icon'><use xlink:href='../studio/svg/icon.svg#ic_lock'></use></svg>" + gLocal.gui.private,
+			id: 10,
+			icon: "<svg class='icon'><use xlink:href='../studio/svg/icon.svg#ic_lock'></use></svg>",
+			name: gLocal.gui.private,
 			tip: gLocal.gui.private_note,
-		},
-		{
-			id: 2,
-			name:
-				"<svg class='icon'><use xlink:href='../studio/svg/icon.svg#eye_disable'></use></svg>" +
-				gLocal.gui.unlisted,
+		} /*
+		,{
+			id: 20,
+			icon: "<svg class='icon'><use xlink:href='../studio/svg/icon.svg#eye_disable'></use></svg>",
+			name: gLocal.gui.unlisted,
 			tip: gLocal.gui.unlisted_note,
-		},
+		}*/,
 		{
-			id: 3,
-			name:
-				"<svg class='icon'><use xlink:href='../studio/svg/icon.svg#eye_enable'></use></svg>" +
-				gLocal.gui.public,
+			id: 30,
+			icon: "<svg class='icon'><use xlink:href='../studio/svg/icon.svg#eye_enable'></use></svg>",
+			name: gLocal.gui.public,
 			tip: gLocal.gui.public_note,
 		},
 	];
+	if (readonly) {
+		for (const iterator of objStatus) {
+			if (iterator.id == status) {
+				return "<div >" + iterator.icon + iterator.name + "</div>";
+			}
+		}
+	} else {
+		let html = "";
+		html += "<select name='status'>";
+		for (const iterator of objStatus) {
+			html += "<option value='" + iterator.id + "' ";
+			if (iterator.id == status) {
+				html += "selected";
+			}
+			html += " >";
+			html += iterator.name;
+			html += "</option>";
+		}
+		html += "</select>";
+		return html;
+	}
 	html += '<div class="case_dropdown"  style="flex:7;">';
 	html += '<input type="hidden" name="status"  value ="' + status + '" />';
 
@@ -136,7 +161,7 @@ function my_article_edit(id) {
 					html += "<input type='hidden' name='tag' value='" + result.tag + "'/>";
 					html += "<input type='hidden' name='status' value='" + result.status + "'/>";
 
-					html += "<input type='checkbox' name='import' />" + gLocal.gui.import + gLocal.gui.text;
+					//html += "<input type='checkbox' name='import' />" + gLocal.gui.import + gLocal.gui.text;
 					html += "<div>";
 					//html += "<div id='article_collect' vui='collect-dlg' ></div>"
 					html += "<div style='display:flex;'>";
@@ -179,7 +204,7 @@ function my_article_edit(id) {
 					$("#article_list").html(html);
 					channal_select_init("channal_selector");
 					tran_lang_select_init("article_lang_select");
-					$("#aritcle_status").html(render_status(result.status));
+					$("#aritcle_status").html(render_status(result.status, false));
 					let html_title =
 						"<input id='input_article_title' type='input' name='title' value='" + result.title + "' />";
 					$("#article_title").html(html_title);

+ 3 - 1
app/article/my_article_index.php

@@ -66,7 +66,9 @@ require_once '../studio/index_head.php';
 			</div>
 		</div>
 	</div>
-	
+	<div class="modal_win_bg">
+	<div id="share_win" class="iframe_container"></div>
+</div>
 <?php
 require_once '../studio/index_foot.php';
 ?>

+ 19 - 10
app/article/my_article_post.php

@@ -4,17 +4,19 @@ require_once "../public/_pdo.php";
 require_once '../public/function.php';
 require_once '../hostsetting/function.php';
 require_once "../ucenter/active.php";
+require_once "../article/function.php";
+require_once "../redis/function.php";
 
 add_edit_event(_ARTICLE_EDIT_,$_POST["id"]);
 
 $respond=array("status"=>0,"message"=>"");
 
-# 检查是否修改权限
-PDO_Connect(""._FILE_DB_USER_ARTICLE_);
-$query = "SELECT owner FROM  article WHERE id= ?";
-$owner = PDO_FetchOne($query,array($_POST["id"]));
-if($owner!=$_COOKIE["userid"]){
-    $respond["status"]=1;
+# 检查是否修改权限
+$redis = redis_connect();
+$article = new Article($redis); 
+$power = $article->getPower($_POST["id"]);
+if($power<20){
+	$respond["status"]=1;
     $respond["message"]="No Power For Edit";
     echo json_encode($respond, JSON_UNESCAPED_UNICODE);
     exit;
@@ -22,6 +24,7 @@ if($owner!=$_COOKIE["userid"]){
 
 $_content = $_POST["content"];
 
+/*
 if($_POST["import"]=='on'){
     $sent = explode("\n",$_POST["content"]);
     if($sent && count($sent)>0){
@@ -45,7 +48,7 @@ if($_POST["import"]=='on'){
         }
         PDO_Connect(""._FILE_DB_SENTENCE_);
 
-        /* 开始一个事务,关闭自动提交 */
+        # 开始一个事务,关闭自动提交 
         $PDO->beginTransaction();
         $query="INSERT INTO sentence ('id','block_id','channal','book','paragraph','begin','end','tag','author','editor','text','language','ver','status','strlen','create_time','modify_time','receive_time') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? , ?, ?)";
         
@@ -96,7 +99,7 @@ if($_POST["import"]=='on'){
         $PDO->commit();
         
         if (!$sth || ($sth && $sth->errorCode() != 0)) {
-            /*  识别错误且回滚更改  */
+            #  识别错误且回滚更改  
             $PDO->rollBack();
             $error = PDO_ErrorInfo();
             $respond['status']=1;
@@ -111,8 +114,8 @@ if($_POST["import"]=='on'){
         }		        
     }
 }
-
-PDO_Connect(""._FILE_DB_USER_ARTICLE_);
+*/
+PDO_Connect(_FILE_DB_USER_ARTICLE_);
 
 $query="UPDATE article SET title = ? , subtitle = ? , summary = ?, content = ?  , tag = ? , setting = ? , status = ? , receive_time= ?  , modify_time= ?   where  id = ?  ";
 $sth = $PDO->prepare($query);
@@ -123,5 +126,11 @@ if (!$sth || ($sth && $sth->errorCode() != 0)) {
 	$respond['status']=1;
 	$respond['message']=$error[2];
 }
+else{
+	if($redis){
+		$redis->del("article://".$_POST["id"]);
+	}
+	
+}
 echo json_encode($respond, JSON_UNESCAPED_UNICODE);
 ?>

+ 6 - 3
app/article/my_article_put.php

@@ -1,4 +1,7 @@
 <?php
+/*
+新建文章
+*/
 require_once "../path.php";
 require_once "../public/_pdo.php";
 require_once '../public/function.php';
@@ -6,15 +9,15 @@ require_once '../hostsetting/function.php';
 require_once "../ucenter/active.php";
 
 $respond=array("status"=>0,"message"=>"");
-PDO_Connect(""._FILE_DB_USER_ARTICLE_);
+PDO_Connect(_FILE_DB_USER_ARTICLE_);
 
 $query="INSERT INTO article ( id,  title  , subtitle  , summary , content   , tag  , owner, setting  , status  , create_time , modify_time , receive_time   )  VALUES  ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? ) ";
 $sth = $PDO->prepare($query);
 $uuid = UUID::v4();
 //写入日志
 add_edit_event(_ARTICLE_NEW_,$uuid);
-
-$sth->execute(array($uuid , $_POST["title"] , "" ,"", "" , "" , $_COOKIE["userid"] , "{}" , 1 , mTime() ,  mTime() , mTime() ));
+#新建文章默认私有
+$sth->execute(array($uuid , $_POST["title"] , "" ,"", "" , "" , $_COOKIE["userid"] , "{}" , 10 , mTime() ,  mTime() , mTime() ));
 $respond=array("status"=>0,"message"=>"");
 if (!$sth || ($sth && $sth->errorCode() != 0)) {
 	$error = PDO_ErrorInfo();

+ 34 - 0
app/channal/card.php

@@ -0,0 +1,34 @@
+<?php
+//
+
+require_once "../path.php";
+require_once "../public/_pdo.php";
+require_once '../ucenter/function.php';
+
+
+if (isset($_GET["id"])) {
+	$output["id"]=$_GET["id"];
+	PDO_Connect( _FILE_DB_CHANNAL_);
+	$query = "SELECT name,create_time,owner,summary FROM channal  WHERE id = ? ";
+	$channel = PDO_FetchRow($query, array($_GET["id"]));
+	$strData="";
+	if ($channel) {
+		
+		$_userinfo = new UserInfo();
+		$name = $_userinfo->getName($channel["owner"]);
+
+		$strData .= "<div>名称:".$channel["name"]."</div>";
+		$strData .=  "<div>创建人:".$name["nickname"]."</div>";
+		$strData .=  "<div>创建时间:".date("Y/m/d",$channel["create_time"]/1000)."</div>";
+		$strData .=  "<div>简介:".$channel["summary"]."</div>";
+	} else {
+		$strData .=  "unkow";
+	}
+	$output["data"] = $strData;
+} else {
+	$output["id"]=0;
+	$output["data"] = "unkow";
+}
+echo json_encode($output, JSON_UNESCAPED_UNICODE);
+
+?>

+ 68 - 17
app/channal/channal.js

@@ -2,9 +2,10 @@ var _my_channal = null;
 var gChannelId;
 var get_channel_list_callback = null;
 channal_list();
-
+var share_win;
 function channal_list_init() {
 	my_channal_list();
+	share_win = iframe_win_init({ container: "share_win", name: "share", width: "500px" });
 	channal_add_dlg_init("channal_add_div");
 }
 function channal_list() {
@@ -45,12 +46,18 @@ function my_channal_list() {
 						html += '<div class="file_list_row" style="padding:5px;">';
 						html += '<div style="max-width:2em;flex:1;"><input type="checkbox" /></div>';
 						html += "<div style='flex:1;'>" + key++ + "</div>";
-						html += "<div style='flex:2;'>" + iterator.name + "</div>";
 						html += "<div style='flex:2;'>";
-						if (iterator.username == getCookie("username")) {
+						html += "<guide url='../channal/card.php' gid='" + iterator.id + "'>";
+						html += iterator.name;
+						html += "</guide>";
+						html += "</div>";
+						html += "<div style='flex:2;'>";
+						if (parseInt(iterator.power) == 30) {
 							html += gLocal.gui.your;
 						} else {
+							html += "<guide url='../ucenter/card.php' gid='" + iterator.owner + "'>";
 							html += iterator.nickname;
+							html += "</guide>";
 						}
 
 						html += "</div>";
@@ -67,16 +74,51 @@ function my_channal_list() {
 						}
 						//render_status(iterator.status) +
 						html += "</div>";
-						html +=
-							"<div style='flex:1;'><a href='../channal/my_channal_edit.php?id=" +
-							iterator.id +
-							"'>" +
-							gLocal.gui.edit +
-							"</a></div>";
-						html += "<div style='flex:1;'></div>";
+
+						switch (parseInt(iterator.power)) {
+							case 10:
+								html += "<div style='flex:1;'>";
+								html += gLocal.gui.read_only;
+								html += "</div>";
+								html += "<div style='flex:1;'>";
+								html += "</div>";
+								break;
+							case 20:
+								html += "<div style='flex:1;'>";
+								html += gLocal.gui.write;
+								html += "</div>";
+								html += "<div style='flex:1;'>";
+								html +=
+									"<a href='../channal/my_channal_edit.php?id=" +
+									iterator.id +
+									"'>" +
+									gLocal.gui.edit +
+									"</a>";
+								html += "</div>";
+								break;
+							case 30:
+								html += "<div style='flex:1;'>";
+								html += gLocal.gui.owner;
+								html += "</div>";
+								html += "<div style='flex:1;'>";
+								html +=
+									"<a href='../channal/my_channal_edit.php?id=" +
+									iterator.id +
+									"'>" +
+									gLocal.gui.edit +
+									"</a>";
+								html += " <a onclick=\"channel_share('" + iterator.id + "')\">Share</a>";
+								html += "</div>";
+
+								break;
+							default:
+								break;
+						}
+
 						html += "</div>";
 					}
 					$("#my_channal_list").html(html);
+					guide_init();
 				} catch (e) {
 					console.error(e);
 				}
@@ -87,6 +129,9 @@ function my_channal_list() {
 	);
 }
 
+function channel_share(id) {
+	share_win.show("../share/share.php?id=" + id + "&type=2");
+}
 /*
 编辑channel信息
 */
@@ -175,14 +220,20 @@ function my_channal_edit(id) {
 					html += "</div>";
 					html += "</div>";
 					html += "</div>";
-
+					/*
+					旧的channel分享方式 删除
 					html += "<div id='coop_div' style='padding:5px;position: relative;'>";
-					html += "<h2>"+gLocal.gui.cooperators+"</h2>";
+					html += "<h2>" + gLocal.gui.cooperators + "</h2>";
 
-					html += "<button onclick='add_coop_user()'>"+gLocal.gui.add+gLocal.gui.cooperators+"</button>";
+					html +=
+						"<button onclick='add_coop_user()'>" + gLocal.gui.add + gLocal.gui.cooperators + "</button>";
 					html += "<div id='add_coop_user_dlg' class='float_dlg' style='left: 0;'></div>";
 
-					html += "<button onclick='add_coop_group()' >"+gLocal.gui.add+gLocal.gui.cooperate_group+"</button>";
+					html +=
+						"<button onclick='add_coop_group()' >" +
+						gLocal.gui.add +
+						gLocal.gui.cooperate_group +
+						"</button>";
 					html += "<div id='add_coop_group_dlg' class='float_dlg' style='left: 0;'></div>";
 					html += "<div id='coop_inner' >";
 					if (typeof result.coop == "undefined" || result.coop.length == 0) {
@@ -191,7 +242,7 @@ function my_channal_edit(id) {
 						for (const coop of result.coop) {
 							html += '<div class="file_list_row" style="padding:5px;">';
 							if (coop.type == 0) {
-								html += '<div style="flex:1;">'+gLocal.gui.personal+'</div>';
+								html += '<div style="flex:1;">' + gLocal.gui.personal + "</div>";
 								html += "<div style='flex:3;'>" + coop.user_name.nickname + "</div>";
 							} else {
 								html += '<div style="flex:1;">' + gLocal.gui.group + "</div>";
@@ -200,14 +251,14 @@ function my_channal_edit(id) {
 
 							html += "<div style='flex:3;'>" + coop.power + "</div>";
 							html += "<div class='hover_button' style='flex:3;'>";
-							html += "<button>"+gLocal.gui.remove+"</button>";
+							html += "<button>" + gLocal.gui.remove + "</button>";
 							html += "</div>";
 							html += "</div>";
 						}
 					}
 					html += "</div>";
 					html += "</div>";
-
+*/
 					$("#channal_info").html(html);
 					user_select_dlg_init("add_coop_user_dlg");
 					tran_lang_select_init("channal_lang_select");

+ 77 - 8
app/channal/function.php

@@ -1,26 +1,95 @@
 <?php
 require_once "../path.php";
+require_once "../share/function.php";
+
+function channel_get_title($id)
+{
+    if (isset($id)) {
+		PDO_Connect( _FILE_DB_CHANNAL_);
+		$query = "SELECT name FROM channal  WHERE id = ? ";
+		$channel = PDO_FetchRow($query, array($id));
+		if ($channel) {
+			return $channel["name"];
+		} else {
+			return "";
+		}
+    } else {
+        return "";
+    }
+}
+
 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){
         $query = "SELECT * FROM channal WHERE id= ? ";
         $stmt = $this->dbh->prepare($query);
         $stmt->execute(array($id));
-        $channal = $stmt->fetchAll(PDO::FETCH_ASSOC);
-        if(count($channal)>0){
-            return $channal[0];
+        $channal = $stmt->fetch(PDO::FETCH_ASSOC);
+        if($channal){
+            return $channal;
         }
         else{
             return false;
         }
-    }
+	}
+	public function getTitle($id)
+	{
+		if (isset($id)) {
+			$query = "SELECT name FROM channal  WHERE id = ? ";
+			$stmt = $this->dbh->prepare($query);
+			$stmt->execute(array($id));
+			$channal = $stmt->fetch(PDO::FETCH_ASSOC);
+			if ($channel) {
+				return $channel["name"];
+			} else {
+				return "";
+			}
+		} else {
+			return "";
+		}
+	}
+	public function getPower($id){
+		#查询用户对此channel是否有权限		
+
+		$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;
+			}
+			else if($channel["status"]>=30){
+				#全网公开的 可以提交pr
+				$channelPower = 10;
+			}
+		}
+		#查询共享权限,如果共享权限更大,覆盖上面的的
+		$sharePower = share_get_res_power($_COOKIE["userid"],$id);
+		if($sharePower>$channelPower){
+			$channelPower=$sharePower;
+		}
+		return $channelPower;
+	}
 
 }
 

+ 27 - 21
app/channal/get.php

@@ -4,12 +4,14 @@
 require_once "../path.php";
 require_once "../public/_pdo.php";
 require_once '../ucenter/function.php';
+require_once '../share/function.php';
 
 if(!isset($_COOKIE["userid"])){
 	echo json_encode(array(), JSON_UNESCAPED_UNICODE);
 	exit;
 }
 
+/*
 # 找我加入的群
 PDO_Connect(""._FILE_DB_GROUP_);
 $query = "SELECT group_id from group_member where user_id = ?  limit 0,100";
@@ -20,40 +22,44 @@ foreach ($my_group as $key => $value) {
 	# code...
 	$userList[]=$value["group_id"];
 }
+*/
+#查重复
+$channelList = array();
 
 //找自己的
 PDO_Connect(""._FILE_DB_CHANNAL_);
-$query = "SELECT * from channal where owner = ?  limit 0,100";
+$query = "SELECT id,owner,name,status,lang FROM channal WHERE owner = ?  LIMIT 0,100";
 $Fetch_my = PDO_FetchAll($query,array($_COOKIE["userid"]));
 
-$place_holders = implode(',', array_fill(0, count($userList), '?'));
+foreach ($Fetch_my as $key => $value) {
+	# code...
+	$channelList[$value["id"]]=array("id"=>$value["id"],"owner"=>$value["owner"],"name"=>$value["name"],"power"=>30,"status"=>$value["status"],"lang"=>$value["lang"]);
+}
+
 # 找协作的
+$coop_channal =  share_res_list_get($_COOKIE["userid"],2);
 $Fetch_coop = array();
-$query = "SELECT channal_id FROM cooperation WHERE  user_id IN ($place_holders) ";
-$coop_channal = PDO_FetchAll($query,$userList);
-if(count($coop_channal)>0){
-    foreach ($coop_channal as $key => $value) {
-        # code...
-        $channal[]=$value["channal_id"];
-    }
-    /*  创建一个填充了和params相同数量占位符的字符串 */
-    $place_holders = implode(',', array_fill(0, count($channal), '?'));
-    $query = "SELECT * FROM channal WHERE id IN ($place_holders) order by owner";
-    $Fetch_coop = PDO_FetchAll($query,$channal);
+foreach ($coop_channal as $key => $value) {
+	# return res_id,res_type,power res_title  res_owner_id
+	if(isset($channelList[$value["res_id"]])){
+		if($channelList[$value["res_id"]]["power"]<(int)$value["power"]){
+			$channelList[$value["res_id"]]["power"]=(int)$value["power"];
+		}
+	}
+	else{
+		$channelList[$value["res_id"]]=array("id"=>$value["res_id"],"owner"=>$value["res_owner_id"],"name"=>$value["res_title"],"power"=>(int)$value["power"],"status"=>(int)$value["status"],"lang"=>(int)$value["lang"]);
+	}
 }
-$all = array_merge_recursive($Fetch_my,$Fetch_coop);
-
-
 
 $_userinfo = new UserInfo();
 
 $output = array();
-foreach ($all as $key => $value) {
+foreach ($channelList as $key => $value) {
     # code...
-    $new = $value;
-    $name = $_userinfo->getName($value["owner"]);
-    $new["username"] = $name["username"];
-	$new["nickname"] = $name["nickname"];
+	$new = $value;
+	$name = $_userinfo->getName($value["owner"]);	
+	$new["username"] = $name["username"];
+	$new["nickname"] = $name["nickname"];	
 	$new["count"] = 0;
     $new["all"] = 1;
     $output[]=$new;

+ 3 - 0
app/channal/my_channal_index.php

@@ -66,6 +66,9 @@ require_once '../studio/index_head.php';
 		
 	</div>
 	
+<div class="modal_win_bg">
+	<div id="share_win" class="iframe_container"></div>
+</div>
 
 <?php
 require_once '../studio/index_foot.php';

+ 34 - 0
app/collect/card.php

@@ -0,0 +1,34 @@
+<?php
+//
+
+require_once "../path.php";
+require_once "../public/_pdo.php";
+require_once '../ucenter/function.php';
+
+
+if (isset($_GET["id"])) {
+	$output["id"]=$_GET["id"];
+	PDO_Connect( _FILE_DB_USER_ARTICLE_);
+	$query = "SELECT title,create_time,owner,summary FROM collect  WHERE id = ? ";
+	$result = PDO_FetchRow($query, array($_GET["id"]));
+	$strData="";
+	if ($result) {
+		
+		$_userinfo = new UserInfo();
+		$name = $_userinfo->getName($result["owner"]);
+
+		$strData .= "<div>标题:".$result["title"]."</div>";
+		$strData .=  "<div>创建人:".$name["nickname"]."</div>";
+		$strData .=  "<div>创建时间:".date("Y/m/d",$result["create_time"]/1000)."</div>";
+		$strData .=  "<div>简介:".$result["summary"]."</div>";
+	} else {
+		$strData .=  "unkow";
+	}
+	$output["data"] = $strData;
+} else {
+	$output["id"]=0;
+	$output["data"] = "unkow";
+}
+echo json_encode($output, JSON_UNESCAPED_UNICODE);
+
+?>

+ 61 - 0
app/commit/commit.css

@@ -0,0 +1,61 @@
+.commit_compare {
+	display: flex;
+	padding: 5px;
+	line-height: 1.8em;
+	border-bottom: 1px solid var(--border-line-color);
+}
+.commit_compare .pali {
+	flex: 3;
+}
+.commit_compare .src_text {
+	flex: 3;
+}
+.commit_compare .dest_text {
+	flex: 3;
+}
+
+del {
+	color: red;
+}
+ins {
+	color: green;
+}
+
+.commit_head {
+	display: flex;
+	justify-content: space-around;
+	padding-bottom: 10px;
+	margin-bottom: 10px;
+	border-bottom: 1px solid var(--border-line-color);
+}
+.commit_step {
+	text-align: center;
+}
+.commit_step .num {
+	font-size: 25px;
+	font-weight: 700;
+	color: var(--btn-color);
+	width: 50px;
+	line-height: 45px;
+	text-align: center;
+	border: 2px solid var(--link-color);
+	border-radius: 99px;
+}
+.step1 > .commit_step_1 > .num {
+	border-color: var(--link-hover-color);
+	color: var(--main-color);
+}
+.step2 > .commit_step_1 > .num,
+.step2 > .commit_step_2 > .num {
+	border-color: var(--link-hover-color);
+	color: var(--main-color);
+}
+.step3 > .commit_step_1 > .num,
+.step3 > .commit_step_2 > .num,
+.step3 > .commit_step_3 > .num {
+	border-color: var(--link-hover-color);
+	color: var(--main-color);
+}
+.commit_win_inner {
+	padding: 1em;
+}

+ 356 - 0
app/commit/commit.js

@@ -0,0 +1,356 @@
+var _commit_data;
+var previewWin;
+var sentData;
+
+function commit_init(param) {
+	previewWin = model_win_init({ container: "model_win" });
+	_commit_data = param;
+
+	previewWin.show(commit_preview_render());
+}
+function commit_render_head(step) {
+	let html = "";
+	html += "<div class='commit_head step" + step + "'>";
+	html += "<div class='commit_step commit_step_1'><div class='num'>1</div><div>选择版本</div></div>";
+	html += "<div class='commit_step commit_step_2'><div class='num'>2</div><div>文本比对</div></div>";
+	html += "<div class='commit_step commit_step_3'><div class='num'>3</div><div>完成</div></div>";
+	html += "</div>";
+	return html;
+}
+function commit_render_channel_select() {
+	let html = "";
+	html += "<div class='commit_win_inner' >";
+	html += commit_render_head(1);
+	html += "<div style='display:flex;'>";
+
+	if (typeof _commit_data.src != "undefined") {
+		html += "<div>译文来源:";
+		let isFound = false;
+		for (const iterator of _my_channal) {
+			if (_commit_data.src == iterator.id) {
+				html += iterator.name;
+				isFound = true;
+				break;
+			}
+		}
+		if (!isFound) {
+			for (const iterator of _channalData) {
+				if (_commit_data.src == iterator.id) {
+					html += iterator.name;
+					isFound = true;
+					break;
+				}
+			}
+		}
+		if (!isFound) {
+			html += "无法找到Channel";
+		}
+		html += "</div>";
+	} else {
+		html += "<div>请选择译文来源";
+		html += "</div>";
+	}
+	html += "<div>==></div>";
+	html += "<div>目标译文:";
+	html += "<select id='dest_channel' onchange='dest_change(this)'>";
+	if (typeof _commit_data.dest == "undefined") {
+		let lastDest = localStorage.getItem("commit_src_" + _commit_data.src);
+		if (typeof lastDest == "undefined") {
+			html += "<option value='' selected>请选择目标版本</option>";
+		} else {
+			_commit_data.dest = lastDest;
+		}
+	}
+	for (const iterator of _my_channal) {
+		if (iterator.status > 0 && _commit_data.src != iterator.id) {
+			html += "<option value='" + iterator.id + "' ";
+			if (_commit_data.dest == iterator.id) {
+				html += " selected ";
+			}
+			if (typeof _commit_data.src != "undefined" && _commit_data.src == iterator.id) {
+				html += "style:'display:none;' ";
+			}
+			html += " >" + iterator.name + "-";
+			if (iterator.power >= 30) {
+				html += gLocal.gui.your;
+			} else if (iterator.power >= 20) {
+				html += "可编辑";
+			} else if (iterator.power >= 10) {
+				html += "只读";
+			} else {
+				html += "停用";
+			}
+			html += "</option>";
+		}
+	}
+	html += "</select>";
+	html += "</div>";
+
+	html += "<div id='commit_preview'>";
+	if (typeof _commit_data.express != "undefined" && _commit_data.express == true) {
+		if (typeof _commit_data.sent != "undefined" && _commit_data.sent.length != 0) {
+			html += "<button onclick='commit_pull()'>推送</button>";
+		} else {
+			html += "没有句子数据";
+		}
+	} else {
+		html += "<button onclick='previewWin.show(commit_preview_render())'>文本比对</button>";
+	}
+
+	html += "</div>";
+	html += "</div>";
+
+	html += "</div>";
+	return html;
+}
+
+function commit_preview_render() {
+	let html = "";
+	html += "<div class='commit_win_inner'>";
+	html += commit_render_head(2);
+
+	if (
+		typeof _commit_data.src != "undefined" &&
+		_commit_data.src != null &&
+		_commit_data.src != "" &&
+		typeof _commit_data.dest != "undefined" &&
+		_commit_data.dest != null &&
+		_commit_data.dest != ""
+	) {
+		if (typeof _commit_data.sent == "undefined" || _commit_data.sent.length == 0) {
+			let sentList = new Array();
+			for (const iterator of _arrData) {
+				sentList.push(iterator.book + "-" + iterator.para + "-" + iterator.begin + "-" + iterator.end);
+			}
+			_commit_data.sent = sentList;
+		}
+
+		let arrSentInfo = new Array();
+		for (const iterator of _commit_data.sent) {
+			let id = com_guid();
+			arrSentInfo.push({ id: id, data: iterator });
+		}
+
+		if (arrSentInfo.length > 0) {
+			let setting = new Object();
+			setting.lang = "";
+			setting.channal = _commit_data.src + "," + _commit_data.dest;
+			$.post(
+				"../term/note.php",
+				{
+					setting: JSON.stringify(setting),
+					data: JSON.stringify(arrSentInfo),
+				},
+				function (data, status) {
+					if (status == "success") {
+						try {
+							sentData = JSON.parse(data);
+						} catch (e) {}
+
+						previewWin.show(commit_render_comp(0));
+					}
+				}
+			);
+			html += "加载中 请稍等……";
+			html += "</div>";
+			return html;
+		} else {
+			html += "没有句子被选择";
+			html += "</div>";
+			return html;
+		}
+	} else {
+		return commit_render_channel_select();
+	}
+}
+function commit_compare_mode_change(obj) {
+	previewWin.show(commit_render_comp(parseInt($(obj).val())));
+}
+function commit_render_comp(mode) {
+	let html = "";
+	html += "<div class='commit_win_inner'>";
+	html += commit_render_head(2);
+	html += "<div>";
+	html += "<button onclick='previewWin.show(commit_render_channel_select())'>返回</button>";
+	html += "<button onclick='commit_pull()'>推送</button>";
+	html += "<button onclick='commit_close()'>放弃</button>";
+	html += "</div>";
+	html += "<div class='commit_compare'>";
+	html += "<div >";
+	html += "<select onchange='commit_compare_mode_change(this)'>";
+	let compareMode = [
+		{ id: 0, string: "自动" },
+		{ id: 1, string: "全选" },
+		{ id: 2, string: "全不选" },
+	];
+	for (const iterator of compareMode) {
+		html += "<option value='" + iterator.id + "' ";
+		if (mode == iterator.id) {
+			html += " selected ";
+		}
+		html += ">" + iterator.string + "</option>";
+	}
+	html += "</select>";
+	html += "</div>";
+	html += "<div class='pali'>巴利原文</div>";
+	html += "<div class='src_text'>当前版本:" + channal_getById(_commit_data.src).name + "</div>";
+	html += "<div class='dest_text'>推送到:" + channal_getById(_commit_data.dest).name + "</div>";
+	html += "</div>";
+
+	let textCount = 0;
+	let sentIndex = 0;
+	for (let iterator of sentData) {
+		iterator.checked = false;
+		if (iterator.translation[0].text != iterator.translation[1].text) {
+			textCount++;
+			if (iterator.translation[0].id != "") {
+				html += "<div class='commit_compare'>";
+				html += "<div >";
+				html += "<input class='sent_checkbox' index='" + sentIndex + "' type='checkbox' ";
+				switch (mode) {
+					case 0:
+						if (iterator.translation[1].id == "") {
+							html += " checked ";
+							iterator.checked = true;
+						} else {
+							if (iterator.translation[0].update_time > iterator.translation[1].update_time) {
+								html += " checked ";
+								iterator.checked = true;
+							}
+						}
+						break;
+					case 1:
+						html += " checked ";
+						iterator.checked = true;
+						break;
+					case 2:
+						break;
+					default:
+						break;
+				}
+				html += " sent_id='" + iterator.pali_sent_id;
+				html += "' onclick='commit_sent_select(this)' /></div>";
+				html += "<div class='pali'>" + iterator.palitext + "</div>";
+				html += "<div class='src_text'>";
+				html += iterator.translation[0].text;
+				html += "</div>";
+				html += "<div ";
+				html += "channel='" + _commit_data.dest + "'";
+				html += "sent_id='" + iterator.pali_sent_id + "'";
+				html += " class='dest_text'>";
+				switch (mode) {
+					case 0:
+						if (iterator.translation[1].id == "") {
+							html += "<ins>" + iterator.translation[0].text + "</ins>";
+						} else {
+							if (iterator.translation[0].update_time > iterator.translation[1].update_time) {
+								html += "<del>" + iterator.translation[1].text + "</del><br>";
+								html += "<ins>" + iterator.translation[0].text + "</ins>";
+							} else {
+								html += "[新]" + iterator.translation[1].text;
+							}
+						}
+						break;
+					case 1:
+						html += "<del>" + iterator.translation[1].text + "</del><br>";
+						html += "<ins>" + iterator.translation[0].text + "</ins>";
+						break;
+					case 2:
+						html += iterator.translation[1].text;
+						break;
+				}
+
+				html += "</div>";
+				html += "</div>";
+			}
+		}
+		sentIndex++;
+	}
+	if (textCount == 0) {
+		html += "译文全部相同,无需推送。";
+	}
+	html += "</div>";
+	return html;
+}
+
+function commit_sent_select(obj) {
+	let sent_id = $(obj).attr("sent_id");
+	for (let iterator of sentData) {
+		if (iterator.pali_sent_id == sent_id) {
+			let html = "";
+			iterator.checked = obj.checked;
+			if (obj.checked) {
+				if (iterator.translation[1].id != "") {
+					html += "<del>" + iterator.translation[1].text + "</del><br>";
+				}
+				html += "<ins>" + iterator.translation[0].text + "</ins>";
+			} else {
+				html += iterator.translation[1].text;
+			}
+			$(".dest_text[sent_id='" + sent_id + "']").html(html);
+		}
+	}
+}
+
+function commit_render_final(result) {
+	let html = "";
+	html += "<div class='commit_win_inner'>";
+	html += commit_render_head(3);
+	if (typeof result.update != "undefined") {
+		html += "<div>修改:" + result.update + "</div>";
+	}
+	if (typeof result.insert != "undefined") {
+		html += "<div>新增:" + result.insert + "</div>";
+	}
+	if (typeof result.pr != "undefined") {
+		html += "<div>提交修改建议:" + result.pr + "</div>";
+	}
+	html +=
+		"<div><a href='' onclick='window.reload()'>刷新页面</a>查看修改结果。<a onclick='previewWin.close()'>关闭</a></div>";
+	html += "</div>";
+	return html;
+}
+function commit_pull() {
+	localStorage.setItem("commit_src_" + _commit_data.src, _commit_data.dest);
+	let pullData = new Array();
+	for (const iterator of sentData) {
+		if (iterator.checked) {
+			for (const iterator of _arrData) {
+				pullData.push(iterator.book + "-" + iterator.para + "-" + iterator.begin + "-" + iterator.end);
+			}
+			_commit_data.sent = pullData;
+		}
+	}
+	if (pullData.length == 0) {
+		alert("没有数据被选择");
+		return;
+	}
+	$.post(
+		"../commit/commit.php",
+		{
+			data: JSON.stringify(_commit_data),
+		},
+		function (data, status) {
+			if (status == "success") {
+				let html = "";
+				try {
+					let result = JSON.parse(data);
+					if (result.status == 0) {
+						previewWin.show(commit_render_final(result));
+					} else {
+						alert(result.message);
+					}
+				} catch (e) {}
+			}
+		}
+	);
+}
+function commit_close() {}
+function dest_change(obj) {
+	_commit_data.dest = $(obj).val();
+	localStorage.setItem("commit_src_" + _commit_data.src, _commit_data.dest);
+}
+function src_change(obj) {
+	_commit_data.src = $(obj).val();
+	localStorage.setItem("commit_last_src", _commit_data.src);
+}

+ 145 - 0
app/commit/commit.php

@@ -0,0 +1,145 @@
+<?php 
+require_once "../path.php";
+require_once "../public/_pdo.php";
+require_once "../public/function.php";
+require_once "../channal/function.php";
+require_once "../redis/function.php";
+require_once "../share/function.php";
+require_once "../usent/function.php";
+
+$respond['message'] = "";
+$respond['status'] = 0;
+
+$_data = array();
+if (isset($_POST["data"])) {
+    $_data = json_decode($_POST["data"], true);
+} else {
+	$respond['message'] = "缺少输入数据";
+	$respond['status'] = 1;
+	echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+	exit;
+}
+$channelInfo  = new Channal();
+$srcChannelPower = $channelInfo->getPower($_data["src"]);
+$destChannelPower = $channelInfo->getPower($_data["dest"]);
+
+
+if($srcChannelPower<10){
+	$respond['message'] = "源channel无权限";
+	$respond['status'] = 1;
+	echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+	exit;		
+}
+if($destChannelPower<10){
+	$respond['message'] = "channel无权限";
+	$respond['status'] = 1;
+	echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+	exit;		
+}
+
+$db_trans_sent = new PDO(_FILE_DB_SENTENCE_, "", "", array(PDO::ATTR_PERSISTENT => true));
+$db_trans_sent->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
+
+$query = "SELECT * FROM sentence WHERE book= ? AND paragraph= ? AND begin= ? AND end= ?  AND channal = ?  ";
+$stmt = $db_trans_sent->prepare($query);
+
+if($stmt){
+	$updateDate=array();
+	$insertData=array();
+	$prData=array();
+	$insertHistoray=array();
+	foreach ($_data["sent"] as $key => $value) {
+		# code...
+		$infoSrc = explode("-",$value);
+		$infoDest = $infoSrc;
+		$infoSrc[]=$_data["src"];
+		$infoDest[]=$_data["dest"];
+		$stmt->execute($infoSrc);
+		$fetchSrc = $stmt->fetch(PDO::FETCH_ASSOC);
+		if ($fetchSrc) {
+			# 有 源数据
+			$newData = $fetchSrc;
+			$newData["modify_time"]=mTime();
+			$newData["channal"]=$_data["dest"];
+			$newData["landmark"]="";
+			$stmt->execute($infoDest);
+			$fetchDest = $stmt->fetch(PDO::FETCH_ASSOC);
+			if ($fetchDest) {
+				#有目标数据,比较时间
+				$insert=false;
+				if(isset($_data["compare"]) && $_data["compare"]=="auto"){
+					if($fetchSrc["modify_time"]>$fetchDest["modify_time"]){
+						$insert = true;
+					}					
+				}
+				else{
+					$insert = true;
+				}
+				if($insert){
+					#新数据 更新
+					if($destChannelPower>=20){
+						#有权限 直接写入
+						$newData["id"]=$fetchDest["id"];
+						$updateDate[] = $newData;
+						$insertHistoray[] = $newData;
+					}
+					else{
+						#pr
+						$prData[] = $newData;
+					}					
+				}
+			}
+			else{
+				#没有目标数据新增
+				if($destChannelPower>=20){
+					#有写入权限 直接写入
+					$newData["id"] = UUID::v4();
+					$insertData[] = $newData;
+					$insertHistoray[] = $newData;
+				}
+				else{
+					#pr
+					$prData[] = $newData;
+				}
+			}
+		}
+	}
+	#到此,所有的数据已经准备好
+
+	$sentDb = new Sent_DB();
+
+	if($sentDb->update($updateDate)){
+		$respond['update'] = count($updateDate);
+	}
+	else{
+		$respond['message'] = $sentDb->getError();
+        $respond['status'] = 1;
+	}
+	if($sentDb->insert($insertData)){
+		$respond['insert'] = count($insertData);
+
+	}else{
+		$respond['message'] = $sentDb->getError();
+        $respond['status'] = 1;
+	}
+	if($sentDb->send_pr($prData)){
+		$respond['pr'] = count($prData);
+
+	}else{
+		$respond['message'] = $sentDb->getError();
+        $respond['status'] = 1;
+	}
+	if($sentDb->historay($insertHistoray)){
+		$respond['historay'] = count($insertHistoray);
+
+	}else{
+		$respond['message'] = $sentDb->getError();
+        $respond['status'] = 1;
+	}
+}
+else{
+	$respond['message'] = $db_trans_sent->errorInfo();
+	$respond['status'] = 1;
+}
+echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+?>

+ 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);
 			}

+ 0 - 1
app/dict/css/style.css

@@ -305,7 +305,6 @@ input[type="submit"] {
 	margin: 2px 0;
 	line-height: 160%;
 	font-weight: 400;
-	display: inline-block;
 	font-style: normal;
 }
 

+ 1 - 12
app/dict/css/style_mobile.css

@@ -122,7 +122,6 @@ body {
 	margin-left: 0.1em;
 	font-size: 120%;
 	padding: 0.3em;
-	width:95%;
 }
 
 #left_menu_button{
@@ -135,13 +134,9 @@ body {
 
 #right_bar{
 	display:none;
-	position: fixed;
-	width: 100%;
 }
 .search_toolbar{
 	padding:0.5em 0;
-	position: fixed;
-	width: 100%;
 }
 
 guide{
@@ -150,10 +145,4 @@ guide{
 
 #search_info {
     display: block;
-}
-#main_result{
-	margin-top: 5em;
-}
-.foot_div {
-	margin-top: 5em;
-}
+}

+ 72 - 13
app/dict/dict_lookup.php

@@ -178,7 +178,7 @@ $right_word_list = "";
 						$dict_list_a[] = array("word_$x", $x);
 						echo "<div class='pali_spell'><a name='word_$x'></a>" . $x . "</div>";
 						echo "<div style='color:gray;'>{$x}->{$x_value["parent"]}->{$word}</div>";
-						//语法信息
+						//替换为本地语法信息
 						foreach ($_local->grammastr as $gr) {
 							$x_value['grammar'] = str_replace($gr->id, $gr->value, $x_value['grammar']);
 						}
@@ -235,7 +235,7 @@ $right_word_list = "";
 		//拆复合词
 		echo "<div id='auto_split'></div>";
 
-/*
+
         //查内容
         if ($count_return < 2) {
             $word1 = $org_word;
@@ -265,14 +265,18 @@ $right_word_list = "";
                     $end = mb_substr($newmean, $pos + mb_strlen($word1, "UTF-8"), null, "UTF-8");
                     $heigh_light_mean = "$head<hl>$mid</hl>$end";
                     echo "<div class='dict_word'>";
-                    echo "<div class='pali'>" . $Fetch[$i]["word"] . "</div>";
+                    echo "<div class='pali'><a href='index.php?key={$Fetch[$i]["word"]}'>" . $Fetch[$i]["word"] . "</a></div>";
                     echo "<div class='dict'>" . $Fetch[$i]["shortname"] . "</div>";
-                    echo "<div class='mean'>" . $heigh_light_mean . "</div>";
+					echo "<div class='mean'>" . $heigh_light_mean . "</div>";
+					echo "<div><a href='index.php?key={$Fetch[$i]["word"]}&hightlight={$org_word}'>详情</a></div>";
                     echo "</div>";
                 }
             }
-        }
-*/
+		}
+		else{
+
+		}
+
         echo "<div id='dictlist'>";
         foreach ($dict_list_a as $x_value) {
             if (substr($x_value[0], 0, 4) == "word") {
@@ -394,7 +398,7 @@ function lookup_user($word){
 	}
 	
 	$iFetch = count($Fetch);
-	$count_return += $iFetch;
+	$count_return += 1;
 	if ($iFetch > 0) {
 		$userlist = array();
 		foreach ($Fetch as $value) {
@@ -404,12 +408,19 @@ function lookup_user($word){
 				$userlist[$value["creator"]] = 1;
 			}
 			$userwordcase = $value["type"] . "#" . $value["gramma"];
-			if (isset($userdict["{$userwordcase}"])) {
-				$userdict["{$userwordcase}"]["mean"] .= $value["mean"] . ";";
-				$userdict["{$userwordcase}"]["factors"] .= $value["factors"];
+			$parent = $value["parent"];
+			if(empty($parent)){
+				$parent = "_null_";
+			}
+			if (isset($userdict["{$parent}"])) {
+				$userdict["{$parent}"]["mean"] .= "$". $value["mean"] ;
+				$userdict["{$parent}"]["factors"] .= "@". $value["factors"];
+				$userdict["{$parent}"]["case"] .= "@".$userwordcase;
+
 			} else {
-				$userdict["{$userwordcase}"]["mean"] = $value["mean"];
-				$userdict["{$userwordcase}"]["factors"] = $value["factors"];
+				$userdict["{$parent}"]["mean"] = $value["mean"];
+				$userdict["{$parent}"]["factors"] = $value["factors"];
+				$userdict["{$parent}"]["case"] = $userwordcase;
 			}
 
 		}
@@ -417,8 +428,56 @@ function lookup_user($word){
 		$output .= "<div class='dict'>{$_local->gui->com_dict}</div><a name='net'></a>";
 		$dict_list_a[] = array("net", $_local->gui->com_dict);
 
+
 		foreach ($userdict as $key => $value) {
-			$output .= "<div class='mean'>{$key}:{$value["mean"]}</div>";
+			#语法信息查重
+			$thiscase = array();
+			$strCase = "";
+			$arrCase = explode("@",$value["case"]);
+			foreach ($arrCase as  $case) {
+				# code...
+				$thiscase[$case] = 1;
+			}
+			foreach ($thiscase as $case => $casevalue) {
+				# code...
+				$strCase .=$case . "; ";
+			}
+			#语法信息替换为本地字符串
+			foreach ($_local->grammastr as $gr) {
+				$strCase = str_replace($gr->id, $gr->value, $strCase);
+			}
+			#拆分查重复
+			$thispart = array();
+			$strPart = "";
+			$arrPart = explode("@",$value["factors"]);
+			foreach ($arrPart as  $part) {
+				# code...
+				$thispart[$part] = 1;
+			}
+			foreach ($thispart as $part => $partvalue) {
+				# code...
+				$strPart .=$part . "; ";
+			}
+
+			#意思查重复
+			$thismean = array();
+			$strMean = "";
+			$arrMean = explode("$",$value["mean"]);
+			foreach ($arrMean as  $mean) {
+				# code...
+				$thismean[$mean] = 1;
+			}
+			foreach ($thismean as $mean => $meanvalue) {
+				# code...
+				$strMean .=$mean . "; ";
+			}
+			$output .= "<div class='mean'><b>语法</b>:{$strCase}</div>";
+			if($key!=="_null_"){
+				$output .= "<div class='mean'><b>原型</b>:<a href='index.php?key={$key}'>{$key}</a></div>";				
+			}
+
+			$output .= "<div class='mean'><b>意思</b>:{$strMean}</div>";
+			$output .= "<div class='mean'><b>组成</b>:{$strPart}</div>";
 		}
 		$output .= "<div><span>{$_local->gui->contributor}:</span>";
 		$userinfo = new UserInfo();

+ 33 - 0
app/doc/card.php

@@ -0,0 +1,33 @@
+<?php
+//
+
+require_once "../path.php";
+require_once "../public/_pdo.php";
+require_once '../ucenter/function.php';
+
+
+if (isset($_GET["id"])) {
+	$output["id"]=$_GET["id"];
+	PDO_Connect( _FILE_DB_FILEINDEX_);
+	$query = "SELECT title,create_time,user_id as owner FROM fileindex  WHERE id = ? ";
+	$result = PDO_FetchRow($query, array($_GET["id"]));
+	$strData="";
+	if ($result) {
+		
+		$_userinfo = new UserInfo();
+		$name = $_userinfo->getName($result["owner"]);
+
+		$strData .= "<div>标题:".$result["title"]."</div>";
+		$strData .=  "<div>创建人:".$name["nickname"]."</div>";
+		$strData .=  "<div>创建时间:".date("Y/m/d",$result["create_time"]/1000)."</div>";
+	} else {
+		$strData .=  "unkow";
+	}
+	$output["data"] = $strData;
+} else {
+	$output["id"]=0;
+	$output["data"] = "unkow";
+}
+echo json_encode($output, JSON_UNESCAPED_UNICODE);
+
+?>

+ 1 - 1
app/doc/coop.php

@@ -49,7 +49,7 @@ $powerlist["10"] = "仅阅读";
 $powerlist["30"] = "可修改";
 //$powerlist["40"] = "管理员";
 
-PDO_Connect("" . _FILE_DB_FILEINDEX_);
+PDO_Connect(_FILE_DB_FILEINDEX_);
 
 echo "<input id='doc_coop_docid' type='hidden' value='{$_doc_id}' />";
 $query = "SELECT * from fileindex where id = ? ";

+ 20 - 0
app/doc/function.php

@@ -0,0 +1,20 @@
+<?php
+
+require_once "../path.php";
+require_once "../public/_pdo.php";
+
+function pcs_get_title($id)
+{
+    if (isset($id)) {
+		PDO_Connect("" . _FILE_DB_FILEINDEX_);
+		$query = "SELECT title FROM fileindex  WHERE id = ? ";
+		$file = PDO_FetchRow($query, array($id));
+		if ($file) {
+			return $file["title"];
+		} else {
+			return "";
+		}
+    } else {
+        return "";
+    }
+}

+ 27 - 0
app/group/function.php

@@ -31,6 +31,7 @@ class GroupInfo
         $this->dbh = new PDO($dns, "", "", array(PDO::ATTR_PERSISTENT => true));
         $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
         $buffer = array();
+        $parentId = array();
     }
 
     public function getName($id)
@@ -57,5 +58,31 @@ class GroupInfo
             $buffer[$id] = "";
             return $buffer[$id];
         }
+	}
+	
+	public function getParentId($id)
+    {
+        if (empty($id)) {
+            return "";
+        }
+        if (isset($parentId[$id])) {
+            return $parentId[$id];
+        }
+        if ($this->dbh) {
+            $query = "SELECT parent FROM group_info WHERE id= ? ";
+            $stmt = $this->dbh->prepare($query);
+            $stmt->execute(array($id));
+            $user = $stmt->fetch(PDO::FETCH_ASSOC);
+            if ($user) {
+                $parentId[$id] = $user["parent"];
+                return $parentId[$id];
+            } else {
+                $parentId[$id] = "";
+                return $parentId[$id];
+            }
+        } else {
+            $parentId[$id] = "";
+            return $parentId[$id];
+        }
     }
 }

+ 8 - 3
app/group/get.php

@@ -5,6 +5,7 @@ require_once "../path.php";
 require_once "../public/_pdo.php";
 require_once '../public/function.php';
 require_once '../ucenter/function.php';
+require_once '../share/function.php';
 
 $output = array();
 if (isset($_GET["id"])) {
@@ -25,8 +26,9 @@ if (isset($_GET["id"])) {
             $parent_group = PDO_FetchRow($query, array($Fetch["parent"]));
             $output["parent"] = $parent_group;
         }
-        #列出组文件
+        #列出组共享资源
         {
+			/*
             PDO_Connect("" . _FILE_DB_FILEINDEX_);
             $query = "SELECT * FROM power  WHERE user = ? ";
             $fileList = PDO_FetchAll($query, array($id));
@@ -39,8 +41,11 @@ if (isset($_GET["id"])) {
                 } else {
                     $fileList[$key]["title"] = "";
                 }
-            }
-            $output["file"] = $fileList;
+			}
+			
+			$output["file"] = $fileList;
+			*/
+			$output["file"] =share_res_list_get($id);
         }
     }
 }

+ 65 - 17
app/group/group.js

@@ -73,7 +73,7 @@ function my_group_list() {
 							"</a></div>";
 						html += "<div style='flex:1;'><div class='hover_button'>";
 						if (parseInt(iterator.power) == 0) {
-							//管理员可以删除group
+							//只有管理员可以删除group
 							html +=
 								"<button onclick=\"group_del('" +
 								iterator.group_id +
@@ -111,14 +111,17 @@ function group_list(id, list) {
 					let html = "";
 					let result = JSON.parse(data);
 					let key = 1;
-					html += "<div class='info_block'>";
-					html += "<h2>" + gLocal.gui.introduction + "</h2>";
-					html += result.info.description;
-					html += "</div>";
+					if (typeof result.info.description != "undefined" && result.info.description.length > 0) {
+						html += "<div class='info_block'>";
+						html += "<h2>" + gLocal.gui.introduction + "</h2>";
+						html += marked(result.info.description);
+						html += "</div>";
+					}
+
 					$("#curr_group").html("/" + result.info.name);
 
 					if (result.parent) {
-						//如果是project 显示 group名
+						//如果是project 显示 group名
 						$("#parent_group").html(
 							" / <a href='../group/index.php?id=" +
 								result.parent.id +
@@ -127,7 +130,9 @@ function group_list(id, list) {
 								"</a> "
 						);
 					} else {
-						if (result.info.creator == getCookie("userid")) {
+						/*
+						关闭子小组功能
+						if (result.info.owner == getCookie("userid")) {
 							$("#button_new_sub_group").show();
 						}
 						//子小组列表
@@ -139,7 +144,7 @@ function group_list(id, list) {
 								html += "<div style='flex:1;'>" + key++ + "</div>";
 								html += "<div style='flex:2;'>" + iterator.name + "</div>";
 								html += "<div style='flex:2;'>";
-								if (iterator.creator == getCookie("userid")) {
+								if (iterator.owner == getCookie("userid")) {
 									html += gLocal.gui.owner;
 								}
 								html += "</div>";
@@ -150,7 +155,7 @@ function group_list(id, list) {
 									gLocal.gui.enter +
 									"</a></div>";
 								html += "<div style='flex:1;'><div class='hover_button'>";
-								if (iterator.creator == getCookie("userid")) {
+								if (iterator.owner == getCookie("userid")) {
 									html +=
 										"<button onclick=\"group_del('" +
 										iterator.id +
@@ -165,6 +170,7 @@ function group_list(id, list) {
 							html += "尚未设置小组";
 						}
 						html += "</div>";
+*/
 					}
 
 					//共享文件列表
@@ -175,25 +181,66 @@ function group_list(id, list) {
 						for (const iterator of result.file) {
 							html += '<div class="file_list_row" style="padding:5px;">';
 							html += "<div style='flex:1;'>" + key++ + "</div>";
-							html += "<div style='flex:2;'>" + iterator.title + "</div>";
+							html += "<div style='flex:1;'>";
+							//资源类型
+							html += "<svg class='icon'>";
+							let cardUrl = "";
+							let doing = "";
+							switch (parseInt(iterator.res_type)) {
+								case 1: //pcs
+									html += "<use xlink:href='../studio/svg/icon.svg#article'></use>";
+									cardUrl = "../doc/card.php";
+									doing +=
+										"<a href='../studio/project.php?op=open&doc_id=" +
+										iterator.res_id +
+										"'>打开</a>";
+									break;
+								case 2: //channel
+									html += "<use xlink:href='../studio/svg/icon.svg#channel_leaves'></use>";
+									cardUrl = "../channal/card.php";
+									break;
+								case 3: //article
+									html += "<use xlink:href='../studio/svg/icon.svg#article-1'></use>";
+									cardUrl = "../article/card.php";
+									doing +=
+										"<a href='../article/?id=" + iterator.res_id + "' target='_blank'>查看</a>";
+									doing +=
+										"|<a href='../article/my_article_edit.php?id=" +
+										iterator.res_id +
+										"' target='_blank'>编辑</a>";
+									break;
+								case 4: //collection
+									break;
+								case 5: //channel片段
+									break;
+								default:
+									html += "unkow";
+									break;
+							}
+
+							html += "</svg>";
+							html += "</div>";
 							html += "<div style='flex:2;'>";
-							switch (iterator.power) {
+							html += "<guide url='" + cardUrl + "' gid='" + iterator.res_id + "'>";
+							html += iterator.res_title + "</guide></div>";
+							html += "<div style='flex:2;'>";
+							switch (parseInt(iterator.power)) {
 								case 10:
 									html += gLocal.gui.read_only;
 									break;
 								case 20:
+									html += gLocal.gui.write;
 									break;
 								case 30:
-									html += gLocal.gui.write;
 									break;
 								default:
 									break;
 							}
 							html += "</div>";
-							html +=
-								"<div style='flex:1;'><a href='../studio/project.php?op=open&doc_id=" +
-								iterator.doc_id +
-								"'>打开</a></div>";
+							html += "<div style='flex:1;'>";
+							//可用的操作
+							html += doing;
+							html += "</div>";
 							html += "</div>";
 						}
 					} else {
@@ -203,6 +250,7 @@ function group_list(id, list) {
 					html += "</div>";
 
 					$("#my_group_list").html(html);
+					guide_init();
 				} catch (e) {
 					console.error(e);
 				}
@@ -237,7 +285,7 @@ function member_list(id) {
 							}
 							html += "</div>";
 							html += "<div style='flex:1;'><div class='hover_button'>";
-							//if (iterator.creator == getCookie("userid"))
+							//if (iterator.owner == getCookie("userid"))
 							{
 								html +=
 									"<button onclick=\"member_del('" +

+ 2 - 2
app/group/group_del.php

@@ -7,11 +7,11 @@ $respond = array("status" => 0, "message" => "");
 if (isset($_COOKIE["userid"]) && isset($_POST["groupid"])) {
     PDO_Connect("" . _FILE_DB_GROUP_);
     #TODO 先查是否有删除权限
-    $query = "SELECT parent from group_info where id=? and creator=? ";
+    $query = "SELECT parent from group_info where id=? and owner=? ";
     $gInfo = PDO_FetchRow($query, array($_POST["groupid"], $_COOKIE["userid"]));
     if ($gInfo) {
         #删除group info
-        $query = "DELETE from group_info where id=? and creator=? ";
+        $query = "DELETE from group_info where id=? and owner=? ";
         PDO_Execute($query, array($_POST["groupid"], $_COOKIE["userid"]));
         #删除 组员
         $query = "DELETE from group_member where group_id=? ";

+ 2 - 1
app/group/index.php

@@ -90,6 +90,7 @@ require_once '../studio/index_head.php';
 						<div id='group_add_div' class="float_dlg"></div>
 					</span>
 
+<!--
 					<span id="button_new_sub_group" class="icon_btn_div">
 						<span class="icon_btn_tip"><?php echo $_local->gui->new_sub_group;?></span>
 						<button id="file_add" type="button" class="icon_btn" title=" "  onclick="group_add_dlg_show()">
@@ -99,7 +100,7 @@ require_once '../studio/index_head.php';
 						</button>
 						<div id='sub_group_add_div' class="float_dlg"></div>
 					</span>
-
+-->
 					<span id="delete" class="icon_btn_div">				
 						<span class="icon_btn_tip"><?php echo $_local->gui->recycle_bin;?></span>
 						<button id="to_recycle" type="button" class="icon_btn" onclick="file_del()" title=" ">

+ 12 - 2
app/group/list.php

@@ -6,9 +6,19 @@ require_once "../public/_pdo.php";
 require_once '../public/function.php';
 require_once '../ucenter/function.php';
 
-//没有id 列出 我的群组
+//列出 我j参与的群组
 PDO_Connect("" . _FILE_DB_GROUP_);
 $query = "SELECT group_name,group_id,power FROM group_member  WHERE level = 0 and user_id=?";
 $Fetch = PDO_FetchAll($query, array($_COOKIE["userid"]));
-
+foreach ($Fetch as $key => $value) {
+	# code...
+	$query = "SELECT name FROM group_info  WHERE id=?";
+	$groupInfo = PDO_FetchRow($query, array($value["group_id"]));
+	if($groupInfo){
+		$Fetch[$key]["group_name"]=$groupInfo["name"];
+	}
+	else{
+		$Fetch[$key]["group_name"]="";
+	}
+}
 echo json_encode($Fetch, JSON_UNESCAPED_UNICODE);

+ 3 - 3
app/group/member_del.php

@@ -18,13 +18,13 @@ if (isset($_POST["groupid"])) {
     $fc = PDO_FetchRow($query, array($_POST["groupid"]));
     if ($fc) {
         if ($fc["parent"] == 0) {
-            if ($fc["creator"] == $_COOKIE["userid"]) {
+            if ($fc["owner"] == $_COOKIE["userid"]) {
                 $mypower = 0;
             }
         } else {
-            $query = "SELECT creator  from group_info where id=?";
+            $query = "SELECT owner  from group_info where id=?";
             $g_parent = PDO_FetchRow($query, array($fc["parent"]));
-            if ($g_parent && $g_parent["creator"] == $_COOKIE["userid"]) {
+            if ($g_parent && $g_parent["owner"] == $_COOKIE["userid"]) {
                 $mypower = 0;
             }
         }

+ 13 - 10
app/group/my_group_put.php

@@ -6,8 +6,17 @@ require_once '../public/function.php';
 
 $respond = array("status" => 0, "message" => "");
 if (isset($_COOKIE["userid"])) {
-    PDO_Connect("" . _FILE_DB_GROUP_);
-    $query = "INSERT INTO group_info ( id,  parent  , name  , description ,  status , creator ,create_time )
+    PDO_Connect(_FILE_DB_GROUP_);
+	#先查询是否有重复的组名
+	$query = "SELECT id FROM group_info  WHERE name = ? ";
+    $Fetch = PDO_FetchRow($query, array($_POST["name"]));
+	if ($Fetch) {
+		$respond['status'] = 1;
+        $respond['message'] = "错误:有相同的组名称,请选择另一个名称。";
+		echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+		exit;
+	}
+    $query = "INSERT INTO group_info ( id,  parent  , name  , description ,  status , owner ,create_time )
 	                       VALUES  ( ?, ? , ? , ? , ? , ?  ,? ) ";
     $sth = $PDO->prepare($query);
     $newid = UUID::v4();
@@ -19,17 +28,11 @@ if (isset($_COOKIE["userid"])) {
         $respond['message'] = $error[2];
     }
 
+	#将创建者添加到成员中
     $query = "INSERT INTO group_member (  user_id  , group_id  , power , group_name , level ,  status )
 		VALUES  (  ? , ? , ? , ? , ?  ,? ) ";
     $sth = $PDO->prepare($query);
-    if ($_POST["parent"] == 0) {
-        $level = 0;
-        $power = 0;
-    } else {
-        $level = 1;
-        $power = 1;
-    }
-    $sth->execute(array($_COOKIE["userid"], $newid, $power, $_POST["name"], $level, 1));
+    $sth->execute(array($_COOKIE["userid"], $newid, 0, $_POST["name"], 0, 1));
     $respond = array("status" => 0, "message" => "");
     if (!$sth || ($sth && $sth->errorCode() != 0)) {
         $error = PDO_ErrorInfo();

+ 5 - 1
app/guide/guide.js

@@ -20,8 +20,12 @@ function guide_init() {
 			return;
 		}
 		let gid = $(this).attr("gid");
+		let url = $(this).attr("url");
+		if (typeof url == "undefined" || url == "") {
+			url = "../guide/get.php";
+		}
 		$.get(
-			"../guide/get.php",
+			url,
 			{
 				id: gid,
 			},

+ 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>

+ 11 - 9
app/redis/upgrade_pali_sent.php → app/pali_sent/redis_upgrade_pali_sent.php

@@ -1,10 +1,13 @@
 <?php
 /*
-get user sentence from db
+从巴利句子列表数据库中提取数据填充redis
+每个句子包含 
+pali 
+id 
+sim_count
  */
 require_once "../path.php";
-require_once "../public/_pdo.php";
-require_once "../public/function.php";
+require_once "../redis/function.php";
 
 if (isset($argv[1])) {
     if ($argv[1] == "del") {
@@ -21,18 +24,17 @@ if (isset($argv[1])) {
 		echo "delete ok ".$count;
     }
 } else {
-    $dns = "" . _FILE_DB_PALI_SENTENCE_;
-    $dbh = new PDO($dns, "", "", array(PDO::ATTR_PERSISTENT => true));
+
+    $dbh = new PDO(_FILE_DB_PALI_SENTENCE_, "", "", array(PDO::ATTR_PERSISTENT => true));
     $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
-	$dns = "" . _FILE_DB_PALI_SENTENCE_SIM_;
-	$db_pali_sent_sim = new PDO($dns, "", "", array(PDO::ATTR_PERSISTENT => true));
+
+	$db_pali_sent_sim = new PDO(_FILE_DB_PALI_SENTENCE_SIM_, "", "", array(PDO::ATTR_PERSISTENT => true));
 	$db_pali_sent_sim->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
 
     $query = "SELECT id, book,paragraph, begin,end ,html FROM pali_sent WHERE 1 ";
     $stmt = $dbh->prepare($query);
     $stmt->execute();
-    $redis = new redis();
-    $r_conn = $redis->connect('127.0.0.1', 6379);
+    $r_conn = redis_connect();
 	$stringSize = 0;
 	$count = 0;
     if ($r_conn) {

+ 1 - 0
app/path.php

@@ -120,3 +120,4 @@ define("_FILE_DB_HOSTSETTING_", "sqlite:" . __DIR__ . "/../tmp/user/hostsetting.
 define("_FILE_DB_USER_SENTENCE_HISTORAY_", "sqlite:" . __DIR__ . "/../tmp/user/usent_historay.db3");
 define("_FILE_DB_USER_ACTIVE_", "sqlite:" . __DIR__ . "/../tmp/user/user_active.db3");
 define("_FILE_DB_USER_ACTIVE_LOG_", "sqlite:" . __DIR__ . "/../tmp/user/user_active_log.db3");
+define("_FILE_DB_USER_SHARE_", "sqlite:" . __DIR__ . "/../tmp/user/share.db3");

+ 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;
+}

+ 220 - 247
app/pcdl/css/font.css

@@ -4,381 +4,354 @@
 /*Pāli Roma*/
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: normal;
-  font-weight: 100;
-  src: local("Noto Sans Thin"),
-    url(../../../font/NotoSans/NotoSans-Thin.ttf) format("truetype");
-  font-display: fallback;
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: normal;
+	font-weight: 100;
+	src: local("Noto Sans Thin"), url(../../../font/NotoSans/NotoSans-Thin.ttf) format("truetype");
+	font-display: fallback;
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: normal;
-  font-weight: 300;
-  src: local("Noto Sans Light"),
-    url(../../../font/NotoSans/NotoSans-Light.ttf) format("truetype");
-  font-display: fallback;
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: normal;
+	font-weight: 300;
+	src: local("Noto Sans Light"), url(../../../font/NotoSans/NotoSans-Light.ttf) format("truetype");
+	font-display: fallback;
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: normal;
-  font-weight: 400;
-  src: local("Noto Sans Regular"),
-    url(../../../font/NotoSans/NotoSans-Regular.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: normal;
+	font-weight: 400;
+	src: local("Noto Sans Regular"), url(../../../font/NotoSans/NotoSans-Regular.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: normal;
-  font-weight: 500;
-  src: local("Noto Sans Medium"),
-    url(../../../font/NotoSans/NotoSans-Medium.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: normal;
+	font-weight: 500;
+	src: local("Noto Sans Medium"), url(../../../font/NotoSans/NotoSans-Medium.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: normal;
-  font-weight: 700;
-  src: local("Noto Sans Bold"),
-    url(../../../font/NotoSans/NotoSans-Bold.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: normal;
+	font-weight: 700;
+	src: local("Noto Sans Bold"), url(../../../font/NotoSans/NotoSans-Bold.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: normal;
-  font-weight: 900;
-  src: local("Noto Sans Black"),
-    url(../../../font/NotoSans/NotoSans-Black.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: normal;
+	font-weight: 900;
+	src: local("Noto Sans Black"), url(../../../font/NotoSans/NotoSans-Black.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: italic;
-  font-weight: 100;
-  src: local("Noto Sans Thin Italic"),
-    url(../../../font/NotoSans/NotoSans-ThinItalic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: italic;
+	font-weight: 100;
+	src: local("Noto Sans Thin Italic"), url(../../../font/NotoSans/NotoSans-ThinItalic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: italic;
-  font-weight: 300;
-  src: local("Noto Sans Light Italic"),
-    url(../../../font/NotoSans/NotoSans-LightItalic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: italic;
+	font-weight: 300;
+	src: local("Noto Sans Light Italic"), url(../../../font/NotoSans/NotoSans-LightItalic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: italic;
-  font-weight: 400;
-  src: local("Noto Sans Italic"),
-    url(../../../font/NotoSans/NotoSans-Italic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: italic;
+	font-weight: 400;
+	src: local("Noto Sans Italic"), url(../../../font/NotoSans/NotoSans-Italic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: italic;
-  font-weight: 500;
-  src: local("Noto Sans Medium Italic"),
-    url(../../../font/NotoSans/NotoSans-MediumItalic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: italic;
+	font-weight: 500;
+	src: local("Noto Sans Medium Italic"), url(../../../font/NotoSans/NotoSans-MediumItalic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: italic;
-  font-weight: 700;
-  src: local("Noto Sans Bold Italic"),
-    url(../../../font/NotoSans/NotoSans-BoldItalic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: italic;
+	font-weight: 700;
+	src: local("Noto Sans Bold Italic"), url(../../../font/NotoSans/NotoSans-BoldItalic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans";
-  font-style: italic;
-  font-weight: 900;
-  src: local("Noto Sans Black Italic"),
-    url(../../../font/NotoSans/NotoSans-BlackItalic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Sans";
+	font-style: italic;
+	font-weight: 900;
+	src: local("Noto Sans Black Italic"), url(../../../font/NotoSans/NotoSans-BlackItalic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: normal;
-  font-weight: 100;
-  src: local("Noto Serif Thin"),
-    url(../../../font/NotoSerif/NotoSerif-Thin.ttf) format("truetype");
-  font-display: fallback;
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: normal;
+	font-weight: 100;
+	src: local("Noto Serif Thin"), url(../../../font/NotoSerif/NotoSerif-Thin.ttf) format("truetype");
+	font-display: fallback;
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: normal;
-  font-weight: 300;
-  src: local("Noto Serif Light"),
-    url(../../../font/NotoSerif/NotoSerif-Light.ttf) format("truetype");
-  font-display: fallback;
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: normal;
+	font-weight: 300;
+	src: local("Noto Serif Light"), url(../../../font/NotoSerif/NotoSerif-Light.ttf) format("truetype");
+	font-display: fallback;
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: normal;
-  font-weight: 400;
-  src: local("Noto Serif Regular"),
-    url(../../../font/NotoSerif/NotoSerif-Regular.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: normal;
+	font-weight: 400;
+	src: local("Noto Serif Regular"), url(../../../font/NotoSerif/NotoSerif-Regular.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: normal;
-  font-weight: 500;
-  src: local("Noto Serif Medium"),
-    url(../../../font/NotoSerif/NotoSerif-Medium.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: normal;
+	font-weight: 500;
+	src: local("Noto Serif Medium"), url(../../../font/NotoSerif/NotoSerif-Medium.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: normal;
-  font-weight: 600;
-  src: local("Noto Serif SemiBold"),
-    url(../../../font/NotoSerif/NotoSerif-SemiBold.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: normal;
+	font-weight: 600;
+	src: local("Noto Serif SemiBold"), url(../../../font/NotoSerif/NotoSerif-SemiBold.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: normal;
-  font-weight: 700;
-  src: local("Noto Serif Bold"),
-    url(../../../font/NotoSerif/NotoSerif-Bold.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: normal;
+	font-weight: 700;
+	src: local("Noto Serif Bold"), url(../../../font/NotoSerif/NotoSerif-Bold.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: normal;
-  font-weight: 900;
-  src: local("Noto Serif Black"),
-    url(../../../font/NotoSerif/NotoSerif-Black.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: normal;
+	font-weight: 900;
+	src: local("Noto Serif Black"), url(../../../font/NotoSerif/NotoSerif-Black.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: italic;
-  font-weight: 100;
-  src: local("Noto Serif Thin Italic"),
-    url(../../../font/NotoSerif/NotoSerif-ThinItalic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: italic;
+	font-weight: 100;
+	src: local("Noto Serif Thin Italic"), url(../../../font/NotoSerif/NotoSerif-ThinItalic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: italic;
-  font-weight: 300;
-  src: local("Noto Serif Light Italic"),
-    url(../../../font/NotoSerif/NotoSerif-LightItalic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: italic;
+	font-weight: 300;
+	src: local("Noto Serif Light Italic"), url(../../../font/NotoSerif/NotoSerif-LightItalic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: italic;
-  font-weight: 400;
-  src: local("Noto Serif Italic"),
-    url(../../../font/NotoSerif/NotoSerif-Italic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: italic;
+	font-weight: 400;
+	src: local("Noto Serif Italic"), url(../../../font/NotoSerif/NotoSerif-Italic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: italic;
-  font-weight: 500;
-  src: local("Noto Serif Medium Italic"),
-    url(../../../font/NotoSerif/NotoSerif-MediumItalic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: italic;
+	font-weight: 500;
+	src: local("Noto Serif Medium Italic"), url(../../../font/NotoSerif/NotoSerif-MediumItalic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: italic;
-  font-weight: 600;
-  src: local("Noto Serif SemiBold Italic"),
-    url(../../../font/NotoSerif/NotoSerif-SemiBoldItalic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: italic;
+	font-weight: 600;
+	src: local("Noto Serif SemiBold Italic"),
+		url(../../../font/NotoSerif/NotoSerif-SemiBoldItalic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: italic;
-  font-weight: 700;
-  src: local("Noto Serif Bold Italic"),
-    url(../../../font/NotoSerif/NotoSerif-BoldItalic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: italic;
+	font-weight: 700;
+	src: local("Noto Serif Bold Italic"), url(../../../font/NotoSerif/NotoSerif-BoldItalic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Serif";
-  font-style: italic;
-  font-weight: 900;
-  src: local("Noto Serif Black Italic"),
-    url(../../../font/NotoSerif/NotoSerif-BlackItalic.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Noto Serif";
+	font-style: italic;
+	font-weight: 900;
+	src: local("Noto Serif Black Italic"), url(../../../font/NotoSerif/NotoSerif-BlackItalic.ttf) format("truetype");
+	font-display: fallback;
 }
 
 /*缅文*/
 @font-face {
-  font-family: "Padauk";
-  font-style: normal;
-  font-weight: 400;
-  src: local("Padauk"),
-    url(../../../font/Padauk/Padauk-Regular.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Padauk";
+	font-style: normal;
+	font-weight: 400;
+	src: local("Padauk"), url(../../../font/Padauk/Padauk-Regular.ttf) format("truetype");
+	font-display: fallback;
 }
-
 @font-face {
-  font-family: "Padauk";
-  font-style: normal;
-  font-weight: 700;
-  src: local("Padauk Bold"),
-    url(../../../font/Padauk/Padauk-Bold.ttf) format("truetype");
-  font-display: fallback;
+	font-family: "Padauk";
+	font-style: normal;
+	font-weight: 700;
+	src: local("Padauk Bold"), url(../../../font/Padauk/Padauk-Bold.ttf) format("truetype");
+	font-display: fallback;
+}
+/*傣仂文*/
+@font-face {
+	font-family: "ATaiThamKHNewV3-Normal";
+	font-style: normal;
+	font-weight: 400;
+	src: local("A Tai Tham KH New V3"), url(../../../font/taitham/tai-tham-kh-new-v3.ttf) format("truetype");
+	font-display: fallback;
 }
+
 /*中文繁體*/
 
 @font-face {
-  font-family: "Noto Sans TC";
-  font-style: normal;
-  font-weight: 300;
-  src: local("Noto Sans TC Light"), local("Noto Sans CJK TC Light"),
-    local("Source Han Sans TWHK Light");
-  /*url(../../font/NotoSansTC/NotoSansCJKtc-Light.otf) format('opentype'),*/
-  /*url(../../font/NotoSansTC/NotoSansTC-Light.woff) format('woff')*/
+	font-family: "Noto Sans TC";
+	font-style: normal;
+	font-weight: 300;
+	src: local("Noto Sans TC Light"), local("Noto Sans CJK TC Light"), local("Source Han Sans TWHK Light");
+	/*url(../../font/NotoSansTC/NotoSansCJKtc-Light.otf) format('opentype'),*/
+	/*url(../../font/NotoSansTC/NotoSansTC-Light.woff) format('woff')*/
 }
 
 @font-face {
-  font-family: "Noto Sans TC";
-  font-style: normal;
-  font-weight: 400;
-  src: local("Noto Sans TC Regular"), local("Noto Sans CJK TC Regular"),
-    local("Source Han Sans TWHK Regular");
-  /*url(../../font/NotoSansTC/NotoSansCJKtc-Regular.otf) format('opentype'),*/
-  /*url(../../font/NotoSansTC/NotoSansTC-Regular.woff) format('woff');*/
-  font-display: fallback;
+	font-family: "Noto Sans TC";
+	font-style: normal;
+	font-weight: 400;
+	src: local("Noto Sans TC Regular"), local("Noto Sans CJK TC Regular"), local("Source Han Sans TWHK Regular");
+	/*url(../../font/NotoSansTC/NotoSansCJKtc-Regular.otf) format('opentype'),*/
+	/*url(../../font/NotoSansTC/NotoSansTC-Regular.woff) format('woff');*/
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans TC";
-  font-style: normal;
-  font-weight: 500;
-  src: local("Noto Sans TC Medium"), local("Noto Sans CJK TC Medium"),
-    local("Source Han Sans TWHK Medium");
-  /*url(../../font/NotoSansTC/NotoSansCJKtc-Medium.otf) format('opentype'),*/
-  /*url(../../font/NotoSansTC/NotoSansTC-Medium.woff) format('woff');*/
-  font-display: fallback;
+	font-family: "Noto Sans TC";
+	font-style: normal;
+	font-weight: 500;
+	src: local("Noto Sans TC Medium"), local("Noto Sans CJK TC Medium"), local("Source Han Sans TWHK Medium");
+	/*url(../../font/NotoSansTC/NotoSansCJKtc-Medium.otf) format('opentype'),*/
+	/*url(../../font/NotoSansTC/NotoSansTC-Medium.woff) format('woff');*/
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans TC";
-  font-style: normal;
-  font-weight: 700;
-  src: local("Noto Sans TC Bold"), local("Noto Sans CJK TC Bold"),
-    local("Source Han Sans TWHK Bold");
-  /*url(../../font/NotoSansTC/NotoSansCJKtc-Bold.otf) format('opentype'),*/
-  /*url(../../font/NotoSansTC/NotoSansTC-Bold.woff) format('woff');*/
-  font-display: fallback;
+	font-family: "Noto Sans TC";
+	font-style: normal;
+	font-weight: 700;
+	src: local("Noto Sans TC Bold"), local("Noto Sans CJK TC Bold"), local("Source Han Sans TWHK Bold");
+	/*url(../../font/NotoSansTC/NotoSansCJKtc-Bold.otf) format('opentype'),*/
+	/*url(../../font/NotoSansTC/NotoSansTC-Bold.woff) format('woff');*/
+	font-display: fallback;
 }
 
 /*中文简体*/
 
 @font-face {
-  font-family: "Noto Sans SC";
-  font-style: normal;
-  font-weight: 300;
-  src: local("Noto Sans SC Light"), local("Noto Sans CJK SC Light"),
-    local("Source Han Sans CN Light");
-  /*url(../../font/NotoSansSC/NotoSansCJKsc-Light.otf) format('opentype'),
+	font-family: "Noto Sans SC";
+	font-style: normal;
+	font-weight: 300;
+	src: local("Noto Sans SC Light"), local("Noto Sans CJK SC Light"), local("Source Han Sans CN Light");
+	/*url(../../font/NotoSansSC/NotoSansCJKsc-Light.otf) format('opentype'),
     url(../../font/NotoSansSC/NotoSansSC-Light.woff) format('woff')*/
 }
 
 @font-face {
-  font-family: "Noto Sans SC";
-  font-style: normal;
-  font-weight: 400;
-  src: local("Noto Sans SC Regular"), local("Noto Sans CJK SC Regular"),
-    local("Source Han Sans CN Regular");
-  /*url(../../font/NotoSansSC/NotoSansCJKsc-Regular.otf) format('opentype'),
+	font-family: "Noto Sans SC";
+	font-style: normal;
+	font-weight: 400;
+	src: local("Noto Sans SC Regular"), local("Noto Sans CJK SC Regular"), local("Source Han Sans CN Regular");
+	/*url(../../font/NotoSansSC/NotoSansCJKsc-Regular.otf) format('opentype'),
     url(../../font/NotoSansSC/NotoSansSC-Regular.woff) format('woff');*/
-  font-display: fallback;
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans SC";
-  font-style: normal;
-  font-weight: 500;
-  src: local("Noto Sans SC Medium"), local("Noto Sans CJK SC Medium"),
-    local("Source Han Sans CN Medium");
-  /*url(../../font/NotoSansSC/NotoSansCJKsc-Medium.otf) format('opentype'),
+	font-family: "Noto Sans SC";
+	font-style: normal;
+	font-weight: 500;
+	src: local("Noto Sans SC Medium"), local("Noto Sans CJK SC Medium"), local("Source Han Sans CN Medium");
+	/*url(../../font/NotoSansSC/NotoSansCJKsc-Medium.otf) format('opentype'),
     url(../../font/NotoSansSC/NotoSansSC-Medium.woff) format('woff');*/
-  font-display: fallback;
+	font-display: fallback;
 }
 
 @font-face {
-  font-family: "Noto Sans SC";
-  font-style: normal;
-  font-weight: 700;
-  src: local("Noto Sans SC Bold"), local("Noto Sans CJK SC Bold"),
-    local("Source Han Sans CN Bold");
-  /*url(../../font/NotoSansSC/NotoSansCJKsc-Bold.otf) format('opentype'),
+	font-family: "Noto Sans SC";
+	font-style: normal;
+	font-weight: 700;
+	src: local("Noto Sans SC Bold"), local("Noto Sans CJK SC Bold"), local("Source Han Sans CN Bold");
+	/*url(../../font/NotoSansSC/NotoSansCJKsc-Bold.otf) format('opentype'),
     url(../../font/NotoSansSC/NotoSansSC-Bold.woff) format('woff');*/
-  font-display: fallback;
+	font-display: fallback;
 }
 
 .font_ch {
-  font-family: "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
-  font-style: normal;
+	font-family: "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
+	font-style: normal;
 }
 
 .font_pali {
-  font-family: "Noto Sans", Arial, Verdana;
-  font-style: normal;
+	font-family: "Noto Sans", Arial, Verdana;
+	font-style: normal;
 }
 
 .font_m {
-  font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
-  font-weight: 500;
-  font-style: normal;
+	font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
+	font-weight: 500;
+	font-style: normal;
 }
 
 .font_r {
-  font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
-  font-weight: 400;
-  font-style: normal;
+	font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
+	font-weight: 400;
+	font-style: normal;
 }
 
 .font_l {
-  font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
-  font-weight: 300;
-  font-style: normal;
+	font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
+	font-weight: 300;
+	font-style: normal;
 }
 
 .font_t {
-  font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
-  font-weight: 100;
-  font-style: normal;
+	font-family: "Noto Sans", "Noto Sans TC", "Noto Sans SC", Arial, Verdana;
+	font-weight: 100;
+	font-style: normal;
 }

+ 22 - 9
app/pcdl/css/style.css

@@ -19,7 +19,7 @@
 }
 
 body {
-	font-family: "Noto Sans", "Noto Sans SC", "Noto Sans TC", "Padauk", Arial, Verdana;
+	font-family: "Noto Sans", "Noto Sans SC", "Noto Sans TC", "Padauk", "ATaiThamKHNewV3-Normal", Arial, Verdana;
 	font-style: normal;
 	color: var(--main-color);
 	font-weight: 400;
@@ -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%;

+ 7 - 0
app/pcdl/html_head.php

@@ -100,6 +100,13 @@ if (isset($_GET["language"])) {
 	<link type="text/css" rel="stylesheet" href="../term/pali_sim_dlg.css" />
 	<script src="../term/related_para.js"></script>
 
+	<script src="../widget/iframe_modal_win.js"></script>
+	<link type="text/css" rel="stylesheet" href="../widget/iframe_modal_win.css"/>
+
+	<script src="../commit/commit.js"></script>
+	<link type="text/css" rel="stylesheet" href="../commit/commit.css"/>
+
+
 	<script src="../inline_dict/inline_dict.js"></script>
 
 	<script src="../widget/click_dropdown.js"></script>

+ 58 - 63
app/pcdl/index.js

@@ -1,80 +1,75 @@
 function index_onload() {
-    index_load_term_new();
-    index_load_collect_new();
-    index_load_course_new();
+	index_load_term_new();
+	index_load_collect_new();
+	index_load_course_new();
 }
 
 function index_load_collect_new() {
-    $.get(
-        "../article/list_new.php", {
-            begin: 0,
-            page: 4,
-        },
-        function(data, status) {
-            let arrCollectList = JSON.parse(data);
-            let html = "";
-            for (const iterator of arrCollectList.data) {
-                html += "<div class='card'>";
+	$.get(
+		"../article/list_new.php",
+		{
+			begin: 0,
+			page: 4,
+		},
+		function (data, status) {
+			let arrCollectList = JSON.parse(data);
+			let html = "";
+			for (const iterator of arrCollectList.data) {
+				html += "<div class='card'>";
 
-                html +=
-                    "<div class='card_state'>" + gLocal.gui.ongoing + "</div>";
+				html += "<div class='card_state'>" + gLocal.gui.ongoing + "</div>";
 
-                //!!!!!請協助補上頭像代碼!!!!!
-                html +=
-                    "<div style='padding:10px 10px 0 0;'><span class='head_img'></span></div>";
+				//!!!!!請協助補上頭像代碼!!!!!
+				html += "<div style='padding:10px 10px 0 0;'><span class='head_img'>";
+				html += iterator.username.nickname.slice(0, 1);
+				html += "</span></div>";
 
-                html += "<div class='article_right'>";
-                gLocal.gui.ongoing + "</div>";
+				html += "<div class='article_right'>";
+				gLocal.gui.ongoing + "</div>";
 
-                html +=
-                    "<div class='title'><a href='../article/?id=" +
-                    iterator.id +
-                    "'>" +
-                    iterator.title +
-                    "</a></div>";
+				html += "<div class='title'>";
+				html += "<a href='../article/?id=" + iterator.id + "'>" + iterator.title + "</a>";
+				html += "</div>";
 
+				html += "<div class='collect'>";
+				if (iterator.collect) {
+					html +=
+						"<a href='../article/?collect=" + iterator.collect.id + "'>" + iterator.collect.title + "</a>";
+				} else {
+					html += "unkow";
+				}
+				html += "</div>";
+				if (iterator.subtitle) {
+					html += "<div>" + iterator.subtitle + "</div>";
+				}
+				if (iterator.summary) {
+					html += "<div>" + iterator.summary + "</div>";
+				}
 
-                html += "<div class='collect'>";
-                if (iterator.collect) {
-                    html += "<a href='../article/?collect=" + iterator.collect.id + "'>" + iterator.collect.title + "</a>";
-                } else {
-                    html += "unkow";
-                }
-                html += "</div>";
-                if (iterator.subtitle) {
-                    html += "<div>" + iterator.subtitle + "</div>";
-                }
-                if (iterator.summary) {
-                    html += "<div>" + iterator.summary + "</div>";
-                }
+				html += "<div style='margin-top:1em;'>" + iterator.username.nickname + "</div>";
 
-
-                html += "<div style='margin-top:1em;'>" + iterator.username.nickname + "</div>";
-
-
-
-                html += "</div>";
-                html += "</div>";
-            }
-            $("#article_new").html(html);
-        }
-    );
+				html += "</div>";
+				html += "</div>";
+			}
+			$("#article_new").html(html);
+		}
+	);
 }
 
 function index_load_term_new() {
-    $.get("../term/new.php", function(data, status) {
-        let xDiv = document.getElementById("pali_pedia");
-        if (xDiv) {
-            xDiv.innerHTML = data;
-        }
-    });
+	$.get("../term/new.php", function (data, status) {
+		let xDiv = document.getElementById("pali_pedia");
+		if (xDiv) {
+			xDiv.innerHTML = data;
+		}
+	});
 }
 
 function index_load_course_new() {
-    $.get("../course/list_new.php", function(data, status) {
-        let xDiv = document.getElementById("course_list_new");
-        if (xDiv) {
-            xDiv.innerHTML = data;
-        }
-    });
-}
+	$.get("../course/list_new.php", function (data, status) {
+		let xDiv = document.getElementById("course_list_new");
+		if (xDiv) {
+			xDiv.innerHTML = data;
+		}
+	});
+}

File diff suppressed because it is too large
+ 14 - 0
app/public/images/svg.md


+ 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();

+ 19 - 0
app/redis/del.php

@@ -0,0 +1,19 @@
+<?php 
+require_once "../path.php";
+require_once "../redis/function.php";
+$redis = redis_connect();
+if($redis==false){
+	echo "redis 连接失败";
+}
+else{
+	$keys = $redis->keys($_GET["key"]);
+		$count=0;
+		foreach ($keys as $key => $value) {
+			# code...
+			$deleted = $redis->del($value);
+			$count += $deleted;
+		}
+		
+		echo "delete ok ".$count;
+}
+?>

+ 90 - 0
app/redis/index.php

@@ -0,0 +1,90 @@
+<?PHP
+require_once "../pcdl/html_head.php";
+require_once "function.php";
+?>
+
+<body>
+<?php
+$redis = redis_connect();
+if($redis==false){
+	echo "redis 连接失败";
+}
+else{
+	$count = $redis->dbSize();
+	echo "Redis has $count keys<br>";
+
+	if(file_exists("redis.json")){
+	$redisList=json_decode(file_get_contents("redis.json"),true);
+	echo "<div>";
+	
+	foreach ($redisList as $key => $value) {
+		# code..
+		echo "<div class='card' style='display:block;";
+		if($value["valid"]==false){
+			echo "background-color:lightpink;";
+		}
+		echo "'>";
+		echo "<div>key:<b>{$value["key"]}</b></div>";
+		echo "<div>type:{$value["type"]}</div>";
+		echo "<div >valid:";
+		if($value["valid"]){
+			echo "有效";
+		}
+		else{
+			echo "已经过时";
+		}
+		echo "</div>";
+		if(isset($value["rebuild"]) && !empty($value["rebuild"])){
+			echo "<div >rebuild:<a href='{$value["rebuild"]}' target='_blank'>{$value["rebuild"]}</a></div>";
+		}
+
+		if(substr($value["key"],-1)==="*"){
+			$keys = $redis->keys($value["key"]);
+		}
+		else{
+			switch ($value["type"]) {
+				case 'hash':
+					# code...
+					$keys = $redis->hKeys($value["key"]);
+					break;
+				default:
+					# code...
+					break;
+			}
+		}
+		echo "<div >count:";
+		if(isset($keys)){
+			echo count($keys);
+		}
+		else{
+			echo "未知";
+		}
+		echo "</div>";
+		echo "<div >description:{$value["description"]}</div>";
+		echo "<div ><button onclick=\"del('{$value["key"]}')\">删除数据</button></div>";
+		
+		echo "</div>";
+	}
+	echo "</div>";
+
+}
+else{
+	echo "no config file";
+}
+}
+
+?>
+<script>
+function del(key){
+	$.get("del.php",
+	{
+		key:key
+	},
+	function(data){
+		alert(data);
+	});
+}
+</script>
+<?php
+include "../pcdl/html_foot.php";
+?>

+ 23 - 0
app/redis/redis.json

@@ -0,0 +1,23 @@
+[
+	{ "key": "ref_dict_idx", "type": "hash", "valid": true, "rebuild": "", "description": "参考字典索引" },
+	{ "key": "pali_sent_*", "type": "string", "valid": false, "description": "巴利句子列表" },
+	{
+		"key": "pali://sent/*",
+		"type": "hash",
+		"valid": true,
+		"rebuild": "../pali_sent/redis_upgrade_pali_sent.php",
+		"description": "巴利句子列表"
+	},
+	{
+		"key": "sent://*",
+		"type": "hash",
+		"valid": true,
+		"description": "译文句子列表 key: sent://channel/book-para-start-end "
+	},
+	{
+		"key": "article://*",
+		"type": "hash",
+		"valid": true,
+		"description": "article 主要信息 key: article://id  字段 title,owner,summary,create_time,modify_time "
+	}
+]

+ 44 - 0
app/share/coop_del.php

@@ -0,0 +1,44 @@
+<?php
+//查询term字典
+
+require_once "../path.php";
+require_once "../public/_pdo.php";
+require_once '../public/function.php';
+require_once '../ucenter/function.php';
+require_once '../group/function.php';
+
+$respond['status']=0;
+$respond['message']="成功";
+if(isset($_POST["res_id"])){
+	PDO_Connect(_FILE_DB_USER_SHARE_);
+
+    $query = "DELETE FROM share_cooperator WHERE res_id=? and cooperator_id = ? ";
+	$sth = $PDO->prepare($query);
+	if($sth)
+	{
+		# code...
+		$sth->execute(array($_POST["res_id"],
+							$_POST["user_id"]
+						));
+		if (!$sth || ($sth && $sth->errorCode() != 0)) {
+			/*  识别错误  */
+			$error = PDO_ErrorInfo();
+			$respond['status']=1;
+			$respond['message']=$error[2];
+			echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+			exit;
+		}
+		else{
+			$respond['status']=0;
+			$respond['message']="成功";
+		}							
+	}
+
+    echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+}
+else{
+	$respond['status']=1;
+	$respond['message']="no res id";
+    echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+}
+?>

+ 44 - 0
app/share/coop_get.php

@@ -0,0 +1,44 @@
+<?php
+//查询term字典
+
+require_once "../path.php";
+require_once "../public/_pdo.php";
+require_once '../public/function.php';
+require_once '../ucenter/function.php';
+require_once '../group/function.php';
+
+if(isset($_GET["res_id"])){
+    PDO_Connect(_FILE_DB_USER_SHARE_);
+    $id=$_GET["res_id"];
+    $type=$_GET["res_type"];
+    $query = "SELECT * FROM share_cooperator  WHERE res_id = ? and res_type=? ";
+	$Fetch = PDO_FetchAll($query,array($id,$type));
+
+	#获取协作者名字
+	if(count($Fetch)>0){
+		$user_info = new UserInfo();
+		$group_info = new GroupInfo();
+		foreach ($Fetch as $key => $value) {
+			# code...
+			switch ($value["cooperator_type"]) {
+				case 0:
+					$Fetch[$key]["user"] = $user_info->getName($value["cooperator_id"]);
+					break;
+				case 1:
+					# 小组协作者
+					$Fetch[$key]["user"] = $group_info->getName($value["cooperator_id"]);
+					$Fetch[$key]["parent_name"] = $group_info->getName($group_info->getParentId($value["cooperator_id"]));
+					break;
+				default:
+					# 未知类型
+					$Fetch[$key]["user"] ="unkow";
+					break;
+			}
+		}
+	}
+    echo json_encode($Fetch, JSON_UNESCAPED_UNICODE);
+}
+else{
+    echo json_encode(array(), JSON_UNESCAPED_UNICODE);
+}
+?>

+ 45 - 0
app/share/coop_post.php

@@ -0,0 +1,45 @@
+<?php
+//查询term字典
+
+require_once "../path.php";
+require_once "../public/_pdo.php";
+require_once '../public/function.php';
+require_once '../ucenter/function.php';
+require_once '../group/function.php';
+
+$respond['status']=0;
+$respond['message']="成功";
+if(isset($_POST["res_id"])){
+	PDO_Connect(_FILE_DB_USER_SHARE_);
+
+    $query = "UPDATE share_cooperator set power = ? WHERE res_id=? and cooperator_id = ? ";
+	$sth = $PDO->prepare($query);
+	if($sth)
+	{
+		# code...
+		$sth->execute(array($_POST["power"],
+							$_POST["res_id"],
+							$_POST["user_id"]
+						));
+		if (!$sth || ($sth && $sth->errorCode() != 0)) {
+			/*  识别错误  */
+			$error = PDO_ErrorInfo();
+			$respond['status']=1;
+			$respond['message']=$error[2];
+			echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+			exit;
+		}
+		else{
+			$respond['status']=0;
+			$respond['message']="成功";
+		}							
+	}
+
+    echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+}
+else{
+	$respond['status']=1;
+	$respond['message']="no res id";
+    echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+}
+?>

+ 52 - 0
app/share/coop_put.php

@@ -0,0 +1,52 @@
+<?php
+//查询term字典
+
+require_once "../path.php";
+require_once "../public/_pdo.php";
+require_once '../public/function.php';
+require_once '../ucenter/function.php';
+require_once '../group/function.php';
+
+$respond['status']=0;
+$respond['message']="成功";
+if(isset($_POST["res_id"])){
+	PDO_Connect(_FILE_DB_USER_SHARE_);
+	$PDO->beginTransaction();
+    $query = "INSERT  INTO share_cooperator ('id','res_id','res_type','cooperator_id','cooperator_type','power','create_time','modify_time','is_deleted') VALUES (null,?,?,?,?,?,?,?,?) ";
+	$sth = $PDO->prepare($query);
+	$data = json_decode($_POST["user_info"]);
+	foreach ($data as $key => $user) {
+		# code...
+		$sth->execute(array($_POST["res_id"],
+							$_POST["res_type"],
+							$user->id,
+							$user->type,
+							$_POST["power"],
+							mTime(),
+							mTime(),
+							0
+						));
+	}
+	$PDO->commit();
+        
+	if (!$sth || ($sth && $sth->errorCode() != 0)) {
+		/*  识别错误且回滚更改  */
+		$PDO->rollBack();
+		$error = PDO_ErrorInfo();
+		$respond['status']=1;
+		$respond['message']=$error[2];
+		echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+		exit;
+	}
+	else{
+		$respond['status']=0;
+		$respond['message']="成功";
+	}	
+    echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+}
+else{
+	$respond['status']=1;
+	$respond['message']="no res id";
+    echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+}
+?>

+ 160 - 0
app/share/function.php

@@ -0,0 +1,160 @@
+<?php 
+require_once "../path.php";
+require_once "../public/_pdo.php";
+require_once '../public/function.php';
+require_once '../ucenter/function.php';
+require_once '../channal/function.php';
+require_once '../article/function.php';
+require_once '../redis/function.php';
+require_once '../doc/function.php';
+/*
+获取某用户的可见的协作资源
+$res_type 见readme.md#资源类型 -1全部类型资源
+*/
+function share_res_list_get($userid,$res_type=-1){
+	$redis = redis_connect();
+	# 找我加入的群
+	$dbhGroup = new PDO(_FILE_DB_GROUP_, "", "");
+    $dbhGroup->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
+	$query = "SELECT group_id from group_member where user_id = ?  limit 0,200";
+	$stmtGroup = $dbhGroup->prepare($query);
+	$stmtGroup->execute(array($userid));
+	$my_group = $stmtGroup->fetchAll(PDO::FETCH_ASSOC);
+	$userList = array();
+	$userList[] = $userid;
+	foreach ($my_group as $key => $value) {
+		# code...
+		$userList[]=$value["group_id"];
+	}
+	
+	$place_holders = implode(',', array_fill(0, count($userList), '?'));
+	$Fetch=array();
+	$PDO = new PDO(_FILE_DB_USER_SHARE_, "", "");
+    $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
+	if($res_type==-1){
+		#所有类型资源
+		$query = "SELECT res_id,res_type,power FROM share_cooperator  WHERE is_deleted=0 AND cooperator_id IN ($place_holders) ";
+		$stmt = $PDO->prepare($query);
+		$stmt->execute($userList);
+		$Fetch =$stmt->fetchAll(PDO::FETCH_ASSOC);
+	}
+	else{
+		#指定类型资源
+		$userList[]=$res_type;
+		$query = "SELECT res_id,res_type,power FROM share_cooperator  WHERE is_deleted=0 AND  cooperator_id IN ($place_holders) AND res_type = ?";
+		$stmt = $PDO->prepare($query);
+		$stmt->execute($userList);
+		$Fetch =$stmt->fetchAll(PDO::FETCH_ASSOC);
+	}
+
+	$resOutput = array();
+	foreach ($Fetch as $key => $value) {
+		# 查重
+		if(isset($resOutput[$value["res_id"]])){
+			if($value["power"]>$resOutput[$value["res_id"]]["power"]){
+				$resOutput[$value["res_id"]]["power"] = $value["power"];
+			}
+		}
+		else{
+			$resOutput[$value["res_id"]]= array("power"=> $value["power"],"type" => $value["res_type"]);
+		}
+	}
+	$resList=array();
+	foreach ($resOutput as $key => $value) {
+		# code...
+		$resList[]=array("res_id"=>$key,"res_type"=>(int)$value["type"],"power"=>(int)$value["power"]);
+	}
+	$channel = new Channal(); 
+	$article = new Article($redis); 
+	foreach ($resList as $key => $res) {
+		# 获取资源标题 和所有者 
+		switch ($res["res_type"]) {
+			case 1:
+				# pcs 文档
+				$resList[$key]["res_title"]=pcs_get_title($res["res_id"]);
+				break;
+			case 2:
+				# channel
+				$channelInfo = $channel->getChannal($res["res_id"]);
+				if($channelInfo){
+					$resList[$key]["res_title"]=$channelInfo["name"];
+					$resList[$key]["res_owner_id"]=$channelInfo["owner"];
+					$resList[$key]["status"]=$channelInfo["status"];
+					$resList[$key]["lang"]=$channelInfo["lang"];
+				}
+				else{
+					$resList[$key]["res_title"]="_unkown_";
+					$resList[$key]["res_owner_id"]="_unkown_";
+					$resList[$key]["status"]="0";
+					$resList[$key]["lang"]="unkow";
+				}
+				break;
+			case 3:
+				# 3 Article 文章
+				$aInfo = $article->getInfo($res["res_id"]);
+				if($aInfo){
+					$resList[$key]["res_title"]=$aInfo["title"];
+					$resList[$key]["res_owner_id"]=$aInfo["owner"];
+					$resList[$key]["status"]=$aInfo["status"];
+					$resList[$key]["lang"]='';
+				}
+				else{
+					$resList[$key]["res_title"]="_unkown_";
+					$resList[$key]["res_owner_id"]="_unkown_";
+					$resList[$key]["status"]="0";
+					$resList[$key]["lang"]="unkow";
+				}
+				break;
+			case 4:
+				# 4 Collection 文集
+				break;
+			case 5:
+				# code...
+				break;
+																		
+			default:
+				# code...
+				break;
+		}
+	}
+
+	return $resList;
+
+}
+
+//获取对某个共享资源的权限
+function share_get_res_power($userid,$res_id){
+		# 找我加入的群
+		$dbhGroup = new PDO(_FILE_DB_GROUP_, "", "");
+		$dbhGroup->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
+		$query = "SELECT group_id from group_member where user_id = ?  limit 0,100";
+		$stmtGroup = $dbhGroup->prepare($query);
+		$stmtGroup->execute(array($userid));
+		$my_group = $stmtGroup->fetchAll(PDO::FETCH_ASSOC);
+		$userList = array();
+		$userList[] = $userid;
+		foreach ($my_group as $key => $value) {
+			# code...
+			$userList[]=$value["group_id"];
+		}
+		
+		$place_holders = implode(',', array_fill(0, count($userList), '?'));
+		$Fetch=array();
+		$PDO = new PDO(_FILE_DB_USER_SHARE_, "", "");
+		$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
+
+			$userList[]=$res_id;
+			$query = "SELECT power FROM share_cooperator  WHERE is_deleted=0 AND  cooperator_id IN ($place_holders) AND res_id = ? ";
+			$stmt = $PDO->prepare($query);
+			$stmt->execute($userList);
+			$Fetch =$stmt->fetchAll(PDO::FETCH_ASSOC);
+		$power=0;
+		foreach ($Fetch as $key => $value) {
+			# code...
+			if((int)$value["power"]>$power){
+				$power = $value["power"];
+			}
+		}
+		return $power;
+}
+?>

+ 15 - 0
app/share/readme.md

@@ -0,0 +1,15 @@
+# 共享与协作
+
+## 资源类型
+
+-   1 PCS 文档
+-   2 Channel 版本
+-   3 Article 文章
+-   4 Collection 文集
+-   5 版本片段
+
+## 权限
+
+-   10 只读
+-   20 写入
+-   30 拥有者

+ 324 - 0
app/share/share.js

@@ -0,0 +1,324 @@
+var _res_id;
+var _res_type;
+var gUserList = new Array();
+
+function share_load(id, type) {
+	refresh_coop_list(id, type);
+}
+
+function refresh_coop_list(id, type) {
+	$.get(
+		"../share/coop_get.php",
+		{
+			res_id: id,
+			res_type: type,
+		},
+		function (data, status) {
+			if (status == "success") {
+				let result = JSON.parse(data);
+				$("#coop_list").html(render_coop_list(result));
+			}
+		}
+	);
+}
+
+function render_coop_list(cooplist) {
+	let html = "";
+	if (typeof cooplist == "undefined" || cooplist.length == 0) {
+		html += gLocal.gui.empty_null_mark;
+	} else {
+		for (const coop of cooplist) {
+			html += '<div class="file_list_row" style="padding:5px;">';
+			let username;
+			if (coop.cooperator_type == 0) {
+				username = coop.user.nickname;
+				html += '<div style="flex:1;" title="' + gLocal.gui.personal + '">';
+				html += "<svg class='icon'>";
+				html += "	<use xlink:href='../studio/svg/icon.svg#ic_person'></use>";
+				html += "</svg>";
+				html += "</div>";
+				html += "<div style='flex:3;'>" + username + "</div>";
+			} else {
+				username = coop.user;
+				html += '<div style="flex:1;" title="' + gLocal.gui.group + '">';
+				html += "<svg class='icon'>";
+				html += "	<use xlink:href='../studio/svg/icon.svg#ic_two_person'></use>";
+				html += "</svg>";
+				html += "</div>";
+				html += "<div style='flex:3;'>";
+				if (coop.parent_name != "") {
+					html += coop.parent_name + "/";
+				}
+				html += username + "</div>";
+			}
+
+			html += "<div style='flex:3;'>";
+			let power = [
+				{ id: 10, string: "查看者" },
+				{ id: 20, string: "编辑者" },
+			];
+			html += "<select onchange=\"coop_set_power('" + coop.cooperator_id + "',this)\">";
+			for (const iterator of power) {
+				html += "<option value='" + iterator.id + "' ";
+				if (iterator.id == coop.power) {
+					html += " selected ";
+				}
+				html += ">" + iterator.string + "</option>";
+			}
+			html += "</select>";
+
+			html += "</div>";
+			html += "<div class='hover_button' style='flex:3;'>";
+			html +=
+				"<button onclick=\"coop_remove('" +
+				coop.cooperator_id +
+				"','" +
+				username +
+				"')\">" +
+				gLocal.gui.remove +
+				"</button>";
+			html += "</div>";
+			html += "</div>";
+		}
+	}
+	return html;
+}
+
+function username_search_keyup(e, obj) {
+	var keynum;
+	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) {
+	} else {
+		if (obj.value.length > 0) {
+			let type = $("#user_type").val();
+			username_search(obj.value, type);
+		} else {
+			$("#user_search").html("");
+		}
+	}
+}
+
+function user_selected(id, name, type) {
+	if (parseInt(type) == 0) {
+		gUserList.push({ id: id, name: name, type: type });
+		$("#user_list").html(render_user_list());
+		$("#user_search").html("");
+	} else {
+		$.get("../group/get.php", { id: id }, function (data, status) {
+			if (status == "success") {
+				try {
+					let result = JSON.parse(data);
+					gUserList.push({ id: id, name: name, type: type, project: result.children });
+					$("#user_list").html(render_user_list());
+					$("#user_search").html("");
+				} catch (e) {}
+			}
+		});
+	}
+}
+function render_user_list() {
+	let html = "<ul>";
+	let arrIndex = 0;
+	for (const iterator of gUserList) {
+		html += "<li>";
+		html += "<span>";
+		if (iterator.type == 1) {
+			//小组
+			html += "👥";
+		} else {
+			html += "👤";
+		}
+		html += iterator.name;
+		html += "</span>";
+		html += "<a class='btn_del' onclick=\"userlist_del(' + arrIndex + ')\">删除</a>";
+		html += "</li>";
+		arrIndex++;
+	}
+	html += "</ul>";
+	return html;
+}
+
+//从候选列表中删除一个元素
+function userlist_del(index) {
+	let deleted = gUserList.splice(index, 1);
+	$("#user_list").html(render_user_list());
+	if (gUserList.length == 0) {
+		$("#coop_new_tools").hide();
+	}
+}
+function username_search(keyword, type) {
+	//let obj = document.querySelector("#cooperator_type_user");
+	if (type == 1) {
+		$.get(
+			"../ucenter/get.php",
+			{
+				username: keyword,
+			},
+			function (data, status) {
+				let result;
+				try {
+					result = JSON.parse(data);
+				} catch (error) {
+					console(error);
+				}
+				let html = "<ul id='user_search_list'>";
+				if (result.length > 0) {
+					$("#coop_new_tools").show();
+					for (const iterator of result) {
+						html +=
+							"<li onclick=\"user_selected('" +
+							iterator.id +
+							"','" +
+							iterator.username +
+							"',0)\">" +
+							iterator.nickname +
+							"@" +
+							iterator.username +
+							"</li>";
+					}
+				} else {
+					$("#coop_new_tools").hide();
+				}
+				html += "</ul>";
+				$("#user_search").html(html);
+			}
+		);
+	} else {
+		$.get(
+			"../group/get_name.php",
+			{
+				name: keyword,
+			},
+			function (data, status) {
+				let result;
+				try {
+					result = JSON.parse(data);
+				} catch (error) {
+					console(error);
+				}
+				let html = "<ul id='user_search_list'>";
+				if (result.length > 0) {
+					$("#coop_new_tools").show();
+					for (const iterator of result) {
+						html +=
+							"<li onclick=\"user_selected('" +
+							iterator.id +
+							"','" +
+							iterator.name +
+							"',1)\">" +
+							iterator.name +
+							"</li>";
+					}
+				} else {
+					$("#coop_new_tools").hide();
+				}
+				html += "</ul>";
+				$("#user_search").html(html);
+			}
+		);
+	}
+}
+
+function add_coop() {
+	let coopList = new Array();
+	for (const itUser of gUserList) {
+		coopList.push({ id: itUser.id, type: itUser.type });
+		/*
+		if (itUser.type == 0) {
+			coopList.push({ id: itUser.id, type: itUser.type });
+		} else if (itUser.type == 1) {
+			let obj = document.querySelector("#prj_" + itUser.id);
+			if (obj.checked) {
+				coopList.push({ id: itUser.id, type: itUser.type });
+			}
+			if (typeof itUser.project != "undefined") {
+				for (const project of itUser.project) {
+					obj = document.querySelector("#prj_" + project.id);
+					if (obj.checked) {
+						coopList.push({ id: project.id, type: itUser.type });
+					}
+				}
+			}
+		}
+		*/
+	}
+	$.post(
+		"../share/coop_put.php",
+		{
+			res_id: _res_id,
+			res_type: _res_type,
+			user_info: JSON.stringify(coopList),
+			power: $("#coop_new_power").val(),
+		},
+		function (data, status) {
+			cancel_coop();
+			let result = JSON.parse(data);
+			if (parseInt(result.status) == 0) {
+				refresh_coop_list(_res_id, _res_type);
+			} else {
+				alert(result.message);
+			}
+		}
+	);
+}
+
+function cancel_coop() {
+	$("#user_list").html("");
+	$("#user_search").html("");
+	$("#coop_new_tools").hide();
+	$("#search_user").val("");
+	gUserList = new Array();
+}
+
+function coop_remove(userid, username) {
+	let strMsg = "要删除%name%吗?";
+	if (confirm(strMsg.replace("%name%", username))) {
+		$.post(
+			"../share/coop_del.php",
+			{
+				res_id: _res_id,
+				res_type: _res_type,
+				user_id: userid,
+			},
+			function (data, status) {
+				cancel_coop();
+				let result = JSON.parse(data);
+				if (parseInt(result.status) == 0) {
+					refresh_coop_list(_res_id, _res_type);
+				} else {
+					alert(result.message);
+				}
+			}
+		);
+	}
+}
+
+function coop_set_power(userid, power) {
+	{
+		$.post(
+			"../share/coop_post.php",
+			{
+				res_id: _res_id,
+				res_type: _res_type,
+				user_id: userid,
+				power: $(power).val(),
+			},
+			function (data, status) {
+				cancel_coop();
+				let result = JSON.parse(data);
+				if (parseInt(result.status) == 0) {
+					refresh_coop_list(_res_id, _res_type);
+				} else {
+					alert(result.message);
+				}
+			}
+		);
+	}
+}

+ 138 - 0
app/share/share.php

@@ -0,0 +1,138 @@
+<?php
+require_once '../studio/index_head.php';
+?>
+
+<body>
+<script language="javascript" src="../share/share.js"></script>
+<style>
+.item_block{
+	border-bottom: 1px solid var(--border-line-color);
+    padding: 0 0 2em 0;
+}
+#coop_new_tools{
+	display:none;
+}
+select{
+	background-color:unset;
+}
+input[type="text"], input[type="input"], input[type="password"], textarea{
+	background-color:unset;
+	color:unset;
+}
+#user_search {
+    border: 1px solid var(--border-line-color);
+    display: inline-block;
+    position: absolute;
+    background-color: var(--drop-bg-color);
+}
+#user_search_list li{
+	padding:5px;
+}
+#user_search_list li:hover{
+	background-color: var(--link-color);
+    color: var(--tool-color);
+}
+.file_list_row:hover {
+    background-color: var(--link-color);
+}
+.icon{
+	fill: var(--main-color);
+	height: 28px;
+    width: 28px;
+}
+#user_list li{
+    border-bottom: 1px solid var(--btn-border-color);
+    width: 270px;
+    border-radius: 5px;
+    line-height: 24px;
+    padding: 0 5px;
+	display:flex;
+	justify-content: space-between;
+}
+#user_list li>.btn_del{
+	visibility: hidden;
+}
+#user_list li:hover .btn_del{
+	visibility: visible;
+}
+</style>
+<div class=" " >
+	<div class="item_block" style="display:none;">
+		<h2 id="res_type"></h2>
+		<div id="res_title">
+		</div>
+	</div>
+	<div class="item_block">
+		<h2>隐私设置</h2>
+		<ul>
+			<li><input type="radio" name="list" checked />私有</li>
+			<li><input type="radio" name="list" />公开列出</li>
+		</ul>
+	</div>
+	<div class="item_block">
+		<h2>分享链接</h2>
+		<div><button>创建分享链接</button></div>
+		<div id="share_link">
+			<button>关闭分享链接</button>
+			<div style="display:flex;"><span style="max-width:200px;"><input type="input" name="" /></span><button>复制分享链接</button></div>
+			<select>
+					<option value="10">查看者</option>
+					<option value="20">编辑者</option>
+			</select>
+		</div>
+	</div>	
+	<div class="item_block">
+		<h2>协作</h2>
+		<div>
+			<div style="display:flex;">
+			<select id="user_type" >
+				<option value="1">👤个人</option>
+				<option value="2">👥工作组</option>
+			</select>
+			<!--			
+			<span>
+				<svg class="icon">
+					<use xlink:href="../studio/svg/icon.svg#ic_add_person"></use>
+				</svg>
+			</span>
+			-->
+			<span style="max-width:200px;">
+			<input id="search_user" type="input" name="" placeholder="输入用户名或组名" onkeyup="username_search_keyup(event,this)" />
+			</span>
+
+			</div>
+			<div id="user_search">
+			</div>
+			<div id="user_list_shell">
+				<div id="user_list">
+				</div>
+				<div id="coop_new_tools">
+					<select id="coop_new_power">
+						<option value="10">查看者</option>
+						<option value="20">编辑者</option>
+					</select>
+					<button onclick="add_coop()">添加</button>
+					<button onclick="cancel_coop()">取消</button>
+				</div>
+			</div>
+		</div>
+		<div>
+		<h3>有权使用的人</h3>
+		<div id="coop_list">
+		</div>
+		</div>
+	</div>	
+</div>
+<script>
+$(document).ready(function(){
+	<?php
+	if(isset($_GET["id"]) && isset($_GET["type"])){
+		echo "_res_id = '{$_GET["id"]}'; \n";
+		echo "_res_type = '{$_GET["type"]}'; \n";
+		echo "share_load('{$_GET["id"]}','{$_GET["type"]}');";
+	}
+	?>
+});
+</script>
+</body>
+</html>

+ 0 - 115
app/statistics/index1.php

@@ -1,115 +0,0 @@
-<?PHP
-require_once "../pcdl/html_head.php";
-?>
-
-<body>
-    <script src="../palicanon/palicanon.js"></script>
-    <script src="../term/term.js"></script>
-
-    <?php
-require_once "../pcdl/head_bar.php";
-?>
-
-	<link type="text/css" rel="stylesheet" href="../palicanon/style.css" />
-	<link type="text/css" rel="stylesheet" href="../palicanon/style_mobile.css" media="screen and (max-width:800px)">
-
-
-    <script>
-        var tag_level = <?php echo file_get_contents("../public/book_tag/tag_list.json"); ?>;
-    </script>
-    <?php
-//
-
-require_once "../path.php";
-require_once "../public/_pdo.php";
-require_once '../media/function.php';
-require_once '../public/function.php';
-?>
-    <div id='course_head_bar' style='background-color:var(--tool-bg-color1);padding:1em 10px 10px 10px;'>
-    <div class='index_inner '>
-    <div style='font-size:140%'>
-    </div>
-    <div id="main_tag"  style="">
-    <span tag="sutta" title="sutta"></span>
-    <span tag="vinaya"  title="vinaya"></span>
-    <span tag="abhidhamma" title="abhidhamma"></span>
-    <span tag="mūla" title="mūla"></span>
-    <span tag="aṭṭhakathā" title="aṭṭhakathā"></span>
-    <span tag="ṭīkā" title="ṭīkā"></span>
-    <span tag="añña" title="añña"></span>
-	</div>
-
-	<div id="select_bar" >
-		<div id="tag_selected"></div>
-		<div><button onclick="tag_list_slide_toggle()">展开</button></div>
-	</div>
-	<div>
-
-		<div id="tag_list">
-			<div level="0" class="tag_others"></div>
-			<div level="1" class="tag_others"></div>
-			<div level="2" class="tag_others"></div>
-			<div level="3" class="tag_others"></div>
-			<div level="4" class="tag_others"></div>
-			<div level="5" class="tag_others"></div>
-			<div level="100" class="tag_others"></div>
-			<div level="8" class="tag_others"></div>
-		</div>
-	</div>
-    </div>
-    </div>
-
-	<div class='index_inner'>
-
-	<div id="chapter_shell" class="chapter_list" >
-	<div id="list_shell_1" class="show" level="1">
-		<ul id="list-1" class="grid" level="1" >
-		</ul>
-	</div>
-
-	<div id="list_shell_2" level="2">
-		<ul id="list-2" class="hidden" level="2"  >
-		</ul>
-	</div>
-
-	<div id="list_shell_3" level="3">
-		<ul id="list-3" class="hidden" level="3" >
-		</ul>
-	</div>
-
-	<div id="list_shell_4" level="4">
-		<ul id="list-4" class="hidden" level="4" >
-		</ul>
-	</div>
-
-	<div id="list_shell_5" level="5">
-		<ul id="list-5" class="hidden" level="5" >
-		</ul>
-	</div>
-
-	<div id="list_shell_6" level="6">
-		<ul id="list-6" class="hidden" level="6" >
-		</ul>
-	</div>
-
-	<div id="list_shell_7" level="7">
-		<ul id="list-7" class="hidden" level="7" >
-		</ul>
-	</div>
-
-	<div id="list_shell_8" level="8">
-		<ul id="list-8" class="hidden" level="8" >
-		</ul>
-	</div>
-
-    </div>
-    </div>
-
-    <script>
-        $(document).ready(function() {
-            palicanon_onload();
-        });
-    </script>
-    <?php
-include "../pcdl/html_foot.php";
-?>

+ 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;

+ 10 - 0
app/studio/index_head.php

@@ -64,6 +64,16 @@ require_once '../public/load_lang.php';
 	<script src="../term/term_popup.js"></script>
 	<link type="text/css" rel="stylesheet" href="../term/term.css"/>
 
+	<script language="javascript" src="../guide/guide.js"></script>
+	<link type="text/css" rel="stylesheet" href="../guide/guide.css"/>
+
+	<script src="../public/js/marked.js"></script>
+	<script src="../public/js/mermaid.min.js"></script>
+
+	<script src="../widget/iframe_modal_win.js"></script>
+	<link type="text/css" rel="stylesheet" href="../widget/iframe_modal_win.css"/>
+
+
 	<script type="text/javascript">
 	<?php require_once '../public/load_lang_js.php';//加载js语言包?>
 		

+ 3 - 1
app/studio/index_tool_bar.php

@@ -110,7 +110,9 @@
 
 				<li id="article"  onclick="goto_url(this,'../article/my_article_index.php')">
 					<span  class="navi_icon">
-						<svg t="1603167726865" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3914" width="32" height="32"><path d="M927.873506 253.409882H768V160.018071C768 71.806494 696.193506 0 607.981929 0H160.015059C71.661929 0 0.144565 71.661929 0 160.018071V863.984941C0 952.193506 71.806494 1024 160.018071 1024h702.238117l0.572236-0.144565 1.153505 0.144565C952.193506 1024 1024 952.193506 1024 863.981929V349.536376c-0.144565-53.097412-43.026071-95.984941-96.126494-96.126494zM525.239718 602.515576H205.203576c-17.700141 0-31.945788-14.390212-31.945788-31.945788 0-17.700141 14.390212-31.9488 31.945788-31.9488h320.036142c17.700141 0 31.945788 14.390212 31.945788 31.9488 0 17.697129-14.245647 31.945788-31.945788 31.945788z m0-159.873505H205.203576c-17.700141 0-31.945788-14.390212-31.945788-31.945789 0-17.700141 14.390212-31.9488 31.945788-31.9488h320.036142c17.700141 0 31.945788 14.390212 31.945788 31.9488 0 17.555576-14.245647 31.945788-31.945788 31.945789z m0-160.021083H205.203576c-17.700141 0-31.945788-14.3872-31.945788-31.945788 0-17.697129 14.390212-31.945788 31.945788-31.945788h320.036142c17.700141 0 31.945788 14.390212 31.945788 31.945788 0 17.558588-14.245647 31.945788-31.945788 31.945788z m434.724141 581.360941c0 52.811294-43.026071 95.984941-95.984941 95.984942-52.952847 0-95.978918-43.173647-95.978918-95.984942V317.446024h160.015059c17.703153 0 31.9488 14.390212 31.9488 31.945788v514.590117z" p-id="3915"></path></svg>	
+					<svg class="icon">
+					<use xlink:href="../studio/svg/icon.svg#article-1"></use>
+					</svg>	
 					</span>	
 					<span class="navi_text">
 					<?php echo $_local->gui->text."DIY";?>

+ 57 - 13
app/studio/js/render.js

@@ -1413,7 +1413,20 @@ function renderWordParBlockInner(elementBlock) {
 				if (_my_channal != null) {
 					for (const iterator of _my_channal) {
 						if (iterator.status > 0) {
-							output += render_tran_sent_block(book, paragraph, sent_begin, word_id, iterator.id, false);
+							let readonly;
+							if (iterator.power > 0 && iterator.power < 20) {
+								readonly = true;
+							} else {
+								readonly = false;
+							}
+							output += render_tran_sent_block(
+								book,
+								paragraph,
+								sent_begin,
+								word_id,
+								iterator.id,
+								readonly
+							);
 						}
 					}
 				}
@@ -1565,7 +1578,13 @@ function renderWordParBlockInner(elementBlock) {
 	if (_my_channal != null) {
 		for (const iterator of _my_channal) {
 			if (iterator.status > 0) {
-				output += render_tran_sent_block(book, paragraph, sent_begin, word_id, iterator.id, false);
+				let readonly;
+				if (iterator.power > 0 && iterator.power < 20) {
+					readonly = true;
+				} else {
+					readonly = false;
+				}
+				output += render_tran_sent_block(book, paragraph, sent_begin, word_id, iterator.id, readonly);
 			}
 		}
 	}
@@ -1705,8 +1724,8 @@ function render_tran_sent_block(book, para, begin, end, channal = 0, readonly =
 		output += "<span>";
 
 		if (thischannal) {
-			output += thischannal.name + "-<b>" + thischannal.lang + "</b>@";
-			if (thischannal.username == getCookie("username")) {
+			output += "<b>" + thischannal.name + "</b>@";
+			if (parseInt(thischannal.power) >= 30) {
 				output += gLocal.gui.your;
 			} else {
 				output += thischannal.nickname;
@@ -1714,6 +1733,7 @@ function render_tran_sent_block(book, para, begin, end, channal = 0, readonly =
 		} else {
 			output += "未知的频道名";
 		}
+		output += "-[" + thischannal.lang + "]";
 		output += "</span>";
 		output +=
 			"<span style='margin-left: auto;' class='send_status' id='send_" +
@@ -2203,11 +2223,19 @@ function renderWordDetailByElement_edit_a(xmlElement) {
 
 		arrFormula = getFormulaList(currGramma);
 		_txtOutDetail += '<div class="case_dropdown">';
-		_txtOutDetail += "<svg class='edit_icon';'><use xlink:href='svg/icon.svg#ic_more'></use></svg>";
+		_txtOutDetail += "<svg class='edit_icon'><use xlink:href='svg/icon.svg#ic_more'></use></svg>";
 		_txtOutDetail += '<div class="case_dropdown-content">';
 		newWord = removeFormula_B(orgMeaning);
-		_txtOutDetail += "<a onclick='fieldListChanged(\"" + wordID + '","mean","[]' + newWord + "\")'>["+gLocal.gui.none+"]</a>";
-		_txtOutDetail += "<a onclick='fieldListChanged(\"" + wordID + '","mean","' + newWord + "\")'>["+gLocal.gui.auto+"]</a>";
+		_txtOutDetail +=
+			"<a onclick='fieldListChanged(\"" +
+			wordID +
+			'","mean","[]' +
+			newWord +
+			"\")'>[" +
+			gLocal.gui.none +
+			"]</a>";
+		_txtOutDetail +=
+			"<a onclick='fieldListChanged(\"" + wordID + '","mean","' + newWord + "\")'>[" + gLocal.gui.auto + "]</a>";
 		for (var i in arrFormula) {
 			newWord = removeFormula_B(orgMeaning);
 			newWord = arrFormula[i].replace("~", newWord);
@@ -2738,11 +2766,19 @@ function renderWordDetailByElement(xmlElement) {
 
 		arrFormula = getFormulaList(currGramma);
 		_txtOutDetail += '<div class="case_dropdown">';
-		_txtOutDetail += "<svg class='edit_icon';'><use xlink:href='svg/icon.svg#ic_more'></use></svg>";
+		_txtOutDetail += "<svg class='edit_icon'><use xlink:href='svg/icon.svg#ic_more'></use></svg>";
 		_txtOutDetail += '<div class="case_dropdown-content">';
 		newWord = removeFormula_B(orgMeaning);
-		_txtOutDetail += "<a onclick='fieldListChanged(\"" + wordID + '","mean","[]' + newWord + "\")'>["+gLocal.gui.none+"]</a>";
-		_txtOutDetail += "<a onclick='fieldListChanged(\"" + wordID + '","mean","' + newWord + "\")'>["+gLocal.gui.auto+"]</a>";
+		_txtOutDetail +=
+			"<a onclick='fieldListChanged(\"" +
+			wordID +
+			'","mean","[]' +
+			newWord +
+			"\")'>[" +
+			gLocal.gui.none +
+			"]</a>";
+		_txtOutDetail +=
+			"<a onclick='fieldListChanged(\"" + wordID + '","mean","' + newWord + "\")'>[" + gLocal.gui.auto + "]</a>";
 		for (var i in arrFormula) {
 			newWord = removeFormula_B(orgMeaning);
 			newWord = arrFormula[i].replace("~", newWord);
@@ -3136,11 +3172,19 @@ function renderWordDetailByElement(xmlElement) {
 
 		arrFormula = getFormulaList(currGramma);
 		_txtOutDetail += '<div class="case_dropdown">';
-		_txtOutDetail += "<svg class='edit_icon';'><use xlink:href='svg/icon.svg#ic_more'></use></svg>";
+		_txtOutDetail += "<svg class='edit_icon'><use xlink:href='svg/icon.svg#ic_more'></use></svg>";
 		_txtOutDetail += '<div class="case_dropdown-content">';
 		newWord = removeFormula_B(orgMeaning);
-		_txtOutDetail += "<a onclick='fieldListChanged(\"" + wordID + '","mean","[]' + newWord + "\")'>["+gLocal.gui.none+"]</a>";
-		_txtOutDetail += "<a onclick='fieldListChanged(\"" + wordID + '","mean","' + newWord + "\")'>["+gLocal.gui.auto+"]</a>";
+		_txtOutDetail +=
+			"<a onclick='fieldListChanged(\"" +
+			wordID +
+			'","mean","[]' +
+			newWord +
+			"\")'>[" +
+			gLocal.gui.none +
+			"]</a>";
+		_txtOutDetail +=
+			"<a onclick='fieldListChanged(\"" + wordID + '","mean","' + newWord + "\")'>[" + gLocal.gui.auto + "]</a>";
 		for (var i in arrFormula) {
 			newWord = removeFormula_B(orgMeaning);
 			newWord = arrFormula[i].replace("~", newWord);

File diff suppressed because it is too large
+ 2 - 0
app/studio/svg/icon.svg


+ 3 - 1
app/term/add.svg

@@ -1 +1,3 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1605399923175" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1947" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M873.753974 149.961384A511.715358 511.715358 0 1 0 149.676742 874.038616 511.715358 511.715358 0 0 0 873.753974 149.961384zM831.537457 828.623878a447.750939 447.750939 0 1 1-633.247756-633.247756 447.750939 447.750939 0 0 1 633.247756 633.247756z" fill="" p-id="1948"></path><path d="M767.573037 480.01779H543.697568V256.142321a31.98221 31.98221 0 0 0-63.96442 0v223.875469H255.857679a31.98221 31.98221 0 0 0 0 63.96442h223.875469V767.857679a31.98221 31.98221 0 0 0 63.96442 0V543.98221H767.573037a31.98221 31.98221 0 0 0 0-63.96442z" fill="" p-id="1949"></path></svg>
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg t="1605399923175" id="add" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1947" xmlns:xlink="http://www.w3.org/1999/xlink" ><path d="M873.753974 149.961384A511.715358 511.715358 0 1 0 149.676742 874.038616 511.715358 511.715358 0 0 0 873.753974 149.961384zM831.537457 828.623878a447.750939 447.750939 0 1 1-633.247756-633.247756 447.750939 447.750939 0 0 1 633.247756 633.247756z" fill="" p-id="1948"></path><path d="M767.573037 480.01779H543.697568V256.142321a31.98221 31.98221 0 0 0-63.96442 0v223.875469H255.857679a31.98221 31.98221 0 0 0 0 63.96442h223.875469V767.857679a31.98221 31.98221 0 0 0 63.96442 0V543.98221H767.573037a31.98221 31.98221 0 0 0 0-63.96442z" fill="" p-id="1949"></path></svg>

+ 25 - 16
app/term/channal_list.php

@@ -5,6 +5,7 @@ require_once "../public/_pdo.php";
 require_once "../path.php";
 require_once '../channal/function.php';
 require_once '../ucenter/function.php';
+require_once '../share/function.php';
 
 $_data = array();
 $output = array();
@@ -30,29 +31,32 @@ $channal = array();
 
 #查询有阅读权限的channel
 $channal_list = array();
+$channel_power=array();
 if (isset($_COOKIE["userid"])) {
+	//找自己的
     PDO_Connect(_FILE_DB_CHANNAL_);
-    $query = "SELECT id from channal where owner = ?   limit 0,100";
+    $query = "SELECT id from channal where owner = ? and status >0   limit 0,100";
     $Fetch_my = PDO_FetchAll($query, array($_COOKIE["userid"]));
     foreach ($Fetch_my as $key => $value) {
         # code...
-        $channal_list[] = $value["id"];
+		$channal_list[] = $value["id"];
+		$channel_power[$value["id"]]=30;
     }
 
-    # 找协作的
-    $Fetch_coop = array();
-    $query = "SELECT channal_id FROM cooperation WHERE  user_id = ? ";
-    $coop_channal = PDO_FetchAll($query, array($_COOKIE["userid"]));
-    if (count($coop_channal) > 0) {
-        foreach ($coop_channal as $key => $value) {
-            # code...
-            $channal_list[] = $value["channal_id"];
-        }
-    }
-    /*  创建一个填充了和params相同数量占位符的字符串 */
-
+	# 找协作的
+	$coop_channal =  share_res_list_get($_COOKIE["userid"],2);
+	foreach ($coop_channal as $key => $value) {
+		# return res_id,res_type,power res_title  res_owner_id
+		$channal_list[] = $value["res_id"];
+		if(isset($channel_power[$value["res_id"]])){
+			if($channel_power[$value["res_id"]]<(int)$value["power"]){
+				$channel_power[$value["res_id"]]=(int)$value["power"];
+			}
+		}
+	}
 }
 if (count($channal_list) > 0) {
+	#  创建一个填充了和params相同数量占位符的字符串 
     $channel_place_holders = implode(',', array_fill(0, count($channal_list), '?'));
     $channel_query = " OR channal IN ($channel_place_holders)";
 } else {
@@ -137,8 +141,13 @@ foreach ($channal as $key => $value) {
     $channalInfo["count"] = $value;
     $channalInfo["all"] = count($_data);
     $channalInfo["final"] = $arr_sent_final;
-    $channalInfo["article_len"] = $article_len;
-
+	$channalInfo["article_len"] = $article_len;
+	if(isset($channel_power[$key])){
+		$channalInfo["power"] =$channel_power[$key];
+	}
+	else{
+		$channalInfo["power"] =10;
+	}
     $output[] = $channalInfo;
 }
 

+ 3 - 4
app/term/new.php

@@ -3,11 +3,11 @@
 
 require_once "../path.php";
 require_once "../public/_pdo.php";
-require_once '../public/load_lang.php';
 require_once '../public/function.php';
+require_once '../ucenter/function.php';
 
-global $PDO;
 PDO_Connect(_FILE_DB_TERM_);
+$userInfo = new UserInfo();
 
 $query = "select word,meaning , owner from term where 1  order by create_time DESC limit 0,4";
 $Fetch = PDO_FetchAll($query);
@@ -17,7 +17,6 @@ foreach ($Fetch as $row) {
     echo '<div class="card">';
     echo '<div class="title"><a href="../wiki/wiki.php?word=' . $row["word"] . '">' . $row["word"] . '</a></div>';
     echo '<div class="summary">' . $row["meaning"] . '</div>';
-    echo '<div class="author">' . $row["owner"] . '</div>';
-
+    echo '<div class="author">' . $userInfo->getName($row["owner"])["nickname"] . '</div>';
     echo '</div>';
 }

+ 672 - 122
app/term/note.js

@@ -225,13 +225,18 @@ function note_refresh_new() {
 						}
 						//处理<code>标签作为气泡注释
 						popup_init();
+
 						//刷新句子链接递归,有加层数限制。
-						note_refresh_new();
+						//note_refresh_new();
 
+						//将新的数据添加到数据总表
 						_arrData = _arrData.concat(sentData);
 						note_ref_init();
+						//获取术语字典
 						term_get_dict();
+						//刷新channel列表
 						note_channal_list();
+						//显示不同的巴利语脚本
 						refresh_pali_script();
 						//把巴利语单词用<w>分隔用于点词查询等
 						splite_pali_word();
@@ -326,7 +331,12 @@ function render_channal_list(channalinfo) {
 		'<div class="channel_select"><input type="checkbox" ' + checked + " channal_id='" + channalinfo.id + "'></div>";
 	output += "<div class='head'>";
 	output += "<span class='head_img'>";
-	output += channalinfo.nickname.slice(0, 2);
+	if (parseInt(channalinfo.power) == 30) {
+		output += gLocal.gui.your.slice(0, 1);
+	} else {
+		output += channalinfo.nickname.slice(0, 1);
+	}
+
 	output += "</span>";
 	output += "</div>";
 
@@ -336,12 +346,36 @@ 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 += "✏️";
+		}
+	}
+	//✋
 	output += "<a onclick=\"set_channal('" + channalinfo.id + "')\">";
 
 	output += channalinfo["name"];
 
 	output += "</a>";
-	output += "@" + channalinfo["nickname"];
+	if (parseInt(channalinfo.power) == 30) {
+		output += "@" + gLocal.gui.your;
+	} else {
+		output += "@" + channalinfo["nickname"];
+	}
 	output += "</div>";
 
 	output += "<div class='userinfo_channal'>";
@@ -355,6 +389,7 @@ function render_channal_list(channalinfo) {
 		let svg_width = article_len;
 		let svg_height = parseInt(article_len / 10);
 		output += '<svg viewBox="0 0 ' + svg_width + " " + svg_height + '" width="100%" >';
+
 		let curr_x = 0;
 		let allFinal = 0;
 		for (const iterator of channalinfo["final"]) {
@@ -499,66 +534,364 @@ 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>";
 	//未选择的其他译文开始
 	output += "<div class='other_tran_div' sent='";
 	output += in_json.book + "-" + in_json.para + "-" + in_json.begin + "-" + in_json.end + "' >";
-	output += "<div class='tool_bar' sent='";
+	output += "<div class='tool_bar' style='display:flex;' sent='";
 	output += in_json.book + "-" + in_json.para + "-" + in_json.begin + "-" + in_json.end + "' >";
+	output += "<span class='tool_left'>";
+	//第一个按钮
+	//新增译文按钮开始
+	output += "<span class='' ";
+	output += "book='" + in_json.book + "' ";
+	output += "para='" + in_json.para + "' ";
+	output += "begin='" + in_json.begin + "' ";
+	output += "end='" + in_json.end + "' ";
+	output += " >";
+	output += "<span class='' onclick='add_new_tran_button_click(this)'>+添加译文</span>";
+	output += "<div class='tran_text_tool_bar'>";
+	output += "</div>";
+	output += "</span>";
+	//新增译文按钮结束
+	output += "<span class='separate_line'></span>";
+	//第二个按钮
 	output += "<span class='more_tran icon_expand'></span>";
 	//其他译文工具条
 	output += "<span class='other_bar'  >";
 	output += "<span class='other_tran_span' >" + gLocal.gui.other + gLocal.gui.translation + "</span>";
 	output += "<span class='other_tran_num'></span>";
 	output += "</span>";
+
 	output += "<span class='separate_line'></span>";
-	//相似句工具条
-	output += "<span class='other_bar' >";
-	output +=
-		"<span class='similar_sent_span' onclick=\"note_show_pali_sim('" +
-		in_json.pali_sent_id +
-		"')\">" +
-		gLocal.gui.similar_sentences +
-		"</span>";
-	output += "<span class='similar_sent_num'>" + in_json.sim + "</span>";
+	//第三个按钮 相似句
+	if (parseInt(in_json.sim) > 0) {
+		output += "<span class='other_bar' >";
+		output +=
+			"<span class='similar_sent_span' onclick=\"note_show_pali_sim('" +
+			in_json.pali_sent_id +
+			"')\">" +
+			gLocal.gui.similar_sentences +
+			"</span>";
+		output += "<span class='similar_sent_num'>" + in_json.sim + "</span>";
+		output += "</span>";
+	}
+
+	//第三个按钮 相似句结束
+	output += "</span>";
+
+	output += "<span class='tool_right'>";
+	//出处路径开始
+	output += "<span class='ref'>" + in_json.ref;
+	output += "<span class='sent_no'>";
+	output += in_json.book + "-" + in_json.para + "-" + in_json.begin + "-" + in_json.end;
+	output += "<span>";
+	output += "</span>";
+	//出处路径结束
 	output += "</span>";
-	output += "</div>";
-	output += "<div class='other_tran'>";
 
 	output += "</div>";
-	output += "</div>";
+	//工具栏结束
+
 	//未选择的其他译文开始
-	//新增译文按钮开始
-	output += "<div class='add_new icon_add' ";
-	output += "book='" + in_json.book + "' ";
-	output += "para='" + in_json.para + "' ";
-	output += "begin='" + in_json.begin + "' ";
-	output += "end='" + in_json.end + "' ";
-	output += " >";
-	output += "<div class='icon_add' onclick='add_new_tran_button_click(this)'></div>";
-	output += "<div class='tran_text_tool_bar'>";
+	output += "<div class='other_tran'>";
 	output += "</div>";
+
 	output += "</div>";
-	//新增译文按钮结束
-	//出处路径开始
-	output += "<div class='ref'>" + in_json.ref;
-	output +=
-		"<span class='sent_no'>" +
-		in_json.book +
-		"-" +
-		in_json.para +
-		"-" +
-		in_json.begin +
-		"-" +
-		in_json.end +
-		"<span>" +
-		"</div>";
-	//出处路径结束
+
 	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 sent_commit(src, id) {
+	commit_init({
+		src: src,
+		sent: [id],
+		express: true,
+	});
+}
+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 += "' dbid='" + iterator.id + "' 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_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 += 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 {
+			//非提交人
+			if (parseInt(iterator.mypower) >= 20) {
+				//有权限 采纳按钮
+				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#accept_copy"></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" >';
+		if (parseInt(iterator.mypower) < 20) {
+			html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#my_idea"></use>';
+		} else {
+			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>";
+
+		//推送按钮
+		let commitIcon = "";
+		let commitTipText = "";
+		if (parseInt(iterator.mypower) >= 30 && parseInt(iterator.status) < 30) {
+			//我的私有资源 公开发布
+			commitIcon = "publish";
+			commitTipText = "公开发布";
+		} else {
+			if (parseInt(iterator.mypower) < 20) {
+				//只读资源 采纳
+				commitIcon = "accept_copy";
+				commitTipText = "采纳";
+			} else {
+				//其他资源 复制到
+				commitIcon = "copy";
+				commitTipText = "复制到";
+			}
+		}
+		html += "<button class='icon_btn tooltip' ";
+		html += " onclick=\"sent_commit('" + iterator.channal + "','" + sid + "')\">";
+		html += '<svg class="icon" >';
+		html += '<use xlink="http://www.w3.org/1999/xlink" href="../studio/svg/icon.svg#' + commitIcon + '"></use>';
+		html += "</svg>";
+		html += "<span class='tooltiptext tooltip-top'>";
+		html += commitTipText;
+		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 + "' ";
+	if (typeof iterator.is_pr != "undefined" && iterator.is_pr == true) {
+		html += 'onchange="note_pr_save(this)"';
+	} else {
+		html += 'onchange="note_sent_save_a(this)"';
+	}
+
+	html += ">" + 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 = "";
@@ -587,9 +920,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 +=
@@ -651,33 +983,63 @@ function render_one_sent_tran(book, para, begin, end, iterator) {
 function add_new_tran_button_click(obj) {
 	let html = "<ul>";
 	for (const iterator of _my_channal) {
-		if (_channal.indexOf(iterator.id) < 0) {
-			html += '<li onclick="';
-			html +=
-				"new_sentence('" +
-				$(obj).parent().attr("book") +
-				"' ,'" +
-				$(obj).parent().attr("para") +
-				"' ,'" +
-				$(obj).parent().attr("begin") +
-				"' ,'" +
-				$(obj).parent().attr("end") +
-				"' ,'" +
-				iterator.id +
-				"',this)";
-			html += '">' + iterator.name + "</li>";
+		if (iterator.status > 0) {
+			if (_channal.indexOf(iterator.id) < 0) {
+				html += '<li onclick="';
+				html +=
+					"new_sentence('" +
+					$(obj).parent().attr("book") +
+					"' ,'" +
+					$(obj).parent().attr("para") +
+					"' ,'" +
+					$(obj).parent().attr("begin") +
+					"' ,'" +
+					$(obj).parent().attr("end") +
+					"' ,'" +
+					iterator.id +
+					"',this)";
+				html += '">' + iterator.name;
+				if (parseInt(iterator.power) < 20) {
+					html += "(建议)";
+				}
+				html += "</li>";
+			}
 		}
 	}
 	html += "</ul>";
 	$(obj).parent().children(".tran_text_tool_bar").first().html(html);
+
 	if ($(obj).parent().children(".tran_text_tool_bar").css("display") == "block") {
 		$(obj).parent().children(".tran_text_tool_bar").first().hide();
 	} else {
 		$(obj).parent().children(".tran_text_tool_bar").first().show();
+		$(document).one("click", function () {
+			$(obj).parent().children(".tran_text_tool_bar").first().hide();
+		});
+		event.stopPropagation();
 		$(obj).parent().show();
 	}
 }
-
+function tool_bar_show(element) {
+	if ($(element).find(".tran_text_tool_bar").css("display") == "none") {
+		$(element).find(".tran_text_tool_bar").css("display", "flex");
+		$(element).find(".icon_expand").css("transform", "rotate(-180deg)");
+		$(element).css("background-color", "var(--btn-bg-color)");
+		$(element).css("visibility", "visible");
+		$(document).one("click", function () {
+			$(element).find(".tran_text_tool_bar").hide();
+			$(element).css("background-color", "var(--nocolor)");
+			$(element).find(".icon_expand").css("transform", "unset");
+			$(element).css("visibility", "");
+		});
+		event.stopPropagation();
+	} else {
+		$(element).find(".tran_text_tool_bar").hide();
+		$(element).css("background-color", "var(--nocolor)");
+		$(element).find(".icon_expand").css("transform", "unset");
+		$(element).css("visibility", "");
+	}
+}
 function new_sentence(book, para, begin, end, channel, obj) {
 	let newsent = { id: "", text: "", lang: "", channal: channel };
 
@@ -730,13 +1092,13 @@ function set_more_button_display() {
 			$(this)
 				.find(".other_bar")
 				.click(function () {
-					const sentid = $(this).parent().attr("sent").split("-");
+					const sentid = $(this).parent().parent().attr("sent").split("-");
 					const book = sentid[0];
 					const para = sentid[1];
 					const begin = sentid[2];
 					const end = sentid[3];
 					let sentId = book + "-" + para + "-" + begin + "-" + end;
-					if ($(this).parent().siblings(".other_tran").first().css("display") == "none") {
+					if ($(this).parent().parent().siblings(".other_tran").first().css("display") == "none") {
 						$(".other_tran_div[sent='" + sentId + "']")
 							.children(".other_tran")
 							.slideDown();
@@ -751,12 +1113,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 +
 									"-" +
@@ -828,16 +1192,48 @@ function note_edit_sentence(book, para, begin, end, channal) {
 
 	alert("未找到句子");
 }
+function update_note_sent_tran(obj) {}
+//保存pr句子 新
+function note_pr_save(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 channel = $(obj).attr("channel");
+	let text = $(obj).val();
+	let sent_tran_div = find_sent_tran_div(obj);
+	$.post(
+		"../usent/pr_post.php",
+		{
+			id: id,
+			book: book,
+			para: para,
+			begin: begin,
+			end: end,
+			channel: channel,
+			text: text,
+		},
+		sent_save_callback
+	);
 
-function note_sent_save() {
-	let id = $("#edit_dialog_text").attr("sent_id");
-	let book = $("#edit_dialog_text").attr("book");
-	let para = $("#edit_dialog_text").attr("para");
-	let begin = $("#edit_dialog_text").attr("begin");
-	let end = $("#edit_dialog_text").attr("end");
-	let channal = $("#edit_dialog_text").attr("channal");
-	let text = $("#edit_dialog_text").val();
+	if (sent_tran_div) {
+		$(sent_tran_div).find(".preview").addClass("loading");
+	}
+}
 
+//保存译文句子 新
+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",
 		{
@@ -850,44 +1246,41 @@ function note_sent_save() {
 			text: text,
 			lang: "zh",
 		},
-		function (data) {
-			let result = JSON.parse(data);
-			if (result.status > 0) {
-				alert("error" + result.message);
-			} else {
-				ntf_show("success");
+		sent_save_callback
+	);
+
+	if (sent_tran_div) {
+		$(sent_tran_div).find(".preview").addClass("loading");
+	}
+}
+
+function sent_save_callback(data) {
+	let result = JSON.parse(data);
+	if (result.status > 0) {
+		alert("error" + result.message);
+	} else {
+		let sid = result.book + "-" + result.para + "-" + result.begin + "-" + result.end;
+
+		let sent_tran_div = $(
+			".sent_tran[dbid='" + result.id + "'][channel='" + result.channal + "'][sid='" + sid + "']"
+		);
+		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;
 					}
-					$(
-						"#tran_text_" +
-							result.book +
-							"_" +
-							result.para +
-							"_" +
-							result.begin +
-							"_" +
-							result.end +
-							"_" +
-							result.channal
-					).html("<span style='color:var(--border-line-color);'>" + channel_info + "</span>");
+					divPreview.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)));
+					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 &&
@@ -904,6 +1297,98 @@ function note_sent_save() {
 						}
 					}
 				}
+				sent_tran_div.find(".preview").removeClass("loading");
+			}
+		} else if (result.commit_type == 3) {
+			ntf_show("已经提交修改建议");
+		} else {
+			ntf_show("未提交");
+		}
+	}
+}
+
+//保存译文句子
+function note_sent_save() {
+	let id = $("#edit_dialog_text").attr("sent_id");
+	let book = $("#edit_dialog_text").attr("book");
+	let para = $("#edit_dialog_text").attr("para");
+	let begin = $("#edit_dialog_text").attr("begin");
+	let end = $("#edit_dialog_text").attr("end");
+	let channal = $("#edit_dialog_text").attr("channal");
+	let text = $("#edit_dialog_text").val();
+
+	$.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 (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("未提交");
+				}
 			}
 		}
 	);
@@ -921,27 +1406,7 @@ function edit_in_studio(book, para, begin, end) {
 	wbw_channal_list_open(book, [para]);
 }
 
-function tool_bar_show(element) {
-	if ($(element).find(".tran_text_tool_bar").css("display") == "none") {
-		$(element).find(".tran_text_tool_bar").css("display", "flex");
-		$(element).find(".icon_expand").css("transform", "rotate(-180deg)");
-		$(element).css("background-color", "var(--btn-bg-color)");
-		$(element).css("visibility", "visible");
-		$(document).one("click", function () {
-			$(element).find(".tran_text_tool_bar").hide();
-			$(element).css("background-color", "var(--nocolor)");
-			$(element).find(".icon_expand").css("transform", "unset");
-			$(element).css("visibility", "");
-		});
-		event.stopPropagation();
-	} else {
-		$(element).find(".tran_text_tool_bar").hide();
-		$(element).css("background-color", "var(--nocolor)");
-		$(element).find(".icon_expand").css("transform", "unset");
-		$(element).css("visibility", "");
-	}
-}
-
+//显示和隐藏某个内容 如 巴利文
 function setVisibility(key, value) {
 	switch (key) {
 		case "palitext":
@@ -1027,3 +1492,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;
+}

+ 68 - 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"])) {
@@ -156,38 +160,91 @@ foreach ($_data as $key => $value) {
 
         $stmt = $db_trans_sent->prepare($query);
         if (empty($_setting["channal"])) {
+			#没有指定channel
             if ($sentChannal == "") {
+				#句子信息也没指定channel
                 $parm = array($bookId, $para, $begin, $end);
                 $parm = array_merge_recursive($parm, $channal_list);
                 $stmt->execute($parm);
                 $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"], 
+										   "status" => $Fetch["status"], 
+										   "editor" => $Fetch["editor"],
+										   "editor_name"=>$_userinfo->getName($Fetch["editor"]),
+										   "update_time"=>$Fetch["modify_time"]
+										);
                     if (!empty($Fetch["channal"])) {
                         $tran_channal[$Fetch["channal"]] = $Fetch["channal"];
                     }
                 }
             } else {
+				#句子信息包含channel
+				#{{book-para-begin-end@channelid}}
                 $stmt->execute(array($bookId, $para, $begin, $end, $sentChannal));
                 $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"], 
+										   "status" => $Fetch["status"], 
+										   "editor" => $Fetch["editor"],
+										   "editor_name"=>$_userinfo->getName($Fetch["editor"]),
+										   "update_time"=>$Fetch["modify_time"]
+										);
                     $tran_channal[$Fetch["channal"]] = $Fetch["channal"];
                 }
             }
         } else {
+			#指定了channel
             $arrChannal = explode(",", $_setting["channal"]);
             foreach ($arrChannal as $key => $value) {
                 # code...
                 $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"]);
+                    $translation[] = array("id" => $Fetch["id"],
+										   "book"=>$bookId,
+										   "para"=>$para,
+										   "begin"=>$begin,
+										   "end"=>$end,
+										   "text" => $Fetch["text"], 
+										   "lang" => $Fetch["language"], 
+										   "channal" => $value, 
+										   "status" => $Fetch["status"], 
+										   "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,
+										   "status" => 0,
+										   "editor" => false,
+										   "editor_name"=>false,
+										   "update_time"=>false
+										);
                 }
                 $tran_channal[$value] = $value;
             }
@@ -201,14 +258,21 @@ 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"];
+            $translation[$key]["status"] = $tran_channal[$value["channal"]]["status"];
+			#查询句子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;
         }
+
     }
 
     //查询路径

+ 158 - 19
app/term/term.css

@@ -189,13 +189,12 @@ note > .tran > .text {
 }
 note > .tran .tran_text_tool_bar,
 .tran_text_tool_bar {
-	padding: 0 0.1em;
+	padding: 0.5em 1em;
 	position: absolute;
 	display: none;
 	color: var(--border-line-color);
 	z-index: 40;
 	width: auto;
-	left: -2em;
 	font-size: 14px;
 	height: auto;
 	line-height: 28px;
@@ -265,13 +264,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 {
@@ -297,17 +292,10 @@ note > .palitext > note {
 }
 
 note .ref {
-	text-align: right;
 	font-size: 75%;
 	white-space: nowrap;
 	overflow-x: scroll;
-	margin-left: auto;
-	border-top: solid 1px var(--nocolor);
-	position: absolute;
-	bottom: -1.3em;
-	right: 0;
 	max-width: 100%;
-	right: 1.3em;
 }
 note:hover .ref {
 	/*border-top: solid 1px var(--border-line-color);*/
@@ -339,7 +327,7 @@ r {
 }
 
 note {
-	padding: 0.5em 2em;
+	padding: 0.5em 0 0 0;
 	margin-bottom: 0.4em;
 	border-radius: 5px;
 	line-height: 1.3em;
@@ -409,13 +397,12 @@ note:hover .add_new {
 	border-top: 1px solid var(--border-line-color);
 }
 .other_tran_div > .tool_bar {
-	position: absolute;
-	margin-top: -0.7em;
 	background-color: var(--btn-bg-color);
 	padding: 0 6px;
-	border-radius: 4px;
+	border-radius: 0 0 4px 4px;
 	cursor: pointer;
 	display: flex;
+	justify-content: space-between;
 }
 .other_tran_div > .other_tran {
 	min-height: 1em;
@@ -504,7 +491,8 @@ note:hover .note_tool_bar {
 	padding: 5px;
 	border-radius: 5px;
 }
-.other_tran_num {
+.other_tran_num,
+.similar_sent_num {
 	-webkit-border-radius: 7px;
 	border-radius: 7px;
 	background-color: cornflowerblue;
@@ -519,6 +507,9 @@ note:hover .note_tool_bar {
 	margin: auto 2px;
 	color: whitesmoke;
 }
+.similar_sent_num {
+	display: unset;
+}
 .separate_line {
 	border: solid 1px #e8e8e8;
 	border-radius: 3px;
@@ -547,3 +538,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>

+ 30 - 0
app/ucenter/card.php

@@ -0,0 +1,30 @@
+<?php
+//
+
+require_once "../path.php";
+require_once "../public/_pdo.php";
+require_once '../ucenter/function.php';
+
+
+if (isset($_GET["id"])) {
+	$output["id"]=$_GET["id"];
+	PDO_Connect( _FILE_DB_USERINFO_);
+    $query = "SELECT userid as id ,username,nickname,create_time FROM user WHERE userid=?";
+	$channel = PDO_FetchRow($query, array($_GET["id"]));
+	$strData="";
+	if ($channel) {
+		$strData .= "<div>昵称:".$channel["nickname"]."</div>";
+		$strData .=  "<div>用户名:".$channel["username"]."</div>";
+		$strData .=  "<div>注册时间:".date("Y/m/d",$channel["create_time"]/1000)."</div>";
+		$strData .=  "<div><a href='../uhome/index.php?userid=".$channel["id"]."' target='_blank'>个人空间</a></div>";
+	} else {
+		$strData .=  "unkow";
+	}
+	$output["data"] = $strData;
+} else {
+	$output["id"]=0;
+	$output["data"] = "unkow";
+}
+echo json_encode($output, JSON_UNESCAPED_UNICODE);
+
+?>

+ 5 - 5
app/ucenter/get.php

@@ -2,22 +2,22 @@
 require_once '../path.php';
 
 //打开数据库
-$dns = "" . _FILE_DB_USERINFO_;
-$dbh = new PDO($dns, "", "", array(PDO::ATTR_PERSISTENT => true));
+
+$dbh = new PDO(_FILE_DB_USERINFO_, "", "", array(PDO::ATTR_PERSISTENT => true));
 $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
 if (isset($_GET["id"])) {
 	if(isset($_GET["bio"])){
-		$query = "select bio,email from profile where user_id = ? ";
+		$query = "SELECT bio,email from profile where user_id = ? ";
 	}
 	else{
-		$query = "select userid as id ,username,nickname from user where userid = ? ";
+		$query = "SELECT userid as id ,username,nickname from user where userid = ? ";
 	}
     
     $stmt = $dbh->prepare($query);
     $stmt->execute(array($_GET["id"]));
     $fUser = $stmt->fetchAll(PDO::FETCH_ASSOC);
 } else if (isset($_GET["username"])) {
-    $query = "select userid as id ,username,nickname,email from user where  nickname like ? limit 0,8";
+    $query = "SELECT userid as id ,username,nickname,email from user where  nickname like ? limit 0,8";
     $stmt = $dbh->prepare($query);
     $username = "%" . $_GET["username"] . "%";
     $stmt->execute(array($username));

+ 337 - 0
app/usent/function.php

@@ -20,3 +20,340 @@ function update_historay($sent_id, $user_id, $text, $landmark)
         return "";
     }
 }
+
+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,channel,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;
+		}
+	}
+
+	public function setPrData($id,$text){
+		if ($this->dbh_sent) {
+            $query = "UPDATE sent_pr set text=? ,modify_time=?  WHERE id = ? and editor= ? ";
+            $stmt = $this->dbh_sent->prepare($query);
+            $stmt->execute(array($text,mTime(),$id,$_COOKIE["userid"]));
+            
+			if (!$stmt || ($stmt && $stmt->errorCode() != 0)) {
+				/*  识别错误  */
+				$error = $this->dbh_sent->errorInfo();
+				//$respond['message'] = $error[2];
+				return false;
+			} else {
+				#没错误 更新历史记录
+				return true;
+			}
+		}
+		else{
+			return false;
+		}
+	}
+}
+
+class Sent_DB
+{
+    private $dbh_sent;
+	private $dbh_his;
+	private $errorMsg="";
+    public function __construct() {
+        $this->dbh_sent = new PDO(_FILE_DB_SENTENCE_, "", "",array(PDO::ATTR_PERSISTENT=>true));
+		$this->dbh_sent->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);  
+		
+		$this->dbh_his = new PDO(_FILE_DB_USER_SENTENCE_HISTORAY_, "", "",array(PDO::ATTR_PERSISTENT=>true));
+        $this->dbh_his->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);  
+	}
+	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){
+		/* 修改现有数据 */
+	
+		if (count($arrData) > 0) {
+			//add_edit_event(_SENT_EDIT_, "{$oldList[0]["book"]}-{$oldList[0]["paragraph"]}-{$oldList[0]["begin"]}-{$oldList[0]["end"]}@{$oldList[0]["channal"]}");
+	
+			$this->dbh_sent->beginTransaction();
+			$query = "UPDATE sentence SET text = ? , strlen = ? , editor=?, modify_time= ?   where  id= ?  ";
+			$sth = $this->dbh_sent->prepare($query);
+	
+			foreach ($arrData as $data) {
+				$sth->execute(array($data["text"],mb_strlen($data["text"],"UTF-8"),$data["editor"],mTime(),$data["id"]));
+			}
+	
+			$this->dbh_sent->commit();
+		
+			if (!$sth || ($sth && $sth->errorCode() != 0)) {
+				/*  识别错误且回滚更改  */
+				$this->dbh_sent->rollBack();
+				$error = $this->dbh_sent->errorInfo();
+				$this->errorMsg = $error[2];
+				return false;
+			} else {
+				#没错误 添加log 
+				$this->errorMsg = "";
+				return true;
+			}
+		}
+		else{
+			$this->errorMsg = "";
+			return true;
+		}
+	}
+
+	public function insert($arrData){
+		/* 插入新数据 */
+		//查询channel语言
+		if (count($arrData) > 0) {
+			//add_edit_event(_SENT_NEW_, "{$newList[0]["book"]}-{$newList[0]["paragraph"]}-{$newList[0]["begin"]}-{$newList[0]["end"]}@{$newList[0]["channal"]}");
+			$this->dbh_sent->beginTransaction();
+			$query = "INSERT INTO sentence (id,
+											parent,
+											book,
+											paragraph,
+											begin,
+											end,
+											channal,
+											tag,
+											author,
+											editor,
+											text,
+											language,
+											ver,
+											status,
+											strlen,
+											modify_time,
+											receive_time,
+											create_time
+											)
+								VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
+			$sth = $this->dbh_sent->prepare($query);
+	
+			$channel_info = new Channal();
+	
+			foreach ($arrData as $data) {
+				if($data["id"]==""){
+					$data["id"] = UUID::v4();
+				}
+				
+				$queryChannel = $channel_info->getChannal($data["channal"]);
+				if ($queryChannel == false) {
+					$lang = $data["language"];
+					$status = 10;
+				} else {
+					$lang = $queryChannel["lang"];
+					$status = $queryChannel["status"];
+				}
+				$sth->execute(array($data["id"],
+					isset($data["parent"]) ? $data["parent"] : "",
+					$data["book"],
+					$data["paragraph"],
+					$data["begin"],
+					$data["end"],
+					$data["channal"],
+					isset($data["tag"]) ? $data["tag"] : "",
+					$data["author"],
+					$data["editor"],
+					$data["text"],
+					$lang,
+					1,
+					$status,
+					mb_strlen($data["text"], "UTF-8"),
+					mTime(),
+					mTime(),
+					mTime(),
+				));
+			}
+			$this->dbh_sent->commit();
+	
+			if (!$sth || ($sth && $sth->errorCode() != 0)) {
+				/*  识别错误且回滚更改  */
+				$this->dbh_sent->rollBack();
+				$error = $this->dbh_sent->errorInfo();
+				$this->errorMsg = $error[2];
+				return false;
+			} else {
+				$this->errorMsg = "";
+				return true;
+			}
+		}
+		else{
+			$this->errorMsg = "";
+			return true;
+		}
+	}
+
+	public function send_pr($arrData){
+		if (count($arrData) ==0) {
+			$this->errorMsg = "";
+			return true;
+		}
+		$this->dbh_sent->beginTransaction();
+		$query = "INSERT INTO sent_pr (id,
+							book,
+							paragraph,
+							begin,
+							end,
+							channel,
+							tag,
+							author,
+							editor,
+							text,
+							language,
+							status,
+							strlen,
+							modify_time,
+							receive_time,
+							create_time
+							)
+							VALUES (NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
+		$stmt = $this->dbh_sent->prepare($query);
+
+		foreach ($arrData as $data) {
+			# 初始状态 1 未处理
+			$stmt->execute(array(
+							$data["book"],
+							$data["para"],
+							$data["begin"],
+							$data["end"],
+							$data["channal"],
+							"",
+							"[]",
+							$data["editor"],
+							$data["text"],
+							$data["language"],
+							1,
+							mb_strlen($data["text"], "UTF-8"),
+							mTime(),
+							mTime(),
+							mTime(),
+							));
+		}
+		$this->dbh_sent->commit();
+		if (!$stmt || ($stmt && $stmt->errorCode() != 0)) {
+			#  识别错误  
+			$this->dbh_sent->rollBack();
+			$error = $this->dbh_sent->errorInfo();
+			$this->errorMsg = $error[2];
+			return false;
+		} else {
+			# 没错误
+			$this->errorMsg = "";
+			return true;
+		}
+	}
+
+	public function historay($arrData)
+	{
+		if (count($arrData) ==0) {
+			$this->errorMsg = "";
+			return true;
+		}
+		$this->dbh_his->beginTransaction();
+		# 更新historay
+		$query = "INSERT INTO sent_historay (sent_id,  user_id,  text,  date, landmark) VALUES (? , ? , ? , ? , ? )";
+		$stmt = $this->dbh_his->prepare($query);
+
+		foreach ($arrData as $data) {
+			$stmt->execute(array($data["id"],
+							$data["editor"],
+							$data["text"],
+							mTime(),
+							$data["landmark"]));
+		}
+		$this->dbh_his->commit();
+		if (!$stmt || ($stmt && $stmt->errorCode() != 0)) {
+			/*  识别错误  */
+			$this->dbh_his->rollBack();
+			$error = $this->dbh_his->errorInfo();
+			$this->errorMsg = $error[2];
+			return false;
+		} else {
+			#没错误
+			$this->errorMsg = "";
+			return true;
+		}
+	}
+}

+ 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);

+ 35 - 0
app/usent/get_pr.php

@@ -0,0 +1,35 @@
+<?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]["channal"]=$value["channel"];
+	$result[$key]["para"]=$value["paragraph"];
+	$result[$key]["channalinfo"] = $channel_info->getChannal($value["channel"]);
+	$result[$key]["mypower"] = $channel_info->getPower($value["channel"]);
+	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);

+ 30 - 0
app/usent/pr_post.php

@@ -0,0 +1,30 @@
+<?php
+
+require_once "../usent/function.php";
+require_once "../channal/function.php";
+require_once "../ucenter/function.php";
+require_once "../redis/function.php";
+
+//回传数据
+$respond = array("status" => 0, "message" => "");
+$respond['id'] = $_POST["id"];
+$respond['book'] = $_POST["book"];
+$respond['para'] = $_POST["para"];
+$respond['begin'] = $_POST["begin"];
+$respond['end'] = $_POST["end"];
+$respond['channal'] = $_POST["channel"];
+$respond['text'] = $_POST["text"];
+$respond['editor'] = $_COOKIE["userid"];
+$respond['commit_type'] = 1;
+
+$redis = redis_connect();
+
+$channel_info = new Channal();
+$user_info = new UserInfo();
+$pr = new SentPr($redis);
+$result = $pr->setPrData($_POST["id"],$_POST["text"]);
+if(!$result){
+	$respond['status']=1;
+	$respond['message']="error";
+}
+echo json_encode($respond, JSON_UNESCAPED_UNICODE);

+ 148 - 43
app/usent/sent_post.php

@@ -5,6 +5,7 @@ require_once "../public/_pdo.php";
 require_once "../public/function.php";
 require_once "../usent/function.php";
 require_once "../ucenter/active.php";
+require_once "../share/function.php";
 
 #检查是否登陆
 if (!isset($_COOKIE["userid"])) {
@@ -20,6 +21,7 @@ if (isset($_POST["landmark"])) {
 }
 //回传数据
 $respond = array("status" => 0, "message" => "");
+$respond['id'] = $_POST["id"];
 $respond['book'] = $_POST["book"];
 $respond['para'] = $_POST["para"];
 $respond['begin'] = $_POST["begin"];
@@ -27,6 +29,9 @@ $respond['end'] = $_POST["end"];
 $respond['channal'] = $_POST["channal"];
 $respond['text'] = $_POST["text"];
 $respond['editor'] = $_COOKIE["userid"];
+$respond['commit_type'] = 0; #0 未提交 1 插入 2 修改 3pr 
+
+add_edit_event(_SENT_EDIT_, "{$_POST["book"]}-{$_POST["para"]}-{$_POST["begin"]}-{$_POST["end"]}@{$_POST["channal"]}");
 
 #先查询对此channal是否有权限修改
 $cooperation = 0;
@@ -39,22 +44,19 @@ if (isset($_POST["channal"])) {
 
     if ($fetch) {
         $text_lang = $fetch["lang"];
-        $channel_status = $fetch["status"];
+		$channel_status = $fetch["status"];
     }
     $respond['lang'] = $text_lang;
     if ($fetch && $fetch["owner"] == $_COOKIE["userid"]) {
         #自己的channal
-        $cooperation = 1;
+        $cooperation = 30;
     } else {
-        $query = "SELECT count(*) FROM cooperation WHERE channal_id= ? and user_id=? ";
-        $fetch = PDO_FetchOne($query, array($_POST["channal"], $_COOKIE["userid"]));
-        if ($fetch > 0) {
-            #有协作权限
-            $cooperation = 1;
-        } else {
-            #无协作权限
-            $cooperation = 0;
-        }
+		$sharePower = share_get_res_power($_COOKIE["userid"],$_POST["channal"]);
+		$cooperation = $sharePower;
+		if($channel_status>=30 && $cooperation<10){
+			#全网公开的 可以提交pr
+			$cooperation = 10;
+		}
     }
 } else {
     $respond["status"] = 1;
@@ -63,9 +65,14 @@ if (isset($_POST["channal"])) {
     exit;
 }
 
-add_edit_event(_SENT_EDIT_, "{$_POST["book"]}-{$_POST["para"]}-{$_POST["begin"]}-{$_POST["end"]}@{$_POST["channal"]}");
+if($cooperation==0){
+	$respond['message'] = "no power";
+	$respond['status'] = 1;
+	echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+    exit;
+}
 
-PDO_Connect("" . _FILE_DB_SENTENCE_);
+PDO_Connect(_FILE_DB_SENTENCE_);
 
 $_id = false;
 if ((isset($_POST["id"]) && empty($_POST["id"])) || !isset($_POST["id"])) {
@@ -79,27 +86,27 @@ if ((isset($_POST["id"]) && empty($_POST["id"])) || !isset($_POST["id"])) {
 
 if ($_id == false) {
     # 没有id新建
-    if ($cooperation == 1) {
-        #有权限
+    if ($cooperation >=20) {
+        #有写入权限
         $query = "INSERT INTO sentence (id,
-                                            parent,
-                                            book,
-                                            paragraph,
-                                            begin,
-                                            end,
-                                            channal,
-                                            tag,
-                                            author,
-                                            editor,
-                                            text,
-                                            language,
-                                            ver,
-                                            status,
-                                            strlen,
-                                            modify_time,
-                                            receive_time,
-                                            create_time
-                                            )
+                                        parent,
+                                        book,
+                                        paragraph,
+                                        begin,
+                                        end,
+                                        channal,
+                                        tag,
+                                        author,
+                                        editor,
+                                        text,
+                                        language,
+                                        ver,
+                                        status,
+                                        strlen,
+                                        modify_time,
+                                        receive_time,
+                                        create_time
+                                        )
 										VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
         $stmt = $PDO->prepare($query);
         $newId = UUID::v4();
@@ -132,7 +139,8 @@ if ($_id == false) {
         } else {
             # 没错误
             # 更新historay
-            #没错误 更新历史记录
+			#没错误 更新历史记录
+			$respond['commit_type'] = 1;
             $respond['message'] = update_historay($newId, $_COOKIE["userid"], $_POST["text"], $_landmark);
             if ($respond['message'] !== "") {
                 $respond['status'] = 1;
@@ -141,15 +149,63 @@ if ($_id == false) {
             }
         }
     } else {
-        #TO DO没权限 插入建议数据
-        $respond['message'] = "没有权限";
-        $respond['status'] = 1;
+		#没写入权限 插入pr数据
+		$query = "INSERT INTO sent_pr (id,
+										book,
+										paragraph,
+										begin,
+										end,
+										channel,
+										tag,
+										author,
+										editor,
+										text,
+										language,
+										status,
+										strlen,
+										modify_time,
+										receive_time,
+										create_time
+										)
+										VALUES (NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
+		$stmt = $PDO->prepare($query);
+		# 初始状态 1 未处理
+		$stmt->execute(array(
+							$_POST["book"],
+							$_POST["para"],
+							$_POST["begin"],
+							$_POST["end"],
+							$_POST["channal"],
+							"",
+							"[]",
+							$_COOKIE["userid"],
+							$_POST["text"],
+							$text_lang,
+							1,
+							mb_strlen($_POST["text"], "UTF-8"),
+							mTime(),
+							mTime(),
+							mTime()
+							));
+		if (!$stmt || ($stmt && $stmt->errorCode() != 0)) {
+			/*  识别错误  */
+			$error = PDO_ErrorInfo();
+			$respond['message'] = $error[2];
+			$respond['status'] = 1;
+			echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+			exit;
+		} else {
+		# 没错误
+			$respond['message'] = "已经提交修改建议";
+			$respond['status'] = 0;
+			$respond['commit_type'] = 3;
+		}
     }
 } else {
     /* 修改现有数据 */
     #判断是否有修改权限
-    if ($cooperation == 1) {
-        #有权限
+    if ($cooperation >=20) {
+        #有写入权限
         $query = "UPDATE sentence SET text= ?  , strlen = ? , editor = ? , receive_time= ?  , modify_time= ?   where  id= ?  ";
         $stmt = PDO_Execute($query,
             array($_POST["text"],
@@ -167,7 +223,7 @@ if ($_id == false) {
             exit;
         } else {
             #没错误 更新历史记录
-
+			$respond['commit_type'] = 2;
             $respond['message'] = update_historay($_id, $_COOKIE["userid"], $_POST["text"], $_landmark);
             if ($respond['message'] !== "") {
                 $respond['status'] = 1;
@@ -176,9 +232,58 @@ if ($_id == false) {
             }
         }
     } else {
-        #TO DO没权限 插入建议数据
-        $respond['message'] = "没有权限";
-        $respond['status'] = 1;
+        #TO DO没权限 插入pr数据
+		#没写入权限 插入pr数据
+		$query = "INSERT INTO sent_pr (id,
+										book,
+										paragraph,
+										begin,
+										end,
+										channel,
+										tag,
+										author,
+										editor,
+										text,
+										language,
+										status,
+										strlen,
+										modify_time,
+										receive_time,
+										create_time
+										)
+										VALUES (NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
+		$stmt = $PDO->prepare($query);
+		# 初始状态 1 未处理
+		$stmt->execute(array(
+							$_POST["book"],
+							$_POST["para"],
+							$_POST["begin"],
+							$_POST["end"],
+							$_POST["channal"],
+							"",
+							"[]",
+							$_COOKIE["userid"],
+							$_POST["text"],
+							$text_lang,
+							1,
+							mb_strlen($_POST["text"], "UTF-8"),
+							mTime(),
+							mTime(),
+							mTime()
+							));
+		if (!$stmt || ($stmt && $stmt->errorCode() != 0)) {
+			/*  识别错误  */
+			$error = PDO_ErrorInfo();
+			$respond['message'] = $error[2];
+			$respond['status'] = 1;
+			echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+			exit;
+		} else {
+		# 没错误
+			$respond['commit_type'] = 3;
+			$respond['message'] = "已经提交修改建议";
+			$respond['status'] = 0;
+		}
     }
 }
 

+ 73 - 0
app/usent/sent_pr_merge.php

@@ -0,0 +1,73 @@
+<?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"]="没有写入权限";
+	}
+}
+
+echo json_encode($respond, JSON_UNESCAPED_UNICODE);
+
+?>

+ 44 - 0
app/widget/iframe_modal_win.css

@@ -0,0 +1,44 @@
+.modal_win_bg {
+	background-color: rgba(0, 0, 0, 0.8);
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	display: none;
+	z-index: 99;
+}
+.iframe_container {
+	display: none;
+	z-index: 100;
+	background-color: var(--bg-color);
+	border-radius: 20px;
+	width: 75%;
+	height: 80%;
+	margin: auto;
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+}
+.iframe_container iframe {
+	width: 100%;
+	height: 100%;
+	border: 0;
+}
+.model_win_container {
+	display: none;
+	z-index: 100;
+	background-color: var(--bg-color);
+	border-radius: 20px;
+	width: 75%;
+	height: 80%;
+	margin: auto;
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	overflow-y: scroll;
+}

+ 77 - 0
app/widget/iframe_modal_win.js

@@ -0,0 +1,77 @@
+/*
+container 容器id
+name=iframe name
+width
+height
+*/
+function iframe_win_init(param) {
+	let iframeWin = new Object();
+	iframeWin.container = param.container;
+	iframeWin.name = param.name;
+	iframeWin.show = function (url) {
+		$(".modal_win_bg").show();
+		$("#" + iframeWin.container).show();
+		window.open(url, this.name);
+	};
+	if (typeof param.onclose != "undefined") {
+		iframeWin.onclose = onclose;
+	} else {
+		iframeWin.onclose = function () {
+			return 1;
+		};
+	}
+	$("#" + iframeWin.container).addClass("iframe_container");
+	if (typeof param.width != "undefined") {
+		$("#" + iframeWin.container).css("width", param.width);
+	}
+	if (typeof param.height != "undefined") {
+		$("#" + iframeWin.container).css("height", param.height);
+	}
+	let iframe = $("#" + iframeWin.container).children("iframe");
+	if (iframe.length == 0) {
+		$("#" + iframeWin.container).append("<iframe name='" + param.name + "'></iframe>");
+	}
+	$(".modal_win_bg").click(function () {
+		$(".modal_win_bg").hide();
+		$(".iframe_container").hide();
+		this.onclose();
+	});
+	return iframeWin;
+}
+
+/*
+container 容器id
+name=iframe name
+width
+height
+*/
+function model_win_init(param) {
+	let modelWin = new Object();
+	modelWin.container = param.container;
+	modelWin.show = function (html) {
+		$(".modal_win_bg").show();
+		$("#" + modelWin.container).html(html);
+		$("#" + modelWin.container).show();
+	};
+	if (typeof param.onclose != "undefined") {
+		modelWin.onclose = onclose;
+	} else {
+		modelWin.onclose = function () {
+			return 1;
+		};
+	}
+	$("#" + modelWin.container).addClass("iframe_container");
+	if (typeof param.width != "undefined") {
+		$("#" + modelWin.container).css("width", param.width);
+	}
+	if (typeof param.height != "undefined") {
+		$("#" + modelWin.container).css("height", param.height);
+	}
+
+	$(".modal_win_bg").click(function () {
+		$(".modal_win_bg").hide();
+		$(".iframe_container").hide();
+		this.onclose();
+	});
+	return modelWin;
+}

BIN
font/taitham/tai-tham-kh-new-v3.ttf


Some files were not shown because too many files changed in this diff