智能电表水表

This commit is contained in:
曹磊 2025-06-10 16:21:17 +08:00
parent a4ba10534c
commit b5d24efeae
7 changed files with 833 additions and 0 deletions

View File

@ -173,8 +173,11 @@ import {
if (percentRate.value >= 100) {
clearInterval(timerRef.value);
canUpload.value = true;
// uploadStop();
}
}).catch(res=>{
clearInterval(timerRef.value);
canUpload.value = true;
console.log(res);
});
}

View File

@ -0,0 +1,46 @@
import { defHttp } from '/@/utils/http/axios';
enum Api {
list = '/iot/tq/electricityMeter/list',
eleReset = '/iot/tq/electricityMeter/eleReset',
eleControl = '/iot/tq/electricityMeter/eleControl',
eleRead = '/iot/tq/electricityMeter/eleRead',
getAllMeter = '/iot/tq/common/device/getAllMeter',
getAllCollector = '/iot/tq/common/device/getAllCollector',
}
/**
*
* @param params
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
/**
*
* @param params
*/
export const eleReset = (params?) => defHttp.get({ url: Api.eleReset, params });
/**
*
* @param params
*/
export const eleControl = (params?) => defHttp.get({ url: Api.eleControl, params });
/**
*
* @param params
*/
export const eleRead = (params?) => defHttp.get({ url: Api.eleRead, params });
/**
*
* @param params
*/
export const getAllMeter = (params?) => defHttp.get({ url: Api.getAllMeter, params });
/**
*
* @param params
*/
export const getAllCollector = (params?) => defHttp.get({ url: Api.getAllCollector, params });

View File

@ -0,0 +1,154 @@
import {BasicColumn} from '/@/components/Table';
import {FormSchema} from '/@/components/Table';
//列表数据
export const columns: BasicColumn[] = [
{
title: '机构',
align: "center",
dataIndex: 'departName'
},
{
title: '护理单元',
align: "center",
dataIndex: 'nuName'
},
{
title: '表号',
align: "center",
dataIndex: 'address'
},
{
title: '采集器号',
align: "center",
dataIndex: 'cid'
},
{
title: '设备状态',
align: "center",
dataIndex: 'relayState',
customRender:({record})=>{
return record.relayState?(record.relayState=='1'?'合闸':'拉闸'):'';
},
},
{
title: '在线状态',
align: "center",
dataIndex: 'online',
customRender:({record})=>{
return record.online?(record.online=='true'?'在线':'离线'):'';
},
},
{
title: '信号强度',
align: "center",
dataIndex: 'csq',
customRender:({record})=>{
if(record.csq){
if(record.csq < 10){
return '低';
}else if(record.csq > 20){
return '高';
}else{
return '中';
}
}else{
return '';
}
}
},
{
title: '用电量KWH',
align: "center",
dataIndex: 'eleValue'
},
{
title: '上次抄表时间',
align: "center",
dataIndex: 'readTime'
},
{
title: '上次上线时间',
align: "center",
dataIndex: 'connectTime'
},
{
title: '上次掉线时间',
align: "center",
dataIndex: 'disconnectTime'
},
{
title: '描述',
align: "center",
dataIndex: 'remark'
},
];
export const searchFormSchema: FormSchema[] = [
{
label: '机构',
field: 'deviceStatus',
component: 'JDictSelectTag',
componentProps: {
placeholder: '请选择机构',
dictCode: 'sys_depart,depart_name,id,org_category = 1 order by depart_name asc',
},
colProps: { span: 6 },
},
{
label: '护理单元',
field: 'deviceStatus',
component: 'JDictSelectTag',
componentProps: {
placeholder: '请选择护理单元',
dictCode: 'nu_base_info,nu_name,id,del_flag = 0 order by nu_name asc',
},
colProps: { span: 6 },
},
{
label: '表号',
field: 'address',
component: 'Input',
colProps: { span: 6 },
},
{
label: '设备状态',
field: 'relayState',
component: 'JDictSelectTag',
componentProps: {
placeholder: '请选择状态',
options: [
{ label: '合闸', value: '1' },
{ label: '拉闸', value: '0' },
],
},
colProps: { span: 6 },
},
{
label: '在线状态',
field: 'online',
component: 'JDictSelectTag',
componentProps: {
placeholder: '请选择状态',
options: [
{ label: '在线', value: 'true' },
{ label: '离线', value: 'false' },
],
},
colProps: { span: 6 },
},
{
label: '信号强度',
field: 'csq',
component: 'JDictSelectTag',
componentProps: {
placeholder: '请选择强度',
options: [
{ label: '高', value: '1' },
{ label: '中', value: '2' },
{ label: '低', value: '3' },
],
},
colProps: { span: 6 },
},
];

