mirror of
https://github.com/kuaifan/dootask.git
synced 2026-06-07 16:08:50 +00:00
perf: 会话顶部提示剩余未读消息
This commit is contained in:
parent
daa88a2cc2
commit
a0e84479f2
@ -457,6 +457,15 @@ class DialogController extends AbstractController
|
||||
->where('web_socket_dialog_msgs.id', '<', $last->id)
|
||||
->orderByDesc('web_socket_dialog_msgs.id')
|
||||
->value('id'));
|
||||
//
|
||||
if (empty($position_id)) {
|
||||
$unreadBuilder = WebSocketDialogMsgRead::whereDialogId($dialog_id)->whereUserid($user->userid)->whereReadAt(null)->where('msg_id', '<', $last->id);
|
||||
$unread = $unreadBuilder->count();
|
||||
$data['before'] = [
|
||||
'unread' => $unread,
|
||||
'first_id' => $unread > 0 ? intval($unreadBuilder->orderBy('msg_id')->value('msg_id')) : 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
$data['list'] = $list;
|
||||
$data['time'] = Base::time();
|
||||
|
||||
@ -97,6 +97,14 @@
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<!--顶部提示-->
|
||||
<div v-if="beforeUnread" class="dialog-top" :class="{'down': tagShow}">
|
||||
<div class="top-unread" @click="goBeforeUnread">
|
||||
<Icon v-if="beforeLoad" type="ios-loading" class="icon-loading"></Icon>
|
||||
<span>{{$L(`未读消息${beforeUnread.unread}条`)}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--消息列表-->
|
||||
<VirtualList
|
||||
ref="scroller"
|
||||
@ -522,6 +530,8 @@ export default {
|
||||
scrollDirection: null,
|
||||
scrollAction: 0,
|
||||
scrollTmp: 0,
|
||||
|
||||
beforeLoad: false,
|
||||
}
|
||||
},
|
||||
|
||||
@ -538,6 +548,7 @@ export default {
|
||||
'dialogMsgs',
|
||||
'dialogTodos',
|
||||
'dialogMsgTransfer',
|
||||
'dialogBeforeUnreads',
|
||||
'cacheDialogs',
|
||||
'wsOpenNum',
|
||||
'touchBackInProgress',
|
||||
@ -751,6 +762,11 @@ export default {
|
||||
}
|
||||
}
|
||||
return null
|
||||
},
|
||||
|
||||
beforeUnread() {
|
||||
const before = this.dialogBeforeUnreads.find(({id}) => id === this.dialogId)
|
||||
return before || null
|
||||
}
|
||||
},
|
||||
|
||||
@ -2202,6 +2218,25 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
goBeforeUnread() {
|
||||
if (!this.beforeUnread || this.beforeLoad) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
this.beforeLoad = true
|
||||
const {first_id} = this.beforeUnread
|
||||
this.$store.dispatch("dialogMsgMark", {
|
||||
dialog_id: this.dialogId,
|
||||
type: 'read'
|
||||
}).then(_ => {
|
||||
this.onPositionId(first_id)
|
||||
}).catch(({msg}) => {
|
||||
$A.modalError(msg)
|
||||
}).finally(_ => {
|
||||
this.beforeLoad = false
|
||||
})
|
||||
},
|
||||
|
||||
getBase64Image(url) {
|
||||
return new Promise(resolve => {
|
||||
let canvas = document.createElement('CANVAS'),
|
||||
|
||||
@ -720,17 +720,12 @@ export default {
|
||||
},
|
||||
|
||||
handleReadClick() {
|
||||
this.$store.dispatch("call", {
|
||||
url: 'dialog/msg/mark',
|
||||
data: {
|
||||
dialog_id: this.operateItem.id,
|
||||
type: $A.getDialogUnread(this.operateItem, true) > 0 ? 'read' : 'unread'
|
||||
},
|
||||
}).then(({data}) => {
|
||||
this.$store.dispatch("saveDialog", data);
|
||||
this.$store.dispatch("dialogMsgMark", {
|
||||
dialog_id: this.operateItem.id,
|
||||
type: $A.getDialogUnread(this.operateItem, true) > 0 ? 'read' : 'unread'
|
||||
}).catch(({msg}) => {
|
||||
$A.modalError(msg);
|
||||
});
|
||||
$A.modalError(msg)
|
||||
})
|
||||
},
|
||||
|
||||
handleSilenceClick() {
|
||||
|
||||
39
resources/assets/js/store/actions.js
vendored
39
resources/assets/js/store/actions.js
vendored
@ -2505,6 +2505,18 @@ export default {
|
||||
dispatch("saveDialogTodo", resData.todo)
|
||||
}
|
||||
//
|
||||
const before = Object.assign({id: data.dialog_id}, resData.before || {});
|
||||
const index = state.dialogBeforeUnreads.findIndex(({id}) => id == data.dialog_id);
|
||||
if (before.unread) {
|
||||
if (index > -1) {
|
||||
state.dialogBeforeUnreads.splice(index, 1, before);
|
||||
} else {
|
||||
state.dialogBeforeUnreads.push(before);
|
||||
}
|
||||
} else if (index > -1) {
|
||||
state.dialogBeforeUnreads.splice(index, 1);
|
||||
}
|
||||
//
|
||||
dispatch("saveDialogMsg", resData.list)
|
||||
resolve(result)
|
||||
}).catch(e => {
|
||||
@ -2569,6 +2581,33 @@ export default {
|
||||
}, 50);
|
||||
},
|
||||
|
||||
/**
|
||||
* 标记已读、未读
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @param data
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
dialogMsgMark({state, dispatch}, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
dispatch("call", {
|
||||
url: 'dialog/msg/mark',
|
||||
data,
|
||||
}).then(result => {
|
||||
if (data.type === 'read') {
|
||||
const index = state.dialogBeforeUnreads.findIndex(({id}) => id == data.dialog_id)
|
||||
if (index > -1) {
|
||||
state.dialogBeforeUnreads.splice(index, 1)
|
||||
}
|
||||
}
|
||||
dispatch("saveDialog", result.data)
|
||||
resolve(result)
|
||||
}).catch(e => {
|
||||
reject(e)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
/** *****************************************************************************************/
|
||||
/** ************************************* loads *********************************************/
|
||||
/** *****************************************************************************************/
|
||||
|
||||
1
resources/assets/js/store/state.js
vendored
1
resources/assets/js/store/state.js
vendored
@ -82,6 +82,7 @@ export default {
|
||||
dialogHistory: [],
|
||||
dialogInputCache: [],
|
||||
dialogMsgTransfer: {time: 0},
|
||||
dialogBeforeUnreads: [],
|
||||
|
||||
// 文件
|
||||
fileLists: [],
|
||||
|
||||
@ -1074,6 +1074,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-top {
|
||||
position: absolute;
|
||||
top: 78px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.top-unread {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 6px 12px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 8px 0 rgba($primary-text-color, 0.33);
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
> i {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
position: relative;
|
||||
padding: 0 24px;
|
||||
@ -1589,6 +1613,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.dialog-top {
|
||||
top: 68px;
|
||||
&.down {
|
||||
top: 98px;
|
||||
}
|
||||
}
|
||||
.dialog-footer {
|
||||
background-color: #f8f8f8;
|
||||
padding: 8px 10px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user