| | |
| | | height: 100%; |
| | | margin: 0; |
| | | padding: 0; |
| | | //控制初始字体大小 |
| | | @media(min-width: 1921px) and (max-width: 3840px) { |
| | | font-size: 32px; |
| | | } |
| | | } |
| | | |
| | | .chromeframe { |
对比新文件 |
| | |
| | | /* |
| | | * @Author: elkers |
| | | * @Date: 2024-08-09 14:29:49 |
| | | * @LastEditors: hqs elkers@163.com |
| | | * @LastEditTime: 2024-08-10 08:57:04 |
| | | * @FilePath: \water-qinghe-web\src\api\alarmApi\alarmHistory.js |
| | | * @Description: 历史记录api |
| | | */ |
| | | import { publicRequest } from '@/utils/request' |
| | | export default function alarmSchemeApi() { |
| | | return { |
| | | create: (data) => { |
| | | return publicRequest({ |
| | | url: '/alarmScheme/create', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }, |
| | | modify: (data) => { |
| | | return publicRequest({ |
| | | url: '/alarmScheme/modify', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }, |
| | | remove: (data) => { |
| | | return publicRequest({ |
| | | url: `/alarmScheme/remove?id=${data}`, |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }, |
| | | stop: (data) => { |
| | | return publicRequest({ |
| | | url: `/alarmScheme/stop?id=${data}`, |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }, |
| | | enable: (data) => { |
| | | return publicRequest({ |
| | | url: `/alarmScheme/enable?id=${data}`, |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }, |
| | | search: (data) => { |
| | | return publicRequest({ |
| | | url: '/alarmScheme/search', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }, |
| | | get: (data) => { |
| | | return publicRequest({ |
| | | url: `/alarmScheme/get?id=${data}`, |
| | | method: 'get', |
| | | data, |
| | | }); |
| | | }, |
| | | setSort: (data) => { |
| | | return publicRequest({ |
| | | url: `/alarmScheme/setSort`, |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | } |
| | | }; |
| | | } |
| | |
| | | |
| | | import { publicRequest } from '@/utils/request.js' |
| | | |
| | | //公司配置信息 |
| | | //配置信息 |
| | | export default function waterFacilityParameter() { |
| | | return { |
| | | create: (data) => { |
| | |
| | | padding-bottom: 5px; |
| | | } |
| | | |
| | | /** 表格布局 **/ |
| | | .pagination-container { |
| | | position: relative; |
| | | height: 25px; |
| | | margin-bottom: 10px; |
| | | margin-top: 15px; |
| | | padding: 10px 20px !important; |
| | | } |
| | | |
| | | .el-dialog .pagination-container { |
| | | position: static !important; |
| | | } |
| | | |
| | | /* tree border */ |
| | | .tree-border { |
| | | margin-top: 5px; |
| | |
| | | background: #FFFFFF none; |
| | | border-radius: 4px; |
| | | width: 100%; |
| | | } |
| | | |
| | | .pagination-container .el-pagination { |
| | | right: 0; |
| | | position: absolute; |
| | | } |
| | | |
| | | @media (max-width: 768px) { |
| | | .pagination-container .el-pagination > .el-pagination__jump { |
| | | display: none !important; |
| | | } |
| | | .pagination-container .el-pagination > .el-pagination__sizes { |
| | | display: none !important; |
| | | } |
| | | } |
| | | |
| | | .el-table .fixed-width .el-button--small { |
| | |
| | | .components-container { |
| | | margin: 30px 50px; |
| | | position: relative; |
| | | } |
| | | |
| | | .pagination-container { |
| | | margin-top: 30px; |
| | | } |
| | | |
| | | .text-center { |
| | |
| | | position: relative; |
| | | } |
| | | |
| | | .pagination-container { |
| | | margin-top: 30px; |
| | | } |
| | | |
| | | .text-center { |
| | | text-align: center |
| | | } |
| | |
| | | padding-bottom: 5px; |
| | | } |
| | | |
| | | /** 表格布局 **/ |
| | | .pagination-container { |
| | | position: relative; |
| | | height: 25px; |
| | | margin-bottom: 10px; |
| | | margin-top: 15px; |
| | | padding: 10px 20px !important; |
| | | } |
| | | |
| | | .el-dialog .pagination-container { |
| | | position: static !important; |
| | | } |
| | | |
| | | /* tree border */ |
| | | .tree-border { |
| | | margin-top: 5px; |
| | |
| | | background: #FFFFFF none; |
| | | border-radius: 4px; |
| | | width: 100%; |
| | | } |
| | | |
| | | .pagination-container .el-pagination { |
| | | right: 0; |
| | | position: absolute; |
| | | } |
| | | |
| | | @media (max-width: 768px) { |
| | | .pagination-container .el-pagination > .el-pagination__jump { |
| | | display: none !important; |
| | | } |
| | | .pagination-container .el-pagination > .el-pagination__sizes { |
| | | display: none !important; |
| | | } |
| | | } |
| | | |
| | | .el-table .fixed-width .el-button--small { |
| | |
| | | padding-bottom:5px |
| | | } |
| | | |
| | | /** 表格布局 **/ |
| | | .pagination-container { |
| | | position: relative; |
| | | height: 25px; |
| | | margin-bottom: 10px; |
| | | margin-top: 15px; |
| | | padding: 10px 20px !important; |
| | | } |
| | | |
| | | .el-dialog .pagination-container { |
| | | position: static !important; |
| | | } |
| | | |
| | | /* tree border */ |
| | | .tree-border { |
| | | margin-top: 5px; |
| | |
| | | background: #FFFFFF none; |
| | | border-radius:4px; |
| | | width: 100%; |
| | | } |
| | | |
| | | .pagination-container .el-pagination { |
| | | right: 0; |
| | | position: absolute; |
| | | } |
| | | |
| | | @media ( max-width : 768px) { |
| | | .pagination-container .el-pagination > .el-pagination__jump { |
| | | display: none !important; |
| | | } |
| | | .pagination-container .el-pagination > .el-pagination__sizes { |
| | | display: none !important; |
| | | } |
| | | } |
| | | |
| | | .el-table .fixed-width .el-button--small { |
| | |
| | | <template> |
| | | <div :class="{ 'hidden': hidden }" class="pagination-container"> |
| | | <el-pagination |
| | | :background="background" |
| | | v-model:current-page="currentPage" |
| | | v-model:page-size="pageSize" |
| | | :layout="layout" |
| | | :page-sizes="pageSizes" |
| | | :pager-count="pagerCount" |
| | | :total="total" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | <el-pagination |
| | | :background="background" |
| | | v-model:current-page="currentPage" |
| | | v-model:page-size="pageSize" |
| | | :layout="layout" |
| | | :page-sizes="pageSizes" |
| | | :pager-count="pagerCount" |
| | | :total="total" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | .pagination-container { |
| | | background: #fff; |
| | | padding: 32px 16px; |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | } |
| | | .pagination-container.hidden { |
| | | display: none; |
对比新文件 |
| | |
| | | <script setup> |
| | | /** |
| | | * getList 获取列表 |
| | | * headList 列定义 |
| | | * order 是否排序 |
| | | * orderFun: function (a, b){ return Number(a.code) > Number(b.code) ? 1 : -1 } 排序函数 |
| | | * fixed 是否固定列 |
| | | * filters 列过滤 |
| | | * filterFun 过滤函数 |
| | | * slot 自定义列, row为当前列插槽传参, 接收 <template #code="scope"> </template>, code为插槽名 |
| | | * select 是否可选择 |
| | | * |
| | | */ |
| | | import {onMounted, ref} from "vue"; |
| | | |
| | | const props = defineProps({ |
| | | getList: { |
| | | type: Function, |
| | | default: () => {}, |
| | | required: true |
| | | }, |
| | | headList: { |
| | | type: Array, |
| | | default: [], |
| | | required: true |
| | | }, |
| | | select: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }) |
| | | |
| | | const state = reactive({ |
| | | page: 1, |
| | | limit: 10, |
| | | total: 0, |
| | | list: [] |
| | | }) |
| | | const loading = ref(false); |
| | | |
| | | const getData = (data) => { |
| | | const pagedata = { limit: state.limit, page: data.page} |
| | | loading.value = true; |
| | | props.getList(pagedata).then(res => { |
| | | state.list = res.list |
| | | state.total = res.total |
| | | }).finally(() => { |
| | | loading.value = false; |
| | | }) |
| | | } |
| | | |
| | | onMounted(() =>{ |
| | | getData({ page: state.page }) |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div style="width: 100%; height: 100%"> |
| | | <el-table :data="state.list" |
| | | v-loading="loading" |
| | | ref="multipleTable" |
| | | style="width: 100%; height: 85%"> |
| | | <el-table-column v-if="props.select" type="selection"></el-table-column> |
| | | <el-table-column |
| | | type="index" |
| | | label="序号" |
| | | align="center" |
| | | width="80px" |
| | | ></el-table-column> |
| | | <template v-for="item in props.headList"> |
| | | <!-- 排序列 --> |
| | | <el-table-column |
| | | v-if="item.order" |
| | | :prop="item.prop" |
| | | :label="item.label" |
| | | :sortable="item?.order" |
| | | :sort-method="item?.orderFun" |
| | | /> |
| | | <!-- 正常列 --> |
| | | <el-table-column |
| | | v-else |
| | | :prop="item.prop" |
| | | :label="item.label" |
| | | :fixed="item?.fixed" |
| | | :filters="item?.filters" |
| | | :filter-method="item?.filterFun" |
| | | > |
| | | <template #default="scope"> |
| | | <!-- 自定义列 --> |
| | | <template v-if="item?.slot"> |
| | | <slot :name="item.prop" :row="scope.row"></slot> |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | </template> |
| | | </el-table> |
| | | <div class="pagination"> |
| | | <div class="pagination-total">共{{state.total}}条</div> |
| | | <pagination |
| | | v-show="state.total > 0" |
| | | layout="prev, pager, next, jumper" |
| | | :total="state.total" |
| | | :page="state.current" |
| | | :limit="state.limit" |
| | | @pagination="getData" |
| | | /> |
| | | <!-- 页面右侧自定义插槽,可以加自定义按钮 --> |
| | | <slot name="pagination"></slot> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .pagination{ |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: flex-end; |
| | | .pagination-total{ |
| | | color: #fff; |
| | | } |
| | | } |
| | | :deep(.pagination-container){ |
| | | background-color: transparent; |
| | | margin: 0; |
| | | padding: 20px; |
| | | } |
| | | </style> |
| | |
| | | |
| | | import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi' |
| | | |
| | | // 按需引入echarts |
| | | import * as echarts from 'echarts/core'; |
| | | import { GridComponent, ToolboxComponent, TooltipComponent, TitleComponent } from 'echarts/components'; |
| | | import { LineChart, BarChart } from 'echarts/charts'; |
| | | import { UniversalTransition } from 'echarts/features'; |
| | | import { CanvasRenderer } from 'echarts/renderers'; |
| | | |
| | | echarts.use([GridComponent, LineChart, BarChart, CanvasRenderer, UniversalTransition, ToolboxComponent, TooltipComponent, TitleComponent]); |
| | | |
| | | // 分页组件 |
| | | import Pagination from '@/components/Pagination' |
| | | // 自定义树选择组件 |
对比新文件 |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true"> |
| | | <el-form-item prop="name"> |
| | | <el-input |
| | | v-model="queryParams.name" |
| | | placeholder="请输入内容" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | >新增</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <!--表格及分页--> |
| | | <el-table v-loading="loading" :data="tableData"> |
| | | <el-table-column |
| | | v-for="(item, key, index) of tableHeader" |
| | | :prop="key.toString()" |
| | | :label="item" |
| | | :key="index" |
| | | align="center" |
| | | > |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="auto" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | :total="pageParam.total" |
| | | v-model:page="pageParam.page" |
| | | v-model:limit="pageParam.limit" |
| | | :page-sizes="[10,20,30]" |
| | | @pagination="getList" |
| | | /> |
| | | <!-- 添加或修改对话框 --> |
| | | <el-dialog :title="title" v-model="open" append-to-body center> |
| | | <el-form class="form-box" ref="formRef" :model="form" :rules="rules" label-width='auto'> |
| | | <el-form-item label="选择设备" prop="facilityId"> |
| | | <el-select v-model="form.facilityId" placeholder="请选择设备" @change="getFacityCodeList"> |
| | | <el-option |
| | | v-for="(item,index) in facityList" |
| | | :label="item.facilityName" |
| | | :value="item.id" |
| | | :key="index" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="设备参数" prop="columnsCode"> |
| | | <el-select v-model="form.columnsCode" placeholder="请选择设备参数"> |
| | | <el-option |
| | | v-for="(item,index) in facityCodeList" |
| | | :label="item.columnsShow" |
| | | :value="item.columnsCode" |
| | | :key="index" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="方案名称" prop="schemeName"> |
| | | <el-input v-model="form.schemeName" placeholder="请输入方案名称" /> |
| | | </el-form-item> |
| | | <el-form-item label="低报警值" prop="lowAlarm"> |
| | | <el-input v-model="form.lowAlarm" placeholder="请输入低报警值" /> |
| | | </el-form-item> |
| | | <el-form-item label="高报警值" prop="tallAlarm"> |
| | | <el-input v-model="form.tallAlarm" placeholder="请输入高报警值" /> |
| | | </el-form-item> |
| | | <el-form-item label="备注" prop="remark"> |
| | | <el-input v-model="form.remark" placeholder="请输入备注" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确 定</el-button> |
| | | <el-button @click="cancel">取 消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Menu"> |
| | | import facilityApi from '@/api/facility/index.js' |
| | | import waterFacilityParameter from '@/api/facility/parameter.js' |
| | | import alarmSchemeApi from '@/api/configuration/warning/alarmScheme.js' |
| | | import setPostParams from "@/utils/searchParams.js"; |
| | | import {onMounted} from "vue"; |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | |
| | | const pageParam = ref({ |
| | | total:0, |
| | | limit:0, |
| | | page:0, |
| | | }) |
| | | const tableData = ref([]); |
| | | let tableHeader = ref({ |
| | | schemeName: '方案名称', |
| | | facilityName: '设备名称', |
| | | columnsName: '参数名称', |
| | | lowAlarm: '低报警值', |
| | | tallAlarm: '高报警值', |
| | | remark: '备注', |
| | | createTimeView: '创建时间', |
| | | }) |
| | | |
| | | const open = ref(false); |
| | | const loading = ref(false); |
| | | const title = ref(""); |
| | | |
| | | const data = reactive({ |
| | | form:{}, |
| | | queryParams: { |
| | | name: undefined, |
| | | }, |
| | | rules: { |
| | | facilityId: [{ required: true, message: "请选择设备", trigger: "blur" }], |
| | | columnsCode: [{ required: true, message: "请选择设备参数", trigger: "blur" }], |
| | | schemeName: [{ required: true, message: "请输入方案名称", trigger: "blur" }], |
| | | lowAlarm: [{ required: true, message: "请输入低报警值", trigger: "blur" }], |
| | | tallAlarm: [{ required: true, message: "请输入高报警值", trigger: "blur" }], |
| | | remark: [{ required: false, message: "请输入备注信息", trigger: "blur" }], |
| | | }, |
| | | }); |
| | | const { queryParams, form, rules } = toRefs(data); |
| | | const facityList = ref([]); //设备列表 |
| | | const facityCodeList = ref([]); //设备参数列表 |
| | | |
| | | /** |
| | | * 搜索相关 |
| | | */ |
| | | /** 搜索按钮操作 */ |
| | | function handleQuery() { |
| | | getList({keywords:queryParams.value.name,page:1}) |
| | | } |
| | | |
| | | /** 重置按钮操作 */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryRef"); |
| | | handleQuery(); |
| | | } |
| | | |
| | | /** 获取列表 */ |
| | | async function getList(val) { |
| | | loading.value = true; |
| | | let postParam = setPostParams(val) |
| | | await alarmSchemeApi().search(postParam).then((res) =>{ |
| | | tableData.value = res.data.list |
| | | pageParam.value.total = res.data.total |
| | | pageParam.value.limit = res.data.limit |
| | | pageParam.value.page = res.data.page |
| | | }) |
| | | loading.value = false; |
| | | } |
| | | |
| | | // 获取设备 |
| | | const getFacityList = () => { |
| | | let postParam = setPostParams() |
| | | facilityApi().search(postParam).then(res => { |
| | | facityList.value = res.data.list |
| | | }) |
| | | } |
| | | |
| | | // 获取设备参数 |
| | | const getFacityCodeList = (id) => { |
| | | const code = id ? id : form.value.facilityId |
| | | waterFacilityParameter().getParam(code).then(res => { |
| | | facityCodeList.value = res.data |
| | | }) |
| | | } |
| | | |
| | | /** 新增按钮操作 */ |
| | | async function handleAdd() { |
| | | reset(); |
| | | open.value = true; |
| | | title.value = "新增方案配置"; |
| | | } |
| | | /** 修改按钮操作 */ |
| | | async function handleUpdate(row) { |
| | | reset(); |
| | | getFacityCodeList(row.facilityId) |
| | | form.value = Object.assign({},row) |
| | | open.value = true; |
| | | title.value = "修改方案配置"; |
| | | } |
| | | /** 删除按钮操作 */ |
| | | function handleDelete(row) { |
| | | proxy.$modal.confirm('是否确认删除名称为"' + row.name + '"的数据项?').then(function() { |
| | | return alarmSchemeApi().remove(row.id); |
| | | }).then(() => { |
| | | getList(); |
| | | proxy.$modal.msgSuccess("删除成功"); |
| | | }).catch(() => {}); |
| | | } |
| | | |
| | | /** 提交按钮 */ |
| | | async function submitForm() { |
| | | proxy.$refs["formRef"].validate( async valid => { |
| | | if (valid) { |
| | | form.value.lowAlarm = Number(form.value.lowAlarm) |
| | | form.value.tallAlarm = Number(form.value.tallAlarm) |
| | | if (form.value.id != undefined) { |
| | | await alarmSchemeApi().modify(form.value).then(res => { |
| | | proxy.$modal.msgSuccess("修改成功"); |
| | | open.value = false; |
| | | getList(); |
| | | }).catch(() =>{ |
| | | open.value = false; |
| | | proxy.$modal.msgError("修改失败"); |
| | | }); |
| | | } else { |
| | | await alarmSchemeApi().create(form.value).then(res => { |
| | | proxy.$modal.msgSuccess("新增成功"); |
| | | open.value = false; |
| | | getList(); |
| | | }).catch(() =>{ |
| | | open.value = false; |
| | | proxy.$modal.msgError("新增失败"); |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** 取消按钮 */ |
| | | function cancel() { |
| | | open.value = false; |
| | | reset(); |
| | | } |
| | | /** 表单重置 */ |
| | | function reset() { |
| | | form.value = { |
| | | facilityId:'', |
| | | columnsCode:'', |
| | | schemeName:'', |
| | | lowAlarm:'', |
| | | tallAlarm:'', |
| | | remark:'', |
| | | }; |
| | | proxy.resetForm("formRef"); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | getFacityList() |
| | | }) |
| | | </script> |
| | |
| | | <script setup> |
| | | import {onMounted, reactive} from 'vue' |
| | | import * as echarts from 'echarts/core'; |
| | | import { GridComponent, ToolboxComponent, TooltipComponent, TitleComponent } from 'echarts/components'; |
| | | import { LineChart, BarChart } from 'echarts/charts'; |
| | | import { UniversalTransition } from 'echarts/features'; |
| | | import { CanvasRenderer } from 'echarts/renderers'; |
| | | |
| | | echarts.use([GridComponent, LineChart, BarChart, CanvasRenderer, UniversalTransition, ToolboxComponent, TooltipComponent, TitleComponent]); |
| | | |
| | | const state = reactive({ |
| | | zhakouVal: 1, |
| | |
| | | height: 96%; |
| | | background: rgba(23,108,229,0.3); |
| | | border: 1px solid #176CE5; |
| | | border-radius: 8px; |
| | | .item-t{ |
| | | height: 10%; |
| | | padding: 0 30px; |
| | |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | <el-input v-model="searchVal" style="width: 20rem" /> |
| | | <el-input v-model="searchVal" style="width: 20rem" placeholder="请输入监测点名称" /> |
| | | <el-button><el-icon><Search /></el-icon>搜索</el-button> |
| | | <el-button style="margin-left: 0" v-if="userType === '1'"><el-icon><Plus /></el-icon>新增</el-button> |
| | | </div> |
| | |
| | | background: rgba(23,108,229,0.3); |
| | | border: 1px solid #176CE5; |
| | | padding: 20px; |
| | | border-radius: 8px; |
| | | .title{ |
| | | height: 12%; |
| | | text-align: center; |
| | |
| | | width: 100%; |
| | | height: 60%; |
| | | background: url("@/assets/images/login_icon.png") no-repeat; |
| | | background-size: 100% 100%; |
| | | } |
| | | .info{ |
| | | width: 100%; |
| | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import Table from '@/components/Table/index.vue' |
| | | |
| | | const selectType = ref(1); |
| | | const typeOption = ref([ |
| | | { label: '水电站流量监测点', value: 1 }, |
| | | { label: '新扎口流量监测点', value: 2 }, |
| | | ]) |
| | | const time = ref() |
| | | let tableHead = [ |
| | | { prop: 'code', label: '报警代码' }, |
| | | { prop: 'shebei', label: '报警设备', }, |
| | | { prop: 'content', label: '报警内容' }, |
| | | { prop: 'time', label: '报警时间' }, |
| | | { prop: 'sure', label: '报警确认', slot: true }, |
| | | ] |
| | | |
| | | const getTableData = () => { |
| | | return new Promise(resolve => { |
| | | let arr = { |
| | | list: [ |
| | | { code: '201', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 1 }, |
| | | { code: '202', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 2 }, |
| | | { code: '203', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 3 }, |
| | | { code: '204', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 1 }, |
| | | { code: '205', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 1 }, |
| | | { code: '206', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 1 }, |
| | | { code: '207', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 1 }, |
| | | { code: '208', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 2 }, |
| | | { code: '209', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 3 }, |
| | | { code: '2010', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 3 }, |
| | | ], |
| | | total: 30, |
| | | } |
| | | resolve(arr) |
| | | }) |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <template> |
| | | <div> |
| | | 报表管理 |
| | | <div class="report"> |
| | | <div class="report-tool"> |
| | | <el-select |
| | | v-model="selectType" |
| | | class="tool-select" |
| | | size="large" |
| | | placeholder="Select" |
| | | style="width: 20rem" |
| | | > |
| | | <el-option |
| | | v-for="item in typeOption" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | <el-select |
| | | v-model="selectType" |
| | | class="tool-select" |
| | | size="large" |
| | | placeholder="Select" |
| | | style="width: 20rem" |
| | | > |
| | | <el-option |
| | | v-for="item in typeOption" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | <el-date-picker |
| | | v-model="time" |
| | | type="datetimerange" |
| | | size="large" |
| | | style="width: 30rem" |
| | | range-separator="至" |
| | | start-placeholder="开始时间" |
| | | end-placeholder="结束时间" |
| | | /> |
| | | <el-button type="success" size="large" style="width: 6rem">一键导出</el-button> |
| | | </div> |
| | | <div class="report-table"> |
| | | <Table :getList="getTableData" :headList="tableHead"></Table> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | |
| | | .report{ |
| | | height: 100%; |
| | | background: linear-gradient( 180deg, #91BDDB 0%, rgba(102, 102, 102, 0.5) 100%); |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | &-tool{ |
| | | padding: 10px 0; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | gap: 30px; |
| | | :deep(.el-date-editor){ |
| | | flex-grow: 0; |
| | | } |
| | | } |
| | | &-table{ |
| | | width: 96%; |
| | | height: 90%; |
| | | background: rgba(23,108,229,0.3); |
| | | border: 1px solid #176CE5; |
| | | border-radius: 8px; |
| | | padding: 20px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import {getUserType} from '@/utils/auth.js' |
| | | |
| | | const userType = ref(getUserType()) |
| | | const monitorRef = ref() |
| | | const searchVal = ref('') |
| | | const selectNum = ref(6); |
| | | const numOption = ref([ |
| | | { label: '6个', value: 6 }, |
| | | { label: '2个', value: 2 }, |
| | | { label: '1个', value: 1 }, |
| | | ]) |
| | | |
| | | const shebeiData = ref([ |
| | | { name: '雷达水位计', code: 'SWY001', image: '', online: true, time: '2025-02-15', address: '上游灌木丛' }, |
| | | { name: '雷达水位计', code: 'SWY001', image: '', online: true, time: '2025-02-15', address: '上游灌木丛' }, |
| | | { name: '雷达水位计', code: 'SWY001', image: '', online: true, time: '2025-02-15', address: '上游灌木丛' }, |
| | | { name: '雷达水位计', code: 'SWY001', image: '', online: true, time: '2025-02-15', address: '上游灌木丛' }, |
| | | { name: '雷达水位计', code: 'SWY001', image: '', online: true, time: '2025-02-15', address: '上游灌木丛' }, |
| | | { name: '雷达水位计', code: 'SWY001', image: '', online: true, time: '2025-02-15', address: '上游灌木丛' }, |
| | | { name: '雷达水位计', code: 'SWY001', image: '', online: true, time: '2025-02-15', address: '上游灌木丛' }, |
| | | { name: '雷达水位计', code: 'SWY001', image: '', online: true, time: '2025-02-15', address: '上游灌木丛' }, |
| | | ]) |
| | | |
| | | // 全屏操作 |
| | | const handleFullScreen = () => { |
| | | monitorRef.value.requestFullscreen() |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <template> |
| | | <div> |
| | | 设备管理 |
| | | <div class="shebei"> |
| | | <div class="shebei-menu"> |
| | | <div class="menu-t">设备列表</div> |
| | | <el-menu class="el-menu"> |
| | | <el-sub-menu index="1"> |
| | | <template #title> |
| | | <span>雷达水位计</span> |
| | | </template> |
| | | <el-menu-item index="1-1">SWY001</el-menu-item> |
| | | <el-menu-item index="1-2">SWY002</el-menu-item> |
| | | </el-sub-menu> |
| | | <el-sub-menu index="2"> |
| | | <template #title> |
| | | <span>雷达测速仪</span> |
| | | </template> |
| | | <el-menu-item index="2-1">CY001</el-menu-item> |
| | | <el-menu-item index="2-2">CY002</el-menu-item> |
| | | </el-sub-menu> |
| | | <el-sub-menu index="3"> |
| | | <template #title> |
| | | <span>雷达流量计</span> |
| | | </template> |
| | | <el-menu-item index="3-1">LJL001</el-menu-item> |
| | | <el-menu-item index="3-2">LJL002</el-menu-item> |
| | | </el-sub-menu> |
| | | </el-menu> |
| | | </div> |
| | | <div class="shebei-monitor"> |
| | | <div class="monitor-tool"> |
| | | <div class="tool-l"> |
| | | <div class="name">展示数量</div> |
| | | <el-select |
| | | v-model="selectNum" |
| | | class="tool-select" |
| | | placeholder="Select" |
| | | style="width: 15rem" |
| | | > |
| | | <el-option |
| | | v-for="item in numOption" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | <el-input v-model="searchVal" style="width: 20rem" placeholder="请输入监测点名称" /> |
| | | <el-button><el-icon><Search /></el-icon>搜索</el-button> |
| | | <el-button style="margin-left: 0" v-if="userType === '1'"><el-icon><Plus /></el-icon>新增</el-button> |
| | | </div> |
| | | <div class="tool-r" @click="handleFullScreen"> |
| | | <img src="@/assets/images/flow/fullscreen.png" /> |
| | | 全屏 |
| | | </div> |
| | | </div> |
| | | <div class="monitor-box" ref="monitorRef"> |
| | | <div class="list-six list" v-if="selectNum === 6"> |
| | | <div class="item" v-for="(item, index) in shebeiData" :key="index"> |
| | | <div class="item-t"> |
| | | <div>{{item.name}}</div> |
| | | <div>{{item.code}}</div> |
| | | </div> |
| | | <div class="item-img"> |
| | | <img v-if="item.image" :src="item.image" /> |
| | | </div> |
| | | <div class="item-info"> |
| | | <div class="online">设备在线状态: <span :style="{color: item.online ? '#56d12c' : '#bababa'}">{{item.online ? '在线' : '掉线'}}</span></div> |
| | | <div class="time">安装时间: <span>{{item.time}}</span></div> |
| | | <div class="address">安装位置: <span>{{item.address}}</span></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="list-two list" v-else-if="selectNum === 2"> |
| | | <div class="item" v-for="(item, index) in shebeiData" :key="index"> |
| | | <div class="item-t"> |
| | | <div>{{item.name}}</div> |
| | | <div>{{item.code}}</div> |
| | | </div> |
| | | <div class="item-img"> |
| | | <img v-if="item.image" :src="item.image" /> |
| | | </div> |
| | | <div class="item-info"> |
| | | <div class="online">设备在线状态: <span :style="{color: item.online ? '#56d12c' : '#bababa'}">{{item.online ? '在线' : '掉线'}}</span></div> |
| | | <div class="time">安装时间: <span>{{item.time}}</span></div> |
| | | <div class="address">安装位置: <span>{{item.address}}</span></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="list-one list" v-else-if="selectNum === 1"> |
| | | <div class="item" v-for="(item, index) in shebeiData" :key="index"> |
| | | <div class="item-t"> |
| | | <div>{{item.name}}</div> |
| | | <div>{{item.code}}</div> |
| | | </div> |
| | | <div class="item-img"> |
| | | <img v-if="item.image" :src="item.image" /> |
| | | </div> |
| | | <div class="item-info"> |
| | | <div class="online">设备在线状态: <span :style="{color: item.online ? '#56d12c' : '#bababa'}">{{item.online ? '在线' : '掉线'}}</span></div> |
| | | <div class="time">安装时间: <span>{{item.time}}</span></div> |
| | | <div class="address">安装位置: <span>{{item.address}}</span></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="list-single" v-else></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | |
| | | .shebei{ |
| | | height: 100%; |
| | | display: flex; |
| | | &-menu{ |
| | | flex-shrink: 0; |
| | | width: 20%; |
| | | height: 100%; |
| | | padding: 10px 0; |
| | | background: linear-gradient( 135deg, #91BDDB 0%, #9EC2DB 99%); |
| | | overflow-y: scroll; |
| | | &::-webkit-scrollbar { |
| | | display: none; |
| | | } |
| | | .menu-t{ |
| | | height: 40px; |
| | | line-height: 40px; |
| | | padding-left: 20px; |
| | | font-size: 26px; |
| | | color: #fff; |
| | | background: url("@/assets/images/flow/monitor-title-bg.png") no-repeat; |
| | | background-size: 100% 100%; |
| | | } |
| | | .el-menu{ |
| | | background-color: transparent; |
| | | border-right: none; |
| | | :deep(.el-menu){ |
| | | background-color: transparent; |
| | | } |
| | | :deep(.el-sub-menu__title:hover) { |
| | | background-color: rgba(0, 0, 0, 0.06); |
| | | } |
| | | :deep(.el-menu-item.is-active) { |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | &-monitor{ |
| | | flex-shrink: 0; |
| | | width: 80%; |
| | | height: 100%; |
| | | background: linear-gradient( 180deg, #91BDDB 0%, rgba(102, 102, 102, 0.5) 100%); |
| | | .monitor-tool{ |
| | | width: 100%; |
| | | height: 60px; |
| | | padding: 0 30px; |
| | | background: linear-gradient( 90deg, #91BDDB 0%, #DADFE3 100%); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | .tool-l{ |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 1rem; |
| | | .name{ |
| | | font-size: 1.1rem; |
| | | } |
| | | } |
| | | .tool-r{ |
| | | display: flex; |
| | | align-items: center; |
| | | img{ |
| | | width: 25px; |
| | | margin-right: 10px; |
| | | } |
| | | } |
| | | } |
| | | .monitor-box{ |
| | | height: calc(100% - 60px); |
| | | padding-top: 10px; |
| | | .list{ |
| | | height: 100%; |
| | | padding: 0 30px; |
| | | overflow-y: scroll; |
| | | &::-webkit-scrollbar { |
| | | display: none; |
| | | } |
| | | .item{ |
| | | flex-shrink: 0; |
| | | background: rgba(23,108,229,0.3); |
| | | border: 1px solid #176CE5; |
| | | border-radius: 8px; |
| | | } |
| | | } |
| | | .list-six{ |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 20px; |
| | | .item{ |
| | | width: 32%; |
| | | height: 48%; |
| | | padding: 10px 20px; |
| | | .item-t{ |
| | | height: 10%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | font-size: 28px; |
| | | color: #fff; |
| | | } |
| | | .item-img{ |
| | | margin-top: 10px; |
| | | width: 100%; |
| | | height: 68%; |
| | | background-color: #000; |
| | | img{ |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
| | | .item-info{ |
| | | height: 18%; |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | color: #fff; |
| | | font-size: 1.2rem; |
| | | .online, |
| | | .time{ |
| | | width: 50%; |
| | | padding: 6px 0; |
| | | } |
| | | .address{ |
| | | width: 100%; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .list-two{ |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 20px; |
| | | .item{ |
| | | width: 49%; |
| | | height: 99%; |
| | | padding: 30px; |
| | | .item-t{ |
| | | height: 10%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | font-size: 36px; |
| | | color: #fff; |
| | | } |
| | | .item-img{ |
| | | margin-top: 10px; |
| | | width: 100%; |
| | | height: 68%; |
| | | background-color: #000; |
| | | img{ |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
| | | .item-info{ |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | color: #fff; |
| | | font-size: 1.5rem; |
| | | .online, |
| | | .time{ |
| | | width: 50%; |
| | | padding: 20px 0; |
| | | } |
| | | .address{ |
| | | width: 100%; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .list-one{ |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | .item{ |
| | | width: 70%; |
| | | height: 99%; |
| | | padding: 30px; |
| | | margin-bottom: 30px; |
| | | .item-t{ |
| | | height: 10%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | font-size: 36px; |
| | | color: #fff; |
| | | } |
| | | .item-img{ |
| | | margin-top: 10px; |
| | | width: 100%; |
| | | height: 75%; |
| | | background-color: #000; |
| | | img{ |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
| | | .item-info{ |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | color: #fff; |
| | | font-size: 1.5rem; |
| | | .online, |
| | | .time{ |
| | | width: 50%; |
| | | padding: 20px 0; |
| | | } |
| | | .address{ |
| | | width: 100%; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <script setup> |
| | | import {onMounted, ref} from "vue"; |
| | | import * as echarts from 'echarts/core'; |
| | | import Table from '@/components/Table/index.vue' |
| | | |
| | | const timeType = ref(0) |
| | | const warnChartRef = ref() |
| | | let warnCharts = null; |
| | | let tableHead = [ |
| | | { prop: 'code', label: '报警代码' }, |
| | | { prop: 'shebei', label: '报警设备', }, |
| | | { prop: 'content', label: '报警内容' }, |
| | | { prop: 'time', label: '报警时间' }, |
| | | { prop: 'sure', label: '报警确认', slot: true }, |
| | | ] |
| | | |
| | | const initWarnChart = () => { |
| | | if(warnChartRef.value) { |
| | | warnCharts = echarts.init(warnChartRef.value); |
| | | const options = { |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | }, |
| | | grid: { |
| | | top: 80, |
| | | left: 60, |
| | | right: 60, |
| | | bottom: 60 |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: ['设备离线', '水位异常', '流量异常', '流速异常', '其他异常'], |
| | | axisLabel: { |
| | | color: '#fff', |
| | | fontSize: '1.2rem' |
| | | } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | name: '次', |
| | | nameTextStyle: { |
| | | color: '#fff', |
| | | fontSize: '1.2rem' |
| | | }, |
| | | axisLabel: { |
| | | color: '#fff', |
| | | fontSize: '1.2rem' |
| | | } |
| | | }, |
| | | series: [ |
| | | { |
| | | data: [36, 44, 38, 24, 63], |
| | | type: 'bar', |
| | | itemStyle: { |
| | | color: 'rgba(187,207,255,0.6)' |
| | | } |
| | | } |
| | | ] |
| | | } |
| | | warnCharts.setOption(options); |
| | | } |
| | | } |
| | | |
| | | const getTableData = () => { |
| | | return new Promise(resolve => { |
| | | let arr = { |
| | | list: [ |
| | | { code: '201', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 1 }, |
| | | { code: '202', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 2 }, |
| | | { code: '203', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 3 }, |
| | | { code: '204', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 1 }, |
| | | { code: '205', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 1 }, |
| | | { code: '206', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 1 }, |
| | | { code: '207', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 1 }, |
| | | { code: '208', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 2 }, |
| | | { code: '209', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 3 }, |
| | | { code: '2010', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 3 }, |
| | | ], |
| | | total: 30, |
| | | } |
| | | resolve(arr) |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | initWarnChart() |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div> |
| | | 预警管理 |
| | | <div class="warn"> |
| | | <div class="warn-l item"> |
| | | <div class="item-t"> |
| | | <div class="name">报警分析</div> |
| | | <div class="select"> |
| | | <el-radio-group v-model="timeType"> |
| | | <el-radio :value="1">日</el-radio> |
| | | <el-radio :value="2">月</el-radio> |
| | | <el-radio :value="3">年</el-radio> |
| | | </el-radio-group> |
| | | </div> |
| | | </div> |
| | | <div class="charts" ref="warnChartRef"></div> |
| | | </div> |
| | | <div class="warn-r item"> |
| | | <div class="item-t"> |
| | | <div class="name">报警记录</div> |
| | | </div> |
| | | <div class="warn-table"> |
| | | <Table :getList="getTableData" :headList="tableHead"> |
| | | <template #sure="scope"> |
| | | <div v-if="scope.row.sure === 1" style="color: #1ab394">已处理</div> |
| | | <div v-else-if="scope.row.sure === 2" style="color: #e8ab04">未处理</div> |
| | | <div v-else style="color: #f30101">待确认</div> |
| | | </template> |
| | | <template v-slot:pagination> |
| | | <el-button type="success" style="width: 6rem">导出</el-button> |
| | | </template> |
| | | </Table> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | |
| | | .warn{ |
| | | height: 100%; |
| | | background: linear-gradient( 180deg, #91BDDB 0%, rgba(102, 102, 102, 0.5) 100%); |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | gap: 30px; |
| | | .item{ |
| | | width: 48%; |
| | | height: 96%; |
| | | background: rgba(23,108,229,0.3); |
| | | border: 1px solid #176CE5; |
| | | border-radius: 8px; |
| | | .item-t{ |
| | | height: 10%; |
| | | padding: 0 30px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | .name{ |
| | | font-size: 36px; |
| | | color: #fff; |
| | | } |
| | | .select{ |
| | | :deep(.el-radio){ |
| | | color: #fff; |
| | | } |
| | | :deep(.el-radio__label){ |
| | | font-size: 20px; |
| | | } |
| | | :deep(.el-radio__input.is-checked+.el-radio__label){ |
| | | color: #00ff00; |
| | | } |
| | | :deep(.el-radio__input.is-checked .el-radio__inner){ |
| | | background-color: #00ff00; |
| | | } |
| | | } |
| | | } |
| | | .charts{ |
| | | height: 90%; |
| | | } |
| | | .warn-table{ |
| | | padding: 0 20px; |
| | | height: 90%; |
| | | } |
| | | } |
| | | } |
| | | </style> |