123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- <template>
- <div class="view-alarm">
- <a-row class="grid-demo" style="margin-bottom: 16px">
- <a-col flex="100px">
- <div>{{ $t('previewList.bjlx') }}</div>
- </a-col>
- <a-col flex="auto">
- <div>{{ data.Name }}</div>
- </a-col>
- </a-row>
- <a-row class="grid-demo" style="margin-bottom: 16px">
- <a-col flex="100px">
- <div>{{ $t('previewList.bjsj') }}</div>
- </a-col>
- <a-col flex="auto">
- <div>{{ data.timeN }}</div>
- </a-col>
- </a-row>
- <template v-if="isShowCl">
- <a-divider />
- <a-row class="grid-demo" justify="center" style="margin-bottom: 16px">
- <a-col :span="19">
- <a-radio-group v-model="alarmArchiving" type="button" size="small">
- <a-radio
- v-for="(item, i) in alarmArchivingOptions"
- :key="i"
- :value="item.value"
- ><div style="display: flex; align-items: center; gap: 4px"
- ><Icon :icon="item.icon" />{{ item.label }}</div
- ></a-radio
- >
- <a-button size="small" @click="() => (alarmArchiving = '0')">
- <template #icon>
- <icon-refresh />
- </template>
- </a-button>
- </a-radio-group>
- </a-col>
- </a-row>
- </template>
- <a-divider />
- <div class="view-alarm-pic">
- <img id="image" class="view-pic" :src="data.tImg" alt="Picture" />
- </div>
- <div id="image-preview">
- <div v-if="loading" class="va-loading">
- <a-spin dot />
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { onMounted, onUnmounted, ref, watch } from 'vue';
- import { Icon } from '@iconify/vue';
- import { getSetArchived } from '@/api/system';
- import Viewer from 'viewerjs';
- import 'viewerjs/dist/viewer.css';
- interface DataProps {
- [key: string]: any;
- }
- const props = defineProps<{
- data: DataProps;
- guid: any;
- isShowCl: boolean;
- }>();
- const emits = defineEmits(['alarmArchiving']);
- const viewer = ref<Viewer | null>(null);
- const loading = ref(true);
- let url: string;
- const init = () => {
- const canvas = document.createElement('canvas');
- const { imgJson, img } = props.data;
- canvas.width = imgJson.imageWidth;
- canvas.height = imgJson.imageHeight;
- const ctx: CanvasRenderingContext2D | null = canvas.getContext('2d');
- const imgObj = new Image(imgJson.imageWidth, imgJson.imageHeight);
- imgObj.setAttribute('crossOrigin', 'anonymous');
- imgObj.src = img;
- imgObj.onload = () => {
- if (ctx) {
- ctx.drawImage(imgObj, 0, 0);
- imgJson.resultData.objectList.forEach((item: any) => {
- // 绘制矩形
- ctx.strokeStyle = 'red';
- ctx.lineWidth = 4;
- ctx.strokeRect(
- item.rect.x,
- item.rect.y,
- item.rect.width,
- item.rect.height
- );
- // 绘制标题
- ctx.fillStyle = 'red';
- ctx.fillRect(
- item.rect.x - 2,
- item.rect.y - 30,
- item.rect.width + 4,
- 40
- );
- // 在矩形框内绘制矩形文字
- ctx.fillStyle = 'white';
- ctx.font = '26px Arial';
- ctx.fillText(props.data.Name, item.rect.x + 6, item.rect.y - 4);
- });
- }
- canvas.toBlob((blob: any) => {
- // 创建一个指向该 Blob 的 URL
- url = URL.createObjectURL(blob);
- viewer.value = new Viewer(
- document.getElementById('image') as HTMLImageElement,
- {
- inline: false,
- navbar: false,
- backdrop: false,
- button: false,
- title: false,
- toolbar: {
- zoomIn: 4,
- zoomOut: 4,
- oneToOne: 4,
- reset: 4,
- prev: 0,
- play: {
- show: 4,
- size: 'large',
- },
- next: 0,
- rotateLeft: 4,
- rotateRight: 4,
- flipHorizontal: 4,
- flipVertical: 4,
- },
- className: 'viewer-box',
- container: '#image-preview',
- url: () => url,
- viewed() {
- const viewImg: any = document.querySelector('.viewer-canvas>img');
- viewer.value?.scale(0.8);
- viewer.value?.moveTo(
- (window.innerWidth - 340) / 2 - viewImg.offsetWidth / 2,
- window.innerHeight / 2 - viewImg.offsetHeight / 2
- );
- loading.value = false;
- },
- }
- );
- viewer.value?.show(true);
- }, 'image/jpeg');
- };
- };
- const alarmArchiving = ref('0');
- const alarmArchivingOptions = ref<any[]>([
- {
- label: '正确报警',
- value: '1',
- icon: 'mdi:alarm-light-outline',
- },
- {
- label: '错误报警',
- value: '2',
- icon: 'mdi:alarm-light-off-outline',
- },
- ]);
- watch(alarmArchiving, async (Archived) => {
- if (Archived === props.data.AlarmArchiving) return;
- emits('alarmArchiving', Archived);
- await getSetArchived(
- {
- AlarmID: props.data.Id,
- Archived,
- },
- { GUID: props.guid }
- );
- });
- onMounted(() => {
- alarmArchiving.value = props.data.AlarmArchiving;
- init();
- });
- onUnmounted(() => {
- viewer.value?.destroy();
- URL.revokeObjectURL(url);
- });
- </script>
- <style lang="less">
- .viewer-box {
- width: 100%;
- position: absolute;
- }
- #image-preview {
- position: fixed;
- left: 0;
- top: 0;
- width: calc(100% - 340px);
- height: 100%;
- }
- .viewer-canvas {
- background-color: #000000a1;
- }
- .view-alarm {
- .va-loading {
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: #000000a1;
- }
- .view-alarm-pic {
- width: 200px;
- img {
- width: 100%;
- }
- }
- }
- </style>
|