From 312acdab51ce3b742d34f2d7e0c02a8aeb3ed047 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Fri, 1 Nov 2024 21:17:23 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Models/WebSocketDialog.php | 12 +++++++- app/Models/WebSocketDialogMsg.php | 46 ++++++++++++++++------------ app/Module/Base.php | 16 ++++++++++ app/Tasks/EmailNoticeTask.php | 2 +- app/Tasks/WebSocketDialogMsgTask.php | 2 +- composer.json | 1 + composer.lock | 20 ++++++------ resources/assets/js/functions/web.js | 13 +++++--- 8 files changed, 75 insertions(+), 37 deletions(-) diff --git a/app/Models/WebSocketDialog.php b/app/Models/WebSocketDialog.php index ec347339a..b67d5c98b 100644 --- a/app/Models/WebSocketDialog.php +++ b/app/Models/WebSocketDialog.php @@ -185,7 +185,7 @@ class WebSocketDialog extends AbstractModel * @param $data * @param int $userid 会员ID * @param bool $hasData 已存在的消息类型 - * @return array|mixed + * @return array */ public static function synthesizeData($data, $userid, $hasData = false) { @@ -250,6 +250,16 @@ class WebSocketDialog extends AbstractModel $data['last_msg'] = $data['last_msg'] ?? WebSocketDialogMsg::whereDialogId($data['id'])->orderByDesc('id')->first()?->toArray(); } + // 最后消息处理 + if ($data['last_msg']) { + foreach ($data['last_msg']['emoji'] as &$value) { + unset($value['userids']); + } + if ($data['last_msg']['type'] === 'text') { + $data['last_msg']['msg']['text'] = WebSocketDialogMsg::previewTextMsg($data['last_msg']['msg']); + } + } + // 对方信息 $data['pinyin'] = Base::cn2pinyin($data['name']); $data['quick_msgs'] = []; diff --git a/app/Models/WebSocketDialogMsg.php b/app/Models/WebSocketDialogMsg.php index d6c04fdef..444fe5930 100644 --- a/app/Models/WebSocketDialogMsg.php +++ b/app/Models/WebSocketDialogMsg.php @@ -541,29 +541,33 @@ class WebSocketDialogMsg extends AbstractModel /** * 预览消息 - * @param bool $preserveHtml 保留html格式 - * @param null|array $data + * @param WebSocketDialogMsg|array $data 消息数据 + * @param bool $preserveHtml 保留html格式 * @return string */ - public function previewMsg($preserveHtml = false, $data = null) + public static function previewMsg($data, $preserveHtml = false) { - if ($data === null) { + if ($data instanceof WebSocketDialogMsg) { $data = [ - 'type' => $this->type, - 'msg' => $this->msg, + 'type' => $data->type, + 'msg' => $data->msg, ]; } + if (!is_array($data)) { + return ''; + } + switch ($data['type']) { case 'text': - return $this->previewTextMsg($data['msg']['text'], $preserveHtml); + return self::previewTextMsg($data['msg'], $preserveHtml); case 'vote': $action = Doo::translate("投票"); - return "[{$action}] {$this->previewTextMsg($data['msg']['text'], $preserveHtml)}"; + return "[{$action}] " . self::previewTextMsg($data['msg'], $preserveHtml); case 'word-chain': $action = Doo::translate("接龙"); - return "[{$action}] {$this->previewTextMsg($data['msg']['text'], $preserveHtml)}"; + return "[{$action}] " . self::previewTextMsg($data['msg'], $preserveHtml); case 'record': $action = Doo::translate("语音"); @@ -574,25 +578,25 @@ class WebSocketDialogMsg extends AbstractModel return "[{$action}] ${$data['msg']['name']}"; case 'file': - return $this->previewFileMsg($data['msg']); + return self::previewFileMsg($data['msg']); case 'tag': $action = Doo::translate($data['msg']['action'] === 'remove' ? '取消标注' : '标注'); - return "[{$action}] {$this->previewMsg(false, $data['msg']['data'])}"; + return "[{$action}] " . self::previewMsg($data['msg']['data']); case 'top': $action = Doo::translate($data['msg']['action'] === 'remove' ? '取消置顶' : '置顶'); - return "[{$action}] {$this->previewMsg(false, $data['msg']['data'])}"; + return "[{$action}] " . self::previewMsg($data['msg']['data']); case 'todo': $action = Doo::translate($data['msg']['action'] === 'remove' ? '取消待办' : ($data['msg']['action'] === 'done' ? '完成' : '设待办')); - return "[{$action}] {$this->previewMsg(false, $data['msg']['data'])}"; + return "[{$action}] " . self::previewMsg($data['msg']['data']); case 'notice': return Doo::translate($data['msg']['notice']); case 'template': - return $this->previewTemplateMsg($data['msg']); + return self::previewTemplateMsg($data['msg']); default: $action = Doo::translate("未知的消息"); @@ -605,7 +609,7 @@ class WebSocketDialogMsg extends AbstractModel * @param $msg * @return string */ - private function previewFileMsg($msg) + private static function previewFileMsg($msg) { if ($msg['type'] == 'img') { $action = Doo::translate("图片"); @@ -623,7 +627,7 @@ class WebSocketDialogMsg extends AbstractModel * @param $msg * @return string */ - private function previewTemplateMsg($msg) + private static function previewTemplateMsg($msg) { if (!empty($msg['title_raw'])) { return $msg['title_raw']; @@ -689,20 +693,24 @@ class WebSocketDialogMsg extends AbstractModel { $msg = $this->msg; if ($this->type === 'text') { - $msg['text'] = $this->previewTextMsg($msg['text']); + $msg['text'] = self::previewTextMsg($msg); } return $msg; } /** * 返回文本预览消息 - * @param $text + * @param array $msgData * @param bool $preserveHtml 保留html格式 * @return string|string[]|null */ - private function previewTextMsg($text, $preserveHtml = false) + public static function previewTextMsg($msgData, $preserveHtml = false) { + $text = $msgData['text'] ?? ''; if (!$text) return ''; + if ($msgData['type'] === 'md') { + $text = Base::markdown2html($text); + } $text = preg_replace("/]*?alt=\"(\S+)\"[^>]*?>/", "[$1]", $text); $text = preg_replace("/]*?>/", "[动画表情]", $text); $text = preg_replace("/]*?>/", "[图片]", $text); diff --git a/app/Module/Base.php b/app/Module/Base.php index ea4990c75..4ca24d9f3 100755 --- a/app/Module/Base.php +++ b/app/Module/Base.php @@ -7,6 +7,8 @@ use App\Models\Setting; use App\Models\Tmp; use Cache; use Carbon\Carbon; +use League\CommonMark\CommonMarkConverter; +use League\CommonMark\Exception\CommonMarkException; use Overtrue\Pinyin\Pinyin; use Redirect; use Request; @@ -3102,4 +3104,18 @@ class Base return $newArray; } + /** + * MD(markdown) 转 html + * @param $markdown + * @return \League\CommonMark\Output\RenderedContentInterface|mixed + */ + public static function markdown2html($markdown) + { + $converter = new CommonMarkConverter(); + try { + return $converter->convert($markdown); + } catch (CommonMarkException $e) { + return $markdown; + } + } } diff --git a/app/Tasks/EmailNoticeTask.php b/app/Tasks/EmailNoticeTask.php index 981c2fb95..d559b839d 100644 --- a/app/Tasks/EmailNoticeTask.php +++ b/app/Tasks/EmailNoticeTask.php @@ -114,7 +114,7 @@ class EmailNoticeTask extends AbstractTask foreach ($items as $item) { $item->cancelAppend(); $item->userInfo = User::userid2basic($item->userid); - $item->preview = $item->previewMsg(true); + $item->preview = WebSocketDialogMsg::previewMsg($item, true); $item->preview = str_replace('