View File

@ -0,0 +1,207 @@
<template>
<div>
<!--引用表格-->
<BasicTable @register="registerTable">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" preIcon="ant-design:sync-outlined" @click="handleSyncDevice"> 同步设备</a-button>
<a-button preIcon="ant-design:sync-outlined" @click="handleSyncCollector"> 同步采集器</a-button>
</template>
<template #bodyCell="{ column, record, index, text }">
<template v-if="column.dataIndex === 'address'">
<a @click="showApiLog(record)"> {{record.address}} </a>
</template>
<template v-if="column.dataIndex === 'relayState'">
<span v-if="record.relayState ==='1'" style="color:green">
合闸
</span>
<span v-else style="color:red">
拉闸
</span>
</template>
<template v-if="column.dataIndex === 'online'">
<span v-if="record.online ==='true'" style="color:green">
在线
</span>
<span v-else style="color:red">
离线
</span>
</template>
<template v-if="column.dataIndex === 'csq'">
<span v-if="record.csq > 20" style="color:green">
</span>
<span v-else-if="record.csq < 10" style="color:red">
</span>
<span v-else style="color:yellow">
</span>
</template>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)"/>
</template>
</BasicTable>
</div>
</template>
<script lang="ts" name="iot-nuIotRegionInfo" setup>
import {reactive, ref,h} from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { useUserStore } from '/@/store/modules/user';
import {Modal} from "ant-design-vue";
import {list, eleReset, eleControl, eleRead, getAllMeter, getAllCollector} from './electricity.api';
import { columns, searchFormSchema } from './electricity.data';
import {useModal} from "@/components/Modal";
const queryParam = reactive<any>({});
//model
const [registerModal, {openModal}] = useModal();
//table
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
tableProps:{
title: '智能电表',
api: list,
columns,
canResize:false,
showIndexColumn: true,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter:true,
showAdvancedButton:true,
fieldMapToNumber: [
],
fieldMapToTime: [
],
},
actionColumn: {
width: 200,
fixed:'right'
},
beforeFetch: (params) => {
return Object.assign(params, queryParam);
},
},
})
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
/**
* 操作栏
*/
function getTableAction(record){
return [
{
label: '抄表',
onClick: handleRead.bind(null, record),
},
{
label: '拉闸',
onClick: handleControlLz.bind(null, record),
},
{
label: '合闸',
onClick: handleControlHz.bind(null, record),
},
{
label: '清零',
popConfirm: {
title: '是否确认清零',
confirm: handleReset.bind(null, record),
placement: 'topLeft',
},
}
]
}
//
async function handleRead(record: Recordable) {
const params = {
'cid' : record.cid,
'address' : record.address,
};
await eleRead(params);
reload();
}
//
async function handleControlLz(record: Recordable) {
if(record.relayState == '0'){
Modal.info({
title: '拉闸',
content: h('div', {}, [
h('p', '此电表已拉闸!'),
]),
onOk() {},
});
return;
}
const params = {
'cid' : record.cid,
'address' : record.address,
'type' : '10',
};
await eleControl(params);
reload();
}
//
async function handleControlHz(record: Recordable) {
if(record.relayState == '1'){
Modal.info({
title: '合闸',
content: h('div', {}, [
h('p', '此电表已合闸!'),
]),
onOk() {},
});
return;
}
const params = {
'cid' : record.cid,
'address' : record.address,
'type' : '11',
};
await eleControl(params);
reload();
}
//
async function handleReset(record: Recordable) {
const params = {
'cid' : record.cid,
'address' : record.address,
};
await eleReset(params);
reload();
}
//
async function handleSyncDevice() {
await getAllMeter({});
reload();
}
//
async function handleSyncCollector() {
await getAllCollector({});
reload();
}
function showApiLog(record){
console.log(record);
}
</script>

