diff --git a/package.json b/package.json index 87e1b8d1..5736fe2d 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "dependencies": { "echarts": "^5.1.1", "element-ui": "^2.15.2", + "notification-koro1": "^1.1.1", "tinymce": "^5.8.1", "tui-calendar-hi": "^1.13.0-5", "view-design-hi": "^4.6.1-1", diff --git a/resources/assets/js/pages/manage.vue b/resources/assets/js/pages/manage.vue index 6c83133d..2d18a38f 100644 --- a/resources/assets/js/pages/manage.vue +++ b/resources/assets/js/pages/manage.vue @@ -124,6 +124,7 @@ import { mapState, mapGetters } from 'vuex' import TaskDetail from "./manage/components/TaskDetail"; import ProjectArchived from "./manage/components/ProjectArchived"; +import notificationKoro from "notification-koro1"; export default { components: {ProjectArchived, TaskDetail}, @@ -153,12 +154,19 @@ export default { openMenu: {}, archivedProjectShow: false, + + natificationHidden: false, + natificationReady: false, + notificationClass: null, } }, mounted() { this.$store.dispatch("getUserInfo"); this.$store.dispatch("getTaskPriority"); + // + this.notificationInit(); + this.onVisibilityChange(); }, deactivated() { @@ -173,6 +181,7 @@ export default { 'dialogs', 'projects', 'taskId', + 'dialogMsgPush', ]), ...mapGetters(['taskData']), @@ -189,6 +198,34 @@ export default { watch: { '$route' (route) { this.curPath = route.path; + }, + dialogMsgPush(data) { + if (this.natificationHidden && this.natificationReady) { + const {userid, type, msg} = data; + let body = ''; + switch (type) { + case 'text': + body = msg.text; + break; + case 'file': + body = '[' + this.$L(msg.type == 'img' ? '图片信息' : '文件信息') + ']' + break; + default: + return; + } + this.$store.dispatch("getUserBasic", { + userid: userid, + success: (user) => { + this.notificationClass.replaceTitle(user.nickname); + this.notificationClass.replaceOptions({ + icon: user.userimg, + body: body, + requireInteraction: true + }); + this.notificationClass.userAgreed(); + } + }); + } } }, @@ -277,6 +314,56 @@ export default { if (!visible) { this.$store.dispatch('openTask', 0) } + }, + + notificationInit() { + this.notificationClass = new notificationKoro(this.$L("打开通知成功")); + if (this.notificationClass.support) { + this.notificationClass.notificationEvent({ + onclick: () => { + window.focus(); + this.notificationClass.close(); + this.goForward({path: '/manage/messenger'}); + this.$store.dispatch("openDialogUserid", this.dialogMsgPush.userid); + }, + }); + this.notificationPermission(); + } + }, + + notificationPermission() { + const userSelectFn = msg => { + switch (msg) { + // 随时可以调用通知 + case 'already granted': + case 'granted': + return this.natificationReady = true; + + // 请求权限通知被关闭,再次调用 + case 'close': + return this.notificationClass.initNotification(userSelectFn); + + // 请求权限当前被拒绝 || 曾经被拒绝 + case 'denied': + case 'already denied': + if (msg === "denied") { + console.log("您刚刚拒绝显示通知 请在设置中更改设置"); + } else { + console.log("您曾级拒绝显示通知 请在设置中更改设置"); + } + break; + } + }; + this.notificationClass.initNotification(userSelectFn); + }, + + onVisibilityChange() { + let hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in document ? 'webkitHidden' : 'mozHidden' in document ? 'mozHidden' : null; + let visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange'); + let visibilityChangeListener = () => { + this.natificationHidden = !!document[hiddenProperty] + } + document.addEventListener(visibilityChangeEvent, visibilityChangeListener); } } } diff --git a/resources/assets/js/pages/manage/messenger.vue b/resources/assets/js/pages/manage/messenger.vue index a90aa444..c3f5bdb2 100644 --- a/resources/assets/js/pages/manage/messenger.vue +++ b/resources/assets/js/pages/manage/messenger.vue @@ -100,7 +100,7 @@ export default { }, computed: { - ...mapState(['userId', 'dialogs']), + ...mapState(['userId', 'dialogs', 'dialogOpenId']), dialogList() { const {dialogActive, dialogKey} = this; @@ -145,6 +145,10 @@ export default { if (val && this.contactsLists === null) { this.getContactsList(); } + }, + dialogOpenId(id) { + this.$store.state.method.setStorage("messenger::dialogId", id) + this.dialogId = id; } }, diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js index 1cabc71a..c97b51a1 100644 --- a/resources/assets/js/store/actions.js +++ b/resources/assets/js/store/actions.js @@ -1127,8 +1127,8 @@ export default { userid, }, }).then(result => { - state.method.setStorage("messengerDialogId", result.data.id) dispatch("saveDialog", result.data); + state.dialogOpenId = result.data.id; resolve(result); }).catch(e => { console.error(e); diff --git a/resources/assets/js/store/state.js b/resources/assets/js/store/state.js index 93e477d0..0b6b835f 100644 --- a/resources/assets/js/store/state.js +++ b/resources/assets/js/store/state.js @@ -259,6 +259,7 @@ state.userOnline = {}; state.dialogs = []; state.dialogMsgs = []; state.dialogMsgPush = {}; +state.dialogOpenId = 0; // 项目任务 state.projectId = 0; diff --git a/resources/assets/statics/public/images/logo.png b/resources/assets/statics/public/images/logo.png new file mode 100644 index 00000000..c83aa431 Binary files /dev/null and b/resources/assets/statics/public/images/logo.png differ