', '

', $item->preview); if (empty($dialogId)) { $dialogId = $item->dialog_id; diff --git a/app/Tasks/WebSocketDialogMsgTask.php b/app/Tasks/WebSocketDialogMsgTask.php index 962a8959e..f8f118ada 100644 --- a/app/Tasks/WebSocketDialogMsgTask.php +++ b/app/Tasks/WebSocketDialogMsgTask.php @@ -194,7 +194,7 @@ class WebSocketDialogMsgTask extends AbstractTask } $this->endArray[] = new PushUmengMsg($umengUserid, [ 'title' => $umengTitle, - 'body' => $msg->previewMsg(), + 'body' => WebSocketDialogMsg::previewMsg($msg), 'description' => "MID:{$msg->id}", 'seconds' => 3600, 'badge' => 1, diff --git a/composer.json b/composer.json index e310deb21..fbb07725d 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "laravel/framework": "^v8.83.27", "laravel/tinker": "^v2.6.1", "lasserafn/php-initial-avatar-generator": "^4.2", + "league/commonmark": "^2.5", "maatwebsite/excel": "^3.1.31", "madnest/madzipper": "^v1.1.0", "mews/captcha": "^3.2.6", diff --git a/composer.lock b/composer.lock index 9d3a7e7e3..9c96ba589 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "61663f2d5fbd196fc797c40ed46a9b2e", + "content-hash": "827e08585b58695c5bee24b1f30fd08a", "packages": [ { "name": "asm89/stack-cors", @@ -2187,16 +2187,16 @@ }, { "name": "league/commonmark", - "version": "2.4.2", + "version": "2.5.3", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf" + "reference": "b650144166dfa7703e62a22e493b853b58d874b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/91c24291965bd6d7c46c46a12ba7492f83b1cadf", - "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/b650144166dfa7703e62a22e493b853b58d874b0", + "reference": "b650144166dfa7703e62a22e493b853b58d874b0", "shasum": "" }, "require": { @@ -2209,8 +2209,8 @@ }, "require-dev": { "cebe/markdown": "^1.0", - "commonmark/cmark": "0.30.3", - "commonmark/commonmark.js": "0.30.0", + "commonmark/cmark": "0.31.1", + "commonmark/commonmark.js": "0.31.1", "composer/package-versions-deprecated": "^1.8", "embed/embed": "^4.4", "erusev/parsedown": "^1.0", @@ -2232,7 +2232,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "2.6-dev" } }, "autoload": { @@ -2289,7 +2289,7 @@ "type": "tidelift" } ], - "time": "2024-02-02T11:59:32+00:00" + "time": "2024-08-16T11:46:16+00:00" }, { "name": "league/config", @@ -10812,5 +10812,5 @@ "ext-zip": "*" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/resources/assets/js/functions/web.js b/resources/assets/js/functions/web.js index 3c6f3b6e5..523f0a8e4 100755 --- a/resources/assets/js/functions/web.js +++ b/resources/assets/js/functions/web.js @@ -236,14 +236,17 @@ import {MarkdownPreview} from "../store/markdown"; /** * 返回文本信息预览格式 - * @param text + * @param msgData * @param imgClassName * @returns {*} */ - getMsgTextPreview(text, imgClassName = null) { + getMsgTextPreview({type, text}, imgClassName = null) { if (!text) { return ''; } + if (type === 'md') { + text = MarkdownPreview(text); + } // text = text.replace(/]*?alt="(\S+)"[^>]*?>/g, "[$1]") text = text.replace(/]*?>/g, `[${$A.L('动画表情')}]`) @@ -398,11 +401,11 @@ import {MarkdownPreview} from "../store/markdown"; } switch (data.type) { case 'text': - return $A.getMsgTextPreview(data.msg.type === 'md' ? MarkdownPreview(data.msg.text) : data.msg.text, imgClassName) + return $A.getMsgTextPreview(data.msg, imgClassName) case 'vote': - return `[${$A.L('投票')}]` + $A.getMsgTextPreview(data.msg.text, imgClassName) + return `[${$A.L('投票')}]` + $A.getMsgTextPreview(data.msg, imgClassName) case 'word-chain': - return `[${$A.L('接龙')}]` + $A.getMsgTextPreview(data.msg.text, imgClassName) + return `[${$A.L('接龙')}]` + $A.getMsgTextPreview(data.msg, imgClassName) case 'record': return `[${$A.L('语音')}]` case 'meeting':