| | |
| | | import { onMounted, reactive, ref } from 'vue'; |
| | | import { Page } from '@vben/common-ui'; |
| | | import { Alert, Button, Card, Form, FormItem, Input, InputNumber, message, Modal, Popconfirm, Select, Space, Table, Tag } from 'ant-design-vue'; |
| | | import { createRiskSource, deleteRiskSource, getRiskSourcePage, updateRiskSource } from '#/api/safety/risk-source'; |
| | | import { createRiskSource, deleteRiskSource, getRiskSourcePage, refreshRiskSourceFromCollect, updateRiskSource } from '#/api/safety/risk-source'; |
| | | |
| | | defineOptions({ name: 'SafetyRiskSource' }); |
| | | const rows=ref<SafetyRiskSource[]>([]); const loading=ref(false); const saving=ref(false); const open=ref(false); |
| | | const filters=reactive<{name?:string}>({}); const paging=reactive({current:1,pageSize:10,total:0}); |
| | | const blank=():SafetyRiskSource=>({name:'',category:'MAJOR',location:'',metricName:'',unit:'',lowerLimit:undefined,upperLimit:undefined,currentValue:undefined,remark:''}); |
| | | const blank=():SafetyRiskSource=>({name:'',category:'MAJOR',location:'',metricName:'',unit:'',lowerLimit:undefined,upperLimit:undefined,currentValue:undefined,remark:'',machineryId:undefined,metricKey:''}); |
| | | const model=reactive<SafetyRiskSource>(blank()); |
| | | const categories:Record<string,string>={MAJOR:'重大危险源',HIGH_VOLTAGE:'高压试验区域',OTHER:'其他'}; |
| | | const states:Record<string,string>={NORMAL:'正常',ALARM:'超限',UNKNOWN:'未知'}; |
| | | const columns=[{title:'危险源名称',dataIndex:'name'},{title:'类别',key:'category'},{title:'位置',dataIndex:'location'}, |
| | | {title:'监测指标',dataIndex:'metricName'},{title:'当前值',key:'value'},{title:'阈值',key:'limits'}, |
| | | {title:'监测指标',dataIndex:'metricName'},{title:'数据来源',key:'source'},{title:'当前值',key:'value'},{title:'阈值',key:'limits'}, |
| | | {title:'数值变更时间',dataIndex:'observedAt'},{title:'状态',key:'status'},{title:'操作',key:'action',width:150}]; |
| | | async function load(reset=false){if(reset)paging.current=1;loading.value=true;try{const r=await getRiskSourcePage({pageNo:paging.current,pageSize:paging.pageSize,...filters});rows.value=r.list;paging.total=r.total;}finally{loading.value=false;}} |
| | | function edit(row?:SafetyRiskSource){Object.assign(model,blank(),{id:undefined},row||{});open.value=true;} |
| | | async function save(){ |
| | | if(!model.name.trim()||!model.metricName.trim()){message.warning('请填写危险源名称和监测指标');return;} |
| | | if(model.lowerLimit!=null&&model.upperLimit!=null&&model.lowerLimit>model.upperLimit){message.warning('下限不能大于上限');return;} |
| | | if(model.machineryId&&!model.metricKey?.trim()){message.warning('绑定设备后必须填写数采指标键');return;} |
| | | if(!model.machineryId&&model.metricKey?.trim()){message.warning('填写数采指标键前请先绑定设备');return;} |
| | | saving.value=true;try{if(model.id)await updateRiskSource(model);else await createRiskSource(model);message.success('保存成功');open.value=false;await load();}finally{saving.value=false;} |
| | | } |
| | | async function remove(id:number){await deleteRiskSource(id);message.success('已删除');await load();} |
| | | /** 从设备采集刷新已绑定设备的危险源 */ |
| | | const refreshing=ref(false); |
| | | async function refreshFromCollect(){ |
| | | if(refreshing.value)return; |
| | | refreshing.value=true; |
| | | try{ |
| | | const alarms=await refreshRiskSourceFromCollect(); |
| | | const count=alarms?.length??0; |
| | | if(count>0){message.warning(`已刷新,${count} 个危险源超限:${alarms.map(a=>a.name).join('、')}`);} |
| | | else{message.success('已刷新,暂无超限危险源');} |
| | | await load(); |
| | | }finally{refreshing.value=false;} |
| | | } |
| | | onMounted(()=>load()); |
| | | </script> |
| | | <template> |
| | | <Page auto-content-height> |
| | | <Card title="危险源台账"> |
| | | <Alert class="mb-4" type="info" show-icon message="人工维护当前监测值和阈值;此页面不代表现场自动采集,亦不保存历史观测序列。" /> |
| | | <Space class="mb-3"><Input v-model:value="filters.name" placeholder="危险源名称" allow-clear /><Button @click="load(true)">查询</Button><Button v-access:code="['safety:risk:create']" type="primary" @click="edit()">新增危险源</Button></Space> |
| | | <Alert class="mb-4" type="info" show-icon message="未绑定设备的危险源由人工维护当前值;绑定设备并填写数采指标键后,可点「从设备采集刷新」自动取值并按阈值判定,不保存历史观测序列。" /> |
| | | <Space class="mb-3"><Input v-model:value="filters.name" placeholder="危险源名称" allow-clear /><Button @click="load(true)">查询</Button><Button v-access:code="['safety:risk:create']" type="primary" @click="edit()">新增危险源</Button><Button v-access:code="['safety:risk:update']" :loading="refreshing" @click="refreshFromCollect">从设备采集刷新</Button></Space> |
| | | <Table :columns="columns" :data-source="rows" :loading="loading" :pagination="paging" row-key="id" :scroll="{x:1100}" @change="p=>{paging.current=p.current||1;paging.pageSize=p.pageSize||10;load();}"> |
| | | <template #bodyCell="{column,record}"> |
| | | <template v-if="column.key==='category'">{{categories[record.category]||record.category}}</template> |
| | | <template v-else-if="column.key==='source'"><Tag :color="record.machineryId?'blue':'default'">{{record.machineryId?`设备采集(${record.metricKey||'-'})`:'人工录入'}}</Tag></template> |
| | | <template v-else-if="column.key==='value'">{{record.currentValue??'未录入'}} {{record.unit||''}}</template> |
| | | <template v-else-if="column.key==='limits'">{{record.lowerLimit??'不限'}} ~ {{record.upperLimit??'不限'}} {{record.unit||''}}</template> |
| | | <Tag v-else-if="column.key==='status'" :color="record.riskStatus==='ALARM'?'red':record.riskStatus==='NORMAL'?'green':'default'">{{states[record.riskStatus]||'未知'}}</Tag> |
| | |
| | | <FormItem label="单位"><Input v-model:value="model.unit" :maxlength="32" /></FormItem> |
| | | <FormItem label="下限(可空)"><InputNumber v-model:value="model.lowerLimit" class="w-full" /></FormItem> |
| | | <FormItem label="上限(可空)"><InputNumber v-model:value="model.upperLimit" class="w-full" /></FormItem> |
| | | <FormItem label="关联设备编号(可空)" extra="填写后由数采自动取值,人工当前值将被覆盖"> |
| | | <InputNumber v-model:value="model.machineryId" class="w-full" :min="1" placeholder="设备台账编号" /> |
| | | </FormItem> |
| | | <FormItem label="数采指标键(可空)" extra="取 mes_collect_realtime.data_json 中的字段名,如 current、speed;也可用 ot/sts/opm"> |
| | | <Input v-model:value="model.metricKey" :maxlength="64" placeholder="如 current" /> |
| | | </FormItem> |
| | | <FormItem label="当前值(人工录入)"><InputNumber v-model:value="model.currentValue" class="w-full" /></FormItem> |
| | | <FormItem label="备注"><Input.TextArea v-model:value="model.remark" :maxlength="500" /></FormItem> |
| | | </Form> |