|
|
@@ -1,335 +1,176 @@
|
|
|
+<script lang="ts" setup>
|
|
|
+import { ref, onMounted, computed, watch } from "vue"
|
|
|
+import { getAssetPath } from "@/core/helpers/assets"
|
|
|
+import Rs from "@/core/services/RequestService"
|
|
|
+import appStore from "@/stores"
|
|
|
+import router from "@/router"
|
|
|
+const total = ref(0)
|
|
|
+const curPage = ref(0)
|
|
|
+const perPage = ref(10)
|
|
|
+const params = computed(() => {
|
|
|
+ return {
|
|
|
+ pageIndex: curPage.value,
|
|
|
+ pageSize: perPage.value,
|
|
|
+ params: { readFlag: false },
|
|
|
+ }
|
|
|
+})
|
|
|
+let reLoadTimre: any
|
|
|
+const listBox = ref<HTMLElement>()
|
|
|
+const dataList = ref<Array<any>>([])
|
|
|
+function jump(item: any) {
|
|
|
+ read(item.id)
|
|
|
+ switch (appStore.authStore.user?.userType) {
|
|
|
+ case "2": //企业账号
|
|
|
+ if (item.eventType == "000100003" || item.eventType == "000100005" || item.eventType == "000100007") {
|
|
|
+ router.push({
|
|
|
+ path: "/Abnormal/AbnormalList/strongWarn",
|
|
|
+ query: {
|
|
|
+ id: item.warn_id,
|
|
|
+ type: item.eventType,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ } else if (item.eventType == "000100006") {
|
|
|
+ router.push({
|
|
|
+ path: "/Abnormal/AbnormalList/disConnect",
|
|
|
+ query: {
|
|
|
+ id: item.warn_id,
|
|
|
+ type: item.eventType,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ router.push({
|
|
|
+ path: "/Abnormal/AbnormalList/overdueWarn",
|
|
|
+ query: {
|
|
|
+ id: item.warn_id,
|
|
|
+ type: item.eventType,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case "0": //系统管理员
|
|
|
+ case "1": //政府账号
|
|
|
+ default:
|
|
|
+ if (item.eventType == "000100003" || item.eventType == "000100005" || item.eventType == "000100007") {
|
|
|
+ router.push({
|
|
|
+ path: "/warn/warnList/concentrationWarn",
|
|
|
+ query: {
|
|
|
+ id: item.warn_id,
|
|
|
+ type: item.eventType,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ } else if (item.eventType == "000100006") {
|
|
|
+ router.push({
|
|
|
+ path: "/warn/warnList/offlineWarn",
|
|
|
+ query: {
|
|
|
+ id: item.warn_id,
|
|
|
+ type: item.eventType,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ router.push({
|
|
|
+ path: "/warn/warnList/overdueWarn",
|
|
|
+ query: {
|
|
|
+ id: item.warn_id,
|
|
|
+ type: item.eventType,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ break
|
|
|
+ }
|
|
|
+}
|
|
|
+function read(id: string) {
|
|
|
+ Rs.get(`sys/pushEvent/read?noticeId=${id}`).then(() => {
|
|
|
+ clearTimeout(reLoadTimre)
|
|
|
+ reLoad()
|
|
|
+ })
|
|
|
+}
|
|
|
+function readAll() {
|
|
|
+ Rs.get(`sys/pushEvent/clear`).then(() => {
|
|
|
+ clearTimeout(reLoadTimre)
|
|
|
+ reLoad()
|
|
|
+ })
|
|
|
+}
|
|
|
+function load() {
|
|
|
+ curPage.value++
|
|
|
+ Rs.post("sys/pushEvent/getList", { data: params.value, successAlert: false }).then((res: any) => {
|
|
|
+ console.log("NOTIFI", res.data)
|
|
|
+ dataList.value.push(...res.data)
|
|
|
+ total.value = res.total
|
|
|
+ })
|
|
|
+}
|
|
|
+function reLoad() {
|
|
|
+ curPage.value = 0
|
|
|
+ load()
|
|
|
+ dataList.value = []
|
|
|
+ reLoadTimre = setTimeout(reLoad, 1000 * 60 * 3)
|
|
|
+}
|
|
|
+const onScroll = () => {
|
|
|
+ if (listBox.value) {
|
|
|
+ const diff = listBox.value.scrollHeight - (listBox.value.scrollTop + listBox.value.clientHeight)
|
|
|
+ //console.log("TOP", diff, listBox.value?.scrollTop, listBox.value?.scrollHeight, listBox.value?.clientHeight)
|
|
|
+ if (diff <= 0) {
|
|
|
+ load()
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+watch(listBox, () => {
|
|
|
+ if (listBox.value) {
|
|
|
+ listBox.value.removeEventListener("scroll", onScroll, true)
|
|
|
+ listBox.value.addEventListener("scroll", onScroll, true)
|
|
|
+ }
|
|
|
+})
|
|
|
+onMounted(() => {
|
|
|
+ reLoad()
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
<template>
|
|
|
- <!--begin::Menu-->
|
|
|
- <div class="menu menu-sub menu-sub-dropdown menu-column w-350px w-lg-375px" data-kt-menu="true">
|
|
|
- <!--begin::Heading-->
|
|
|
+ <div
|
|
|
+ class="btn btn-icon btn-custom btn-icon-muted btn-active-light btn-active-color-primary w-30px h-30px w-md-40px h-md-40px position-relative"
|
|
|
+ data-kt-menu-trigger="click"
|
|
|
+ data-kt-menu-attach="parent"
|
|
|
+ data-kt-menu-placement="bottom-end"
|
|
|
+ >
|
|
|
+ <span class="svg-icon svg-icon-1">
|
|
|
+ <inline-svg :src="getAssetPath('media/icons/duotune/general/gen022.svg')" />
|
|
|
+ </span>
|
|
|
+ <span
|
|
|
+ v-if="total > 0"
|
|
|
+ class="bullet bullet-dot bg-warning h-6px w-6px position-absolute translate-middle top-0 start-50 animation-blink"
|
|
|
+ ></span>
|
|
|
+ </div>
|
|
|
+ <div class="menu menu-sub menu-sub-dropdown menu-column w-350px w-lg-400px" data-kt-menu="true">
|
|
|
<div
|
|
|
class="d-flex flex-column bgi-no-repeat rounded-top"
|
|
|
:style="`background-image: url('${getAssetPath('/media/misc/menu-header-bg.jpg')}')`"
|
|
|
>
|
|
|
- <!--begin::Title-->
|
|
|
- <h3 class="text-white fw-semobold px-9 mt-10 mb-6">
|
|
|
- Notifications
|
|
|
- <span class="fs-8 opacity-75 ps-3">24 reports</span>
|
|
|
+ <h3 class="text-white fw-semobold px-9 mt-10 mb-6 d-flex align-items-center justify-content-between">
|
|
|
+ <span>
|
|
|
+ 消息通知
|
|
|
+ <span class="fs-8 opacity-75 ps-3" v-if="total > 0">{{ total }} 条</span>
|
|
|
+ </span>
|
|
|
+ <span class="svg-icon svg-icon-1 btn p-1" @click="readAll" v-tooltip title="清空通知">
|
|
|
+ <inline-svg :src="getAssetPath('media/icons/duotune/general/gen064.svg')" />
|
|
|
+ </span>
|
|
|
</h3>
|
|
|
- <!--end::Title-->
|
|
|
-
|
|
|
- <!--begin::Tabs-->
|
|
|
- <ul class="nav nav-line-tabs nav-line-tabs-2x nav-stretch fw-semobold px-9">
|
|
|
- <li class="nav-item">
|
|
|
- <a
|
|
|
- class="nav-link text-white opacity-75 opacity-state-100 pb-4"
|
|
|
- data-bs-toggle="tab"
|
|
|
- href="#kt_topbar_notifications_1"
|
|
|
- >
|
|
|
- Alerts
|
|
|
- </a>
|
|
|
- </li>
|
|
|
-
|
|
|
- <li class="nav-item">
|
|
|
- <a
|
|
|
- class="nav-link text-white opacity-75 opacity-state-100 pb-4 active"
|
|
|
- data-bs-toggle="tab"
|
|
|
- href="#kt_topbar_notifications_2"
|
|
|
- >
|
|
|
- Updates
|
|
|
- </a>
|
|
|
- </li>
|
|
|
-
|
|
|
- <li class="nav-item">
|
|
|
- <a
|
|
|
- class="nav-link text-white opacity-75 opacity-state-100 pb-4"
|
|
|
- data-bs-toggle="tab"
|
|
|
- href="#kt_topbar_notifications_3"
|
|
|
- >
|
|
|
- Logs
|
|
|
- </a>
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- <!--end::Tabs-->
|
|
|
</div>
|
|
|
- <!--end::Heading-->
|
|
|
-
|
|
|
- <!--begin::Tab content-->
|
|
|
- <div class="tab-content">
|
|
|
- <!--begin::Tab panel-->
|
|
|
- <div class="tab-pane fade" id="kt_topbar_notifications_1" role="tabpanel">
|
|
|
- <!--begin::Items-->
|
|
|
- <div class="scroll-y mh-325px my-5 px-8">
|
|
|
- <template v-for="(item, index) in data1" :key="index">
|
|
|
- <!--begin::Item-->
|
|
|
- <div class="d-flex flex-stack py-4">
|
|
|
- <!--begin::Section-->
|
|
|
- <div class="d-flex align-items-center">
|
|
|
- <!--begin::Symbol-->
|
|
|
- <div class="symbol symbol-35px me-4">
|
|
|
- <span :class="`bg-light-${item.state}`" class="symbol-label">
|
|
|
- <span :class="`svg-icon-${item.state}`" class="svg-icon svg-icon-2">
|
|
|
- <inline-svg :src="item.icon" />
|
|
|
- </span>
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- <!--end::Symbol-->
|
|
|
-
|
|
|
- <!--begin::Title-->
|
|
|
- <div class="mb-0 me-2">
|
|
|
- <a href="#" class="fs-6 text-gray-800 text-hover-primary fw-bold">{{ item.title }}</a>
|
|
|
- <div class="text-gray-400 fs-7">
|
|
|
- {{ item.description }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!--end::Title-->
|
|
|
- </div>
|
|
|
- <!--end::Section-->
|
|
|
-
|
|
|
- <!--begin::Label-->
|
|
|
- <span class="badge badge-light fs-8">{{ item.time }}</span>
|
|
|
- <!--end::Label-->
|
|
|
- </div>
|
|
|
- <!--end::Item-->
|
|
|
- </template>
|
|
|
- </div>
|
|
|
- <!--end::Items-->
|
|
|
-
|
|
|
- <!--begin::View more-->
|
|
|
- <div class="py-3 text-center border-top">
|
|
|
- <a href="#" class="btn btn-color-gray-600 btn-active-color-primary">
|
|
|
- View All
|
|
|
- <span class="svg-icon svg-icon-5">
|
|
|
- <inline-svg :src="getAssetPath('media/icons/duotune/arrows/arr064.svg')" />
|
|
|
- </span>
|
|
|
- </a>
|
|
|
- </div>
|
|
|
- <!--end::View more-->
|
|
|
- </div>
|
|
|
- <!--end::Tab panel-->
|
|
|
-
|
|
|
- <!--begin::Tab panel-->
|
|
|
- <div class="tab-pane fade show active" id="kt_topbar_notifications_2" role="tabpanel">
|
|
|
- <!--begin::Wrapper-->
|
|
|
- <div class="d-flex flex-column px-9">
|
|
|
- <!--begin::Section-->
|
|
|
- <div class="pt-10 pb-0">
|
|
|
- <!--begin::Title-->
|
|
|
- <h3 class="text-dark text-center fw-bold">Get Pro Access</h3>
|
|
|
- <!--end::Title-->
|
|
|
-
|
|
|
- <!--begin::Text-->
|
|
|
- <div class="text-center text-gray-600 fw-semobold pt-1">
|
|
|
- Outlines keep you honest. They stoping you from amazing poorly about drive
|
|
|
- </div>
|
|
|
- <!--end::Text-->
|
|
|
-
|
|
|
- <!--begin::Action-->
|
|
|
- <div class="text-center mt-5 mb-9">
|
|
|
- <a
|
|
|
- href="#"
|
|
|
- class="btn btn-sm btn-primary px-6"
|
|
|
- data-bs-toggle="modal"
|
|
|
- data-bs-target="#kt_modal_upgrade_plan"
|
|
|
- >
|
|
|
- Upgrade
|
|
|
- </a>
|
|
|
- </div>
|
|
|
- <!--end::Action-->
|
|
|
+ <div ref="listBox" v-if="dataList.length" class="h-500px overflow-auto p-2">
|
|
|
+ <template v-for="(v, i) in dataList" :key="i">
|
|
|
+ <div class="d-flex px-3 align-items-center" @click="jump(v)" style="cursor: pointer">
|
|
|
+ <span class="svg-icon svg-icon-1 svg-icon-warning ps-2 pe-5">
|
|
|
+ <inline-svg :src="getAssetPath('media/icons/duotune/abstract/abs038.svg')" />
|
|
|
+ </span>
|
|
|
+ <div class="d-flex flex-column">
|
|
|
+ <span class="text-gray-700">{{ v.content }}</span>
|
|
|
+ <span class="text-gray-600">{{ v.time }}</span>
|
|
|
</div>
|
|
|
- <!--end::Section-->
|
|
|
-
|
|
|
- <!--begin::Illustration-->
|
|
|
- <img class="mw-100 mh-200px" alt="metronic" :src="getIllustrationsPath('1.png')" />
|
|
|
- <!--end::Illustration-->
|
|
|
- </div>
|
|
|
- <!--end::Wrapper-->
|
|
|
- </div>
|
|
|
- <!--end::Tab panel-->
|
|
|
-
|
|
|
- <!--begin::Tab panel-->
|
|
|
- <div class="tab-pane fade" id="kt_topbar_notifications_3" role="tabpanel">
|
|
|
- <!--begin::Items-->
|
|
|
- <div class="scroll-y mh-325px my-5 px-8">
|
|
|
- <template v-for="(item, index) in data2" :key="index">
|
|
|
- <!--begin::Item-->
|
|
|
- <div class="d-flex flex-stack py-4">
|
|
|
- <!--begin::Section-->
|
|
|
- <div class="d-flex align-items-center me-2">
|
|
|
- <!--begin::Code-->
|
|
|
- <span class="w-70px badge me-4" :class="`badge-light-${item.state}`">{{ item.code }}</span>
|
|
|
- <!--end::Code-->
|
|
|
-
|
|
|
- <!--begin::Title-->
|
|
|
- <a href="#" class="text-gray-800 text-hover-primary fw-semobold">{{ item.message }}</a>
|
|
|
- <!--end::Title-->
|
|
|
- </div>
|
|
|
- <!--end::Section-->
|
|
|
-
|
|
|
- <!--begin::Label-->
|
|
|
- <span class="badge badge-light fs-8">{{ item.time }}</span>
|
|
|
- <!--end::Label-->
|
|
|
- </div>
|
|
|
- <!--end::Item-->
|
|
|
- </template>
|
|
|
- </div>
|
|
|
- <!--end::Items-->
|
|
|
-
|
|
|
- <!--begin::View more-->
|
|
|
- <div class="py-3 text-center border-top">
|
|
|
- <a href="#" class="btn btn-color-gray-600 btn-active-color-primary">
|
|
|
- View All
|
|
|
- <span class="svg-icon-svg-icon-5">
|
|
|
- <inline-svg :src="getAssetPath('media/icons/duotune/arrows/arr064.svg')" />
|
|
|
- </span>
|
|
|
- </a>
|
|
|
</div>
|
|
|
- <!--end::View more-->
|
|
|
- </div>
|
|
|
- <!--end::Tab panel-->
|
|
|
+ <div class="separator my-2"></div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <div v-else class="h-150px d-flex justify-content-center flex-column align-items-center">
|
|
|
+ <img class="mb-2" :src="getAssetPath('media/table/empty.svg')" />
|
|
|
+ <span class="text-gray-500">暂无消息通知</span>
|
|
|
</div>
|
|
|
- <!--end::Tab content-->
|
|
|
</div>
|
|
|
- <!--end::Menu-->
|
|
|
</template>
|
|
|
-
|
|
|
-<script lang="ts">
|
|
|
-import { getAssetPath } from "@/core/helpers/assets"
|
|
|
-import { defineComponent } from "vue"
|
|
|
-import { getIllustrationsPath } from "@/core/helpers/assets"
|
|
|
-
|
|
|
-export default defineComponent({
|
|
|
- name: "notifications-menu",
|
|
|
- components: {},
|
|
|
- setup() {
|
|
|
- const data1 = [
|
|
|
- {
|
|
|
- title: "Project Alice",
|
|
|
- description: "Phase 1 development",
|
|
|
- time: "1 hr",
|
|
|
- icon: getAssetPath("media/icons/duotune/technology/teh008.svg"),
|
|
|
- state: "primary",
|
|
|
- },
|
|
|
- {
|
|
|
- title: "HR Confidential",
|
|
|
- description: "Confidential staff documents",
|
|
|
- time: "2 hrs",
|
|
|
- icon: getAssetPath("media/icons/duotune/general/gen044.svg"),
|
|
|
- state: "danger",
|
|
|
- },
|
|
|
- {
|
|
|
- title: "Company HR",
|
|
|
- description: "Corporeate staff profiles",
|
|
|
- time: "5 hrs",
|
|
|
- icon: getAssetPath("media/icons/duotune/finance/fin006.svg"),
|
|
|
- state: "warning",
|
|
|
- },
|
|
|
- {
|
|
|
- title: "Project Redux",
|
|
|
- description: "New frontend admin theme",
|
|
|
- time: "2 days",
|
|
|
- icon: getAssetPath("media/icons/duotune/files/fil023.svg"),
|
|
|
- state: "success",
|
|
|
- },
|
|
|
- {
|
|
|
- title: "Project Breafing",
|
|
|
- description: "Product launch status update",
|
|
|
- time: "21 Jan",
|
|
|
- icon: getAssetPath("media/icons/duotune/maps/map001.svg"),
|
|
|
- state: "primary",
|
|
|
- },
|
|
|
- {
|
|
|
- title: "Banner Assets",
|
|
|
- description: "Collection of banner images",
|
|
|
- time: "21 Jan",
|
|
|
- icon: getAssetPath("media/icons/duotune/general/gen006.svg"),
|
|
|
- state: "info",
|
|
|
- },
|
|
|
- {
|
|
|
- title: "Icon Assets",
|
|
|
- description: "Collection of SVG icons",
|
|
|
- time: "20 March",
|
|
|
- icon: getAssetPath("media/icons/duotune/art/art002.svg"),
|
|
|
- state: "warning",
|
|
|
- },
|
|
|
- ]
|
|
|
-
|
|
|
- const data2 = [
|
|
|
- {
|
|
|
- code: "200 OK",
|
|
|
- state: "success",
|
|
|
- message: "New order",
|
|
|
- time: "Just now",
|
|
|
- },
|
|
|
- {
|
|
|
- code: "500 ERR",
|
|
|
- state: "danger",
|
|
|
- message: "New customer",
|
|
|
- time: "2 hrs",
|
|
|
- },
|
|
|
- {
|
|
|
- code: "200 OK",
|
|
|
- state: "success",
|
|
|
- message: "Payment process",
|
|
|
- time: "5 hrs",
|
|
|
- },
|
|
|
- {
|
|
|
- code: "300 WRN",
|
|
|
- state: "warning",
|
|
|
- message: "Search query",
|
|
|
- time: "2 days",
|
|
|
- },
|
|
|
- {
|
|
|
- code: "200 OK",
|
|
|
- state: "success",
|
|
|
- message: "API connection",
|
|
|
- time: "1 week",
|
|
|
- },
|
|
|
- {
|
|
|
- code: "200 OK",
|
|
|
- state: "success",
|
|
|
- message: "Database restore",
|
|
|
- time: "Mar 5",
|
|
|
- },
|
|
|
- {
|
|
|
- code: "300 WRN",
|
|
|
- state: "warning",
|
|
|
- message: "System update",
|
|
|
- time: "May 15",
|
|
|
- },
|
|
|
- {
|
|
|
- code: "300 WRN",
|
|
|
- state: "warning",
|
|
|
- message: "Server OS update",
|
|
|
- time: "Apr 3",
|
|
|
- },
|
|
|
- {
|
|
|
- code: "300 WRN",
|
|
|
- state: "warning",
|
|
|
- message: "API rollback",
|
|
|
- time: "Jun 30",
|
|
|
- },
|
|
|
- {
|
|
|
- code: "500 ERR",
|
|
|
- state: "danger",
|
|
|
- message: "Refund process",
|
|
|
- time: "Jul 10",
|
|
|
- },
|
|
|
- {
|
|
|
- code: "500 ERR",
|
|
|
- state: "danger",
|
|
|
- message: "Withdrawal process",
|
|
|
- time: "Sep 10",
|
|
|
- },
|
|
|
- {
|
|
|
- code: "500 ERR",
|
|
|
- state: "danger",
|
|
|
- message: "Mail tasks",
|
|
|
- time: "Dec 10",
|
|
|
- },
|
|
|
- ]
|
|
|
-
|
|
|
- return {
|
|
|
- data1,
|
|
|
- data2,
|
|
|
- getIllustrationsPath,
|
|
|
- getAssetPath,
|
|
|
- }
|
|
|
- },
|
|
|
-})
|
|
|
-</script>
|