From 9bba7c624d6f12b56f2d0040d02dd5c97e4b63e1 Mon Sep 17 00:00:00 2001 From: wangyidong Date: Tue, 11 Apr 2023 14:43:53 +0800 Subject: [PATCH] * code for task #90783. --- db/update18.3.sql | 1 + db/zentao.sql | 1 + module/doc/config.php | 9 ++-- module/doc/control.php | 12 ++++-- module/doc/js/edit.js | 9 ---- module/doc/lang/de.php | 1 + module/doc/lang/en.php | 1 + module/doc/lang/fr.php | 1 + module/doc/lang/zh-cn.php | 1 + module/doc/model.php | 59 ++++++++++++++++++++++---- module/doc/view/editothertype.html.php | 1 - module/doc/view/edittexttype.html.php | 15 ++++++- 12 files changed, 84 insertions(+), 27 deletions(-) diff --git a/db/update18.3.sql b/db/update18.3.sql index aadaf5e657..c80e86121a 100644 --- a/db/update18.3.sql +++ b/db/update18.3.sql @@ -773,3 +773,4 @@ CREATE TABLE IF NOT EXISTS `zt_docaction` ( KEY `doc` (`doc`), KEY `actor` (`actor`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +ALTER TABLE `zt_doc` ADD `editingDate` text NULL AFTER `editedDate`; diff --git a/db/zentao.sql b/db/zentao.sql index facafa7967..40af3c18f5 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -675,6 +675,7 @@ CREATE TABLE IF NOT EXISTS `zt_doc` ( `approvedDate` date NULL, `editedBy` varchar(30) NOT NULL DEFAULT '', `editedDate` datetime NULL, + `editingDate` text NULL, `mailto` text, `acl` varchar(10) NOT NULL DEFAULT 'open', `groups` varchar(255) NOT NULL, diff --git a/module/doc/config.php b/module/doc/config.php index 2a640cbce6..21a2ed42f0 100644 --- a/module/doc/config.php +++ b/module/doc/config.php @@ -12,10 +12,11 @@ $config->doc->editlib->requiredFields = 'name'; $config->doc->create->requiredFields = 'lib,title'; $config->doc->edit->requiredFields = 'title'; -$config->doc->customObjectLibs = 'files,customFiles'; -$config->doc->notArticleType = ''; -$config->doc->officeTypes = 'word,ppt,excel'; -$config->doc->textTypes = 'html,markdown,text'; +$config->doc->customObjectLibs = 'files,customFiles'; +$config->doc->notArticleType = ''; +$config->doc->officeTypes = 'word,ppt,excel'; +$config->doc->textTypes = 'html,markdown,text'; +$config->doc->saveDraftInterval = '60'; $config->doc->custom = new stdclass(); $config->doc->custom->objectLibs = $config->doc->customObjectLibs; diff --git a/module/doc/control.php b/module/doc/control.php index f82610933d..a400bbd989 100755 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -55,8 +55,15 @@ class doc extends control * @access public * @return void */ - public function mySpace($type = 'mine', $libID = 0, $moduleID = 0, $browseType = 'all', $param = 0, $orderBy = 'status,id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + public function mySpace($type = 'mine', $libID = 0, $moduleID = 0, $browseType = 'all', $param = 0, $orderBy = '', $recTotal = 0, $recPerPage = 20, $pageID = 1) { + $browseType = strtolower($browseType); + $type = strtolower($type); + + if(empty($orderBy) and $type == 'mine') $orderBy = 'status,editedDate_desc'; + if(empty($orderBy) and ($type == 'view' or $type == 'collect')) $orderBy = 'status,date_desc'; + if(empty($orderBy) and ($type == 'createdby')) $orderBy = 'status,addedDate_desc'; + /* Save session, load module. */ $uri = $this->app->getURI(true); $this->session->set('docList', $uri, 'doc'); @@ -70,8 +77,6 @@ class doc extends control list($libs, $libID, $object, $objectID, $objectDropdown) = $this->doc->setMenuByType('mine', 0, $libID); /* Build the search form. */ - $browseType = strtolower($browseType); - $type = strtolower($type); $queryID = $browseType == 'bysearch' ? (int)$param : 0; $params = "libID=$libID&moduleID=$moduleID&browseType=bySearch¶m=myQueryID&orderBy=$orderBy"; if($this->app->rawMethod == 'myspace') $params = "type=$type&" . $params; @@ -618,6 +623,7 @@ class doc extends control $this->view->from = $from; $this->view->files = $this->loadModel('file')->getByObject('doc', $docID); $this->view->objectID = $objectID; + $this->view->otherEditing = $this->doc->checkOtherEditing($docID); $this->display(); } diff --git a/module/doc/js/edit.js b/module/doc/js/edit.js index 83e3d51d72..6e91b9a86e 100644 --- a/module/doc/js/edit.js +++ b/module/doc/js/edit.js @@ -37,17 +37,8 @@ $(function() } }, 100) - $('#top-submit').click(function() - { - $(this).addClass('disabled'); - $('form').submit(); - }) - $('#subNavbar li[data-id="doc"]').addClass('active'); - /* Automatically save document contents. */ - setInterval("saveDraft()", 60 * 1000); - $(document).on("mouseup", 'span[data-name="fullscreen"]', function() { if(config.onlybody == 'no') diff --git a/module/doc/lang/de.php b/module/doc/lang/de.php index 4b509ad6d0..96b543a40d 100644 --- a/module/doc/lang/de.php +++ b/module/doc/lang/de.php @@ -287,6 +287,7 @@ $lang->doc->confirmDelete = "Möchten Sie dieses Dokument löschen?"; $lang->doc->confirmDeleteLib = "Möchten Sie diese Bibliothek löschen?"; $lang->doc->confirmDeleteBook = "Do you want to delete this book?"; $lang->doc->confirmDeleteChapter = "Do you want to delete this chapter?"; +$lang->doc->confirmOtherEditing = "This document is currently editing. Continuing to edit will overwrite the content edited by others. Do you want to continue?"; $lang->doc->errorEditSystemDoc = "System Dokumentenbibliothek darf nicht geändert werden."; $lang->doc->errorEmptyProduct = "Kein {$lang->productCommon}. Kann nicht erstellt werden."; $lang->doc->errorEmptyProject = "Kein {$lang->executionCommon}. Kann nicht erstellt werden."; diff --git a/module/doc/lang/en.php b/module/doc/lang/en.php index 9d2e64c92a..8f37a1dcf2 100644 --- a/module/doc/lang/en.php +++ b/module/doc/lang/en.php @@ -287,6 +287,7 @@ $lang->doc->confirmDelete = "Do you want to delete this document?"; $lang->doc->confirmDeleteLib = "Do you want to delete this document library?"; $lang->doc->confirmDeleteBook = "Do you want to delete this book?"; $lang->doc->confirmDeleteChapter = "Do you want to delete this chapter?"; +$lang->doc->confirmOtherEditing = "This document is currently editing. Continuing to edit will overwrite the content edited by others. Do you want to continue?"; $lang->doc->errorEditSystemDoc = "You don't have to change system document library."; $lang->doc->errorEmptyProduct = "No {$lang->productCommon}. It cannot be created."; $lang->doc->errorEmptyProject = "No {$lang->executionCommon}. It cannot be created."; diff --git a/module/doc/lang/fr.php b/module/doc/lang/fr.php index 004dfe78da..c6b8a3e9c5 100644 --- a/module/doc/lang/fr.php +++ b/module/doc/lang/fr.php @@ -287,6 +287,7 @@ $lang->doc->confirmDelete = "Voulez-vous supprimer ce document ?"; $lang->doc->confirmDeleteLib = "Voulez-vous supprimer cette Bibliothèque ?"; $lang->doc->confirmDeleteBook = "Do you want to delete this book?"; $lang->doc->confirmDeleteChapter = "Do you want to delete this chapter?"; +$lang->doc->confirmOtherEditing = "This document is currently editing. Continuing to edit will overwrite the content edited by others. Do you want to continue?"; $lang->doc->errorEditSystemDoc = "Vous n'avez pas besoin de changer de système de Bibliothèque."; $lang->doc->errorEmptyProduct = "Aucun {$lang->productCommon}. Il ne peut pas être créé."; $lang->doc->errorEmptyProject = "Aucun {$lang->executionCommon}. Il ne peut pas être créé."; diff --git a/module/doc/lang/zh-cn.php b/module/doc/lang/zh-cn.php index 3e9ec2fa10..5d6130f3a2 100644 --- a/module/doc/lang/zh-cn.php +++ b/module/doc/lang/zh-cn.php @@ -287,6 +287,7 @@ $lang->doc->confirmDelete = "您确定删除该文档吗?"; $lang->doc->confirmDeleteLib = "您确定删除该文档库吗?"; $lang->doc->confirmDeleteBook = "您确定删除该手册吗?"; $lang->doc->confirmDeleteChapter = "您确定删除该章节吗?"; +$lang->doc->confirmOtherEditing = "该文档正在编辑中,如果继续编辑将覆盖他人编辑内容,是否继续?"; $lang->doc->errorEditSystemDoc = "系统文档库无需修改。"; $lang->doc->errorEmptyProduct = "没有{$lang->productCommon},无法创建文档"; $lang->doc->errorEmptyProject = "没有{$lang->executionCommon},无法创建文档"; diff --git a/module/doc/model.php b/module/doc/model.php index 8980aef732..b763bbbeb5 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -923,14 +923,11 @@ class docModel extends model public function update($docID) { $oldDoc = $this->dao->select('*')->from(TABLE_DOC)->where('id')->eq((int)$docID)->fetch(); - if(!empty($_POST['editedDate']) and $oldDoc->editedDate != $this->post->editedDate) - { - dao::$errors[] = $this->lang->error->editedByOther; - return false; - } if(!isset($_POST['lib']) and strpos($_POST['module'], '_') !== false) list($_POST['lib'], $_POST['module']) = explode('_', $_POST['module']); - $doc = fixer::input('post')->setDefault('module', 0) + $account = $this->app->user->account; + $now = helper::now(); + $doc = fixer::input('post')->setDefault('module', 0) ->callFunc('title', 'trim') ->stripTags($this->config->doc->editor->edit['id'], $this->config->allowedTags) ->setDefault('users', '') @@ -938,8 +935,8 @@ class docModel extends model ->setDefault('product', 0) ->setDefault('execution', 0) ->setDefault('mailto', '') - ->add('editedBy', $this->app->user->account) - ->add('editedDate', helper::now()) + ->add('editedBy', $account) + ->add('editedDate', $now) ->cleanInt('project,product,execution,lib,module') ->join('groups', ',') ->join('users', ',') @@ -947,6 +944,10 @@ class docModel extends model ->remove('comment,files,labels,uid,contactListMenu') ->get(); + $editingDate = $oldDoc->editingDate ? json_decode($oldDoc->editingDate, true) : array(); + unset($editingDate[$account]); + $doc->editingDate = json_encode($editingDate); + if($doc->acl == 'open') $doc->users = $doc->groups = ''; if($doc->type == 'chapter' and $doc->parent) { @@ -1041,11 +1042,19 @@ class docModel extends model */ public function saveDraft($docID) { + $docID = (int)$docID; + $oldDoc = $this->dao->select('id,editingDate')->from(TABLE_DOC)->where('id')->eq($docID)->fetch(); + $account = $this->app->user->account; + $data = fixer::input('post')->stripTags($this->config->doc->editor->edit['id'], $this->config->allowedTags)->get(); $doc = new stdclass(); $doc->draft = $data->content; - $docType = $this->dao->select('type')->from(TABLE_DOCCONTENT)->where('doc')->eq((int)$docID)->orderBy('version_desc')->fetch(); + $doc->editingDate = $oldDoc->editingDate ? json_decode($oldDoc->editingDate, true) : array(); + $doc->editingDate[$account] = time(); + $doc->editingDate = json_encode($doc->editingDate); + + $docType = $this->dao->select('type')->from(TABLE_DOCCONTENT)->where('doc')->eq($docID)->orderBy('version_desc')->fetch(); if($docType == 'markdown') $doc->draft = $this->post->content; $this->dao->update(TABLE_DOC)->data($doc)->where('id')->eq($docID)->exec(); @@ -3309,4 +3318,36 @@ class docModel extends model } return $docs; } + + /** + * Check other editing. + * + * @param int $docID + * @access public + * @return bool + */ + public function checkOtherEditing($docID) + { + $now = time(); + $account = $this->app->user->account; + $docID = (int)$docID; + $doc = $this->dao->select('id,editingDate')->from(TABLE_DOC)->where('id')->eq($docID)->fetch(); + if(empty($doc)) return false; + + $editingDate = $doc->editingDate ? json_decode($doc->editingDate, true) : array(); + $otherEditing = false; + foreach($editingDate as $editingAccount => $timestamp) + { + if($editingAccount != $account and ($now - $timestamp) <= $this->config->doc->saveDraftInterval) + { + $otherEditing = true; + break; + } + } + + $editingDate[$account] = $now; + $this->dao->update(TABLE_DOC)->set('editingDate')->eq(json_encode($editingDate))->where('id')->eq($docID)->exec(); + + return $otherEditing; + } } diff --git a/module/doc/view/editothertype.html.php b/module/doc/view/editothertype.html.php index 983e8586d1..4e4731fd01 100644 --- a/module/doc/view/editothertype.html.php +++ b/module/doc/view/editothertype.html.php @@ -82,7 +82,6 @@ contentType); echo html::hidden('type', $doc->type); - echo html::hidden('editedDate', $doc->editedDate); echo html::hidden('status', $doc->status); echo html::hidden('parent', $doc->parent); echo html::submitButton(); diff --git a/module/doc/view/edittexttype.html.php b/module/doc/view/edittexttype.html.php index cc6e1f388a..5f1192c429 100644 --- a/module/doc/view/edittexttype.html.php +++ b/module/doc/view/edittexttype.html.php @@ -44,7 +44,6 @@
content), "style='width:100%;'");?>
contentType);?> - editedDate);?> status);?> @@ -129,6 +128,20 @@ + content != $doc->draft);?> doc->confirmUpdateContent);?> id);?>