1.修改 推送数据内容

2.修改 web-ui 推送组件
This commit is contained in:
Wang Chen Chen
2023-10-30 15:03:16 +08:00
parent f92ac1b168
commit 74e6cbf211
11 changed files with 88 additions and 50 deletions

View File

@@ -21,6 +21,8 @@ import org.springframework.security.core.context.SecurityContextHolder;
import java.time.LocalDateTime;
import java.util.Set;
import static com.xaaef.molly.system.cron.TestCronAsync.randomChinese;
@SpringBootTest
public class MollyApplicationTests {
@@ -75,13 +77,4 @@ public class MollyApplicationTests {
}
}
private String randomChinese(int len) {
var chars = new char[len];
for (int i = 0; i < len; i++) {
chars[i] = RandomUtil.randomChinese();
}
return new String(chars);
}
}

View File

@@ -3,6 +3,7 @@ package com.xaaef.molly.system.cron;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.xaaef.molly.auth.service.JwtTokenService;
import com.xaaef.molly.common.util.IdUtils;
import com.xaaef.molly.common.util.JsonUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -10,8 +11,10 @@ import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
* <p>
@@ -40,35 +43,58 @@ public class TestCronAsync {
"I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z");
private final static AtomicInteger count1 = new AtomicInteger(8760);
@Scheduled(fixedRate = 5000)
@Scheduled(fixedRate = 30000)
public void cron1() {
if (!tokenService.listLoginIds().isEmpty()) {
var ind = count1.decrementAndGet();
var map = Map.of(
"id", RandomUtil.randomInt(10000, 99999),
"msg", RandomUtil.randomString(12),
"dataArr", RandomUtil.randomEleSet(arrs, 3)
"id", IdUtils.getStandaloneId(),
"title", String.format("广播消息=>%d", RandomUtil.randomInt(10000, 99999)),
"message", randomChinese(20),
"createTime", LocalDateTime.now().minusHours(ind)
);
var json = JsonUtils.toJson(map);
// 广播通知 给所有用户
messagingTemplate.convertAndSend("/topic/broadcast/notice", json);
if (ind == 1) {
count2.set(8760);
}
}
}
@Scheduled(fixedRate = 8000)
private final static AtomicInteger count2 = new AtomicInteger(8760);
@Scheduled(fixedRate = 60000)
public void cron2() {
var ind = count2.decrementAndGet();
tokenService.listLoginUsers().forEach(user -> {
var map = Map.of(
"id", RandomUtil.randomInt(10000, 99999),
"msg", StrUtil.format("hello : {} => {}", user.getUsername(), RandomUtil.randomString(15)),
"dataArr", RandomUtil.randomEleSet(arrs, 3)
"id", IdUtils.getStandaloneId(),
"title", String.format("推送消息=>%d", RandomUtil.randomInt(10000, 99999)),
"message", randomChinese(20),
"createTime", LocalDateTime.now().minusHours(ind)
);
var json = JsonUtils.toJson(map);
// 推送给指定用户 , /user/queue/single/push
messagingTemplate.convertAndSendToUser(user.getLoginId(), "/queue/single/push", json);
if (ind == 1) {
count2.set(8760);
}
});
}
public static String randomChinese(int len) {
var chars = new char[len];
for (int i = 0; i < len; i++) {
chars[i] = RandomUtil.randomChinese();
}
return new String(chars);
}
}

View File

@@ -1,8 +1,8 @@
<script lang="ts" setup>
import { type ListItem } from "./data"
import { IPushMessage } from "@/types/base"
interface Props {
list: ListItem[]
list: IPushMessage[]
}
const props = defineProps<Props>()
@@ -14,19 +14,13 @@ const props = defineProps<Props>()
<template #header>
<div class="card-header">
<div>
<span>
<span class="card-title">{{ item.title }}</span>
<el-tag v-if="item.extra" :type="item.status" effect="plain" size="small">{{ item.extra }}</el-tag>
</span>
<div class="card-time">{{ item.datetime }}</div>
</div>
<div v-if="item.avatar" class="card-avatar">
<img :src="item.avatar" width="34" />
<span class="card-title">{{ item.title }}</span>
<div class="card-time">{{ item.createTime }}</div>
</div>
</div>
</template>
<div class="card-body">
{{ item.description ?? "No Data" }}
{{ item.message ?? "No Data" }}
</div>
</el-card>
</template>
@@ -34,25 +28,29 @@ const props = defineProps<Props>()
<style lang="scss" scoped>
.card-container {
margin-bottom: 10px;
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
.card-title {
font-weight: bold;
margin-right: 10px;
}
.card-time {
font-size: 12px;
color: grey;
}
.card-avatar {
display: flex;
align-items: center;
}
}
.card-body {
font-size: 12px;
}
}
</style>
}</style>

View File

