const violate

本文深入探讨了C语言中const关键字的用法,包括它如何影响指针、函数参数和返回值,以及如何通过volatile关键字来提升编译器效率。重点解释了不同语法结构下const的作用,并提供了实例说明。

在C语言中,const修饰的变量是只读的,其本质还是变量,其仍然会占用内存空间,在编译时有用,在运行时没有作用,本质上是告诉编译器const修饰的变量只能在等号的右边,但是这并不代表const修饰的变量是不能改变的。

const int* p; //p可变,p指向的内容不可变


int const* p; //p可变,p指向的内容不可变

int* const p; //p不可变,p指向的内容可变

const int* const p; //p和p指向的内容都不可变

一个简单的口诀就是 “左数右指”

当const出现在*号左边时指针指向的数据为常量
当const出现在*后右边时指针本身为常量

const修饰函数参数表示在函数体内不希望改变参数的值

const修饰函数返回值表示返回值不可改变,多用于返回指针的情形


volatile可理解为 编译器警告指示字

volatile用于告诉编译器必须每次去内存中取变量值

volatile主要修饰可能被多个线程访问的变量

volatile也可以修饰可能被未知因数更改的变量










<template> <div class="listManagePage EventAlarmDetail"> <a-breadcrumb separator=">" v-if="route.query.origin == 'violate'"> <img class="dw_img" src="@/assets/images/demoImg/mbx_dw.png" alt=""> <a-breadcrumb-item><a @click="()=>router.push('/roomInOut/personnelViolate')">人员违规行为台账</a></a-breadcrumb-item> <a-breadcrumb-item>人员违规行为台账详情</a-breadcrumb-item> </a-breadcrumb> <a-breadcrumb separator=">" v-else-if="route.query.origin == 'ledger'"> <img class="dw_img" src="@/assets/images/demoImg/mbx_dw.png" alt=""> <a-breadcrumb-item><a @click="()=>router.push('/roomInOut/eventLedger')">事件台账列表</a></a-breadcrumb-item> <a-breadcrumb-item>事件台账详情</a-breadcrumb-item> </a-breadcrumb> <a-breadcrumb separator=">" v-else> <img class="dw_img" src="@/assets/images/demoImg/mbx_dw.png" alt=""> <a-breadcrumb-item><a @click="()=>router.push('/eventManage/eventAlarm')">AI事件告警处理列表</a></a-breadcrumb-item> <a-breadcrumb-item>AI事件告警处理事件详情</a-breadcrumb-item> </a-breadcrumb> <a-spin :spinning="loading"> <div class="topPart"> <div class="header_right"> <img src="@/assets/images/abnormalEvent.jpg" alt=""> <div> <h5>{{formModel.deviceName}}-{{formModel.eventName}}事件</h5> <p><span class="num_header">NO.</span>{{formModel.eventId}}</p> </div> </div> </div> <div class="bj_white_height"> <div class="tableTitleLine page-header-btn"> <i class="titleIcon"></i> <span class="title">事件信息</span> </div> <a-form ref="topFormRef" class="topForm firstForm" layout="inline" :model="formModel" :label-col="firstLabelCol" :wrapper-col="firstWrapperCol"> <a-row style="width:100%"> <a-col :span="6"> <a-form-item label="事件ID:"> <span> {{ formModel.eventId }} </span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="事件等级:"> <span>{{ formModel.eventLevel }}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="发生时间:"> <span>{{ formModel.occurrenceTime }}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="事件分类:"> <span>{{ formModel.eventClassification }}</span> </a-form-item> </a-col> </a-row> <a-row style="width:100%"> <a-col :span="6"> <a-form-item label="事件名称:"> <span>{{ formModel.eventName }}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="事件标题:"> <span>{{ formModel.eventTitle }}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="关联摄像头:"> <span>{{ formModel.deviceName }}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="地市:"> <span>{{ formModel.city }}</span> </a-form-item> </a-col> </a-row> <a-row style="width:100%"> <a-col :span="6"> <a-form-item label="区县:"> <span>{{ formModel.district }}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="所属机楼:"> <span>{{ formModel.facilityName }}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="所属机房:"> <span>{{ formModel.roomName }}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="所属设备:"> <span>{{ formModel.cameraName }}</span> </a-form-item> </a-col> </a-row> <!-- <a-row style="width:100%"> <a-col :span="6"> <a-form-item label="事件触发人员名称:"> <span>{{ formModel.triggerPersonName }}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="身份证号:"> <span>{{ formModel.triggerIdNumber }}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="手机号:"> <span>{{ formModel.triggerPhoneNumber }}</span> </a-form-item> </a-col> </a-row> --> <a-row style="width:100%"> <a-col :span="12"> <a-form-item label="事件图片:"> <div class="image-container" ref="containerRef"> <img v-if="formModel.eventPicture" class="img_size" :src="`/bit-dfs/file/download?fileId=${formModel.eventPicture}&sourceSystem=ULTRA-AIMR`" @load="onImageLoad" ref="imgRef" /> <canvas ref="canvasRef" class="overlay-canvas"></canvas> </div> </a-form-item> </a-col> <a-col :span="12"> <a-form-item label="事件视频:"> <EventAlarmVideo v-if="formModel.eventVideoFileId || formModel.eventVideo" :formModel="formModel" :deviceId="route.query.deviceRowId"/> <!-- <video ref="videoPlayer" controls class="img_size" :src="formModel.eventVideo" ></video> --> <!-- <img src="https://www.antdv.com/#error"/> --> </a-form-item> </a-col> </a-row> </a-form> <div class="tableTitleLine page-header-btn"> <i class="titleIcon"></i> <span class="title">触发事件人员</span> </div> <a-table :dataSource="dataSource" :columns="columns" :pagination="false" :scroll="{ y: 500 }"/> <div class="tableTitleLine page-header-btn" style="margin-top: 20px;"> <i class="titleIcon"></i> <span class="title">事件处理</span> </div> <a-form ref="formRef" class="topForm secform" layout="vertical" :model="formData" :rules="rules"> <a-row :gutter="24"> <a-col :span="6"> <a-form-item :label="`是否真实告警:`" name="isTrueAlert"> <a-select v-if="route.query.type!='view'" v-model:value="formData.isTrueAlert" placeholder="" :options="needDispatchData" > </a-select> <span v-else>{{formModel.isTrueAlert}}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item :label="`是否清除:`" name="isRecovered"> <a-select v-if="route.query.type!='view'" v-model:value="formData.isRecovered" placeholder="" :options="isRecoveredData" > </a-select> <span v-else>{{formModel.isRecovered}}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item :label="`告警清除时间:`"> <a-date-picker v-if="route.query.type!='view'" v-model:value="formData.alertResolvedTime" show-time type="date" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择" style="width: 100%" :disabled-date="disabledBeforeOccurrenceDate" :disabled-time="disabledBeforeOccurrenceTime" :disabled="formData.isRecovered === '否'" /> <span v-else>{{formModel.alertResolvedTime}}</span> </a-form-item> </a-col> <!-- <a-col :span="6"> <a-form-item :label="`是否需要派单:`"> <a-select v-if="route.query.type!='view'" v-model:value="formData.needDispatch" placeholder="否" :options="needDispatchData" > </a-select> <span v-else>{{formModel.needDispatch}}</span> </a-form-item> </a-col> <a-col :span="6"> <a-form-item :label="`派发至:`"> <a-select v-if="route.query.type!='view'" v-model:value="formData.dispatchTarget" placeholder="无" :options="dispatchTargetData" > </a-select> <span v-else>{{formModel.dispatchTarget}}</span> </a-form-item> </a-col> --> </a-row> <a-row style="width:100%"> <a-col :span="24"> <a-form-item label="告警说明:" name="alertDescription"> <a-textarea v-if="route.query.type!='view'" placeholder="请输入说明内容" :rows="2" v-model:value="formData.alertDescription" /> <span v-else>{{formModel.alertDescription}}</span> </a-form-item> </a-col> </a-row> </a-form> <div class="footer_btn"> <a-button style="margin-right: 20px;" @click="backToList">{{route.query.type!='view'?'取消':'关闭'}}</a-button> <a-button v-if="route.query.type!='view'" type="primary" @click="confirmData">确认</a-button> </div> </div> </a-spin> </div> </template> <script setup lang="ts"> import { ref, onMounted, nextTick, reactive, watch,watchEffect,computed } from 'vue' import {useRoute, useRouter} from 'vue-router' import { updateEventAlarm, queryEventAlarmById } from "@/api/eventManage" import { message } from 'ant-design-vue' import moment from 'moment' import EventAlarmVideo from '@/views/components/EventAlarmVideo.vue' import axios from 'axios' const route = useRoute() const router = useRouter() const firstLabelCol = ref({ style: { width: '100px' }}) const firstWrapperCol = ref({ span: 14 }) const formModel = ref({ eventId: '', eventLevel: '', eventTitle: '', occurrenceTime: '', eventClassification: '', eventName: '', city: '', cameraName: '', district: '', facilityName: '', roomName: '', equipmentName: '', triggerPersonName: '', triggerIdNumber: '', triggerPhoneNumber: '', eventVideo: '', eventPicture: '', deviceName: '', isTrueAlert: '', isRecovered: '', alertResolvedTime: '', // needDispatch: '', // dispatchTarget: '', alertDescription: '', }) const recognizeCoordinates = ref([]) const formData = ref({ isTrueAlert: '', isRecovered: '', alertResolvedTime: '', // needDispatch: '', // dispatchTarget: '', alertDescription: '', }) const loading = ref(false) const isRecoveredData = ref([ { value: '是', label: '是', }, { value: '否', label: '否', }, ]) const needDispatchData = ref([ { value: '是', label: '是', }, { value: '否', label: '否', }, ]) const formRef = ref() const rules = { isTrueAlert: [{ required: true, message: '请选择是否真实告警', trigger: 'change' }], isRecovered: [{ required: true, message: '请选择是否清除', trigger: 'change' }], // alertResolvedTime: [{ required: true, message: '请选择告警清除时间', trigger: 'change', type: 'object' }], alertDescription: [{ required: true, message: '请输入告警说明', trigger: 'blur' }], } const videoData = ref ({}) const dataSource = ref ([]) const columns = ref([ { title: '姓名', dataIndex: 'triggerPersonName', key: 'triggerPersonName', }, { title: '公司', dataIndex: 'triggerCorporation', key: 'triggerCorporation', }, { title: '手机号', dataIndex: 'triggerPhoneNumber', key: 'triggerPhoneNumber', }, { title: '身份证号', dataIndex: 'triggerIdNumber', key: 'triggerIdNumber', }, ]) onMounted(() => { fetchData() }) const fetchData = () => { loading.value = true queryEventAlarmById(route.query.id).then(res => { if(res) { recognizeCoordinates.value = res.recognizeCoordinates || [] formModel.value = res dataSource.value = res.triggerPersonInfoList || [] Object.keys(formData.value).forEach(key => { if (res[key] !== undefined) { formData.value[key] = res[key] } }) // 确保图片加载完成后绘制 nextTick(() => { if (imgRef.value && imgRef.value.complete) { onImageLoad() } }) } }).catch((error: any) => { console.log(error) }).finally(()=> { loading.value = false }) } const confirmData = () => { if(!route.query.id) { return } formRef.value.validate().then(() => { loading.value = true let data = { eventId: route.query.id, ...formData.value } // console.log(data, 'formData') updateEventAlarm(data).then((res) => { message.success('保存成功') setTimeout(()=>{ backToList() }, 1000) }).catch((error: any) => { console.log(error) message.error(error.message) }).finally(()=> { loading.value = false }) }) .catch(error => { console.log('error', error); }) } const backToList = () => { if(route.query.origin == 'violate'){ router.push({ path: '/roomInOut/personnelViolate',query: route.query }) }else if(route.query.origin == 'ledger'){ router.push({ path: '/roomInOut/eventLedger',query: route.query }) }else{ router.push({ path: '/eventManage/eventAlarm',query: route.query }) } } // 计算属性:将发生时间转换为 moment 对象 const occurrenceTimeObj = computed(() => { if (!formModel.value.occurrenceTime) return null; return moment(formModel.value.occurrenceTime, 'YYYY-MM-DD HH:mm:ss'); }); // 禁用发生时间之前的日期 const disabledBeforeOccurrenceDate = (current) => { if (!occurrenceTimeObj.value) return false; // 禁用发生日期之前的所有日期 return current && current < moment(occurrenceTimeObj.value).startOf('day'); }; // 禁用发生时间当天的之前时间 const disabledBeforeOccurrenceTime = () => { if (!occurrenceTimeObj.value || !formModel.value.alertResolvedTime) { return { disabledHours: () => [], disabledMinutes: () => [], disabledSeconds: () => [] }; } const selectedDate = moment(formModel.value.alertResolvedTime); const occurrenceDate = moment(occurrenceTimeObj.value); // 如果选择的日期大于发生日期,则不禁用任何时间 if (selectedDate.isAfter(occurrenceDate, 'day')) { return { disabledHours: () => [], disabledMinutes: () => [], disabledSeconds: () => [] }; } // 如果选择的日期等于发生日期,则禁用发生时间之前的时间 if (selectedDate.isSame(occurrenceDate, 'day')) { const occurrenceHour = occurrenceDate.hour(); const occurrenceMinute = occurrenceDate.minute(); const occurrenceSecond = occurrenceDate.second(); return { disabledHours: () => Array.from({ length: occurrenceHour }, (_, i) => i), disabledMinutes: (h) => h === occurrenceHour ? Array.from({ length: occurrenceMinute }, (_, i) => i) : [], disabledSeconds: (h, m) => h === occurrenceHour && m === occurrenceMinute ? Array.from({ length: occurrenceSecond }, (_, i) => i) : [] }; } // 默认不禁用任何时间 return { disabledHours: () => [], disabledMinutes: () => [], disabledSeconds: () => [] }; }; // 监听发生时间变化,自动调整已选的清除时间 watchEffect(() => { if ( formData.value.alertResolvedTime && occurrenceTimeObj.value && moment(formData.value.alertResolvedTime).isBefore(occurrenceTimeObj.value) ) { // 如果已选的清除时间早于发生时间,则重置为发生时间 formData.value.alertResolvedTime = occurrenceTimeObj.value.format('YYYY-MM-DD HH:mm:ss'); } }); watch( () => formData.value.isRecovered, (newValue) => { // 当值为"否"时,清空告警清除时间 if (newValue === '否') { formData.value.alertResolvedTime = ''; } }, { immediate: true } // 初始化时也执行一次 ); const imgRef = ref(null) const canvasRef = ref(null) const containerRef = ref(null) const onImageLoad = () => { nextTick(() => { try { if (!imgRef.value || !canvasRef.value) return const img = imgRef.value const canvas = canvasRef.value // 确保图片已加载 if (!img.complete) { img.onload = onImageLoad return } // 设置canvas尺寸与图片相同 canvas.width = img.naturalWidth canvas.height = img.naturalHeight const ctx = canvas.getContext('2d') if (!ctx) return // 清除之前绘制的内容 ctx.clearRect(0, 0, canvas.width, canvas.height) // 如果没有坐标数据则返回 if (!recognizeCoordinates.value || recognizeCoordinates.value.length === 0) { console.warn('No recognition coordinates to draw') return } // 绘制所有识别框 recognizeCoordinates.value.forEach(item => { if (item.bbox && item.bbox.length === 4) { drawBoundingBox(ctx, item.bbox, item.label, item.score) } }) } catch (error) { console.error('Error drawing bounding boxes:', error) } }) } // 修改绘制函数,添加参数验证 const drawBoundingBox = (ctx, bbox, label, score) => { if (!bbox || bbox.length !== 4) return const [x1, y1, x2, y2] = bbox const width = x2 - x1 const height = y2 - y1 // 验证坐标是否有效 if (width <= 0 || height <= 0) return // 绘制矩形框 ctx.strokeStyle = '#FF0000' ctx.lineWidth = 2 ctx.strokeRect(x1, y1, width, height) // 绘制标签背景 ctx.fillStyle = '#FF0000' ctx.globalAlpha = 0.7 ctx.fillRect(x1, y1, Math.max(80, width * 0.3), 20) ctx.globalAlpha = 1 // 绘制标签文本 ctx.fillStyle = '#FFFFFF' ctx.font = '12px Arial' const labelText = `${label || 'unknown'} ${(parseFloat(score) * 100).toFixed(0)}%` ctx.fillText(labelText, x1 + 5, y1 + 15) } // 添加对图片的额外监听 watch(imgRef, (newImg) => { if (newImg) { if (newImg.complete) { onImageLoad() } else { newImg.onload = onImageLoad } } }) // 确保在坐标数据变化时重新绘制 watch(() => recognizeCoordinates.value, (newVal) => { if (newVal && imgRef.value && imgRef.value.complete) { onImageLoad() } }, { deep: true }) </script> <style lang="less" scoped> .EventAlarmDetail { padding-bottom: 20px; } .EventAlarmDetail .topPart { padding: 16px; } .header_right { display: flex; } .header_right img { width: 48px; height: 48px; margin-right: 16px; } .header_right h5 { height: 14px; font-size: 14px; color: #333330; font-weight: 400; margin-bottom: 14px; } .header_right .num_header { display: inline-block; width: 31px; height: 18px; line-height: 18px; text-align: center; background: rgba(0, 86, 245, 0.1); border-radius: 3px; font-size: 10px; color: #0056F5; font-weight: 400; margin-right: 8px; } .header_right p { height: 10px; font-size: 10px; color: #0056F5; font-weight: 400; margin-bottom: 2px; } :deep(.ant-page-header .ant-page-header-content) { padding: 0; } :deep(.ant-descriptions .ant-descriptions-title) { margin-top: 15px!important; } .listManagePage .topPart { display: flex; align-items: center; margin: 0 16px 16px 0; background: rgba(255, 255, 255, 0.70); border: 1px solid #FFFFFF; box-shadow: 0 2px 4px 0 rgba(0,0,0,0.10); border-radius: 3px; } .footer_btn { position: fixed; bottom: 0; right: 0; box-sizing: border-box; margin-right: 16px; background: #fff; padding-bottom: -16px; text-align: right; width: 100%; padding: 12px 17px 12px 0; border: 1px solid #FFFFFF; box-shadow: 0 -2px 6px 0 rgba(0,27,77,0.06); } .topForm { padding: 6px 16px; background: #F3F7FE; } .firstForm { margin-bottom: 24px; } .secform { padding: 16px 16px 36px; } .tableTitleLine { margin-bottom: 14px; } :deep(.ant-form-item .ant-form-item-control-input-content) { font-size: 12px; color: #666666; font-weight: 400; } :deep(.ant-input:placeholder-shown) { font-size: 12px; color: #DBDFE8; font-weight: 400; } .img_size { // width:100%; height:200px; } :deep(.ant-image .ant-image-img) { width: 350px; height: 200px; } :deep(.ant-form-item .ant-form-item-explain-error) { font-size: 12px; } .image-container { position: relative; display: inline-block; line-height: 0; /* 防止图片下方有间隙 */ } .overlay-canvas { position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; z-index: 2; /* 确保canvas在图片上方 */ } .img_size { display: block; max-width: 100%; height:200px; position: relative; z-index: 1; } </style> 在事件图片的效果上再实现可以图片预览,预览图片的时候,绘制图也跟着变化
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值