feat: 语音消息未阅读红点提示

This commit is contained in:
kuaifan 2024-05-01 11:47:02 +08:00
parent e325698899
commit 6f38c4efdd
6 changed files with 136 additions and 3 deletions

View File

@ -503,6 +503,7 @@ class DialogController extends AbstractController
$builder = WebSocketDialogMsg::select([ $builder = WebSocketDialogMsg::select([
'web_socket_dialog_msgs.*', 'web_socket_dialog_msgs.*',
'read.mention', 'read.mention',
'read.dot',
'read.read_at', 'read.read_at',
])->leftJoin('web_socket_dialog_msg_reads as read', function ($leftJoin) use ($user) { ])->leftJoin('web_socket_dialog_msg_reads as read', function ($leftJoin) use ($user) {
$leftJoin $leftJoin
@ -620,6 +621,7 @@ class DialogController extends AbstractController
$builder = WebSocketDialogMsg::select([ $builder = WebSocketDialogMsg::select([
'web_socket_dialog_msgs.*', 'web_socket_dialog_msgs.*',
'read.mention', 'read.mention',
'read.dot',
'read.read_at', 'read.read_at',
])->leftJoin('web_socket_dialog_msg_reads as read', function ($leftJoin) use ($user) { ])->leftJoin('web_socket_dialog_msg_reads as read', function ($leftJoin) use ($user) {
$leftJoin $leftJoin
@ -718,6 +720,39 @@ class DialogController extends AbstractController
return Base::retSuccess('success', $msg); return Base::retSuccess('success', $msg);
} }
/**
* @api {get} api/dialog/msg/dot 16. 聊天消息去除点
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName msg__dot
*
* @apiParam {Number} id 消息ID
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function msg__dot()
{
$user = User::auth();
//
$id = intval(Request::input('id'));
//
$msg = WebSocketDialogMsg::find($id);
if (empty($msg)) {
return Base::retError("消息不存在或已被删除");
}
//
WebSocketDialogMsgRead::whereMsgId($id)->whereUserid($user->userid)->change(['dot' => 0]);
//
return Base::retSuccess('success', [
'id' => $msg->id,
'dot' => 0,
]);
}
/** /**
* @api {get} api/dialog/msg/read 16. 已读聊天消息 * @api {get} api/dialog/msg/read 16. 已读聊天消息
* *

View File

@ -112,24 +112,28 @@ class WebSocketDialogMsgTask extends AbstractTask
if ($userid == $msg->userid) { if ($userid == $msg->userid) {
$array[$userid] = [ $array[$userid] = [
'userid' => $userid, 'userid' => $userid,
'mention' => false, 'mention' => 0,
'silence' => $silence, 'silence' => $silence,
'dot' => 0,
'updated' => $updated, 'updated' => $updated,
]; ];
} else { } else {
$mention = array_intersect([0, $userid], $mentions) ? 1 : 0; $mention = array_intersect([0, $userid], $mentions) ? 1 : 0;
$silence = $mention ? false : $silence; $silence = $mention ? false : $silence;
$dot = $msg->type === 'record' ? 1 : 0;
WebSocketDialogMsgRead::createInstance([ WebSocketDialogMsgRead::createInstance([
'dialog_id' => $msg->dialog_id, 'dialog_id' => $msg->dialog_id,
'msg_id' => $msg->id, 'msg_id' => $msg->id,
'userid' => $userid, 'userid' => $userid,
'mention' => $mention, 'mention' => $mention,
'silence' => $silence, 'silence' => $silence,
'dot' => $dot,
])->saveOrIgnore(); ])->saveOrIgnore();
$array[$userid] = [ $array[$userid] = [
'userid' => $userid, 'userid' => $userid,
'mention' => $mention, 'mention' => $mention,
'silence' => $silence, 'silence' => $silence,
'dot' => $dot,
'updated' => $updated, 'updated' => $updated,
]; ];
// 机器人收到消处理 // 机器人收到消处理
@ -169,6 +173,7 @@ class WebSocketDialogMsgTask extends AbstractTask
'silence' => $item['silence'] ? 1 : 0, 'silence' => $item['silence'] ? 1 : 0,
'data' => array_merge($msg->toArray(), [ 'data' => array_merge($msg->toArray(), [
'mention' => $item['mention'], 'mention' => $item['mention'],
'dot' => $item['dot'],
'user_at' => Carbon::parse($item['updated'])->toDateTimeString('millisecond'), 'user_at' => Carbon::parse($item['updated'])->toDateTimeString('millisecond'),
'user_ms' => Carbon::parse($item['updated'])->valueOf(), 'user_ms' => Carbon::parse($item['updated'])->valueOf(),
]), ]),

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddWebSocketDialogMsgReadsDot extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('web_socket_dialog_msg_reads', function (Blueprint $table) {
if (!Schema::hasColumn('web_socket_dialog_msg_reads', 'dot')) {
$table->integer('dot')->nullable()->default(0)->after('after')->comment('红点标记');
}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('web_socket_dialog_msg_reads', function (Blueprint $table) {
$table->dropColumn("dot");
});
}
}

View File

@ -8,6 +8,7 @@
<div <div
class="dialog-head" class="dialog-head"
:class="headClass" :class="headClass"
@click="handleClick"
v-longpress="{callback: handleLongpress, delay: 300}"> v-longpress="{callback: handleLongpress, delay: 300}">
<!--回复--> <!--回复-->
<div v-if="!hideReply && msgData.reply_id && showReplyData(msgData.msg.reply_data)" class="dialog-reply no-dark-content" @click="viewReply"> <div v-if="!hideReply && msgData.reply_id && showReplyData(msgData.msg.reply_data)" class="dialog-reply no-dark-content" @click="viewReply">
@ -329,7 +330,8 @@ export default {
emojiUsersNum: 5, emojiUsersNum: 5,
voteData: {}, voteData: {},
unfoldWordChainData: [] dotClicks: [],
unfoldWordChainData: [],
} }
}, },
@ -390,8 +392,11 @@ export default {
}, },
headClass() { headClass() {
const {reply_id, type, msg, emoji} = this.msgData; const {id, reply_id, type, msg, emoji, dot} = this.msgData;
const array = []; const array = [];
if (dot && !this.dotClicks.includes(id)) {
array.push('dot')
}
if (reply_id === 0 && $A.arrayLength(emoji) === 0) { if (reply_id === 0 && $A.arrayLength(emoji) === 0) {
if (type === 'text') { if (type === 'text') {
if (/^<img\s+class="emoticon"[^>]*?>$/.test(msg.text) if (/^<img\s+class="emoticon"[^>]*?>$/.test(msg.text)
@ -447,6 +452,13 @@ export default {
this.$emit("on-longpress", {event, el, msgData: this.msgData}) this.$emit("on-longpress", {event, el, msgData: this.msgData})
}, },
handleClick() {
if (this.msgData.dot) {
this.dotClicks.push(this.msgData.id);
this.$store.dispatch("dialogMsgDot", this.msgData);
}
},
openTodo() { openTodo() {
if (this.todoLoad > 0) { if (this.todoLoad > 0) {
return; return;

View File

@ -3262,6 +3262,31 @@ export default {
}, 50); }, 50);
}, },
/**
* 消息去除点
* @param state
* @param dispatch
* @param data
*/
dialogMsgDot({state, dispatch}, data) {
if (!$A.isJson(data)) {
return;
}
if (!data.dot) {
return;
}
data.dot = 0;
//
dispatch("call", {
url: 'dialog/msg/dot',
data: {
id: data.id
}
}).then(({data}) => {
dispatch("saveDialog", data)
});
},
/** /**
* 标记已读未读 * 标记已读未读
* @param state * @param state

View File

@ -685,6 +685,21 @@
background-color: transparent !important; background-color: transparent !important;
} }
&.dot {
position: relative;
&:after {
content: "";
position: absolute;
top: 50%;
right: -16px;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #ed4014;
transform: translateY(-50%);
}
}
.dialog-reply { .dialog-reply {
position: relative; position: relative;
padding-left: 9px; padding-left: 9px;
@ -1553,6 +1568,13 @@
background-color: $primary-color; background-color: $primary-color;
border-radius: 8px 2px 8px 8px; border-radius: 8px 2px 8px 8px;
&.dot {
&:after {
left: -16px;
right: unset;
}
}
.dialog-reply { .dialog-reply {
color: #ffffff; color: #ffffff;
&:after { &:after {