wyf před 5 měsíci
rodič
revize
6efccef43b

binární
src/assets/icons/alarm-icon.png


binární
src/assets/icons/close-icon.png


binární
src/assets/images/institute-safety/gd-hbimg.png


+ 14 - 0
src/components/custom-notivue/index.vue

@@ -0,0 +1,14 @@
+<template>
+  <Notivue v-slot="item">
+    <Notification :item="item"></Notification>
+  </Notivue>
+</template>
+<script lang="ts" setup>
+  import { Notivue } from 'notivue';
+  import Notification from './notification.vue';
+</script>
+<style>
+  :root {
+    --nv-root-top: 200px;
+  }
+</style>

+ 106 - 0
src/components/custom-notivue/notification.vue

@@ -0,0 +1,106 @@
+<template>
+  <div class="custom-notification">
+    <div class="titleWrapper">
+      <img class="alarmIcon" :src="alarmIcon" />
+      <div class="title"> 告警通知 </div>
+      <div class="close" @click.stop="item.clear">
+        <img :src="closeIcon" alt="close" />
+      </div>
+    </div>
+
+    <div class="contentWrapper">
+      <div
+        :style="{ 'background-image': `url('${item.props?.thumbnail}')` }"
+        class="thumbnail"
+        v-if="item.props?.thumbnail"
+      ></div>
+      <div class="info"></div>
+    </div>
+    <div class="footerWrapper"></div>
+  </div>
+</template>
+<script lang="ts" setup>
+  import type { NotivueItem } from 'notivue';
+  import closeIcon from '@/assets/icons/close-icon.png';
+  import alarmIcon from '@/assets/icons/alarm-icon.png';
+
+  export interface FollowerNotificationProps {
+    thumbnail: string;
+    type: string;
+    device: string;
+    place: string;
+    time: string;
+    onClick: () => unknown;
+  }
+
+  const props = defineProps<{
+    item: NotivueItem<FollowerNotificationProps>;
+  }>();
+
+  const handleClick = (item) => {
+    item.props.onClick();
+    item.clear();
+  };
+</script>
+<style scoped lang="scss">
+  .custom-notification {
+    background: url('@/assets/images/institute-safety/gd-hbimg.png') 100% 100%;
+    top: 150px;
+    display: flex;
+    position: relative;
+    padding: 20px 24px;
+    width: 490px;
+    height: 260px;
+    border-radius: 8px;
+    cursor: pointer;
+
+    .contentWrapper {
+      margin-left: 16px;
+    }
+
+    .titleWrapper {
+      display: flex;
+      align-items: center;
+    }
+    .title {
+      text-align: left;
+      font-size: 20px;
+      color: #fff;
+      margin-left: 5px;
+    }
+    .thumbnail {
+      width: 199px;
+      height: 112px;
+      border-radius: 4px;
+      background-position: center;
+      background-repeat: no-repeat;
+      background-size: cover;
+      display: inline-block;
+      flex-grow: 0;
+      flex-shrink: 0;
+      margin-top: 5px;
+    }
+    .close {
+      position: absolute;
+      right: -12px;
+      top: -12px;
+      width: 24px;
+      height: 24px;
+      cursor: pointer;
+
+      img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    // .textWrapper {
+    //   text-align: left;
+    //   color: rgba(255, 255, 255, 0.9);
+    // }
+
+    .alarmIcon {
+      width: 23px;
+      height: 23px;
+    }
+  }
+</style>

+ 14 - 0
src/components/custom-notivue/notivue-conf.ts

@@ -0,0 +1,14 @@
+import { createNotivue } from 'notivue';
+
+export const notivue = createNotivue({
+  position: 'top-center',
+  transition: 'none',
+  limit: 1,
+  enqueue: true,
+  teleportTo: '#company-home',
+  notifications: {
+    global: {
+      duration: 1000000000,
+    },
+  },
+});

+ 5 - 0
src/layout/FixedScreenLayout.vue

@@ -4,6 +4,7 @@
       <Nav :usePx="true" />
       <router-view />
     </div>
+    <CustomNotice />
   </div>
 </template>
 
@@ -12,6 +13,10 @@
   import { storeToRefs } from 'pinia';
   import usePageSizeStore from '@/hooks/usePageSizeStore';
   import Nav from '@/components/Nav.vue';
+  import useViolationNoticeStore from '@/views/institute-safety/modules/safety-company-home/stores/use-violation-notice-store';
+  import CustomNotice from '@/components/custom-notivue/index.vue';
+
+  useViolationNoticeStore();
 
   const pageSize = usePageSizeStore();
   const { ratio, rotate } = storeToRefs(pageSize);

+ 3 - 0
src/main.ts

@@ -9,6 +9,8 @@ import { setupElement, setupDirectives } from '@/plugins';
 import dayjs from 'dayjs';
 import 'dayjs/locale/zh-cn';
 import '@/utils/g6Extensions';
+import 'notivue/animations.css'; // Only needed if using built-in animations
+import { notivue } from '@/components/custom-notivue/notivue-conf';
 
 import 'virtual:svg-icons-register';
 
@@ -16,6 +18,7 @@ dayjs.locale('zh-cn');
 
 async function bootstrap() {
   const app = createApp(App);
+  app.use(notivue);
 
   // 全局完整引入 element 组件
   setupElement(app);

+ 10 - 2
src/views/institute-safety/modules/safety-company-home/CompanyHome.vue

@@ -1,7 +1,13 @@
 <template>
-  <div class="company-home">
+  <div class="company-home" id="company-home">
     <RealtimeSurveillance v-if="curCamera?.code" />
-    <img v-else style="width: 100%" src="@/assets/images/sfy.jpg" alt="" />
+    <img
+      v-else
+      style="width: 100%"
+      src="@/assets/images/sfy.jpg"
+      alt=""
+      @click="push.success('Your message has been successfully sent.')"
+    />
     <CompanyRating v-if="!curCamera?.code" />
     <ControlTab @open-surveillance-list="showSurveillanceList = true" @open-question-list="handleOpenQuestionList" />
     <SurveillanceList v-if="showSurveillanceList" @close="showSurveillanceList = false" />
@@ -25,6 +31,8 @@
   import { storeToRefs } from 'pinia';
   import { WORKSHOP_INFOS } from '../safety-workshop-list/constants';
 
+  import { push } from 'notivue';
+
   const showSurveillanceList = ref(false);
 
   useViolationNoticeCompany();

+ 45 - 21
src/views/institute-safety/modules/safety-company-home/hooks/use-violation-notice-company.ts

@@ -5,7 +5,7 @@ import useViolationNoticeStore, { getPlace, emitter } from '../stores/use-violat
 import { onUnmounted, onMounted } from 'vue';
 import dayjs from 'dayjs';
 import { push } from 'notivue';
-
+import TestImg from 'D:/任务/机场节点.2png.png';
 const useViolationRealtimeCompany = () => {
   /** 消息队列,最新的排在最前面,最老的排在最后面 */
   // 报警消息最后返回数据的id
@@ -17,32 +17,56 @@ const useViolationRealtimeCompany = () => {
   const showNotice = () => {
     const showItem = violationStore.getLastNotice();
     // 从数组最末尾弹出消息
-    if (!showItem) return;
 
-    // 只显示当天的时分秒
-    const renderTime = dayjs(showItem.createdAt).format('HH:mm:ss');
-    const renderPlace = getPlace([showItem.workshopName, showItem.workspaceName]);
-    push.success({
-      props: {
-        thumbnail: showItem.pictures?.[0],
-        title: showItem.title,
-        message: `<div>
+    if (!showItem) {
+      const renderTime = dayjs().format('HH:mm:ss');
+      const renderPlace = 'test place';
+      push.success({
+        props: {
+          thumbnail: TestImg,
+          title: '报警标题',
+          message: `<div>
       <div>地点:${renderPlace}</div>
       <div>时间:${renderTime}</div>
       </div>`,
-        onClick: () => {
-          // 这里打开问题列表
+          onClick: () => {
+            // 这里打开问题列表
+          },
         },
-      },
-      onAutoClear(item) {
-        showNotice();
-      },
-      onManualClear(item) {
-        showNotice();
-      },
-    });
-  };
+        onAutoClear(item) {
+          showNotice();
+        },
+        onManualClear(item) {
+          showNotice();
+        },
+      });
+    }
+    // if (!showItem) return;
 
+    // 只显示当天的时分秒
+    // const renderTime = dayjs(showItem.createdAt).format('HH:mm:ss');
+    // const renderPlace = getPlace([showItem.workshopName, showItem.workspaceName]);
+    // push.success({
+    //   props: {
+    //     thumbnail: showItem.pictures?.[0],
+    //     title: showItem.title,
+    //     message: `<div>
+    //   <div>地点:${renderPlace}</div>
+    //   <div>时间:${renderTime}</div>
+    //   </div>`,
+    //     onClick: () => {
+    //       // 这里打开问题列表
+    //     },
+    //   },
+    //   onAutoClear(item) {
+    //     showNotice();
+    //   },
+    //   onManualClear(item) {
+    //     showNotice();
+    //   },
+    // });
+  };
+  showNotice();
   emitter.on('showNotice', showNotice);
 
   const getViolationsRealtime = () => {