View File

@ -0,0 +1,215 @@
<template>
<div>
<!--引用表格-->
<BasicTable @register="registerTable">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" preIcon="ant-design:sync-outlined" @click="handleSyncDevice"> 同步设备</a-button>
<a-button preIcon="ant-design:sync-outlined" @click="handleSyncCollector"> 同步采集器</a-button>
</template>
<template #bodyCell="{ column, record, index, text }">
<template v-if="column.dataIndex === 'address'">
<a @click="showApiLog(record)"> {{record.address}} </a>
</template>
<template v-if="column.dataIndex === 'relayState'">
<span v-if="record.relayState ==='1'" style="color:green">
开阀
</span>
<span v-else style="color:red">
关阀
</span>
</template>
<!-- <template v-if="column.dataIndex === 'batteryState'">
<span v-if="record.batteryState ==='0'" style="color:green">
正常
</span>
<span v-else style="color:red">
低电
</span>
</template>-->
<template v-if="column.dataIndex === 'online'">
<span v-if="record.online ==='true'" style="color:green">
在线
</span>
<span v-else style="color:red">
离线
</span>
</template>
<template v-if="column.dataIndex === 'csq'">
<span v-if="record.csq > 20" style="color:green">
</span>
<span v-else-if="record.csq < 10" style="color:red">
</span>
<span v-else style="color:yellow">
</span>
</template>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)"/>
</template>
</BasicTable>
</div>
</template>
<script lang="ts" name="iot-nuIotRegionInfo" setup>
import {reactive, ref,h} from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { useUserStore } from '/@/store/modules/user';
import {Modal} from "ant-design-vue";
import {list, waterReset, waterControl, waterRead, getAllMeter, getAllCollector} from './water.api';
import { columns, searchFormSchema } from './water.data';
import {useModal} from "@/components/Modal";
const queryParam = reactive<any>({});
//model
const [registerModal, {openModal}] = useModal();
//table
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
tableProps:{
title: '智能水表',
api: list,
columns,
canResize:false,
showIndexColumn: true,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter:true,
showAdvancedButton:true,
fieldMapToNumber: [
],
fieldMapToTime: [
],
},
actionColumn: {
width: 200,
fixed:'right'
},
beforeFetch: (params) => {
return Object.assign(params, queryParam);
},
},
})
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
/**
* 操作栏
*/
function getTableAction(record){
return [
{
label: '抄表',
onClick: handleRead.bind(null, record),
},
{
label: '开阀',
onClick: handleWaterControlKf.bind(null, record),
},
{
label: '关阀',
onClick: handleWaterControlGf.bind(null, record),
},
{
label: '清零',
popConfirm: {
title: '是否确认清零',
confirm: handleReset.bind(null, record),
placement: 'topLeft',
},
}
]
}
//
async function handleRead(record: Recordable) {
const params = {
'cid' : record.cid,
'address' : record.address,
};
await waterRead(params);
reload();
}
//
async function handleWaterControlGf(record: Recordable) {
if(record.relayState == '0'){
Modal.info({
title: '关阀',
content: h('div', {}, [
h('p', '此水表已关阀!'),
]),
onOk() {},
});
return;
}
const params = {
'cid' : record.cid,
'address' : record.address,
'type' : '53',
};
await waterControl(params);
reload();
}
//
async function handleWaterControlKf(record: Recordable) {
if(record.relayState == '1'){
Modal.info({
title: '开阀',
content: h('div', {}, [
h('p', '此水表已开阀!'),
]),
onOk() {},
});
return;
}
const params = {
'cid' : record.cid,
'address' : record.address,
'type' : '43',
};
await waterControl(params);
reload();
}
//
async function handleReset(record: Recordable) {
const params = {
'cid' : record.cid,
'address' : record.address,
};
await waterReset(params);
reload();
}
//
async function handleSyncDevice() {
await getAllMeter({});
reload();
}
//
async function handleSyncCollector() {
await getAllCollector({});
reload();
}
function showApiLog(record){
console.log(record);
}
</script>

View File

