Browse Source

add news

master
godo 9 months ago
parent
commit
6cbb5e3ec8
  1. 1
      frontend/components.d.ts
  2. 128
      frontend/src/components/taskbar/MessageCenterPop.vue
  3. 40
      frontend/src/stores/notify.ts
  4. 40
      frontend/src/system/notification/Notification.ts

1
frontend/components.d.ts

@ -54,6 +54,7 @@ declare module 'vue' {
ElInput: typeof import('element-plus/es')['ElInput']
ElLink: typeof import('element-plus/es')['ElLink']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElRow: typeof import('element-plus/es')['ElRow']

128
frontend/src/components/taskbar/MessageCenterPop.vue

@ -3,44 +3,60 @@
<div v-if="isPopShow" class="message scroll-bar" @mousedown.stop="">
<div class="notify-center">
<div class="message-title">
{{ notifyGroup.length }}条提醒
<span @click="allClear" class="allclear">×</span>
{{ store.page.total }}条通知
</div>
<div class="message-group scroll-bar">
<div class="message-item" v-for="notify in notifyGroup" :key="notify.id">
<div class="message-item-title">
<div class="message-item" v-for="notify in store.notifyList" :key="notify.id">
<div class="message-item-title" @click="showDetail(notify)">
<span>{{ notify.title }}</span>
</div>
<div class="message-item-body">
<span>{{ notify.content }}</span>
</div>
</div>
<el-row justify="center" style="margin-top: 15px" v-if="store.page.pages > 1">
<el-pagination background layout="prev, pager, next" v-model:current-page="store.page.current"
v-model:page-size="store.page.size" :total="store.page.total"
@current-change="(val: any) => store.pageClick(val)" />
</el-row>
</div>
</div>
</div>
</Transition>
<el-dialog v-model="showNews" :title="newsDetail.title" show-close="true" width="600">
<div class="new-content">
<div class="news-detail" v-html="newsDetail.content"></div>
<p class="new-time"><strong>发布时间:</strong> {{ newsDetail.showtime }}</p>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import { useSystem } from '@/system';
import { useNotifyStore } from '@/stores/notify';
import { ref } from 'vue';
import { mountEvent } from '@/system/event';
const rootState = useSystem()._rootState;
const notifyGroup = rootState.message.notify;
// const systemGroup = rootState.message.system;
const store = useNotifyStore()
const isPopShow = ref(false);
const newsDetail: any = ref({})
const showNews = ref(false)
mountEvent('messagecenter.show', () => {
isPopShow.value = !isPopShow.value;
});
mountEvent('messagecenter.hidden', () => {
isPopShow.value = false;
});
function allClear() {
rootState.message.notify.splice(0, notifyGroup.length);
isPopShow.value = false;
onMounted(async () => {
// store.init();
await store.getList()
});
const showDetail = (notify: any) => {
const timestamp = notify.add_time * 1000; // 10 13
const date = new Date(timestamp);
notify.showtime = date.toLocaleString();
newsDetail.value = notify
showNews.value = true
}
</script>
<style lang="scss" scoped>
@import '@/assets/main.scss';
.message {
position: absolute;
top: 0;
@ -48,8 +64,10 @@ function allClear() {
width: 300px;
height: 100%;
z-index: 400;
background-color: #F5F5F5; /* 更接近Win10的背景颜色 */
border-left: 1px solid #E5E5E5; /* 边框颜色调整 */
background-color: #F5F5F5;
/* 更接近Win10的背景颜色 */
border-left: 1px solid #E5E5E5;
/* 边框颜色调整 */
overflow-y: auto;
user-select: none;
box-sizing: content-box;
@ -58,19 +76,25 @@ function allClear() {
.message-title {
padding: 10px 20px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* 使用Win10默认字体 */
font-size: 14px; /* 字体大小调整 */
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
/* 使用Win10默认字体 */
font-size: 14px;
/* 字体大小调整 */
font-weight: bold;
border-bottom: 1px solid #E5E5E5; /* 边框颜色调整 */
border-bottom: 1px solid #E5E5E5;
/* 边框颜色调整 */
display: flex;
justify-content: space-between;
align-items: flex-end;
.allclear {
font-size: 12px; /* 字体大小调整 */
font-size: 12px;
/* 字体大小调整 */
cursor: pointer;
&:hover {
color: #0078D4; /* Win10主题蓝色 */
color: #0078D4;
/* Win10主题蓝色 */
}
}
}
@ -88,16 +112,22 @@ function allClear() {
}
.message-item {
padding: 10px 16px;
background-color: #FFFFFF; /* 消息项背景色调整 */
width: 100%; /* 设置为100%,以便内容自适应 */
padding: 15px 16px;
background-color: #FFFFFF;
/* 消息项背景色调整 */
width: 100%;
/* 设置为100%,以便内容自适应 */
overflow: hidden;
margin-bottom: 8px; /* 增加间距 */
border: 1px solid #E5E5E5; /* 边框颜色调整 */
border-radius: 4px; /* 添加圆角 */
margin-bottom: 8px;
/* 增加间距 */
border: 1px solid #E5E5E5;
/* 边框颜色调整 */
border-radius: 4px;
/* 添加圆角 */
transition: all 0.2s ease;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
/* 添加阴影效果 */
.message-item-title {
font-size: 14px;
font-weight: bold;
@ -107,18 +137,21 @@ function allClear() {
}
.message-item-body {
font-size: 13px; /* 字体大小调整 */
font-size: 13px;
/* 字体大小调整 */
}
&:hover {
border-color: #C7C7C7; /* 鼠标悬停时边框颜色变淡 */
border-color: #C7C7C7;
/* 鼠标悬停时边框颜色变淡 */
}
}
}
.fade-enter-active,
.fade-leave-active {
transition: all 0.3s ease; /* 修改过渡效果 */
transition: all 0.3s ease;
/* 修改过渡效果 */
}
.fade-enter-to,
@ -132,4 +165,35 @@ function allClear() {
opacity: 0;
transform: translateX(100%);
}
.new-content {
padding: 20px;
background-color: #F5F5F5;
border: 1px solid #E5E5E5;
border-radius: 4px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
.new-time {
margin-bottom: 10px;
font-size: 14px;
color: #666;
strong {
font-weight: bold;
color: #333;
}
}
.news-detail {
font-size: 16px;
line-height: 1.5;
color: #333;
white-space: pre-wrap;
}
.news-detail:deep(img){
max-width: 90%;
}
}
</style>

40
frontend/src/stores/notify.ts

@ -0,0 +1,40 @@
import { defineStore } from "pinia";
import { ref } from "vue";
import { getSystemConfig,fetchGet } from "@/system/config";
export const useNotifyStore = defineStore('notifyStore', () => {
const config = getSystemConfig();
const notifyList:any = ref([]);
const page = ref({
current: 1,
size: 10,
total: 0,
pages: 0,
})
async function getList(){
if(config.userType == 'person'){
return
}
const complition = await fetchGet(config.userInfo.url + '/news/list?page=' + page.value.current + '&limit='+ page.value.size)
if(!complition.ok){
return;
}
const data = await complition.json();
if(data.success){
page.value.total = data.data.total;
notifyList.value = data.data.list;
page.value.pages = Math.ceil(page.value.total / page.value.size)
}
}
const pageClick = async (pageNum: any) => {
//console.log(pageNum)
page.value.current = pageNum
await getList()
}
return {
notifyList,
getList,
page,
pageClick
}
})

40
frontend/src/system/notification/Notification.ts

@ -20,27 +20,27 @@ export class Notify {
this.close();
}, option.timeout || 5000);
// // 检查浏览器是否支持通知
// if ('Notification' in window) {
// // 请求通知权限
// Notification.requestPermission().then(function (permission) {
// if (permission === 'granted') {
// // 创建通知
// const notification = new Notification(option.title, {
// body: option.content,
// });
// 检查浏览器是否支持通知
if ('Notification' in window) {
// 请求通知权限
Notification.requestPermission().then(function (permission) {
if (permission === 'granted') {
// 创建通知
const notification = new Notification(option.title, {
body: option.content,
});
// // 点击通知时触发的事件
// notification.onclick = function () {
// // console.log('通知被点击了');
// };
// } else {
// // console.warn('用户拒绝了通知权限');
// }
// });
// } else {
// // console.error('浏览器不支持通知');
// }
// 点击通知时触发的事件
notification.onclick = function () {
// console.log('通知被点击了');
};
} else {
// console.warn('用户拒绝了通知权限');
}
});
} else {
// console.error('浏览器不支持通知');
}
}
close() {
const sys = useSystem();

Loading…
Cancel
Save