From 27441eb82efe0d336f8e38f5120195f9fe5f2506 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Fri, 1 Jul 2022 11:22:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=96=B0=E5=A2=9E=E9=93=BE?= =?UTF-8?q?=E6=8E=A5=E7=B1=BB=E5=9E=8B=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/DialogController.php | 5 +- app/Models/WebSocketDialog.php | 10 ++- app/Models/WebSocketDialogMsg.php | 20 ++++-- ...103147_add_web_socket_dialog_msgs_link.php | 47 ++++++++++++ .../pages/manage/components/DialogWrapper.vue | 71 +++++++++++++------ .../sass/pages/components/dialog-wrapper.scss | 15 ++-- 6 files changed, 134 insertions(+), 34 deletions(-) create mode 100644 database/migrations/2022_07_01_103147_add_web_socket_dialog_msgs_link.php diff --git a/app/Http/Controllers/Api/DialogController.php b/app/Http/Controllers/Api/DialogController.php index 3865a317a..b1ef213d0 100755 --- a/app/Http/Controllers/Api/DialogController.php +++ b/app/Http/Controllers/Api/DialogController.php @@ -286,6 +286,7 @@ class DialogController extends AbstractController * - position_id、prev_id、next_id 只有一个有效,优先循序为:position_id > prev_id > next_id * @apiParam {String} [mtype] 消息类型 * - tag: 标记 + * - link: 链接 * - text: 文本 * - image: 图片 * - file: 文件 @@ -327,6 +328,8 @@ class DialogController extends AbstractController // if ($mtype === 'tag') { $builder->where('tag', '>', 0); + } elseif ($mtype === 'link') { + $builder->whereLink(1); } elseif (in_array($mtype, ['text', 'image', 'file', 'record', 'meeting'])) { $builder->whereMtype($mtype); } @@ -382,7 +385,7 @@ class DialogController extends AbstractController } // if ($reDialog) { - $data['dialog'] = $dialog->formatData($user->userid); + $data['dialog'] = $dialog->formatData($user->userid, true); } return Base::retSuccess('success', $data); } diff --git a/app/Models/WebSocketDialog.php b/app/Models/WebSocketDialog.php index 76fc9c32f..d2e95806f 100644 --- a/app/Models/WebSocketDialog.php +++ b/app/Models/WebSocketDialog.php @@ -54,9 +54,10 @@ class WebSocketDialog extends AbstractModel /** * 格式化对话 * @param int $userid 会员ID + * @param bool $hasData * @return $this */ - public function formatData($userid) + public function formatData($userid, $hasData = false) { if (isset($this->search_msg_id)) { // 最后消息 (搜索预览消息) @@ -118,6 +119,13 @@ class WebSocketDialog extends AbstractModel } break; } + if ($hasData === true) { + $msgBuilder = WebSocketDialogMsg::whereDialogId($this->id); + $this->has_tag = $msgBuilder->clone()->where('tag', '>', 0)->exists(); + $this->has_image = $msgBuilder->clone()->whereMtype('image')->exists(); + $this->has_file = $msgBuilder->clone()->whereMtype('file')->exists(); + $this->has_link = $msgBuilder->clone()->whereLink(1)->exists(); + } return $this; } diff --git a/app/Models/WebSocketDialogMsg.php b/app/Models/WebSocketDialogMsg.php index 594addf2f..7de4b8a9b 100644 --- a/app/Models/WebSocketDialogMsg.php +++ b/app/Models/WebSocketDialogMsg.php @@ -25,6 +25,7 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @property int|null $read 已阅数量 * @property int|null $send 发送数量 * @property int|null $tag 标注会员ID + * @property int|null $link 是否存在链接 * @property int|null $reply_num 有多少条回复 * @property int|null $reply_id 回复ID * @property \Illuminate\Support\Carbon|null $created_at @@ -44,6 +45,7 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereEmoji($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereId($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereKey($value) + * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereLink($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereMsg($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereMtype($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereRead($value) @@ -521,12 +523,19 @@ class WebSocketDialogMsg extends AbstractModel */ public static function sendMsg($dialog_id, $reply_id, $type, $msg, $sender = 0) { + $link = 0; $mtype = $type; - if ($type === 'text' && str_contains($msg['text'], ' $sender ?: User::userid(), 'type' => $type, 'mtype' => $mtype, + 'link' => $link, 'msg' => $msg, 'read' => 0, ]); diff --git a/database/migrations/2022_07_01_103147_add_web_socket_dialog_msgs_link.php b/database/migrations/2022_07_01_103147_add_web_socket_dialog_msgs_link.php new file mode 100644 index 000000000..ef46e9d24 --- /dev/null +++ b/database/migrations/2022_07_01_103147_add_web_socket_dialog_msgs_link.php @@ -0,0 +1,47 @@ +boolean('link')->default(0)->after('tag')->nullable()->comment('是否存在链接'); + } + }); + if ($isAdd) { + DB::table('web_socket_dialog_msgs')->where('type', 'text')->where('msg', 'LIKE', '%update([ + 'link' => 1 + ]); + DB::table('web_socket_dialog_msgs')->where('type', 'text')->where('msg', 'LIKE', '%http:%')->update([ + 'link' => 1 + ]); + DB::table('web_socket_dialog_msgs')->where('type', 'text')->where('msg', 'LIKE', '%https:%')->update([ + 'link' => 1 + ]); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('web_socket_dialog_msgs', function (Blueprint $table) { + $table->dropColumn("link"); + }); + } +} diff --git a/resources/assets/js/pages/manage/components/DialogWrapper.vue b/resources/assets/js/pages/manage/components/DialogWrapper.vue index faf44e221..7cef0cf33 100644 --- a/resources/assets/js/pages/manage/components/DialogWrapper.vue +++ b/resources/assets/js/pages/manage/components/DialogWrapper.vue @@ -64,16 +64,18 @@ - + + + @@ -81,6 +83,7 @@ this.msgFilter(item)).sort((a, b) => { - return a.id - b.id; - }); + return this.dialogMsgs.filter(item => item.dialog_id == this.dialogId); }, tempMsgList() { if (!this.isReady) { return []; } - return this.tempMsgs.filter(item => this.msgFilter(item)); + return this.tempMsgs.filter(item => item.dialog_id == this.dialogId); }, allMsgList() { - const {dialogMsgList, tempMsgList} = this; + const dialogMsgList = this.dialogMsgList.filter(item => this.msgFilter(item)).sort((a, b) => { + return a.id - b.id; + }) + const tempMsgList = this.tempMsgList.filter(item => this.msgFilter(item)) if (tempMsgList.length > 0) { const array = []; array.push(...dialogMsgList); @@ -477,6 +474,25 @@ export default { return '发送文件' }, + msgTags() { + const array = [ + {icon: '', type: '', label: '消息'}, + ]; + if (this.dialogData.has_tag) { + array.push({icon: '', type: 'tag', label: '标注'}) + } + if (this.dialogData.has_image) { + array.push({icon: '', type: 'image', label: '图片'}) + } + if (this.dialogData.has_file) { + array.push({icon: '', type: 'file', label: '文件'}) + } + if (this.dialogData.has_link) { + array.push({icon: '', type: 'link', label: '链接'}) + } + return array + }, + wrapperClass() { if (['ready', 'ing'].includes(this.recordState)) { return ['record-ready'] @@ -484,6 +500,10 @@ export default { return null }, + scrollerClass() { + return !this.$slots.head && this.msgTags.length > 1 && this.windowScrollY === 0 ? 'default-header' : null + }, + pasteWrapperClass() { if (this.pasteItem.find(({type}) => type !== 'image')) { return ['multiple']; @@ -567,6 +587,7 @@ export default { msgType(type) { if (!type) return + this.onToBottom() this.$store.dispatch("getDialogMsgs", { dialog_id: this.dialogId, msg_id: this.msgId, @@ -780,6 +801,10 @@ export default { if (!item.tag) { return false } + } else if (this.msgType === 'link') { + if (!item.link) { + return false + } } else if (this.msgType !== item.mtype) { return false } @@ -789,7 +814,7 @@ export default { return false } } - return item.dialog_id == this.dialogId; + return true }, onSearchMsgId() { diff --git a/resources/assets/sass/pages/components/dialog-wrapper.scss b/resources/assets/sass/pages/components/dialog-wrapper.scss index ec6ee8e29..5f4b261a4 100644 --- a/resources/assets/sass/pages/components/dialog-wrapper.scss +++ b/resources/assets/sass/pages/components/dialog-wrapper.scss @@ -32,7 +32,7 @@ } .dialog-scroller { - padding: 16px 16px 0; + padding-right: 16px; } } @@ -223,7 +223,7 @@ list-style: none; display: flex; align-items: center; - margin: 0 8px; + margin: 0 7px; padding: 3px 8px; background-color: #c0c4cc; color: #fff; @@ -232,7 +232,6 @@ cursor: pointer; box-shadow: 0 1px 6px rgba(255, 255, 255, 0.2); - .taskfont { font-size: 13px; padding-right: 6px; @@ -254,7 +253,11 @@ .dialog-scroller { flex: 1; position: relative; - padding: 48px 32px 0; + padding: 16px 32px 0; + + &.default-header { + padding-top: 48px; + } .dialog-shake { animation: ani-dialog-shake 600ms ease-in-out; @@ -1276,6 +1279,10 @@ } .nav-tags { top: 60px; + + > li { + margin: 0 5px; + } } } .dialog-scroller {