no message
This commit is contained in:
parent
b8d06fcd36
commit
2f9cd34ad2
@ -42,11 +42,11 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话基础信息
|
||||
* 获取单个会话信息
|
||||
*
|
||||
* @apiParam {Number} dialog_id 对话ID
|
||||
*/
|
||||
public function basic()
|
||||
public function one()
|
||||
{
|
||||
$user = User::auth();
|
||||
//
|
||||
|
@ -29,7 +29,7 @@
|
||||
<li @click="toggleRoute('messenger')" :class="classNameRoute('messenger')">
|
||||
<i class="iconfont"></i>
|
||||
<div class="menu-title">{{$L('消息')}}</div>
|
||||
<Badge class="menu-badge" :count="dialogMsgUnread"></Badge>
|
||||
<Badge class="menu-badge" :count="msgAllUnread"></Badge>
|
||||
</li>
|
||||
<li class="menu-project">
|
||||
<ul>
|
||||
@ -165,30 +165,25 @@ export default {
|
||||
...mapState([
|
||||
'userId',
|
||||
'userInfo',
|
||||
'dialogMsgUnread',
|
||||
'dialogs',
|
||||
'projects',
|
||||
'projectChatShow',
|
||||
'taskId',
|
||||
]),
|
||||
...mapGetters(['taskData'])
|
||||
|
||||
...mapGetters(['taskData']),
|
||||
|
||||
msgAllUnread() {
|
||||
let num = 0;
|
||||
this.dialogs.map(({unread}) => {
|
||||
num += unread;
|
||||
})
|
||||
return num;
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
'$route' (route) {
|
||||
this.curPath = route.path;
|
||||
},
|
||||
taskId (id) {
|
||||
if (id > 0) {
|
||||
if (this.projectChatShow) {
|
||||
this._projectChatShow = true;
|
||||
this.$store.dispatch("toggleBoolean", "projectChatShow");
|
||||
}
|
||||
} else {
|
||||
if (this._projectChatShow) {
|
||||
this._projectChatShow = false;
|
||||
this.$store.dispatch("toggleBoolean", "projectChatShow");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -7,14 +7,14 @@
|
||||
<slot name="head">
|
||||
<div class="dialog-title">
|
||||
<div class="main-title">
|
||||
<h2>{{dialogDetail.name}}</h2>
|
||||
<h2>{{dialogData.name}}</h2>
|
||||
<em v-if="peopleNum > 0">({{peopleNum}})</em>
|
||||
</div>
|
||||
<template v-if="dialogDetail.type === 'group'">
|
||||
<div v-if="dialogDetail.group_type === 'project'" class="sub-title pointer" @click="openProject">
|
||||
<template v-if="dialogData.type === 'group'">
|
||||
<div v-if="dialogData.group_type === 'project'" class="sub-title pointer" @click="openProject">
|
||||
{{$L('项目聊天室')}} {{$L('打开项目管理')}}
|
||||
</div>
|
||||
<div v-else-if="dialogDetail.group_type === 'task'" class="sub-title pointer" @click="openTask">
|
||||
<div v-else-if="dialogData.group_type === 'task'" class="sub-title pointer" @click="openTask">
|
||||
{{$L('任务聊天室')}} {{$L('查看任务详情')}}
|
||||
</div>
|
||||
</template>
|
||||
@ -28,11 +28,11 @@
|
||||
static>
|
||||
<div ref="manageList" class="dialog-list">
|
||||
<ul>
|
||||
<li v-if="dialogMsgHasMorePages" class="history" @click="loadNextPage">{{$L('加载历史消息')}}</li>
|
||||
<li v-else-if="dialogMsgLoad > 0 && dialogMsgList.length === 0" class="loading"><Loading/></li>
|
||||
<li v-if="dialogData.hasMorePages" class="history" @click="loadNextPage">{{$L('加载历史消息')}}</li>
|
||||
<li v-else-if="dialogData.loading > 0 && dialogMsgList.length === 0" class="loading"><Loading/></li>
|
||||
<li v-else-if="dialogMsgList.length === 0" class="nothing">{{$L('暂无消息')}}</li>
|
||||
<li
|
||||
v-for="item in dialogMsgLists"
|
||||
v-for="item in dialogMsgList"
|
||||
:id="'view_' + item.id"
|
||||
:key="item.id"
|
||||
:class="{self:item.userid == userId, 'history-tip': topId == item.id}">
|
||||
@ -40,7 +40,17 @@
|
||||
<div class="dialog-avatar">
|
||||
<UserAvatar :userid="item.userid" :tooltip-disabled="item.userid == userId" :size="30"/>
|
||||
</div>
|
||||
<DialogView :msg-data="item" :dialog-type="dialogDetail.type"/>
|
||||
<DialogView :msg-data="item" :dialog-type="dialogData.type"/>
|
||||
</li>
|
||||
<li
|
||||
v-for="item in tempMsgList"
|
||||
:id="'tmp_' + item.id"
|
||||
:key="'tmp_' + item.id"
|
||||
:class="{self:item.userid == userId}">
|
||||
<div class="dialog-avatar">
|
||||
<UserAvatar :userid="item.userid" :tooltip-disabled="item.userid == userId" :size="30"/>
|
||||
</div>
|
||||
<DialogView :msg-data="item" :dialog-type="dialogData.type"/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -83,6 +93,13 @@ import DialogUpload from "./DialogUpload";
|
||||
export default {
|
||||
name: "DialogWrapper",
|
||||
components: {DialogUpload, DialogView, ScrollerY, DragInput},
|
||||
props: {
|
||||
dialogId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
autoBottom: true,
|
||||
@ -93,37 +110,45 @@ export default {
|
||||
msgText: '',
|
||||
msgNew: 0,
|
||||
topId: 0,
|
||||
|
||||
tempMsgs: []
|
||||
}
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
this.$store.state.dialogId = 0;
|
||||
},
|
||||
|
||||
deactivated() {
|
||||
this.$store.state.dialogId = 0;
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState([
|
||||
'userId',
|
||||
'dialogId',
|
||||
'dialogDetail',
|
||||
'dialogMsgLoad',
|
||||
'dialogs',
|
||||
'dialogMsgs',
|
||||
'dialogMsgPush',
|
||||
'dialogMsgList',
|
||||
'dialogMsgHasMorePages',
|
||||
]),
|
||||
|
||||
dialogMsgLists() {
|
||||
const list = $A.cloneJSON(this.dialogMsgList);
|
||||
return list.sort((a, b) => {
|
||||
dialogData() {
|
||||
return this.dialogs.find(({id}) => id == this.dialogId) || {};
|
||||
},
|
||||
|
||||
dialogMsgList() {
|
||||
if (!this.dialogId) {
|
||||
return [];
|
||||
}
|
||||
return $A.cloneJSON(this.dialogMsgs.filter(({dialog_id}) => {
|
||||
return dialog_id == this.dialogId;
|
||||
})).sort((a, b) => {
|
||||
return a.id - b.id;
|
||||
});
|
||||
},
|
||||
|
||||
tempMsgList() {
|
||||
if (!this.dialogId) {
|
||||
return [];
|
||||
}
|
||||
return $A.cloneJSON(this.tempMsgs.filter(({dialog_id}) => {
|
||||
return dialog_id == this.dialogId;
|
||||
}));
|
||||
},
|
||||
|
||||
peopleNum() {
|
||||
return this.dialogDetail.type === 'group' ? $A.runNum(this.dialogDetail.people) : 0;
|
||||
return this.dialogData.type === 'group' ? $A.runNum(this.dialogData.people) : 0;
|
||||
}
|
||||
},
|
||||
|
||||
@ -136,10 +161,14 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
dialogId() {
|
||||
this.autoBottom = true;
|
||||
this.msgNew = 0;
|
||||
this.topId = -1;
|
||||
dialogId: {
|
||||
handler(id) {
|
||||
this.autoBottom = true;
|
||||
this.msgNew = 0;
|
||||
this.topId = -1;
|
||||
this.$store.dispatch("getDialogMsgs", id);
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
|
||||
@ -153,8 +182,9 @@ export default {
|
||||
return;
|
||||
}
|
||||
let tempId = $A.randomString(16);
|
||||
this.dialogMsgList.push({
|
||||
this.tempMsgs.push({
|
||||
id: tempId,
|
||||
dialog_id: this.dialogData.id,
|
||||
type: 'text',
|
||||
userid: this.userId,
|
||||
msg: {
|
||||
@ -162,7 +192,6 @@ export default {
|
||||
},
|
||||
});
|
||||
this.autoBottom = true;
|
||||
this.$store.commit("dialogMoveToTop", this.dialogId);
|
||||
this.onActive();
|
||||
//
|
||||
this.$store.dispatch("call", {
|
||||
@ -172,13 +201,15 @@ export default {
|
||||
text: this.msgText,
|
||||
},
|
||||
}).then(({data}) => {
|
||||
this.$store.dispatch("dialogMsgUpdate", {id: tempId, data});
|
||||
this.tempMsgs = this.tempMsgs.filter(({id}) => id != tempId)
|
||||
this.$store.dispatch("saveDialogMsg", data);
|
||||
}).catch(({msg}) => {
|
||||
$A.modalError(msg);
|
||||
this.$store.dispatch("dialogMsgUpdate", {id: tempId});
|
||||
this.tempMsgs = this.tempMsgs.filter(({id}) => id != tempId)
|
||||
});
|
||||
//
|
||||
this.msgText = '';
|
||||
this.$store.dispatch("dialogMoveTop", this.dialogId);
|
||||
},
|
||||
|
||||
chatKeydown(e) {
|
||||
@ -233,23 +264,25 @@ export default {
|
||||
chatFile(type, file) {
|
||||
switch (type) {
|
||||
case 'progress':
|
||||
this.dialogMsgList.push({
|
||||
this.tempMsgs.push({
|
||||
id: file.tempId,
|
||||
dialog_id: this.dialogData.id,
|
||||
type: 'loading',
|
||||
userid: this.userId,
|
||||
msg: { },
|
||||
});
|
||||
this.autoBottom = true;
|
||||
this.$store.commit("dialogMoveToTop", this.dialogId);
|
||||
this.$store.dispatch("dialogMoveTop", this.dialogId);
|
||||
this.onActive();
|
||||
break;
|
||||
|
||||
case 'error':
|
||||
this.$store.dispatch("dialogMsgUpdate", {id: file.tempId});
|
||||
this.tempMsgs = this.tempMsgs.filter(({id}) => id != tempId)
|
||||
break;
|
||||
|
||||
case 'success':
|
||||
this.$store.dispatch("dialogMsgUpdate", {id: file.tempId, data: file.data});
|
||||
this.tempMsgs = this.tempMsgs.filter(({id}) => id != tempId)
|
||||
this.$store.dispatch("saveDialogMsg", file.data);
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -308,22 +341,22 @@ export default {
|
||||
},
|
||||
|
||||
openProject() {
|
||||
if (!this.dialogDetail.group_info) {
|
||||
if (!this.dialogData.group_info) {
|
||||
return;
|
||||
}
|
||||
this.goForward({path: '/manage/project/' + this.dialogDetail.group_info.id});
|
||||
this.goForward({path: '/manage/project/' + this.dialogData.group_info.id});
|
||||
},
|
||||
|
||||
openTask() {
|
||||
if (!this.dialogDetail.group_info) {
|
||||
if (!this.dialogData.group_info) {
|
||||
return;
|
||||
}
|
||||
this.$store.dispatch("openTask", this.dialogDetail.group_info.id);
|
||||
this.$store.dispatch("openTask", this.dialogData.group_info.id);
|
||||
},
|
||||
|
||||
loadNextPage() {
|
||||
let topId = this.dialogMsgLists[0].id;
|
||||
this.$store.dispatch('getDialogMsgListNextPage').then(() => {
|
||||
let topId = this.dialogMsgList[0].id;
|
||||
this.$store.dispatch('getDialogMsgNextPage').then(() => {
|
||||
this.$nextTick(() => {
|
||||
this.topId = topId;
|
||||
let dom = document.getElementById("view_" + topId);
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="project-dialog">
|
||||
<DialogWrapper class="project-dialog-wrapper">
|
||||
<DialogWrapper :dialog-id="projectData.dialog_id" class="project-dialog-wrapper">
|
||||
<div slot="head">
|
||||
<div class="dialog-user">
|
||||
<div class="member-head">
|
||||
@ -22,7 +22,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters, mapState} from "vuex";
|
||||
import {mapGetters} from "vuex";
|
||||
import DialogWrapper from "./DialogWrapper";
|
||||
|
||||
export default {
|
||||
@ -35,29 +35,7 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['projectChatShow']),
|
||||
|
||||
...mapGetters(['projectData'])
|
||||
},
|
||||
|
||||
watch: {
|
||||
'projectData.dialog_id' () {
|
||||
this.getMsgList()
|
||||
},
|
||||
projectChatShow: {
|
||||
handler() {
|
||||
this.getMsgList()
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getMsgList() {
|
||||
if (this.projectChatShow && this.projectData.dialog_id) {
|
||||
this.$store.dispatch("getDialogMsgList", this.projectData.dialog_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -23,7 +23,7 @@
|
||||
</div>
|
||||
</Tooltip>
|
||||
</li>
|
||||
<li :class="['project-icon', projectChatShow ? 'active' : '']" @click="$store.dispatch('toggleBoolean', 'projectChatShow')">
|
||||
<li :class="['project-icon', tablePanel('chat') ? 'active' : '']" @click="$store.dispatch('toggleTablePanel', 'chat')">
|
||||
<Icon class="menu-icon" type="ios-chatbubbles" />
|
||||
<Badge class="menu-badge" :count="msgUnread"></Badge>
|
||||
</li>
|
||||
@ -46,7 +46,7 @@
|
||||
<div v-if="projectData.desc" class="project-subtitle">{{projectData.desc}}</div>
|
||||
<div class="project-switch">
|
||||
<div v-if="completedCount > 0" class="project-checkbox">
|
||||
<Checkbox :value="projectCompleteShow" @on-change="$store.dispatch('toggleBoolean', 'projectCompleteShow')">{{$L('显示已完成')}}</Checkbox>
|
||||
<Checkbox :value="showCompletedTask" @on-change="$store.dispatch('toggleBoolean', 'showCompletedTask')">{{$L('显示已完成')}}</Checkbox>
|
||||
</div>
|
||||
<div :class="['project-switch-button', !tablePanel('card') ? 'menu' : '']" @click="$store.dispatch('toggleTablePanel', 'card')">
|
||||
<div><i class="iconfont"></i></div>
|
||||
@ -401,29 +401,28 @@ export default {
|
||||
computed: {
|
||||
...mapState([
|
||||
'userId',
|
||||
'dialogList',
|
||||
'dialogs',
|
||||
|
||||
'projectId',
|
||||
'projectLoad',
|
||||
'tasks',
|
||||
'columns',
|
||||
|
||||
'projectChatShow',
|
||||
'projectCompleteShow',
|
||||
'showCompletedTask',
|
||||
]),
|
||||
|
||||
...mapGetters(['projectData', 'tablePanel']),
|
||||
|
||||
msgUnread() {
|
||||
const {dialogList, projectData} = this;
|
||||
const dialog = dialogList.find(({id}) => id === projectData.dialog_id);
|
||||
const {dialogs, projectData} = this;
|
||||
const dialog = dialogs.find(({id}) => id === projectData.dialog_id);
|
||||
return dialog ? dialog.unread : 0;
|
||||
},
|
||||
|
||||
panelTask() {
|
||||
const {searchText, projectCompleteShow} = this;
|
||||
const {searchText, showCompletedTask} = this;
|
||||
return function (list) {
|
||||
if (!projectCompleteShow) {
|
||||
if (!showCompletedTask) {
|
||||
list = list.filter(({complete_at}) => {
|
||||
return !complete_at;
|
||||
});
|
||||
@ -438,12 +437,12 @@ export default {
|
||||
},
|
||||
|
||||
myList() {
|
||||
const {projectId, tasks, searchText, projectCompleteShow, userId} = this;
|
||||
const {projectId, tasks, searchText, showCompletedTask, userId} = this;
|
||||
const array = tasks.filter((task) => {
|
||||
if (task.project_id != projectId) {
|
||||
return false;
|
||||
}
|
||||
if (!projectCompleteShow) {
|
||||
if (!showCompletedTask) {
|
||||
if (task.complete_at) {
|
||||
return false;
|
||||
}
|
||||
@ -467,12 +466,12 @@ export default {
|
||||
},
|
||||
|
||||
undoneList() {
|
||||
const {projectId, tasks, searchText, projectCompleteShow} = this;
|
||||
const {projectId, tasks, searchText, showCompletedTask} = this;
|
||||
const array = tasks.filter((task) => {
|
||||
if (task.project_id != projectId) {
|
||||
return false;
|
||||
}
|
||||
if (!projectCompleteShow) {
|
||||
if (!showCompletedTask) {
|
||||
if (task.complete_at) {
|
||||
return false;
|
||||
}
|
||||
@ -936,8 +935,8 @@ export default {
|
||||
|
||||
taskIsHidden(task) {
|
||||
const {name, desc, complete_at} = task;
|
||||
const {searchText, projectCompleteShow} = this;
|
||||
if (!projectCompleteShow) {
|
||||
const {searchText, showCompletedTask} = this;
|
||||
if (!showCompletedTask) {
|
||||
if (complete_at) {
|
||||
return true;
|
||||
}
|
||||
|
@ -332,7 +332,7 @@
|
||||
</div>
|
||||
<div class="task-dialog" :style="dialogStyle">
|
||||
<template v-if="taskDetail.dialog_id > 0">
|
||||
<DialogWrapper ref="dialog">
|
||||
<DialogWrapper ref="dialog" :dialog-id="taskDetail.dialog_id">
|
||||
<div slot="head" class="head">
|
||||
<Icon class="icon" type="ios-chatbubbles-outline" />
|
||||
<div class="nav">
|
||||
@ -638,11 +638,6 @@ export default {
|
||||
immediate: true,
|
||||
deep: true
|
||||
},
|
||||
'openTask.dialog_id' (dialog_id) {
|
||||
if (dialog_id) {
|
||||
this.$store.dispatch("getDialogMsgList", dialog_id)
|
||||
}
|
||||
},
|
||||
'openTask._show' (show) {
|
||||
if (show) {
|
||||
this.$nextTick(() => {
|
||||
|
@ -9,15 +9,16 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="tabActive==='dialog'" class="messenger-nav">
|
||||
<p :class="{active:dialogType==''}" @click="dialogType=''">{{$L('全部')}}</p>
|
||||
<p :class="{active:dialogType=='project'}" @click="dialogType='project'">{{$L('项目')}}</p>
|
||||
<p :class="{active:dialogType=='task'}" @click="dialogType='task'">{{$L('任务')}}</p>
|
||||
<p :class="{active:dialogType=='user'}" @click="dialogType='user'">{{$L('个人')}}</p>
|
||||
<p
|
||||
v-for="(item, key) in dialogType"
|
||||
:key="key"
|
||||
:class="{active:dialogActive==item.type}"
|
||||
@click="dialogActive=item.type">{{$L(item.name)}}</p>
|
||||
</div>
|
||||
<div ref="list" class="messenger-list overlay-y">
|
||||
<ul v-if="tabActive==='dialog'" class="dialog">
|
||||
<li
|
||||
v-for="(dialog, key) in dialogLists"
|
||||
v-for="(dialog, key) in dialogList"
|
||||
:key="key"
|
||||
:class="{active: dialog.id == dialogId}"
|
||||
@click="openDialog(dialog, true)">
|
||||
@ -38,7 +39,6 @@
|
||||
</div>
|
||||
<Badge class="dialog-num" :count="dialog.unread"/>
|
||||
</li>
|
||||
<li v-if="dialogLoad > 0" class="loading"><Loading/></li>
|
||||
</ul>
|
||||
<ul v-else class="contacts">
|
||||
<li v-for="(users, label) in contactsLists">
|
||||
@ -60,7 +60,7 @@
|
||||
</div>
|
||||
|
||||
<div class="messenger-msg">
|
||||
<DialogWrapper v-if="dialogId > 0" @on-active="scrollIntoActive"/>
|
||||
<DialogWrapper v-if="dialogId > 0" :dialogId="dialogId" @on-active="scrollIntoActive"/>
|
||||
<div v-else class="dialog-no">
|
||||
<div class="dialog-no-icon"><Icon type="ios-chatbubbles" /></div>
|
||||
<div class="dialog-no-text">{{$L('选择一个会话开始聊天')}}</div>
|
||||
@ -80,50 +80,40 @@ export default {
|
||||
return {
|
||||
tabActive: 'dialog',
|
||||
|
||||
dialogLoad: 0,
|
||||
dialogType: [
|
||||
{type: '', name: '全部'},
|
||||
{type: 'project', name: '项目'},
|
||||
{type: 'task', name: '任务'},
|
||||
{type: 'user', name: '个人'},
|
||||
],
|
||||
dialogActive: '',
|
||||
dialogKey: '',
|
||||
dialogType: '',
|
||||
dialogMounted: false,
|
||||
dialogId: 0,
|
||||
|
||||
contactsLoad: 0,
|
||||
contactsLists: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.dialogLoad++;
|
||||
this.$store.dispatch("getDialogList").then(() => {
|
||||
this.dialogLoad--;
|
||||
this.dialogMounted = true;
|
||||
this.openDialogStorage();
|
||||
}).catch(() => {
|
||||
this.dialogLoad--;
|
||||
this.dialogMounted = true;
|
||||
this.openDialogStorage();
|
||||
});
|
||||
},
|
||||
|
||||
activated() {
|
||||
if (this.dialogMounted) {
|
||||
this.$store.dispatch("getDialogList");
|
||||
this.openDialogStorage();
|
||||
}
|
||||
this.$store.dispatch("getDialogs");
|
||||
this.openDialogStorage();
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['userId', 'dialogId', 'dialogList']),
|
||||
...mapState(['userId', 'dialogs']),
|
||||
|
||||
dialogLists() {
|
||||
const {dialogType, dialogKey} = this;
|
||||
if (dialogType == '' && dialogKey == '') {
|
||||
return this.dialogList;
|
||||
dialogList() {
|
||||
const {dialogActive, dialogKey} = this;
|
||||
if (dialogActive == '' && dialogKey == '') {
|
||||
return this.dialogs;
|
||||
}
|
||||
return this.dialogList.filter(({name, type, group_type, last_msg}) => {
|
||||
if (dialogType) {
|
||||
switch (dialogType) {
|
||||
return this.dialogs.filter(({name, type, group_type, last_msg}) => {
|
||||
if (dialogActive) {
|
||||
switch (dialogActive) {
|
||||
case 'project':
|
||||
case 'task':
|
||||
if (group_type != dialogType) {
|
||||
if (group_type != dialogActive) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@ -158,15 +148,15 @@ export default {
|
||||
|
||||
methods: {
|
||||
openDialog(dialog, smooth) {
|
||||
this.$store.state.method.setStorage("messengerDialogId", dialog.id)
|
||||
this.$store.dispatch("getDialogMsgList", dialog.id);
|
||||
this.$store.state.method.setStorage("messenger::dialogId", dialog.id)
|
||||
this.dialogId = dialog.id;
|
||||
this.scrollIntoActive(smooth);
|
||||
},
|
||||
|
||||
openDialogStorage() {
|
||||
let tmpId = this.$store.state.method.getStorageInt("messengerDialogId")
|
||||
if (tmpId > 0) {
|
||||
const dialog = this.dialogList.find(({id}) => id === tmpId);
|
||||
this.dialogId = this.$store.state.method.getStorageInt("messenger::dialogId")
|
||||
if (this.dialogId > 0) {
|
||||
const dialog = this.dialogs.find(({id}) => id === this.dialogId);
|
||||
dialog && this.openDialog(dialog, false);
|
||||
}
|
||||
},
|
||||
@ -259,9 +249,9 @@ export default {
|
||||
scrollMode: 'if-needed',
|
||||
});
|
||||
} else {
|
||||
let dialog = this.dialogList.find(({id}) => id == this.dialogId)
|
||||
if (dialog && this.dialogType) {
|
||||
this.dialogType = '';
|
||||
let dialog = this.dialogs.find(({id}) => id == this.dialogId)
|
||||
if (dialog && this.dialogActive) {
|
||||
this.dialogActive = '';
|
||||
this.$nextTick(() => {
|
||||
let active = this.$refs.list.querySelector(".active")
|
||||
if (active) {
|
||||
|
@ -2,11 +2,12 @@
|
||||
<div class="page-project">
|
||||
<PageTitle>{{ $L('项目面板') }}</PageTitle>
|
||||
<ProjectList/>
|
||||
<ProjectDialog v-if="$store.state.projectChatShow"/>
|
||||
<ProjectDialog v-if="tablePanel('chat')"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import ProjectList from "./components/ProjectList";
|
||||
import ProjectDialog from "./components/ProjectDialog";
|
||||
export default {
|
||||
@ -16,9 +17,15 @@ export default {
|
||||
project_id: 0,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.project_id = this.$route.params.id;
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters(['tablePanel']),
|
||||
},
|
||||
|
||||
watch: {
|
||||
'$route' (route) {
|
||||
this.project_id = route.params.id;
|
||||
|
254
resources/assets/js/store/actions.js
vendored
254
resources/assets/js/store/actions.js
vendored
@ -191,7 +191,7 @@ export default {
|
||||
state.userIsAdmin = state.method.inArray('admin', userInfo.identity);
|
||||
state.method.setStorage("userInfo", state.userInfo);
|
||||
dispatch("getProjects");
|
||||
dispatch("getDialogMsgUnread");
|
||||
dispatch("getDialogs");
|
||||
dispatch("websocketConnection");
|
||||
resolve()
|
||||
});
|
||||
@ -543,7 +543,6 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/** *****************************************************************************************/
|
||||
/** ************************************** 任务 **********************************************/
|
||||
/** *****************************************************************************************/
|
||||
@ -941,7 +940,6 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/** *****************************************************************************************/
|
||||
/** ************************************** 会话 **********************************************/
|
||||
/** *****************************************************************************************/
|
||||
@ -953,15 +951,21 @@ export default {
|
||||
* @param data
|
||||
*/
|
||||
saveDialog({state, dispatch}, data) {
|
||||
let splice = false;
|
||||
state.dialogList.some(({id, unread}, index) => {
|
||||
if (id == data.id) {
|
||||
unread !== data.unread && dispatch('getDialogMsgUnread');
|
||||
state.dialogList.splice(index, 1, data);
|
||||
return splice = true;
|
||||
if (state.method.isArray(data)) {
|
||||
data.forEach((dialog) => {
|
||||
dispatch("saveDialog", dialog)
|
||||
});
|
||||
} else if (state.method.isJson(data)) {
|
||||
let index = state.dialogs.findIndex(({id}) => id == data.id);
|
||||
if (index > -1) {
|
||||
state.dialogs.splice(index, 1, Object.assign(state.dialogs[index], data));
|
||||
} else {
|
||||
state.dialogs.push(data);
|
||||
}
|
||||
});
|
||||
!splice && state.dialogList.unshift(data)
|
||||
setTimeout(() => {
|
||||
state.method.setStorage("cacheDialogs", state.cacheDialogs = state.dialogs);
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -969,23 +973,12 @@ export default {
|
||||
* @param state
|
||||
* @param dispatch
|
||||
*/
|
||||
getDialogList({state, dispatch}) {
|
||||
getDialogs({state, dispatch}) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
dispatch("call", {
|
||||
url: 'dialog/lists',
|
||||
}).then(result => {
|
||||
if (state.dialogList.length === 0) {
|
||||
state.dialogList = result.data.data;
|
||||
} else {
|
||||
result.data.data.forEach((dialog) => {
|
||||
let index = state.dialogList.findIndex(({id}) => id == dialog.id);
|
||||
if (index > -1) {
|
||||
dialog = Object.assign(state.dialogList[index], dialog)
|
||||
state.dialogList.splice(index, 1);
|
||||
}
|
||||
state.dialogList.push(dialog);
|
||||
});
|
||||
}
|
||||
dispatch("saveDialog", result.data.data);
|
||||
resolve(result);
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
@ -1000,9 +993,9 @@ export default {
|
||||
* @param dispatch
|
||||
* @param dialog_id
|
||||
*/
|
||||
getDialogBasic({state, dispatch}, dialog_id) {
|
||||
getDialogOne({state, dispatch}, dialog_id) {
|
||||
dispatch("call", {
|
||||
url: 'dialog/basic',
|
||||
url: 'dialog/one',
|
||||
data: {
|
||||
dialog_id,
|
||||
},
|
||||
@ -1029,7 +1022,6 @@ export default {
|
||||
},
|
||||
}).then(result => {
|
||||
state.method.setStorage("messengerDialogId", result.data.id)
|
||||
dispatch("getDialogMsgList", result.data.id);
|
||||
dispatch("saveDialog", result.data);
|
||||
resolve(result);
|
||||
}).catch(e => {
|
||||
@ -1039,62 +1031,83 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 将会话移动到首位
|
||||
* @param state
|
||||
* @param dialog_id
|
||||
*/
|
||||
dialogMoveTop({state}, dialog_id) {
|
||||
const index = state.dialogs.findIndex(({id}) => id == dialog_id);
|
||||
if (index > -1) {
|
||||
const tmp = state.method.cloneJSON(state.dialogs[index]);
|
||||
state.dialogs.splice(index, 1);
|
||||
state.dialogs.unshift(tmp);
|
||||
}
|
||||
},
|
||||
|
||||
/** *****************************************************************************************/
|
||||
/** ************************************** 消息 **********************************************/
|
||||
/** *****************************************************************************************/
|
||||
|
||||
/**
|
||||
* 更新消息数据
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @param data
|
||||
*/
|
||||
saveDialogMsg({state, dispatch}, data) {
|
||||
if (state.method.isArray(data)) {
|
||||
data.forEach((msg) => {
|
||||
dispatch("saveDialogMsg", msg)
|
||||
});
|
||||
} else if (state.method.isJson(data)) {
|
||||
let index = state.dialogMsgs.findIndex(({id}) => id == data.id);
|
||||
if (index > -1) {
|
||||
state.dialogMsgs.splice(index, 1, Object.assign(state.dialogMsgs[index], data));
|
||||
} else {
|
||||
state.dialogMsgs.push(data);
|
||||
}
|
||||
setTimeout(() => {
|
||||
state.method.setStorage("cacheDialogMsgs", state.cacheDialogMsgs = state.dialogMsgs);
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取会话消息
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @param commit
|
||||
* @param dialog_id
|
||||
*/
|
||||
getDialogMsgList({state, dispatch, commit}, dialog_id) {
|
||||
if (state.method.runNum(dialog_id) === 0) {
|
||||
getDialogMsgs({state, dispatch}, dialog_id) {
|
||||
const dialog = state.dialogs.filter(({id}) => id == dialog_id);
|
||||
if (!dialog) {
|
||||
return;
|
||||
}
|
||||
if (state.dialogId == dialog_id) {
|
||||
if (dialog.loading) {
|
||||
return;
|
||||
}
|
||||
dialog.loading = true;
|
||||
dialog.currentPage = 1;
|
||||
dialog.hasMorePages = false;
|
||||
//
|
||||
state.dialogMsgList = [];
|
||||
state.dialogMsgCurrentPage = 1;
|
||||
state.dialogMsgHasMorePages = false;
|
||||
if (state.method.isJson(state.cacheDialogMsg[dialog_id])) {
|
||||
let length = state.cacheDialogMsg[dialog_id].data.length;
|
||||
if (length > 50) {
|
||||
state.cacheDialogMsg[dialog_id].data.splice(0, length - 50);
|
||||
}
|
||||
state.dialogDetail = state.cacheDialogMsg[dialog_id].dialog
|
||||
state.dialogMsgList = state.cacheDialogMsg[dialog_id].data
|
||||
}
|
||||
state.dialogId = dialog_id;
|
||||
//
|
||||
if (state.cacheDialogMsg[dialog_id + "::load"]) {
|
||||
return;
|
||||
}
|
||||
state.cacheDialogMsg[dialog_id + "::load"] = true;
|
||||
//
|
||||
state.dialogMsgLoad++;
|
||||
dispatch("call", {
|
||||
url: 'dialog/msg/lists',
|
||||
data: {
|
||||
dialog_id: dialog_id,
|
||||
page: state.dialogMsgCurrentPage
|
||||
page: dialog.currentPage
|
||||
},
|
||||
}).then(result => {
|
||||
state.dialogMsgLoad--;
|
||||
state.cacheDialogMsg[dialog_id + "::load"] = false;
|
||||
const data = result.data;
|
||||
// 更新缓存
|
||||
state.cacheDialogMsg[dialog_id] = {
|
||||
dialog: data.dialog,
|
||||
data: [],
|
||||
};
|
||||
state.method.setStorage("cacheDialogMsg", state.cacheDialogMsg);
|
||||
// 更新当前会话消息
|
||||
commit("dialogMsgListSuccess", data);
|
||||
dialog.loading = false;
|
||||
const ids = result.data.data.map(({id}) => id)
|
||||
if (ids.length == 0) {
|
||||
return;
|
||||
}
|
||||
state.dialogMsgs = state.dialogMsgs.filter((item) => item.dialog_id != dialog_id || ids.includes(item.id));
|
||||
dispatch("saveDialogMsg", result.data.data);
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
state.dialogMsgLoad--;
|
||||
state.cacheDialogMsg[dialog_id + "::load"] = false;
|
||||
dialog.loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
@ -1102,97 +1115,41 @@ export default {
|
||||
* 获取下一页会话消息
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @param commit
|
||||
* @param dialog_id
|
||||
*/
|
||||
getDialogMsgListNextPage({state, dispatch, commit}) {
|
||||
getDialogMsgNextPage({state, dispatch}, dialog_id) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (!state.dialogMsgHasMorePages) {
|
||||
const dialog = state.dialogs.filter(({id}) => id == dialog_id);
|
||||
if (!dialog) {
|
||||
return;
|
||||
}
|
||||
state.dialogMsgHasMorePages = false;
|
||||
state.dialogMsgCurrentPage++;
|
||||
if (!dialog.hasMorePages) {
|
||||
return;
|
||||
}
|
||||
if (dialog.loading) {
|
||||
return;
|
||||
}
|
||||
dialog.loading = true;
|
||||
dialog.currentPage++;
|
||||
//
|
||||
const dialog_id = state.dialogId;
|
||||
//
|
||||
state.dialogMsgLoad++;
|
||||
dispatch("call", {
|
||||
url: 'dialog/msg/lists',
|
||||
data: {
|
||||
dialog_id: dialog_id,
|
||||
page: state.dialogMsgCurrentPage
|
||||
page: dialog.currentPage
|
||||
},
|
||||
}).then(result => {
|
||||
state.dialogMsgLoad--;
|
||||
commit("dialogMsgListSuccess", result.data);
|
||||
dialog.loading = false;
|
||||
dispatch("saveDialogMsg", result.data);
|
||||
resolve(result)
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
state.dialogMsgLoad--;
|
||||
dialog.loading = false;
|
||||
reject(e)
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取未读信息
|
||||
* @param state
|
||||
* @param dispatch
|
||||
*/
|
||||
getDialogMsgUnread({state, dispatch}) {
|
||||
if (state.userId === 0) {
|
||||
state.dialogMsgUnread = 0;
|
||||
return;
|
||||
}
|
||||
const unread = state.dialogMsgUnread;
|
||||
dispatch("call", {
|
||||
url: 'dialog/msg/unread',
|
||||
}).then(result => {
|
||||
if (unread == state.dialogMsgUnread) {
|
||||
state.dialogMsgUnread = result.data.unread;
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
dispatch('getDialogMsgUnread');
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 根据消息ID 删除 或 替换 会话数据
|
||||
* @param state
|
||||
* @param commit
|
||||
* @param params {id, data}
|
||||
*/
|
||||
dialogMsgUpdate({state, commit}, params) {
|
||||
let {id, data} = params;
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
if (state.method.isJson(data)) {
|
||||
const task = state.tasks.find(({dialog_id}) => dialog_id === data.dialog_id);
|
||||
if (task) {
|
||||
task.msg_num++;
|
||||
}
|
||||
if (data.id && state.dialogMsgList.find(m => m.id == data.id)) {
|
||||
data = null;
|
||||
}
|
||||
}
|
||||
let index = state.dialogMsgList.findIndex(m => m.id == id);
|
||||
if (index > -1) {
|
||||
if (data) {
|
||||
state.dialogMsgList.splice(index, 1, state.method.cloneJSON(data));
|
||||
commit("dialogMsgListStorageCurrent");
|
||||
// 是最后一条消息时更新会话 last_msg
|
||||
if (state.dialogMsgList.length - 1 == index) {
|
||||
const dialog = state.dialogList.find(({id}) => id == data.dialog_id);
|
||||
if (dialog) dialog.last_msg = data;
|
||||
}
|
||||
} else {
|
||||
state.dialogMsgList.splice(index, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 发送已阅消息
|
||||
* @param state
|
||||
@ -1208,10 +1165,9 @@ export default {
|
||||
return;
|
||||
}
|
||||
r.read_at = state.method.formatDate('Y-m-d H:i:s');
|
||||
let dialog = state.dialogList.find(({id}) => id == dialog_id);
|
||||
let dialog = state.dialogs.find(({id}) => id == dialog_id);
|
||||
if (dialog && dialog.unread > 0) {
|
||||
dialog.unread--
|
||||
state.dialogMsgUnread--;
|
||||
}
|
||||
//
|
||||
state.wsReadWaitList.push(id);
|
||||
@ -1312,25 +1268,17 @@ export default {
|
||||
const {mode, data} = msg;
|
||||
const {dialog_id} = data;
|
||||
// 更新消息列表
|
||||
if (dialog_id == state.dialogId) {
|
||||
let index = state.dialogMsgList.findIndex(({id}) => id == data.id);
|
||||
if (index === -1) {
|
||||
state.dialogMsgPush = data;
|
||||
state.dialogMsgList.push(data);
|
||||
} else {
|
||||
state.dialogMsgList.splice(index, 1, data);
|
||||
}
|
||||
commit("dialogMsgListStorageCurrent");
|
||||
}
|
||||
state.dialogMsgPush = data;
|
||||
dispatch("saveDialogMsg", data)
|
||||
if (mode === "add2") {
|
||||
return;
|
||||
}
|
||||
// 更新最后消息
|
||||
let dialog = state.dialogList.find(({id}) => id == dialog_id);
|
||||
let dialog = state.dialogs.find(({id}) => id == dialog_id);
|
||||
if (dialog) {
|
||||
dialog.last_msg = data;
|
||||
} else {
|
||||
dispatch("getDialogBasic", dialog_id);
|
||||
dispatch("getDialogOne", dialog_id);
|
||||
}
|
||||
if (mode === "add1") {
|
||||
// 更新对话列表
|
||||
@ -1338,13 +1286,11 @@ export default {
|
||||
// 新增未读数
|
||||
if (data.userid !== state.userId) dialog.unread++;
|
||||
// 移动到首位
|
||||
commit("dialogMoveToTop", dialog_id);
|
||||
dispatch("dialogMoveTop", dialog_id);
|
||||
}
|
||||
// 新增任务消息数量
|
||||
const task = state.tasks.find(({dialog_id}) => dialog_id === data.dialog_id);
|
||||
const task = state.tasks.find(({dialog_id}) => dialog_id === dialog_id);
|
||||
if (task) task.msg_num++;
|
||||
// 新增总未读数
|
||||
if (data.userid !== state.userId) state.dialogMsgUnread++;
|
||||
}
|
||||
})(msgDetail);
|
||||
break;
|
||||
|
1
resources/assets/js/store/getters.js
vendored
1
resources/assets/js/store/getters.js
vendored
@ -59,6 +59,7 @@ export default {
|
||||
cache = {
|
||||
project_id: state.projectId,
|
||||
card: true,
|
||||
chat: false,
|
||||
showMy: true,
|
||||
showUndone: true,
|
||||
showCompleted: false,
|
||||
|
53
resources/assets/js/store/mutations.js
vendored
53
resources/assets/js/store/mutations.js
vendored
@ -1,56 +1,3 @@
|
||||
export default {
|
||||
/**
|
||||
* 会话消息列表
|
||||
* @param state
|
||||
* @param data
|
||||
*/
|
||||
dialogMsgListSuccess(state, data) {
|
||||
const dialog = data.dialog;
|
||||
const list = data.data;
|
||||
// 更新当前会话消息
|
||||
if (state.dialogId == dialog.id) {
|
||||
state.dialogDetail = dialog;
|
||||
list.forEach((item) => {
|
||||
let index = state.dialogMsgList.findIndex(({id}) => id == item.id);
|
||||
if (index === -1) {
|
||||
state.dialogMsgList.unshift(item);
|
||||
} else {
|
||||
state.dialogMsgList.splice(index, 1, item);
|
||||
}
|
||||
});
|
||||
this.commit("dialogMsgListStorageCurrent");
|
||||
}
|
||||
// 页数数据
|
||||
state.dialogMsgCurrentPage = data.current_page;
|
||||
state.dialogMsgHasMorePages = data.current_page < data.last_page;
|
||||
// 更新会话数据
|
||||
this.dispatch("saveDialog", dialog);
|
||||
},
|
||||
|
||||
/**
|
||||
* 保存当前会话消息
|
||||
* @param state
|
||||
*/
|
||||
dialogMsgListStorageCurrent(state) {
|
||||
if (!state.method.isJson(state.cacheDialogMsg[state.dialogId])) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
state.cacheDialogMsg[state.dialogId].data = state.dialogMsgList;
|
||||
state.method.setStorage("cacheDialogMsg", state.cacheDialogMsg);
|
||||
},
|
||||
|
||||
/**
|
||||
* 将会话移动到首位
|
||||
* @param state
|
||||
* @param dialog_id
|
||||
*/
|
||||
dialogMoveToTop(state, dialog_id) {
|
||||
const index = state.dialogList.findIndex(({id}) => id == dialog_id);
|
||||
if (index > -1) {
|
||||
const tmp = state.method.cloneJSON(state.dialogList[index]);
|
||||
state.dialogList.splice(index, 1);
|
||||
state.dialogList.unshift(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
46
resources/assets/js/store/state.js
vendored
46
resources/assets/js/store/state.js
vendored
@ -226,11 +226,6 @@ const method = {
|
||||
// 方法类
|
||||
const state = { method };
|
||||
|
||||
// ajax
|
||||
state.ajaxLoadNum = 0;
|
||||
state.ajaxWsReady = false;
|
||||
state.ajaxWsListener = [];
|
||||
|
||||
// 数据缓存
|
||||
state.cacheUserBasic = state.method.getStorageJson("cacheUserBasic");
|
||||
state.cacheDialogMsg = state.method.getStorageJson("cacheDialogMsg");
|
||||
@ -239,15 +234,12 @@ state.cacheColumns = state.method.getStorageArray("cacheColumns");
|
||||
state.cacheTasks = state.method.getStorageArray("cacheTasks");
|
||||
state.cacheTaskSubs = state.method.getStorageArray("cacheTaskSubs");
|
||||
state.cacheTablePanel = state.method.getStorageArray("cacheTablePanel");
|
||||
state.projectChatShow = state.method.getStorageBoolean("boolean:projectChatShow", false)
|
||||
state.projectCompleteShow = state.method.getStorageBoolean("boolean:projectCompleteShow", false)
|
||||
state.showCompletedTask = state.method.getStorageBoolean("boolean:showCompletedTask")
|
||||
|
||||
// 会员信息
|
||||
state.userInfo = state.method.getStorageJson("userInfo");
|
||||
state.userId = state.userInfo.userid = state.method.runNum(state.userInfo.userid);
|
||||
state.userToken = state.userInfo.token;
|
||||
state.userIsAdmin = state.method.inArray("admin", state.userInfo.identity);
|
||||
state.userOnline = {};
|
||||
// Ajax
|
||||
state.ajaxLoadNum = 0;
|
||||
state.ajaxWsReady = false;
|
||||
state.ajaxWsListener = [];
|
||||
|
||||
// Websocket
|
||||
state.ws = null;
|
||||
@ -258,30 +250,30 @@ state.wsListener = {};
|
||||
state.wsReadTimeout = null;
|
||||
state.wsReadWaitList = [];
|
||||
|
||||
// 会员信息
|
||||
state.userInfo = state.method.getStorageJson("userInfo");
|
||||
state.userId = state.userInfo.userid = state.method.runNum(state.userInfo.userid);
|
||||
state.userToken = state.userInfo.token;
|
||||
state.userIsAdmin = state.method.inArray("admin", state.userInfo.identity);
|
||||
state.userOnline = {};
|
||||
|
||||
// 会话聊天
|
||||
state.dialogs = [];
|
||||
state.dialogMsgs = [];
|
||||
state.dialogMsgPush = {};
|
||||
|
||||
// 项目任务
|
||||
state.projectId = 0;
|
||||
state.projects = [];
|
||||
state.projectLoad = 0;
|
||||
state.projectStatistics = {};
|
||||
state.columns = [];
|
||||
state.taskId = 0;
|
||||
state.tasks = [];
|
||||
state.taskSubs = [];
|
||||
state.taskContents = [];
|
||||
state.taskFiles = [];
|
||||
state.taskLogs = [];
|
||||
state.projectId = 0;
|
||||
state.taskId = 0;
|
||||
|
||||
// 会话聊天
|
||||
state.dialogId = 0;
|
||||
state.dialogList = [];
|
||||
state.dialogDetail = {};
|
||||
|
||||
state.dialogMsgUnread = 0;
|
||||
state.dialogMsgLoad = 0;
|
||||
state.dialogMsgPush = {};
|
||||
state.dialogMsgList = [];
|
||||
state.dialogMsgCurrentPage = 1;
|
||||
state.dialogMsgHasMorePages = false;
|
||||
|
||||
// 任务优先级
|
||||
state.taskPriority = [];
|
||||
|
Loading…
x
Reference in New Issue
Block a user