@@ -3,14 +3,17 @@ import { ref, computed } from "vue"
import { ElMessage } from "element-plus"
import { Bell } from "@element-plus/icons-vue"
import NotifyList from "./NotifyList.vue"
import { type ListItem, notifyData, messageData, todoData } from "./data"
import { useNoticeStoreHook } from "@/store/modules/notice"
import { IPushMessage } from "@/types/base"
const { broadcast, pushNotices } = useNoticeStoreHook()
type TabName = "通知" | "消息" | "待办"
interface DataItem {
name: TabName
type: "primary" | "success" | "warning" | "danger" | "info"
list: ListItem[]
list: IPushMessage[]
}
/** 角标当前值 */
@@ -29,19 +32,19 @@ const data = ref<DataItem[]>([
{
name: "通知",
type: "primary",
list: notifyData
list: broadcast
},
// 消息数据
{
name: "消息",
type: "danger",
list: messageData
list: pushNotices
},
// 待办数据
{
name: "待办",
type: "warning",
list: todoData
list: []
}
])

View File

@@ -45,6 +45,7 @@
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:page-sizes="[5, 10, 20, 50]"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@@ -73,7 +74,7 @@ const loading = ref(false)
const params = reactive({
pageTotal: 0,
pageIndex: 1,
pageSize: 10,
pageSize: 5,
keywords: ""
})

View File

@@ -44,6 +44,7 @@
<el-pagination
v-model:current-page="params.pageIndex"
:page-size="params.pageSize"
:page-sizes="[5, 10, 20, 50]"
:background="true"
layout="sizes, total, prev, pager, next, jumper"
:total="params.pageTotal"
@@ -73,7 +74,7 @@ const loading = ref(false)
const params = reactive({
pageTotal: 0,
pageIndex: 1,
pageSize: 10,
pageSize: 5,
keywords: ""
})

View File

@@ -3,7 +3,7 @@ import { type RouteLocationNormalized } from "vue-router"
const loginUrl = "/login"
/** 免登录白名单(匹配路由 path */
const whiteListByPath: string[] = ["/login"]
const whiteListByPath: string[] = [loginUrl]
/** 免登录白名单(匹配路由 name */
const whiteListByName: string[] = []

View File

@@ -14,6 +14,7 @@ interface PaginationData {
pageSizes?: number[]
pageSize?: number
layout?: string
keywords?: string
}
/** 默认的分页参数 */
@@ -25,16 +26,20 @@ const defaultPaginationData: DefaultPaginationData = {
layout: "total, sizes, prev, pager, next, jumper"
}
export function usePagination(initialPaginationData: PaginationData = {}) {
export function usePagination(fn: Function, initialPaginationData: PaginationData = {}) {
/** 合并分页参数 */
const paginationData = reactive({ ...defaultPaginationData, ...initialPaginationData })
/** 改变当前页码 */
const handleCurrentChange = (value: number) => {
paginationData.currentPage = value
fn()
}
/** 改变页面大小 */
const handleSizeChange = (value: number) => {
paginationData.pageSize = value
fn()
}
return { paginationData, handleCurrentChange, handleSizeChange }

View File

@@ -5,12 +5,12 @@ import { useTenantStoreHook } from "@/store/modules/tenant"
const projectStore = useProjectStoreHook()
const tenantStore = useTenantStoreHook()
// 租户ID 和 项目 组成的 唯一ID
const currentOnlyId = computed(() => {
return tenantStore.getCurrentTenantId() + projectStore.getCurrentProjectId()
})
export function useTenantAndProject() {
// 租户ID 和 项目 组成的 唯一ID
const currentOnlyId = computed(() => {
return tenantStore.getCurrentTenantId() + projectStore.getCurrentProjectId()
})
return {
currentOnlyId
}

View File

@@ -7,13 +7,14 @@ import SockJS from "sockjs-client/dist/sockjs.min.js"
import { getToken } from "@/utils/cache/cookies"
import { useTenantStoreHook } from "./tenant"
import { getEnvBaseURL } from "@/utils"
import { IPushMessage } from "@/types/base"
export const useNoticeStore = defineStore("notice", () => {
// 广播消息
const broadcast = ref<any[]>([])
const broadcast = ref<IPushMessage[]>([])
// 推送消息
const pushNotices = ref<any[]>([])
const pushNotices = ref<IPushMessage[]>([])
const stompClientActive = ref<boolean>(false)
@@ -51,15 +52,13 @@ export const useNoticeStore = defineStore("notice", () => {
// 订阅广播主题
stompClientAgent.subscribe("/topic/broadcast/notice", (resp) => {
const result = JSON.parse(resp.body)
console.log("广播 :>> ", result)
const result = JSON.parse(resp.body) as IPushMessage
broadcast.value?.push(result)
})
// 订阅推送主题
stompClientAgent.subscribe("/user/queue/single/push", (resp) => {
const result = JSON.parse(resp.body)
console.log("推送 :>> ", result)
const result = JSON.parse(resp.body) as IPushMessage
pushNotices.value?.push(result)
})
}

View File

@@ -99,3 +99,15 @@ export interface IUpdateMenus {
/** 全部的菜单 */
all: ISimpleMenu[]
}
// 推送消息
export interface IPushMessage {
/** ID */
id: number
/** 标题 */
title: string
/** 消息 */
message: string
/** 创建时间 */
createTime: string
}