@ -0,0 +1,46 @@
import { defHttp } from '/@/utils/http/axios';
enum Api {
list = '/iot/tq/waterMeter/list',
waterReset = '/iot/tq/waterMeter/waterReset',
waterControl = '/iot/tq/waterMeter/waterControl',
waterRead = '/iot/tq/waterMeter/waterRead',
getAllMeter = '/iot/tq/common/device/getAllMeter',
getAllCollector = '/iot/tq/common/device/getAllCollector',
}
/**
*
* @param params
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
/**
*
* @param params
*/
export const waterReset = (params?) => defHttp.get({ url: Api.waterReset, params });
/**
*
* @param params
*/
export const waterControl = (params?) => defHttp.get({ url: Api.waterControl, params });
/**
*
* @param params
*/
export const waterRead = (params?) => defHttp.get({ url: Api.waterRead, params });
/**
*
* @param params
*/
export const getAllMeter = (params?) => defHttp.get({ url: Api.getAllMeter, params });
/**
*
* @param params
*/
export const getAllCollector = (params?) => defHttp.get({ url: Api.getAllCollector, params });

View File

@ -0,0 +1,162 @@
import {BasicColumn} from '/@/components/Table';
import {FormSchema} from '/@/components/Table';
//列表数据
export const columns: BasicColumn[] = [
{
title: '机构',
align: "center",
dataIndex: 'departName'
},
{
title: '护理单元',
align: "center",
dataIndex: 'nuName'
},
{
title: '表号',
align: "center",
dataIndex: 'address'
},
{
title: '采集器号',
align: "center",
dataIndex: 'cid'
},
{
title: '设备状态',
align: "center",
dataIndex: 'relayState',
customRender:({record})=>{
return record.relayState?(record.relayState=='1'?'合闸':'拉闸'):'';
},
},
// {
// title: '电池状态',
// align: "center",
// dataIndex: 'batteryState',
// customRender:({record})=>{
// return record.batteryState?(record.batteryState=='0'?'正常':'低电'):'';
// },
// },
{
title: '在线状态',
align: "center",
dataIndex: 'online',
customRender:({record})=>{
return record.online?(record.online=='true'?'在线':'离线'):'';
},
},
{
title: '信号强度',
align: "center",
dataIndex: 'csq',
customRender:({record})=>{
if(record.csq){
if(record.csq < 10){
return '低';
}else if(record.csq > 20){
return '高';
}else{
return '中';
}
}else{
return '';
}
}
},
{
title: '用水量m³',
align: "center",
dataIndex: 'waterValue'
},
{
title: '上次抄表时间',
align: "center",
dataIndex: 'readTime'
},
{
title: '上次上线时间',
align: "center",
dataIndex: 'connectTime'
},
{
title: '上次掉线时间',
align: "center",
dataIndex: 'disconnectTime'
},
{
title: '描述',
align: "center",
dataIndex: 'remark'
},
];
export const searchFormSchema: FormSchema[] = [
{
label: '机构',
field: 'deviceStatus',
component: 'JDictSelectTag',
componentProps: {
placeholder: '请选择机构',
dictCode: 'sys_depart,depart_name,id,org_category = 1 order by depart_name asc',
},
colProps: { span: 6 },
},
{
label: '护理单元',
field: 'deviceStatus',
component: 'JDictSelectTag',
componentProps: {
placeholder: '请选择护理单元',
dictCode: 'nu_base_info,nu_name,id,del_flag = 0 order by nu_name asc',
},
colProps: { span: 6 },
},
{
label: '表号',
field: 'address',
component: 'Input',
colProps: { span: 6 },
},
{
label: '设备状态',
field: 'relayState',
component: 'JDictSelectTag',
componentProps: {
placeholder: '请选择状态',
options: [
{ label: '合闸', value: '1' },
{ label: '拉闸', value: '0' },
],
},
colProps: { span: 6 },
},
{
label: '在线状态',
field: 'online',
component: 'JDictSelectTag',
componentProps: {
placeholder: '请选择状态',
options: [
{ label: '在线', value: 'true' },
{ label: '离线', value: 'false' },
],
},
colProps: { span: 6 },
},
{
label: '信号强度',
field: 'csq',
component: 'JDictSelectTag',
componentProps: {
placeholder: '请选择强度',
options: [
{ label: '高', value: '1' },
{ label: '中', value: '2' },
{ label: '低', value: '3' },
],
},
colProps: { span: 6 },
},
];