|
@@ -3,81 +3,201 @@
|
|
|
placement="bottom"
|
|
|
width="400"
|
|
|
trigger="click"
|
|
|
+ @show="onOpen"
|
|
|
>
|
|
|
<div>
|
|
|
<div class="top">
|
|
|
- 通知
|
|
|
+ 通知 ( {{ total }} )
|
|
|
<div class="tool">
|
|
|
- <m-button type="primary" size="mini" text class="pa-0">查看全部信息</m-button>
|
|
|
- <m-button type="primary" size="mini" text class="pa-0">全部标记为已读</m-button>
|
|
|
+ <m-button type="primary" size="mini" text class="pa-0" @click="onOpen">刷新</m-button>
|
|
|
+ <m-button type="primary" size="mini" text class="pa-0" @click="onSetAllRead">全部标记为已读</m-button>
|
|
|
+ <m-button type="primary" size="mini" text class="pa-0" @click="onDeleteRead">删除已读</m-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="message">
|
|
|
- <div v-for="item in items" :key="item.id" class="message-box" :class="{ disabled: item.status === 0 }" @click="onTo(item)">
|
|
|
- <div class="message-box-title">{{ item.title }}</div>
|
|
|
- <div class="message-box-content">{{ item.content }}</div>
|
|
|
- <div class="message-box-footer">
|
|
|
- <div class="message-box-footer-time">{{ item.time }}</div>
|
|
|
- <div v-if="item.status === 1" class="message-box-footer-actions">
|
|
|
- <m-button text type="primary" size="mini" @click.stop="onSet(item)">标记为已读</m-button>
|
|
|
- <m-button text type="danger" size="mini" @click.stop="onDelete(item)">删除</m-button>
|
|
|
+ <div
|
|
|
+ class="message"
|
|
|
+ v-loading="loading"
|
|
|
+ v-infinite-scroll="onLoadMessage"
|
|
|
+ :infinite-scroll-disabled="total <= items.length"
|
|
|
+ >
|
|
|
+ <div>
|
|
|
+ <div v-for="(item, index) in items" :key="item.id" class="message-box" @click="onTo(item)">
|
|
|
+ <div class="message-box-title" :class="{ op5: item.readState === 1}">{{ index }}{{ item.title }}</div>
|
|
|
+ <div class="message-box-content" :class="{ op5: item.readState === 1}">{{ item.content }}</div>
|
|
|
+ <div class="message-box-footer">
|
|
|
+ <div class="message-box-footer-time" :class="{ op5: item.readState === 1}">{{ item.createTime }}</div>
|
|
|
+ <div>
|
|
|
+ <m-button v-if="item.readState === 0" text type="primary" size="mini" @click.stop="onSet(item)">标记为已读</m-button>
|
|
|
+ <m-button text type="danger" size="mini" @click.stop="onDelete(item, index)">删除</m-button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ <div class="loading" v-loading="true" v-if="items.length < total"></div>
|
|
|
+ <m-divider v-if="items.length > 0 && items.length >= total">没有更多了</m-divider>
|
|
|
+ <el-empty v-if="items.length === 0" description="暂无通知"></el-empty>
|
|
|
</div>
|
|
|
- <m-divider v-if="items.length > 0 && items.length >= total">没有更多消息了</m-divider>
|
|
|
- <el-empty v-if="items.length === 0" description="暂无通知"></el-empty>
|
|
|
</div>
|
|
|
- <el-badge class="cursor-pointer" slot="reference" :value="badgeValue" :max="99" :hidden="badgeValue === 0">
|
|
|
+ <el-badge class="cursor-pointer" slot="reference" :value="unreadTotal" :max="99" :hidden="unreadTotal === 0">
|
|
|
<span class="el-icon-bell"></span>
|
|
|
</el-badge>
|
|
|
</el-popover>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
+import {
|
|
|
+ getMessage,
|
|
|
+ setMessageRead,
|
|
|
+ deleteMessage,
|
|
|
+ deleteMessageRead,
|
|
|
+ setMessageAllRead
|
|
|
+} from '@/api/message'
|
|
|
+import { mapGetters } from 'vuex'
|
|
|
export default {
|
|
|
name: 'LayoutNotification',
|
|
|
data () {
|
|
|
return {
|
|
|
activeName: 'inform',
|
|
|
total: 0,
|
|
|
- items: [
|
|
|
- {
|
|
|
- title: '您有新的审核提醒',
|
|
|
- content: '通知内容1',
|
|
|
- time: '2020-01-01 12:00:00',
|
|
|
- status: 1,
|
|
|
- id: '1'
|
|
|
- },
|
|
|
- {
|
|
|
- title: '您有新的审核提醒',
|
|
|
- content: '通知内容1',
|
|
|
- time: '2020-01-01 12:00:00',
|
|
|
- status: 1,
|
|
|
- id: '2'
|
|
|
- }
|
|
|
- ]
|
|
|
+ pageInfo: {
|
|
|
+ size: 10,
|
|
|
+ current: 1
|
|
|
+ },
|
|
|
+ loading: false,
|
|
|
+ items: [],
|
|
|
+ timer: null,
|
|
|
+ unreadTotal: 0
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
- badgeValue () {
|
|
|
- return this.items.filter(item => item.status === 1).length
|
|
|
+ ...mapGetters(['userInfo'])
|
|
|
+ },
|
|
|
+ created () {
|
|
|
+ this.getUnread()
|
|
|
+ if (this.timer) {
|
|
|
+ clearInterval(this.timer)
|
|
|
+ }
|
|
|
+ this.timer = setInterval(() => {
|
|
|
+ this.getUnread()
|
|
|
+ }, 3000)
|
|
|
+ },
|
|
|
+ beforeDestroy () {
|
|
|
+ if (this.timer) {
|
|
|
+ clearInterval(this.timer)
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
- onSet (item) {
|
|
|
- item.status = 0
|
|
|
+ onLoadMessage () {
|
|
|
+ this.pageInfo.current++
|
|
|
+ this.onInit()
|
|
|
+ },
|
|
|
+ async onOpen () {
|
|
|
+ this.loading = true
|
|
|
+ this.pageInfo.current = 1
|
|
|
+ this.total = 0
|
|
|
+ this.items = []
|
|
|
+ await this.onInit()
|
|
|
+ this.loading = false
|
|
|
+ },
|
|
|
+ async getUnread () {
|
|
|
+ try {
|
|
|
+ const { data } = await getMessage({
|
|
|
+ userId: this.userInfo.id,
|
|
|
+ readState: 0,
|
|
|
+ page: {
|
|
|
+ size: 1,
|
|
|
+ current: 1
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.unreadTotal = data.total
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.error(error)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async onInit () {
|
|
|
+ try {
|
|
|
+ const { data } = await getMessage({
|
|
|
+ userId: this.userInfo.id,
|
|
|
+ page: {
|
|
|
+ ...this.pageInfo
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.items.push(...data.records)
|
|
|
+ this.total = data.total
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.error(error)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async onSet (item) {
|
|
|
+ try {
|
|
|
+ await setMessageRead({ messageId: item.messageId })
|
|
|
+ this.unreadTotal--
|
|
|
+ item.readState = 1
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.error(error)
|
|
|
+ }
|
|
|
},
|
|
|
onTo (item) {
|
|
|
this.$message('开发中,敬请期待')
|
|
|
- // console.log(2)
|
|
|
},
|
|
|
- onDelete () {}
|
|
|
+ async onDelete ({ messageId }, index) {
|
|
|
+ try {
|
|
|
+ await deleteMessage({ messageId })
|
|
|
+ // 动态移除一条
|
|
|
+ this.items.splice(index, 1)
|
|
|
+ this.total--
|
|
|
+ // 已全部加载完毕
|
|
|
+ if (this.total <= this.items.length) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 底下还有数据,继续加载
|
|
|
+ const { data } = await getMessage({
|
|
|
+ userId: this.userInfo.id,
|
|
|
+ page: {
|
|
|
+ size: 1,
|
|
|
+ current: this.items.length + 1
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.items.push(...data.records)
|
|
|
+ this.$message.success('删除成功')
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.error(error)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async onDeleteRead () {
|
|
|
+ this.loading = true
|
|
|
+ try {
|
|
|
+ await deleteMessageRead()
|
|
|
+ this.pageInfo.current = 1
|
|
|
+ this.items = []
|
|
|
+ this.total = 0
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.error(error)
|
|
|
+ } finally {
|
|
|
+ this.loading = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async onSetAllRead () {
|
|
|
+ this.loading = true
|
|
|
+ try {
|
|
|
+ await setMessageAllRead()
|
|
|
+ this.items.forEach(e => {
|
|
|
+ e.readState = 1
|
|
|
+ })
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.error(error)
|
|
|
+ } finally {
|
|
|
+ this.loading = false
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+.loading {
|
|
|
+ height: 50px;
|
|
|
+}
|
|
|
.tool {
|
|
|
text-align: right;
|
|
|
font-size: 0;
|
|
@@ -91,8 +211,12 @@ export default {
|
|
|
border-bottom: 1px solid #eee;
|
|
|
color: $theme-color;
|
|
|
}
|
|
|
+.op5 {
|
|
|
+ opacity: .5;
|
|
|
+}
|
|
|
.message {
|
|
|
max-height: 600px;
|
|
|
+ min-height: 400px;
|
|
|
overflow: auto;
|
|
|
&-box {
|
|
|
&.disabled {
|