消息新增链接类型筛选

This commit is contained in:
kuaifan 2022-07-01 11:22:58 +08:00
parent 49f8e23aae
commit 27441eb82e
6 changed files with 134 additions and 34 deletions

View File

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

View File

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

View File

@ -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'], '<img ')) {
$mtype = 'image';
}
if ($type === 'file' && in_array($msg['ext'], ['jpg', 'jpeg', 'png', 'gif'])) {
$mtype = 'image';
if ($type === 'text') {
if (str_contains($msg['text'], '<a ') || preg_match("/https*:\/\//", $msg['text'])) {
$link = 1;
}
if (str_contains($msg['text'], '<img ')) {
$mtype = 'image';
}
} elseif ($type === 'file') {
if (in_array($msg['ext'], ['jpg', 'jpeg', 'png', 'gif'])) {
$mtype = 'image';
}
}
//
$dialogMsg = self::createInstance([
@ -535,6 +544,7 @@ class WebSocketDialogMsg extends AbstractModel
'userid' => $sender ?: User::userid(),
'type' => $type,
'mtype' => $mtype,
'link' => $link,
'msg' => $msg,
'read' => 0,
]);

View File

@ -0,0 +1,47 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddWebSocketDialogMsgsLink extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$isAdd = false;
Schema::table('web_socket_dialog_msgs', function (Blueprint $table) use (&$isAdd) {
if (!Schema::hasColumn('web_socket_dialog_msgs', 'link')) {
$isAdd = true;
$table->boolean('link')->default(0)->after('tag')->nullable()->comment('是否存在链接');
}
});
if ($isAdd) {
DB::table('web_socket_dialog_msgs')->where('type', 'text')->where('msg', 'LIKE', '%<a %')->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");
});
}
}

View File

@ -64,16 +64,18 @@
<i class="taskfont dialog-create" @click="openCreateGroup">&#xe646;</i>
</ETooltip>
</div>
<ul class="nav-tags">
<li
v-for="item in msgTags"
:key="item.type"
:class="{active: msgType === item.type}"
@click="msgType=item.type">
<i class="taskfont" v-html="item.icon"></i>
<span>{{$L(item.label)}}</span>
</li>
</ul>
<transition name="fade">
<ul v-if="dialogMsgList.length > 10 && msgTags.length > 1 && windowScrollY === 0" class="nav-tags">
<li
v-for="item in msgTags"
:key="item.type"
:class="{active: msgType === item.type}"
@click="msgType=item.type">
<i class="taskfont" v-html="item.icon"></i>
<span>{{$L(item.label)}}</span>
</li>
</ul>
</transition>
</slot>
</div>
@ -81,6 +83,7 @@
<VirtualList
ref="scroller"
class="dialog-scroller scrollbar-overlay"
:class="scrollerClass"
:data-key="'id'"
:data-sources="allMsgs"
:data-component="msgItem"
@ -340,14 +343,7 @@ export default {
msgItem: DialogItem,
msgText: '',
msgNew: 0,
msgType: '',
msgTags: [
{icon: '&#xe6eb;', type: '', label: '消息'},
{icon: '&#xe61e;', type: 'tag', label: '标注'},
{icon: '&#xe7bc;', type: 'image', label: '图片'},
{icon: '&#xe7c0;', type: 'file', label: '文件'},
],
allMsgs: [],
tempMsgs: [],
@ -427,20 +423,21 @@ export default {
if (!this.isReady) {
return [];
}
return this.dialogMsgs.filter(item => 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: '&#xe6eb;', type: '', label: '消息'},
];
if (this.dialogData.has_tag) {
array.push({icon: '&#xe61e;', type: 'tag', label: '标注'})
}
if (this.dialogData.has_image) {
array.push({icon: '&#xe7bc;', type: 'image', label: '图片'})
}
if (this.dialogData.has_file) {
array.push({icon: '&#xe7c0;', type: 'file', label: '文件'})
}
if (this.dialogData.has_link) {
array.push({icon: '&#xe786;', 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() {

View File

@ -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 {