diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php
index 2b85a19d3..4c17846da 100755
--- a/app/Http/Controllers/Api/ProjectController.php
+++ b/app/Http/Controllers/Api/ProjectController.php
@@ -1945,7 +1945,7 @@ class ProjectController extends AbstractController
$task->pushMsgVisibleAdd($data);
}
if ($param['visibility_appointor']) {
- $newVisibleUserIds = $param['visibility_appointor'] ?? [];
+ $newVisibleUserIds = is_array($param['visibility_appointor']) ? $param['visibility_appointor'] : [];
$deleteUserIds = array_diff($visible, $newVisibleUserIds, $subUserids);
$addUserIds = array_diff($newVisibleUserIds, $visible);
$task->pushMsgVisibleUpdate($data, $deleteUserIds, $addUserIds);
diff --git a/app/Models/ProjectTask.php b/app/Models/ProjectTask.php
index 5dcb487a2..4c0c29306 100644
--- a/app/Models/ProjectTask.php
+++ b/app/Models/ProjectTask.php
@@ -352,6 +352,25 @@ class ProjectTask extends AbstractModel
return $query;
}
+ /**
+ * 生成描述
+ * @param $content
+ * @return string
+ */
+ public static function generateDesc($content)
+ {
+ $content = preg_replace_callback('/
(.+?)<\/ul>/is', function ($matches) {
+ return preg_replace_callback('/- ]*)>(.+?)<\/li>/is', function ($m) {
+ if (str_contains($m[1], 'tox-checklist--checked')) {
+ return "
- [√]{$m[2]}
";
+ } else {
+ return "- [ ]{$m[2]}
";
+ }
+ }, $matches[0]);
+ }, $content);
+ return Base::cutStr(strip_tags($content), 100, 0, "...");
+ }
+
/**
* 添加任务
* @param $data
@@ -407,7 +426,7 @@ class ProjectTask extends AbstractModel
'visibility' => $visibility ?: 1
]);
if ($content) {
- $task->desc = Base::getHtml($content, 100);
+ $task->desc = self::generateDesc($content);
}
// 标题
if (empty($name)) {
@@ -901,7 +920,7 @@ class ProjectTask extends AbstractModel
'url' => ProjectTaskContent::saveContent($this->id, $data['content'])
],
])->save();
- $this->desc = Base::getHtml($data['content'], 100);
+ $this->desc = self::generateDesc($data['content']);
$this->addLog("修改{任务}详细描述");
$updateMarking['is_update_content'] = true;
}
diff --git a/app/Module/Base.php b/app/Module/Base.php
index 8bb3520e1..03b44af28 100755
--- a/app/Module/Base.php
+++ b/app/Module/Base.php
@@ -359,17 +359,6 @@ class Base
}
}
- /**
- * 去除html
- * @param $text
- * @param int $length
- * @return string
- */
- public static function getHtml($text, $length = 250)
- {
- return Base::cutStr(strip_tags($text), $length, 0, "...");
- }
-
/**
*
* 截取字符串
diff --git a/resources/assets/js/components/TEditor.vue b/resources/assets/js/components/TEditor.vue
index 288fd9515..5debbd32c 100755
--- a/resources/assets/js/components/TEditor.vue
+++ b/resources/assets/js/components/TEditor.vue
@@ -56,607 +56,607 @@
diff --git a/resources/assets/js/components/TEditorTask.vue b/resources/assets/js/components/TEditorTask.vue
index 6a89ebc82..aef094fac 100755
--- a/resources/assets/js/components/TEditorTask.vue
+++ b/resources/assets/js/components/TEditorTask.vue
@@ -69,7 +69,7 @@ export default {
content: this.value,
plugins: [
- 'advlist autolink lists link image charmap print preview hr anchor pagebreak',
+ 'advlist autolink lists checklist link image charmap print preview hr anchor pagebreak',
'searchreplace visualblocks visualchars code',
'insertdatetime media nonbreaking save table directionality',
'emoticons paste codesample',
@@ -81,16 +81,17 @@ export default {
autoresize_bottom_margin: 2,
min_height: 200,
max_height: 380,
- contextmenu: 'bold italic underline forecolor backcolor | link | codesample | uploadImages imagePreview | preview screenload',
- valid_elements: 'a[href|title|target=_blank],em,strong/b,div[align],span[style],a,br,p,img[src|alt|witdh|height],pre[class],code',
+ contextmenu: 'checklist | bold italic underline forecolor backcolor | link | uploadImages imagePreview | screenload',
+ valid_elements: 'a[href|title|target=_blank],em,strong/b,div[align],span[style],a,br,p,img[src|alt|witdh|height],pre[class],code,ol[class],ul[class],li[class]',
extended_valid_elements: 'a[href|title|target=_blank]',
toolbar: false
},
optionFull: {
menubar: 'file edit view',
- valid_elements: 'a[href|title|target=_blank],em,strong/b,div[align],span[style],a,br,p,img[src|alt|witdh|height],pre[class],code',
+ removed_menuitems: 'preview,print',
+ valid_elements: 'a[href|title|target=_blank],em,strong/b,div[align],span[style],a,br,p,img[src|alt|witdh|height],pre[class],code,ol[class],ul[class],li[class]',
extended_valid_elements: 'a[href|title|target=_blank]',
- toolbar: 'uploadImages | bold italic underline | forecolor backcolor'
+ toolbar: 'uploadImages | checklist | bold italic underline | forecolor backcolor'
},
operateStyles: {},
diff --git a/resources/assets/sass/components/t-editor.scss b/resources/assets/sass/components/t-editor.scss
index 2462dc6e7..a65da4f0d 100755
--- a/resources/assets/sass/components/t-editor.scss
+++ b/resources/assets/sass/components/t-editor.scss
@@ -22,6 +22,10 @@
opacity: 0;
}
+ .tox-checklist {
+ padding-inline-start: 26px;
+ }
+
.tox-tinymce {
box-shadow: none;
box-sizing: border-box;
diff --git a/resources/assets/statics/public/js/tinymce/plugins/checklist/index.js b/resources/assets/statics/public/js/tinymce/plugins/checklist/index.js
new file mode 100644
index 000000000..bee74091f
--- /dev/null
+++ b/resources/assets/statics/public/js/tinymce/plugins/checklist/index.js
@@ -0,0 +1,7 @@
+// Exports the "checklist" plugin for usage with module loaders
+// Usage:
+// CommonJS:
+// require('tinymce/plugins/checklist')
+// ES2015:
+// import 'tinymce/plugins/checklist'
+require('./plugin.js');
diff --git a/resources/assets/statics/public/js/tinymce/plugins/checklist/plugin.js b/resources/assets/statics/public/js/tinymce/plugins/checklist/plugin.js
new file mode 100644
index 000000000..981e28abf
--- /dev/null
+++ b/resources/assets/statics/public/js/tinymce/plugins/checklist/plugin.js
@@ -0,0 +1,8 @@
+/*!
+ * Tiny Checklist plugin
+ *
+ * Copyright 2010-2021 Tiny Technologies, Inc. All rights reserved.
+ *
+ * Version: 1.1.0-25
+ */
+!function(o){"use strict";function O(n){return function(){return n}}function n(){return c}var e,i=O(!1),u=O(!0),c=(e={fold:function(n,e){return n()},is:i,isSome:i,isNone:u,getOr:s,getOrThunk:t,getOrDie:function(n){throw new Error(n||"error: getOrDie called on none.")},getOrNull:O(null),getOrUndefined:O(void 0),or:s,orThunk:t,map:n,each:function(){},bind:n,exists:i,forall:u,filter:n,equals:r,equals_:r,toArray:function(){return[]},toString:O("none()")},Object.freeze&&Object.freeze(e),e);function r(n){return n.isNone()}function t(n){return n()}function s(n){return n}function a(n){return parseInt(n,10)}function f(n,e){var r=n-e;return 0==r?0:0