Browse Source

页面合并处理

IoT
fuguobin 12 months ago
parent
commit
37e3db7b6f
  1. 3
      package.json
  2. 52
      pnpm-lock.yaml
  3. 296
      src/api/monitoring/table/index.js
  4. 3
      src/main.js
  5. 2
      src/plugins/bus.js
  6. 10
      src/router/index.js
  7. 6
      src/styles/index.scss
  8. 109
      src/utils/index.js
  9. 6
      src/utils/request.js
  10. 105
      src/views/monitoring/data-monitor/index.vue
  11. 472
      src/views/monitoring/equipment/components/header.vue
  12. 440
      src/views/monitoring/equipment/components/main.vue
  13. 314
      src/views/monitoring/equipment/components/menu.vue
  14. 766
      src/views/monitoring/equipment/index.scss
  15. 67
      src/views/monitoring/equipment/index.vue
  16. 300
      src/views/monitoring/graph/index.scss
  17. 1228
      src/views/monitoring/graph/index.vue
  18. 162
      src/views/monitoring/station/components/bar - 副本.vue
  19. 154
      src/views/monitoring/station/components/boxPlot - 副本.vue
  20. 142
      src/views/monitoring/station/components/table - 副本.vue
  21. 2
      src/views/monitoring/station/components/table.vue
  22. 715
      src/views/system/menu/index.vue
  23. 14
      vite/plugins/auto-import.js
  24. 22
      vite/plugins/index.js

3
package.json

@ -55,9 +55,9 @@
"xe-utils": "^3.5.14"
},
"devDependencies": {
"@types/crypto-js": "^4.2.1",
"@typescript-eslint/eslint-plugin": "^5.19.0",
"@typescript-eslint/parser": "^5.19.0",
"@types/crypto-js": "^4.2.1",
"@vicons/antd": "^0.12.0",
"@vicons/ionicons5": "^0.12.0",
"@vicons/tabler": "^0.12.0",
@ -67,6 +67,7 @@
"sass": "1.56.1",
"typescript": "^4.7.4",
"unplugin-auto-import": "^0.11.5",
"unplugin-vue-components": "^0.26.0",
"vite": "^3.2.3",
"vite-plugin-compression": "0.5.1",
"vite-plugin-svg-icons": "2.0.1",

52
pnpm-lock.yaml

@ -157,6 +157,9 @@ devDependencies:
unplugin-auto-import:
specifier: ^0.11.5
version: 0.11.5(@vueuse/core@9.5.0)
unplugin-vue-components:
specifier: ^0.26.0
version: 0.26.0(vue@3.2.45)
vite:
specifier: ^3.2.3
version: 3.2.8(sass@1.56.1)
@ -976,6 +979,12 @@ packages:
concat-map: 0.0.1
dev: true
/brace-expansion@2.0.1:
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
dependencies:
balanced-match: 1.0.2
dev: true
/braces@2.3.2:
resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==}
engines: {node: '>=0.10.0'}
@ -2430,6 +2439,13 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.15
dev: true
/magic-string@0.30.8:
resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==}
engines: {node: '>=12'}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
dev: true
/map-cache@0.2.2:
resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==}
engines: {node: '>=0.10.0'}
@ -2521,6 +2537,13 @@ packages:
brace-expansion: 1.1.11
dev: true
/minimatch@9.0.3:
resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
brace-expansion: 2.0.1
dev: true
/minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
dev: true
@ -3383,6 +3406,35 @@ packages:
- rollup
dev: true
/unplugin-vue-components@0.26.0(vue@3.2.45):
resolution: {integrity: sha512-s7IdPDlnOvPamjunVxw8kNgKNK8A5KM1YpK5j/p97jEKTjlPNrA0nZBiSfAKKlK1gWZuyWXlKL5dk3EDw874LQ==}
engines: {node: '>=14'}
peerDependencies:
'@babel/parser': ^7.15.8
'@nuxt/kit': ^3.2.2
vue: 2 || 3
peerDependenciesMeta:
'@babel/parser':
optional: true
'@nuxt/kit':
optional: true
dependencies:
'@antfu/utils': 0.7.7
'@rollup/pluginutils': 5.1.0
chokidar: 3.6.0
debug: 4.3.4
fast-glob: 3.3.2
local-pkg: 0.4.3
magic-string: 0.30.8
minimatch: 9.0.3
resolve: 1.22.8
unplugin: 1.9.0
vue: 3.2.45
transitivePeerDependencies:
- rollup
- supports-color
dev: true
/unplugin@1.9.0:
resolution: {integrity: sha512-14PslvMY3gNbXnQtNIRB566Q057L5Fe7f5LDEamxVi0QQVxoz5hrveBwwZLcKyHtZ09ysmipxRRj5Lv+BGz2Iw==}
engines: {node: '>=14.0.0'}

296
src/api/monitoring/table/index.js

@ -0,0 +1,296 @@
import request from "@/utils/request";
/**
* 获取左侧菜单
*/
export function getMenu() {
return request({
url: "/bi/opt/getMenu",
method: "get",
});
}
/**
* 获取热源信息
*/
export function getStationInfo() {
return request({
url: "/bi/opt/getStationInfo",
method: "get",
});
}
/**
* 获取表格header
*/
export function getTableHeader() {
return request({
// url: '/bi/opt/getTableHeader',
url: "/dc/data/monitor/table/header",
method: "get",
});
}
// /**
// * 获取表格数据
// *
// * @param id
// */
// export function getTableData(params): AxiosPromise<TableVo> {
// return request({
// url: '/bi/opt/getTableData/' + params,
// method: 'get'
// });
// }
/**
* 获取表格数据
*
* @param data
*/
export function getTableData(data) {
return request({
// url: '/bi/opt/getTableDataPage',
url: "/dc/data/monitor/table/data",
method: "post",
data: data,
});
}
/**
* 获取供暖办表格header
*/
export function getMockTableHeader() {
return request({
// url: '/bi/opt/getTableHeader',
url: "/dc/mock/data/monitor/table/header",
method: "get",
});
}
/**
* 获取供暖办表格数据
*
* @param data
*/
export function getMockTableData(data) {
return request({
// url: '/bi/opt/mock/getTableDataPage',
url: "/dc/mock/data/monitor/table/data",
method: "post",
data: data,
});
}
/**
* 配置项修改
*
* @param data
*/
export function editConfig(data) {
return request({
url: "/dc/dcUserMonitorConfig/A",
method: "post",
data: data,
});
}
/**
* 获取底部面板信息
*/
export function getTableFooter(params) {
return request({
url: "/bi/opt/getTableFooter/" + params,
method: "get",
});
}
/** 发送控制参数 */
export function sendCtrl(data) {
return request({
url: "/bi/opt/device/ctrl",
method: "post",
data: data,
});
}
/**
* 获取报表统计
*
* @param queryParams
*/
export function dcBusiDayReport(queryParams) {
return request({
url: "/dc/dcBusiDayReport/list",
method: "get",
params: queryParams,
});
}
/**
* 获取报警列表
*
* @param data
*/
export function getWarList(data) {
return request({
url: "/dc/dcBusiAlertJob/list/vo",
method: "post",
data: data,
});
}
/**
* 获取报警列表确认
*
* @param params id
*/
export function process(id) {
return request({
url: "/dc/dcBusiAlertJob/process/" + id,
method: "post",
});
}
/**
* 关闭报警
*
* @param data
*/
export function setAlarm(data) {
return request({
url: "/dc/dcBusiAlertJob/alertSwith",
method: "post",
data: data,
});
}
/**
* 获取左侧菜单
*/
export function getMenuData() {
return request({
url: "/bi/configuration/getMenuData",
method: "get",
});
}
/**
* 获取用户部门
*/
export function getDept() {
return request({
url: "/bi/configuration/getMenu",
method: "get",
});
}
/**
* 获取设备列表
*
* @param params 部门Id
*/
export function getDeviceList(params) {
return request({
url: "/bi/configuration/getDeviceListByDept/" + params,
method: "get",
});
}
/**
* 获取设备列表
*
* @param params 设备Id
*/
export function getViewInfo(params) {
return request({
url: "/bi/configuration/getViewInfoById/" + params,
method: "get",
});
}
/**
* 获取图表详情设备筛选项
*/
export function getDevices(params) {
return request({
// url: '/dc/dcDeviceEcharts/getDevices/' + params,
url: "/dc/data/monitor/asset/list/" + params,
method: "get",
});
}
/**
* 获取图表详情设备筛选项
*/
export function getAllDevices() {
return request({
url: "/dc/dcDeviceEcharts/getAllDevices",
method: "get",
});
}
/**
* 获取图表详情参数集
*/
export function getClass() {
return request({
url: "/dc/dcDeviceEcharts/getParamSet",
method: "get",
});
}
/**
* 获取图表详情参数筛选项
*/
export function getParams() {
return request({
url: "/dc/dcDeviceEcharts/getParams",
method: "get",
});
}
/**
* 获取图表详情分区筛选项
*/
export function getPortions() {
return request({
url: "/dc/dcDeviceEcharts/getPortions",
method: "get",
});
}
/**
* 获取折线图数据
*
* @param data
*/
export function getDeviceInfos(data) {
return request({
// url: '/dc/dcDeviceEcharts/getDeviceInfos',
url: "/dc/data/monitor/history/data",
method: "post",
data: data,
});
}
/**
* 获取轮询折线图数据
*
* @param data
*/
export function getDeviceInfosPolling(data) {
return request({
// url: '/dc/dcDeviceEcharts/device/realtime/data',
url: "/dc/data/monitor/realtime/data",
method: "post",
data: data,
});
}
/**
* 天气数据图表
*
* @param data
*/
export function weatherHoursList(data) {
return request({
url: "/dc/dcDeviceEcharts/weatherHoursList",
method: "post",
data: data,
});
}

3
src/main.js

@ -3,6 +3,7 @@ import { createApp } from "vue";
import Cookies from "js-cookie";
import ElementPlus from "element-plus";
import naive from "naive-ui";
import locale from "element-plus/lib/locale/lang/zh-cn"; // 中文语言
import { useTable } from "./plugins/vxe-table";
@ -107,6 +108,6 @@ app.use(ElementPlus, {
// 支持 large、default、small
size: Cookies.get("size") || "default",
});
app.use(naive);
app.use(useTable);
app.mount("#app");

2
src/plugins/bus.js

@ -0,0 +1,2 @@
import mitt from 'mitt'
export default mitt()

10
src/router/index.js

@ -47,11 +47,21 @@ export const constantRoutes = [
component: () => import("@/views/register"),
hidden: true,
},
{
path: "/monitoring/equipment",
component: () => import("@/views/monitoring/equipment/index"),
hidden: true,
},
{
path: "/monitoring/station",
component: () => import("@/views/monitoring/station/index"),
hidden: true,
},
{
path: "/monitoring/graph",
component: () => import("@/views/monitoring/graph/index"),
hidden: true,
},
{
path: "/index1",
component: () => import("@/views/index1"),

6
src/styles/index.scss

@ -184,9 +184,9 @@
}
}
.el-overlay {
z-index: 99999 !important;
}
// .el-overlay {
// z-index: 99999 !important;
// }
.el-notification {
border: none !important;

109
src/utils/index.js

@ -421,6 +421,90 @@ export function throttle(handler, wait) {
}
};
}
/**
* 数组对象根据字段去重
* @param {array} arr 要去重的数组
* @param {string} key 根据去重的字段名
*/
export function uniqueArrayObject(arr = [], key = "id") {
if (arr.length === 0) return;
let list = [];
const map = {};
arr.forEach((item) => {
if (!map[item[key]]) {
map[item[key]] = item;
}
});
list = Object.values(map);
return list;
}
/**
* 获取数组对象最后一个层级的数据
* @param {array} data 数组
*/
export function getLastLevelNode(data) {
if (data.length === 0) {
return null; // 数组为空,返回null或自定义默认值
}
const lastItem = data[data.length - 1]; // 获取数组的最后一个元素
if (lastItem.children && lastItem.children.length > 0) {
return getLastLevelNode(lastItem.children); // 继续递归调用
}
return lastItem; // 返回最后一个层级
}
/**
* 获取数组对象第一个节点最后一个层级的数据
* @param {array} data 数组
*/
export function getFirstNodeLastLevel(data) {
if (data.length === 0) {
return null; // 数组为空,返回null或自定义默认值
}
const firstNode = data[0];
if (firstNode.children && firstNode.children.length > 0) {
return getFirstNodeLastLevel(firstNode.children);
}
return firstNode; // 返回第一个节点的最后一个层级的数据
}
/**
* 获取数组对象第一个节点最后一个层级的数据
* @param {array} obj1 数组1
* @param {array} obj2 数组2
*/
export function isEqual(obj1, obj2) {
// 判断两个对象的类型是否相同
if (typeof obj1 !== typeof obj2) {
return false;
}
// 如果是基本类型数据,则直接比较它们的值
if (typeof obj1 !== "object") {
return obj1 === obj2;
}
// 获取obj1和obj2的属性名称
const obj1Keys = Object.keys(obj1);
const obj2Keys = Object.keys(obj2);
// 如果两个对象的属性数量不同,则它们不相等
if (obj1Keys.length !== obj2Keys.length) {
return false;
}
// 递归比较obj1和obj2的属性和值
for (let key of obj1Keys) {
if (!isEqual(obj1[key], obj2[key])) {
return false;
}
}
// 如果所有属性和值都相等,则两个对象相等
return true;
}
/**
* 值之间的过度
* @param {number} num 需要过度的数值
@ -471,3 +555,28 @@ export function getUrlRouter() {
var hrefarr = args[1].split("/")[1].split("?");
return hrefarr;
}
/**
* 计算当前之后一段时间
* @param {Date} currentTime 当前时间
* @param {string} type 类型1:,2:,3:,4:,5:,6:
*/
export const endTime = (currentTime, type) => {
const today = new Date(currentTime);
switch (type) {
case "1":
return new Date(today.getTime() + 24 * 60 * 60 * 1000);
case "2":
return new Date(today.getTime() + 60 * 60 * 1000);
case "3":
return new Date(today.getTime() + 60 * 1000);
case "4":
return new Date(today.getTime() + 1000);
case "5":
return new Date(today.getTime() + 30 * 24 * 60 * 60 * 1000);
case "6":
return new Date(today.getTime() + 365 * 24 * 60 * 60 * 1000);
default:
return today;
}
};

6
src/utils/request.js

@ -69,12 +69,6 @@ service.interceptors.request.use(
const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
console.log(
"s_data:",
s_data === requestObj.data && requestObj.time - s_time
);
console.log("interval:", interval);
console.log("s_url:", s_url === requestObj.url);
if (
s_data === requestObj.data &&
requestObj.time - s_time < interval &&

105
src/views/monitoring/data-monitor/index.vue

@ -1,108 +1,7 @@
<template>
<div>
<vxe-grid v-bind="gridOptions">
<template #toolbar_buttons>
<vxe-button @click="gridOptions.align = 'left'">居左</vxe-button>
<vxe-button @click="gridOptions.align = 'center'">居中</vxe-button>
<vxe-button @click="gridOptions.align = 'right'">居右</vxe-button>
</template>
</vxe-grid>
<n-button type="primary"> Primary </n-button>
</div>
</template>
<script setup>
import { reactive } from "vue";
const gridOptions = reactive({
border: true,
height: 300,
align: null,
columnConfig: {
resizable: true,
},
columns: [
{ type: "seq", width: 50 },
{ field: "name", title: "name" },
{ field: "sex", title: "sex" },
{ field: "address", title: "Address" },
],
toolbarConfig: {
slots: {
buttons: "toolbar_buttons",
},
},
data: [
{
id: 10001,
name: "Test1",
nickname: "T1",
role: "Develop",
sex: "Man",
age: 28,
address: "Shenzhen",
},
{
id: 10002,
name: "Test2",
nickname: "T2",
role: "Test",
sex: "Women",
age: 22,
address: "Guangzhou",
},
{
id: 10003,
name: "Test3",
nickname: "T3",
role: "PM",
sex: "Man",
age: 32,
address: "Shanghai",
},
{
id: 10004,
name: "Test4",
nickname: "T4",
role: "Designer",
sex: "Women",
age: 23,
address: "Shenzhen",
},
{
id: 10005,
name: "Test5",
nickname: "T5",
role: "Develop",
sex: "Women",
age: 30,
address: "Shanghai",
},
{
id: 10006,
name: "Test6",
nickname: "T6",
role: "Designer",
sex: "Women",
age: 21,
address: "Shenzhen",
},
{
id: 10007,
name: "Test7",
nickname: "T7",
role: "Test",
sex: "Man",
age: 29,
address: "Shenzhen",
},
{
id: 10008,
name: "Test8",
nickname: "T8",
role: "Develop",
sex: "Man",
age: 35,
address: "Shenzhen",
},
],
});
</script>
<script setup></script>

472
src/views/monitoring/equipment/components/header.vue

@ -0,0 +1,472 @@
<template>
<div class="title">
<h3>{{ titleData }}</h3>
</div>
<div class="weather">
<div class="time">{{ currentTime }} {{ lunarDay.ncWeek }}</div>
<div class="line"></div>
<div class="forecast">
<span
>{{ weatherData.city }}{{ weatherData.weather }}
{{ weatherData.temperature }}</span
>
<svg-icon class="weatherSvg" :icon-class="weatherData.weatherImg" />
<!-- <img src="../../../assets/images/weather/duoyun.png" /> -->
</div>
</div>
<div class="seeting">
<n-tooltip trigger="hover">
<template #trigger>
<n-button class="tooltips" circle quaternary @click="returnBack">
<template #icon>
<n-icon>
<ReturnDownBack />
</n-icon>
</template>
</n-button>
</template>
返回上一页
</n-tooltip>
<n-tooltip trigger="hover">
<template #trigger>
<n-button class="tooltips" circle quaternary @click="lineClick">
<template #icon>
<n-icon>
<ChartLine />
</n-icon>
</template>
</n-button>
</template>
图表
</n-tooltip>
<n-tooltip trigger="hover" v-if="settingShow">
<template #trigger>
<n-button class="tooltips" circle quaternary @click="showClick">
<template #icon>
<n-icon>
<Settings />
</n-icon>
</template>
</n-button>
</template>
显示项
</n-tooltip>
<n-tooltip trigger="hover" v-if="warningShow">
<template #trigger>
<n-badge class="warningbadge" :value="waringData.length" :max="15">
<n-button class="tooltips" circle quaternary @click="waringClick">
<template #icon>
<n-icon>
<Bell />
</n-icon>
</template>
</n-button>
</n-badge>
</template>
报警
</n-tooltip>
</div>
<n-drawer
class="waringDrawer"
v-model:show="waringDrawer"
:default-width="420"
resizable
placement="right"
>
<n-drawer-content closable>
<template #header>
<div class="title">
<span>消息</span>
<span class="button" @click="waringMore">更多</span>
</div>
</template>
<div class="waringList">
<div class="item" v-for="(item, index) in waringData" :key="index">
<div class="name">
<span>{{ item.deviceName }}</span>
<span class="time">{{ item.alertTime }}</span>
</div>
<div class="info">
<span>{{ item.paramName }}</span>
<n-button type="info" size="small" @click="waringConfirm(item)"
>确认</n-button
>
</div>
</div>
</div>
</n-drawer-content>
</n-drawer>
<n-modal class="waringModal" v-model:show="waringModal">
<n-card :bordered="false" size="huge" role="dialog" aria-modal="true">
<el-table
class="waringTable"
:data="waringList"
header-row-class-name="headerRowClass"
header-cell-class-name="headerCellClass"
row-class-name="rowClass"
cell-class-name="cellClass"
height="350"
stripe
>
<el-table-column prop="deviceName" label="设备名称" align="center" />
<el-table-column prop="paramName" label="变量名称" align="center" />
<el-table-column prop="alertName" label="告警级别" align="center">
<template #default="scope">
<span class="level">{{ scope.row.alertName }}</span>
</template>
</el-table-column>
<el-table-column prop="totalCounts" label="告警累计" align="center" />
<el-table-column label="报警时间" align="center">
<el-table-column
prop="alertFirstTimeS"
label="首次告警时间"
align="center"
/>
<el-table-column
prop="alertLastTimeS"
label="末次告警时间"
align="center"
/>
</el-table-column>
<el-table-column fixed="right" label="操作" align="center">
<template #default="scope">
<el-button
class="confirm"
type="info"
size="small"
@click="waringConfirm(scope.row)"
>确认</el-button
>
</template>
</el-table-column>
</el-table>
<el-pagination
class="waringPagination"
layout="prev, pager, next"
:current-page.sync="params.pageNum"
:page-size="params.pageSize"
:total="params.total"
hide-on-single-page
@current-change="handleCurrentChange"
/>
<div class="warClose" @click="warClose">
<CloseCircleOutline />
</div>
</n-card>
</n-modal>
</template>
<script setup>
import { useRoute, useRouter } from "vue-router";
import { getWeather } from "@/api/system/user";
import { getWarList, process } from "@/api/monitoring/table";
import {
Filter,
Maximize,
Settings,
Power,
Bell,
ChartLine,
} from "@vicons/tabler";
import { CloseCircleOutline, ReturnDownBack } from "@vicons/ionicons5";
import { useDateFormat, useNow } from "@vueuse/core";
// import { uniqueArrayObject } from "@/utils/index";
import mitt from "@/plugins/bus";
import calendar from "@/utils/lunar";
const route = useRoute();
const router = useRouter();
const currentTime = useDateFormat(useNow(), "YYYY-MM-DD HH:mm:ss");
const emit = defineEmits(["showModalClick", "returnClick"]);
const timer = ref();
const isCurrentRoute = ref(true);
const waringDrawer = ref(false);
const waringModal = ref(false);
const waringData = ref([]);
const waringList = ref([]);
const routerType = ref("");
const deptId = ref(0);
const params = reactive({
total: 10,
pageSize: 10,
pageNum: 1,
});
const weatherData = ref({
city: "",
weather: "",
temperature: "",
weatherImg: "",
});
const lunarDay = calendar.solarToLunar(
useNow().value.getUTCFullYear(),
useNow().value.getUTCMonth() + 1,
useNow().value.getUTCDate()
);
const props = defineProps({
titleData: {
type: String,
default: "数据监控",
},
settingShow: {
type: Boolean,
default: false,
},
warningShow: {
type: Boolean,
default: false,
},
});
onMounted(() => {
deptId.value =
sessionStorage.getItem("deptId") === null
? 0
: Number(sessionStorage.getItem("deptId"));
routerType.value = route.query?.id === undefined ? "0" : "1";
getWeatherData();
});
mitt.on("waringMessage", (res) => {
//
console.log("waringMessage--", res.data);
waringData.value = res.data;
// waringData.value.push(res.data)
// console.log("waringData--", waringData.value);
// waringData.value = uniqueArrayObject(waringData.value, "id")
// console.log("waringData--", waringData.value);
});
function showClick() {
///
emit("showModalClick", true);
// showModal.value = true;
}
function returnBack() {
//
// emit('returnClick', '');
console.log("route.path:", route.path);
if (routerType.value === "1" && route.path != "/monitoring/data-monitor") {
router.push({
path: "/monitoring/data-monitor",
query: { id: sessionStorage.getItem("id") },
});
} else {
router.go(-1);
}
}
function waringClick() {
//
// if (waringData.value.length === 0) {
// ElNotification({
// message: '',
// type: 'info',
// })
// } else {
waringDrawer.value = true;
// }
}
function lineClick() {
//
router.push({
path: "/monitoring/graph",
});
}
function handleCurrentChange(val) {
//
params.pageNum = val;
getwaringList();
}
function getWeatherData() {
//
getWeather().then((res) => {
if (res.code === 200) {
if (isCurrentRoute) {
timer.value = setTimeout(async () => {
await (timer.value && clearTimeout(timer.value));
await getWeatherData();
}, 600000);
}
weatherData.value = res.data;
} else {
clearTimeout(timer.value);
}
});
}
function waringMore() {
//
waringDrawer.value = false;
waringModal.value = true;
getwaringList();
}
function getwaringList() {
//
const paramsr = {
beginTime: "",
endTime: "",
orgCode:
sessionStorage.getItem("deptId") === null
? 0
: Number(sessionStorage.getItem("deptId")),
params,
};
getWarList(paramsr).then((res) => {
if (res.code === 200) {
waringList.value = res.rows;
params.total = res.total;
// page.pageSize = res.size;
// page.pageSize = res.current;
}
});
}
function waringConfirm(item) {
//
ElMessageBox.confirm("是否确认操作?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
const params = item.id;
process(params).then((res) => {
if (res.code === 200) {
waringList.value = res.data;
// waringDrawer.value = false
// waringModal.value = false
getwaringList();
ElMessage({
message: res.msg,
grouping: true, //
type: "success",
});
}
});
})
.catch(() => {});
}
function warClose() {
//
waringModal.value = false;
}
</script>
<style lang="scss" scoped>
.header {
display: flex;
justify-content: space-between;
align-items: center;
// height: 5.7rem;
.title {
width: 80%;
background: url(@/assets/images/title-bg.png);
background-size: 100%;
text-align: center;
padding-bottom: 38px;
margin: 0 auto;
h3 {
height: 57px;
font-size: 3.8rem;
font-family: "YouSheBiaoTiHei";
font-weight: 400;
letter-spacing: 4px;
background: linear-gradient(180deg, #fefdff 0%, #95daff 97%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0;
}
}
}
.weather {
display: flex;
align-items: center;
position: absolute;
top: 2.5rem;
left: 7rem;
color: #b2d4ff;
font-size: 1.8rem;
line-height: 2.2rem;
font-family: "AlibabaPuHuiTiRegular";
.line {
width: 2px;
height: 2rem;
background: linear-gradient(to top, #000e38, #1ea8dd, #000e38);
margin: 0 1rem;
}
.forecast {
display: flex;
align-items: center;
.weatherSvg {
width: 1.5em !important;
height: 1.5em !important;
margin-left: 10px;
}
// img {
// width: 25px;
// margin-left: 10px;
// }
}
}
.seeting {
position: absolute;
top: 2.5rem;
right: 7rem;
.warningbadge {
margin-top: -10px;
}
.tooltips {
width: 36px;
height: 36px;
background: linear-gradient(
180deg,
#003269 1%,
rgba(3, 79, 163, 0.2314) 56%,
#003269 100%
);
border-radius: 0px 0px 0px 0px;
opacity: 1;
:deep(span) {
color: #5beff9;
}
margin-left: 10px;
}
}
.waringModal {
.waringPagination {
justify-content: right;
margin-top: 5px;
:deep(button) {
color: #b1e3ff;
background: transparent;
}
:deep(.el-pager) {
.number,
.more {
color: #b1e3ff;
background: transparent;
}
.number.is-active {
color: #409eff;
}
}
}
}
</style>

440
src/views/monitoring/equipment/components/main.vue

@ -0,0 +1,440 @@
<template>
<div class="devicePrt">
<div class="deviceImg deviceImgA" v-if="zoneType === 1">
<div class="card card_a">
<div class="dataInfo" v-html="doubleCount('013', 0)"></div>
<div class="dataInfo" v-html="doubleCount('011', 0)"></div>
<div class="dataInfo" v-html="doubleCount('014', 0)"></div>
<div class="dataInfo" v-html="doubleCount('012', 0)"></div>
</div>
<div class="card card_b">
<div class="dataInfo" v-html="doubleCount('002', 0)"></div>
<div class="dataInfo" v-html="doubleCount('007', 0)"></div>
</div>
<div class="card card_c">
<div class="dataInfo" v-html="doubleCount('047', 0)"></div>
<div class="dataInfo" v-html="doubleCount('045', 0)"></div>
<div class="dataInfo" v-html="doubleCount('048', 0)"></div>
<div class="dataInfo" v-html="doubleCount('046', 0)"></div>
</div>
<div class="card card_f">
<div class="dataInfo" v-html="doubleCount('015', 0)"></div>
</div>
<!-- <div class="switch switch_a" @click="switchClick('001', 0)"></div> -->
<!-- <div class="switch switch_b" @click="switchClick('065', 0)"></div> -->
<img class="deviceImg" :src="deviceImg" />
<!-- <img class="deviceImg" src="@/assets/images/device01.gif" /> -->
</div>
<div class="deviceImg deviceImgB" v-if="zoneType === 2">
<div class="card card_a">
<div class="dataInfo" v-html="doubleCount('013', 0)"></div>
<div class="dataInfo" v-html="doubleCount('011', 0)"></div>
<div class="dataInfo" v-html="doubleCount('014', 0)"></div>
<div class="dataInfo" v-html="doubleCount('012', 0)"></div>
</div>
<div class="card card_b">
<div class="dataInfo" v-html="doubleCount('002', 0)"></div>
<div class="dataInfo" v-html="doubleCount('007', 0)"></div>
<div class="dataInfo" v-html="doubleCount('002', 1)"></div>
<div class="dataInfo" v-html="doubleCount('007', 1)"></div>
</div>
<div class="card card_c">
<div class="dataInfo" v-html="doubleCount('047', 0)"></div>
<div class="dataInfo" v-html="doubleCount('045', 0)"></div>
<div class="dataInfo" v-html="doubleCount('048', 0)"></div>
<div class="dataInfo" v-html="doubleCount('046', 0)"></div>
</div>
<div class="card card_d">
<div class="dataInfo" v-html="doubleCount('047', 1)"></div>
<div class="dataInfo" v-html="doubleCount('045', 1)"></div>
<div class="dataInfo" v-html="doubleCount('048', 1)"></div>
<div class="dataInfo" v-html="doubleCount('046', 1)"></div>
</div>
<div class="card card_f">
<div class="dataInfo" v-html="doubleCount('015', 0)"></div>
</div>
<img class="deviceImg" :src="deviceImg" />
<!-- <img class="deviceImg" src="@/assets/images/device02.gif" /> -->
</div>
<div class="deviceImg deviceImgC" v-if="zoneType === 3">
<div class="card card_a">
<div class="dataInfo" v-html="doubleCount('013', 0)"></div>
<div class="dataInfo" v-html="doubleCount('011', 0)"></div>
<div class="dataInfo" v-html="doubleCount('014', 0)"></div>
<div class="dataInfo" v-html="doubleCount('012', 0)"></div>
</div>
<div class="card card_b">
<div class="dataInfo" v-html="doubleCount('002', 0)"></div>
<div class="dataInfo" v-html="doubleCount('002', 1)"></div>
<div class="dataInfo" v-html="doubleCount('002', 2)"></div>
<div class="dataInfo" v-html="doubleCount('007', 0)"></div>
<div class="dataInfo" v-html="doubleCount('007', 1)"></div>
<div class="dataInfo" v-html="doubleCount('007', 2)"></div>
</div>
<!-- <div class="card card_g">
<div class="dataInfo" v-html="doubleCount('002', 1)"></div>
<div class="dataInfo" v-html="doubleCount('007', 1)"></div>
</div>
<div class="card card_h">
<div class="dataInfo" v-html="doubleCount('002', 2)"></div>
<div class="dataInfo" v-html="doubleCount('007', 2)"></div>
</div> -->
<div class="card card_c">
<div class="dataInfo" v-html="doubleCount('047', 0)"></div>
<div class="dataInfo" v-html="doubleCount('045', 0)"></div>
<div class="dataInfo" v-html="doubleCount('048', 0)"></div>
<div class="dataInfo" v-html="doubleCount('046', 0)"></div>
</div>
<div class="card card_d">
<div class="dataInfo" v-html="doubleCount('047', 1)"></div>
<div class="dataInfo" v-html="doubleCount('045', 1)"></div>
<div class="dataInfo" v-html="doubleCount('048', 1)"></div>
<div class="dataInfo" v-html="doubleCount('046', 1)"></div>
</div>
<div class="card card_e">
<div class="dataInfo" v-html="doubleCount('047', 2)"></div>
<div class="dataInfo" v-html="doubleCount('045', 2)"></div>
<div class="dataInfo" v-html="doubleCount('048', 2)"></div>
<div class="dataInfo" v-html="doubleCount('046', 2)"></div>
</div>
<div class="card card_f">
<div class="dataInfo" v-html="doubleCount('015', 0)"></div>
</div>
<img class="deviceImg" :src="deviceImg" />
<!-- <img class="deviceImg" src="@/assets/images/device03.gif" /> -->
</div>
<div class="devicInfo" v-if="infoData?.length != 0">
<div class="title">
<i />
<span>阀门控制</span>
</div>
<div class="infoPanel">
<n-scrollbar class="item">
<n-collapse class="collapse" :default-expanded-names="[0, 1, 2]">
<template #arrow>
<img src="@/assets/images/col_icon.png" />
</template>
<n-collapse-item
class="colItem"
:title="item.label"
:name="index"
v-for="(item, index) in infoData"
:key="index"
>
<div class="content">
<span v-for="(res, index) in item.header_valve" :key="index">
<i>{{ res.label }} </i>
<i v-if="res.ctrlFlag === 0"
>{{ res.value }}{{ res.paramUnit }}</i
>
<i v-if="res.ctrlFlag === 1">
<n-switch
class="switch"
size="small"
v-model:value="res.value"
style="
--n-rail-color-active: #409eff;
--n-rail-color: #ff4949;
"
@update:value="submitBlur(res)"
v-if="res.ctrlpro.valueType === 'bool'"
>
<template #checked></template>
<template #unchecked></template>
</n-switch>
<n-input
size="tiny"
v-model:value="res.value"
readonly
placeholder="0"
style="width: 80px; opacity: 0.9; text-align: center"
v-if="res.ctrlpro.valueType != 'bool'"
@click="inputClick(res)"
/>
<!-- <n-input-group v-if="res.ctrlpro.valueType != 'bool'">
<n-input-number
size="tiny"
v-model:value="res.value"
style="width: 80px; opacity: 0.9; text-align: center"
button-placement="both"
placeholder=""
@keyup.enter="submitBlur(res)"
/>
<n-input-group-label
size="tiny"
style="opacity: 0.9; text-align: center; cursor: pointer"
@click="submitBlur(res)"
>确定</n-input-group-label
>
</n-input-group> -->
<!-- <n-input-number
size="tiny"
v-model:value="res.value"
style="width: 100px; opacity: 0.9; text-align: center"
button-placement="both"
placeholder=""
@blur="submitBlur(res)"
v-if="res.ctrlpro.valueType != 'bool'"
/> -->
</i>
</span>
</div>
</n-collapse-item>
</n-collapse>
</n-scrollbar>
<n-scrollbar class="item">
<n-collapse class="collapse" :default-expanded-names="[0, 1, 2]">
<template #arrow>
<img src="@/assets/images/col_icon.png" />
</template>
<n-collapse-item
class="colItem"
:title="item.label"
:name="index"
v-for="(item, index) in infoData"
:key="index"
>
<div class="content pump">
<span v-for="(res, index) in item.header_pumpx" :key="index">
<i>{{ res.label }} </i>
<i v-if="res.ctrlFlag === 0"
>{{ res.value }}{{ res.paramUnit }}</i
>
<i v-if="res.ctrlFlag === 1">
<n-switch
class="switch"
size="small"
v-model:value="res.value"
style="
--n-rail-color-active: #409eff;
--n-rail-color: #ff4949;
"
@update:value="submitBlur(res)"
v-if="res.ctrlpro.valueType === 'bool'"
>
<template #checked></template>
<template #unchecked></template>
</n-switch>
<n-input
size="tiny"
v-model:value="res.value"
readonly
placeholder="0"
style="width: 80px; opacity: 0.9; text-align: center"
v-if="res.ctrlpro.valueType != 'bool'"
@click="inputClick(res)"
/>
</i>
</span>
<span v-for="(res, index) in item.header_pump" :key="index">
<i>{{ res.label }} </i>
<i v-if="res.ctrlFlag === 0"
>{{ res.value }}{{ res.paramUnit }}</i
>
<i v-if="res.ctrlFlag === 1">
<n-switch
class="switch"
size="small"
v-model:value="res.value"
style="
--n-rail-color-active: #409eff;
--n-rail-color: #ff4949;
"
@update:value="submitBlur(res)"
v-if="res.ctrlpro.valueType === 'bool'"
>
<template #checked></template>
<template #unchecked></template>
</n-switch>
<n-input
size="tiny"
v-model:value="res.value"
readonly
placeholder="0"
style="width: 80px; opacity: 0.9; text-align: center"
v-if="res.ctrlpro.valueType != 'bool'"
@click="inputClick(res)"
/>
</i>
</span>
</div>
</n-collapse-item>
</n-collapse>
</n-scrollbar>
</div>
<!-- <div class="valves">
<div class="title l_green">阀门控制</div>
<div class="info">
<div class="table">
<div class="item" v-for="(item, index) in infoData" :key="index">
<div class="lable l_green">{{ item.label }}</div>
<div class="parameters">
<span class="name" v-for="(res, index) in item.header_valve" :key="index">{{ res.label }}:{{ res.value }}
{{ res.paramUnit }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="pump">
<div class="item" v-for="(item, index) in infoData" :key="index">
<div class="title l_green">
{{ item.label }}循环泵控制
</div>
<div class="info">
<span class="name" v-for="(res, index) in item.header_pump" :key="index">{{ res.label }}:{{ res.value }}
{{ res.paramUnit }}</span>
</div>
</div>
</div> -->
</div>
<div class="tips" v-if="infoData?.length === 0">暂无设备信息</div>
<n-modal class="modalClass" v-model:show="showModal">
<n-card
:title="labelValue"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
style="width: 40rem"
>
<n-input-number
v-model:value="ctrlproValue"
clearable
placeholder="请输入数值"
/>
<template #footer>
<n-button @click="cancelClick">取消</n-button>
<n-button type="info" @click="submitClick(submitData)">确认</n-button>
</template>
</n-card>
</n-modal>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import { getViewInfo, sendCtrl } from "@/api/monitoring/table";
import mitt from "@/plugins/bus";
// const active = ref(true)
const deviceMenuKey = ref();
const infoData = ref();
const zoneType = ref(); //1:,2:2,3:3:,4:
const deviceImg = ref();
const timer = ref();
const isCurrentRoute = ref(true);
const showModal = ref(false);
const submitData = ref();
const labelValue = ref("设备");
const ctrlproValue = ref(null);
defineProps({
sidebarHeight: {
type: Number,
default: 0,
},
});
mitt.on("deviceMenuKey", (res) => {
//
deviceMenuKey.value = res;
gitDevice();
});
function gitDevice() {
//
const params = deviceMenuKey.value;
getViewInfo(params).then((res) => {
if (res.code === 200) {
if (isCurrentRoute.value) {
timer.value = setTimeout(async () => {
await (timer.value && clearTimeout(timer.value));
await gitDevice();
}, 20000);
}
infoData.value = Object.keys(res.data).length === 0 ? [] : res.data.datas;
zoneType.value =
Object.keys(res.data).length === 0 ? 0 : res.data.pCounts;
deviceImg.value =
Object.keys(res.data).length === 0 ? "" : res.data.imgIndex;
console.log(deviceImg.value);
} else {
clearTimeout(timer.value);
}
});
}
onUnmounted(() => {
//setTimeout
if (timer.value !== null || timer.value !== undefined) {
clearTimeout(timer.value);
}
});
// function doubleCount (id:string) {
// const arr = infoData.value[0].header_main
// const obj=arr.find((item) => item.id === id)
// const lable=obj!=undefined?`${obj.label}:${obj.value}`:''
// return lable;
// };
// const doubleCount = computed(() => {
// function doubleCount(id: string) {
// const arr = infoData.value[0].header_main
// const obj = arr.find((item) => item.id === id)
// const lable = obj != undefined ? `${obj.label}:${obj.value}` : ''
// return lable;
// };
// });
const doubleCount = (id, index) => {
const label = infoData.value[index].label;
const arr = infoData.value[index].header_main;
const obj = arr?.find((item) => item.id === id);
const mainLable =
obj != undefined && obj?.value !== ""
? `<span>${obj.label}(${label}):</span><span>${
obj.value === "" ? "--" : obj.value
} ${obj.paramUnit}</span>`
: "";
// const lable = obj != undefined ? `${obj.label}` : ''
// const value = obj != undefined ? `${obj.value}` : '0.0'
return mainLable;
};
console.log("doubleCount-", doubleCount);
function inputClick(data) {
//
submitData.value = data;
labelValue.value = data.label;
ctrlproValue.value = data.value;
showModal.value = true;
}
function cancelClick() {
//
labelValue.value = "设备";
ctrlproValue.value = null;
showModal.value = false;
}
function submitClick(data) {
//
if (ctrlproValue.value === "" || ctrlproValue.value === null) {
ElNotification({ message: "请输入数值!" });
} else {
data.value = ctrlproValue.value;
submitBlur(data);
}
}
function submitBlur(data) {
///
const submitData = data.ctrlpro;
submitData.value = data.value;
console.log(submitData);
sendCtrl(submitData).then((res) => {
if (res.code === 200) {
console.log(res.data);
showModal.value = false;
ElNotification({ message: res.data.msg });
}
});
}
</script>

314
src/views/monitoring/equipment/components/menu.vue

@ -0,0 +1,314 @@
<template>
<div class="menuCantent">
<n-menu
ref="menuInstRef"
class="menu"
:indent="0"
:options="menuOptions"
v-model:value="selectedKey"
key-field="deptId"
label-field="deptName"
:default-expand-all="false"
:watch-props="['defaultExpandedKeys']"
:render-label="renderMenuLabel"
@update:value="menuUpdateValue"
/>
</div>
</template>
<script setup>
import { ref, onMounted, h } from "vue";
import { NEllipsis } from "naive-ui";
import { useRoute } from "vue-router";
// import { NEllipsis } from 'naive-ui';
import { getMenu, getMenuData } from "@/api/monitoring/table";
import { getFirstNodeLastLevel } from "@/utils/index";
import useStorage from "@/utils/useStorage";
import mitt from "@/plugins/bus";
const router = useRoute();
const menuOptions = ref([]);
const selectedKey = ref();
const sessionStorageIns = useStorage("sessionStorage");
const routerType = ref("");
const id = ref(0);
const deptId = ref(0);
const menuDeptKey = ref(0);
const menuIdKey = ref(0);
const emit = defineEmits(["tableMenuData"]);
const props = defineProps({
menuType: {
type: String,
default: "1",
},
});
onMounted(() => {
routerType.value = router.query?.id === undefined ? "0" : "1";
id.value =
sessionStorage.getItem("id") === null
? 0
: Number(sessionStorage.getItem("id"));
deptId.value =
sessionStorage.getItem("deptId") === null
? 0
: Number(sessionStorage.getItem("deptId"));
if (props.menuType === "1") {
menuApi();
} else if (props.menuType === "2") {
comMenuApi();
}
});
function menuApi() {
//
getMenu().then((res) => {
if (res.code === 200) {
menuDeptKey.value =
routerType.value === "1"
? deptId.value
: routerType.value === "0" && deptId.value != 0
? deptId.value
: getFirstNodeLastLevel(res.data).deptId;
removeChildren(res.data);
menuOptions.value = res.data;
selectedKey.value = menuDeptKey.value;
sessionStorageIns.setUseStorage("deptId", menuDeptKey.value);
mitt.emit("menuKey", menuDeptKey.value);
emit("tableMenuData", res.data);
}
});
}
function comMenuApi() {
//
getMenuData().then((res) => {
if (res.code === 200) {
menuIdKey.value =
routerType.value === "1"
? id.value
: routerType.value === "0" && id.value != 0
? id.value
: getFirstNodeLastLevel(res.data).deptId;
const parentId =
routerType.value === "1"
? deptId.value
: getFirstNodeLastLevel(res.data).parentId;
removeChildren(res.data);
menuOptions.value = res.data;
selectedKey.value = menuIdKey.value;
sessionStorageIns.setUseStorage(
"deptId",
routerType.value === "1" ? deptId.value : parentId
);
mitt.emit("deviceMenuKey", menuIdKey.value);
emit("tableMenuData", res.data);
}
});
}
function removeChildren(menu) {
//children
if (!Array.isArray(menu)) {
return;
}
menu.forEach((item) => {
if (item.children && item.children.length === 0) {
delete item.children;
} else {
removeChildren(item.children);
}
});
}
// function renderMenuLabel(option) {
const renderMenuLabel = (option) => {
//
// return h(NEllipsis, null, option.deptName as string);
return h(NEllipsis, null, { default: () => option.deptName });
};
function menuUpdateValue(key, item) {
//
sessionStorageIns.setUseStorage(
props.menuType === "1" ? "deptId" : "id",
key
);
sessionStorageIns.setUseStorage("currentPage", 1);
if (props.menuType === "1") {
mitt.emit("currentPageEmit", 1);
}
if (props.menuType === "2") {
sessionStorageIns.setUseStorage("deptId", item.parentId);
}
mitt.emit(props.menuType === "1" ? "menuKey" : "deviceMenuKey", key);
console.log(key, item);
}
</script>
<style lang="scss" scoped>
:root {
--n-item-text-color-child-active-hover: #fff;
--n-item-text-color-active-hover: #fff;
--n-item-text-color-child-active: #fff;
}
.menuCantent {
height: -webkit-fill-available;
overflow: auto;
.menu {
text-align: center;
:deep(.n-submenu) {
--n-item-color-hover: auto;
.n-menu-item {
.n-menu-item-content {
padding: 0 !important;
.n-ellipsis {
font-family: "AlibabaPuHuiTiBold";
padding: 0 15px;
}
.n-menu-item-content__arrow {
color: #b1e3ff;
}
}
.n-menu-item-content.n-menu-item-content--child-active {
.n-menu-item-content-header {
color: #b1e3ff;
}
.n-menu-item-content__arrow {
color: #b1e3ff;
}
}
// .n-menu-item-content--child-active {
// .n-menu-item-content-header:hover {
// color: #fff !important;
// }
// .n-menu-item-content__arrow:hover {
// color: #fff !important;
// }
// }
// .n-menu-item-content--child-active:hover{
// color: #fff !important;
// }
.n-menu-item-content-header {
font-size: 2.2rem;
color: #b1e3ff;
}
}
.n-menu-item:hover {
color: red;
}
.n-submenu-children {
.n-menu-item-content-header {
font-size: 1.6rem;
}
.n-menu-item-content--selected {
.n-menu-item-content-header {
color: #fff;
.n-ellipsis {
position: relative;
span {
padding: 0 10px;
}
span::before {
content: "";
position: absolute;
left: 0;
top: 0.7rem;
width: 1.8rem;
height: 1.8rem;
background: url(@/assets/images/taps.png) no-repeat;
background-size: cover;
}
}
}
}
.n-menu-item-content--selected::before {
background: -webkit-linear-gradient(
left,
#1fc7ff29 0%,
#1177e700 100%
);
left: 0;
right: 0;
}
.n-menu-item-content--selected::after {
content: "";
position: absolute;
bottom: 0;
width: 100%;
height: 2px;
background: -webkit-linear-gradient(
left,
#1fc7ff29 0%,
#1177e700 100%
);
}
}
.n-base-icon {
color: #84e0f7;
right: 10px;
}
}
}
}
/*滚动条整体部分*/
.menuCantent::-webkit-scrollbar,
.tableGrid ::-webkit-scrollbar {
width: 8px;
height: 8px;
}
/*滚动条的轨道*/
.menuCantent::-webkit-scrollbar-track,
.tableGrid ::-webkit-scrollbar-track {
background-color: transparent;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
}
/*滚动条里面的小方块,能向上向下移动*/
.menuCantent::-webkit-scrollbar-thumb,
.tableGrid ::-webkit-scrollbar-thumb {
background-color: rgb(147, 147, 153, 0.5);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
}
.menuCantent::-webkit-scrollbar-thumb:hover,
.tableGrid ::-webkit-scrollbar-thumb:hover {
background-color: #a8a8a8;
}
.menuCantent::-webkit-scrollbar-thumb:active,
.tableGrid :-webkit-scrollbar-thumb:active {
background-color: #787878;
}
/*边角,即两个滚动条的交汇处*/
.menuCantent::-webkit-scrollbar-corner,
.tableGrid ::-webkit-scrollbar-corner {
background-color: transparent;
}
</style>

766
src/views/monitoring/equipment/index.scss

@ -0,0 +1,766 @@
@import url('@/assets/fonts/font.css');
.devicemanage {
position: relative;
width: 100%;
height: 100vh;
background: url(@/assets/images/screen.png);
// background-color: var(--tableBg);
background-size: 100% 100%;
// background-color: rgba(0, 0, 0, 0.3);
// background-blend-mode: multiply;
padding: 0 25px;
overflow: hidden;
.layout {
display: flex;
.sidebar {
width: 12%;
height: calc(100vh - 95px - 30px); //屏幕高度-头部header高度-底部高度
flex-shrink: 0;
border: 1px solid #0d55b0;
padding: 10px 0;
// box-shadow: inset 0px 0px 10px 0px rgb(36, 90, 12);
margin-right: 1vw;
position: relative;
overflow: hidden;
transition: width 0.28s;
background-color: rgba(2, 8, 46, 0.8);
// .menu {
// text-align: center;
// :deep(.n-submenu) {
// --n-item-color-hover: auto;
// .n-menu-item {
// .n-menu-item-content {
// padding: 0 !important;
// .n-ellipsis {
// font-family: 'AlibabaPuHuiTiBold';
// padding: 0 15px;
// }
// }
// .n-menu-item-content-header {
// font-size: 2.4rem;
// color: #B1E3FF;
// }
// }
// .n-submenu-children {
// .n-menu-item-content-header {
// font-size: 1.8rem;
// }
// .n-menu-item-content--selected {
// .n-menu-item-content-header {
// color: #fff;
// .n-ellipsis {
// position: relative;
// span {
// padding: 0 10px;
// }
// span::before {
// content: '';
// position: absolute;
// left: 0;
// top: 0.7rem;
// width: 1.8rem;
// height: 1.8rem;
// background: url(../../../assets/images/taps.png) no-repeat;
// background-size: cover;
// }
// }
// }
// }
// .n-menu-item-content--selected::before {
// background: -webkit-linear-gradient(left, #1fc7ff29 0%, #1177e700 100%);
// left: 0;
// right: 0;
// }
// .n-menu-item-content--selected::after {
// content: '';
// position: absolute;
// bottom: 0;
// width: 100%;
// height: 2px;
// background: -webkit-linear-gradient(left, #1fc7ff29 0%, #1177e700 100%);
// }
// }
// .n-base-icon {
// color: #84e0f7;
// right: 10px;
// }
// }
// }
}
.sidebar::after {
content: '';
position: absolute;
bottom: 0;
width: 100%;
height: 18rem;
background: url(@/assets/images/menu_bg.png) no-repeat;
background-size: 100% 100%;
}
.main {
width: 87%;
border: 2px solid #1e60a6;
box-shadow: inset 0px 0px 10px 0px rgb(36, 90, 124);
background-color: rgba(2, 8, 46, 0.8);
:deep(.devicePrt) {
.deviceImg {
position: relative;
.deviceImg {
width: 100%;
}
.card {
position: absolute;
display: inline-block;
color: #87e8de;
font-size: 1.4rem;
padding: 10px 20px;
border-radius: 10px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 0 80px rgba(0, 0, 0, 0.25);
z-index: 99;
overflow: hidden;
.dataInfo {
span {
display: inline-block;
padding: 5px 0;
}
}
.dataFlex {
display: flex;
.flexItem {
margin-right: 15px;
}
.flexItem:last-child {
margin-right: 0;
}
}
}
// .card.card_a{
// .dataInfo{
// span{
// display: inline-block;
// }
// }
// }
// .switch {
// position: absolute;
// z-index: 99;
// cursor: pointer;
// overflow: hidden;
// }
// .dataInfo {
// position: absolute;
// display: inline-block;
// color: #87e8de;
// padding: 10px;
// font-size: 16px;
// // border: 2px solid #39c33c;
// z-index: 99;
// span {
// display: block;
// }
// }
}
.deviceImgA {
.card_a {
top: 50%;
left: 1%;
}
.card_b {
top: 18%;
left: 1%;
}
.card_c {
top: 35%;
right: 1%;
}
.card_f {
top: 35%;
right: 17%;
}
// .switch_a {
// width: 35px;
// height: 60px;
// background: red;
// top: 23%;
// left: 16.5%;
// }
// .switch_b {
// width: 40px;
// height: 65px;
// background: red;
// top: 59%;
// left: 15.5%;
// }
}
.deviceImgB {
.card_a {
top: 42%;
left: 2%;
}
.card_b {
top: 8%;
left: 2%;
}
.card_c {
top: 16%;
right: 2%;
}
.card_d {
top: 52%;
right: 2%;
}
.card_f {
top: 30%;
right: 18%;
}
}
.deviceImgC {
.card_a {
top: 6%;
left: 4%;
}
.card_b {
top: 40%;
left: 1%;
}
// .card_g {
// top: 60%;
// left: 5%;
// }
// .card_h {
// top: 80%;
// left: 5%;
// }
.card_c {
top: 2%;
right: 2%;
}
.card_d {
top: 35%;
right: 2%;
}
.card_e {
top: 68%;
right: 2%;
}
.card_f {
top: 36%;
right: 18%;
}
}
// .deviceImgA {
// .dataInfo0 {
// top: 7%;
// left: 6%;
// }
// .dataInfo1 {
// top: 35%;
// left: 9%;
// }
// .dataInfo2 {
// top: 0%;
// left: 18%;
// }
// .dataInfo3 {
// top: 0%;
// left: 25%;
// }
// .dataInfo4 {
// top: 15%;
// left: 17.5%;
// }
// .dataInfo5 {
// top: 26%;
// left: 17.5%;
// }
// .dataInfo6 {
// top: 0%;
// right: 20%;
// }
// .dataInfo7 {
// top: 10%;
// right: 20%;
// }
// }
// .deviceImgB {
// .dataInfo0 {
// top: 23%;
// left: 10.5%;
// }
// .dataInfo1 {
// top: 55%;
// left: 12%;
// }
// .dataInfo2 {
// top: 0%;
// left: 23%;
// }
// .dataInfo3 {
// top: 0%;
// left: 30%;
// }
// .dataInfo4 {
// top: 10%;
// left: 23%;
// }
// .dataInfo5 {
// top: 20%;
// left: 23%;
// }
// .dataInfo6 {
// top: 0%;
// right: 36%;
// }
// .dataInfo7 {
// top: 10%;
// right: 36%;
// }
// .dataInfo8 {
// top: 26%;
// right: 31%;
// }
// .dataInfo9 {
// top: 36%;
// right: 31%;
// }
// }
// .deviceImgC {
// .dataInfo0 {
// bottom: 38%;
// left: 8.5%;
// }
// .dataInfo1 {
// bottom: 1%;
// left: 11%;
// }
// .dataInfo2 {
// top: 0%;
// left: 23%;
// }
// .dataInfo3 {
// top: 0%;
// left: 30%;
// }
// .dataInfo4 {
// top: 10%;
// left: 23%;
// }
// .dataInfo5 {
// top: 20%;
// left: 23%;
// }
// .dataInfo6 {
// top: 0%;
// right: 36%;
// }
// .dataInfo7 {
// top: 0%;
// right: 29%;
// }
// .dataInfo8 {
// top: 22%;
// right: 36%;
// }
// .dataInfo9 {
// top: 22%;
// right: 29%;
// }
// .dataInfo10 {
// top: 47%;
// right: 36%;
// }
// .dataInfo11 {
// top: 47%;
// right: 29%;
// }
// }
.devicInfo {
color: #b1e3ff;
padding: 0 3rem;
font-family: 'AlibabaPuHuiTiRegular';
.title {
display: flex;
align-items: center;
font-size: 20px;
background: url(@/assets/images/info_bg.png) no-repeat center;
background-size: 100% 100%;
i {
display: block;
width: 6px;
height: 50px;
background: linear-gradient(270deg, #679fff 0%, rgba(17, 119, 231, 0.698) 100%);
border-radius: 0px 0px 0px 0px;
margin-right: 18px;
}
}
.infoPanel {
display: flex;
justify-content: space-between;
margin-top: 15px;
.item {
width: 49%;
height: calc(100vh - 150px - 53rem);
padding: 15px 0;
background: -webkit-linear-gradient(top, #052266 0%, #011341 100%);
overflow: auto;
.collapse {
.colItem {
.n-collapse-item__header-main {
font-size: 18px;
color: #1fb1ff;
padding: 0 22px;
.n-collapse-item-arrow {
margin-right: 10px;
img {
width: 18px;
height: 16px;
}
}
}
.n-collapse-item__content-wrapper {
.n-collapse-item__content-inner {
padding-top: 10px;
.content {
display: flex;
flex-wrap: wrap;
padding: 0 15px;
font-size: 16px;
color: #c15757;
line-height: 30px;
span {
display: flex;
align-items: center;
flex: 0 0 calc(100% / 2);
i {
font-style: normal;
display: flex;
align-items: center;
.n-input-number {
display: flex;
align-items: center;
}
}
.switch {
font-size: 13px;
}
}
span:nth-child(even) {
color: #41a5d7;
}
}
// .content.pump {
// span {
// flex: auto;
// }
// }
}
}
}
.colItem.n-collapse-item--active {
.n-collapse-item-arrow {
transform: none;
}
}
.colItem:not(:first-child) {
border-top: none;
}
.colItem:not(:first-child)::before {
display: block;
content: '';
width: 100%;
height: 1px;
background: linear-gradient(
90deg,
rgba(31, 225, 255, 0) 0%,
rgba(189, 220, 255, 0.94) 50%,
rgba(31, 225, 255, 0) 97%
);
}
}
}
}
// .l_green {
// color: #39c33c;
// }
// .l_blue {
// color: #41a5d7;
// }
// .orange {
// color: #c15757;
// }
// .title {
// font-size: 16px;
// }
// .valves {
// display: flex;
// align-items: center;
// flex-shrink: 0;
// width: 40%;
// .title {
// writing-mode: vertical-rl;
// // transform: rotate(180deg);
// }
// .info {
// .select {
// font-weight: 800;
// .n-button {
// margin-right: 5px;
// background: linear-gradient(#3370cb, #162f68, #162f68);
// }
// }
// .table {
// border: 1px solid #39c33c;
// border-radius: 3px;
// margin: 10px 0 10px 20px;
// .item {
// display: flex;
// align-items: center;
// padding: 10px 20px;
// line-height: 26px;
// border-bottom: 1px solid #39c33c;
// .lable {
// font-size: 16px;
// flex-shrink: 0;
// }
// .parameters {
// display: flex;
// flex-wrap: wrap;
// .name {
// color: #c15757;
// margin-left: 15px;
// }
// .name:nth-child(even) {
// color: #41a5d7;
// }
// .n-radio__label {
// color: #41a5d7;
// }
// }
// }
// .item:last-child {
// border-bottom: none;
// }
// }
// .switch {
// display: flex;
// span {
// display: flex;
// align-items: center;
// margin-right: 5px;
// }
// }
// }
// }
// .pump {
// width: 55%;
// padding: 5px 10px;
// border: 1px solid #39c33c;
// .item {
// line-height: 28px;
// .info {
// display: flex;
// flex-wrap: wrap;
// .name {
// color: #c15757;
// margin-left: 15px;
// }
// .name:nth-child(even) {
// color: #41a5d7;
// }
// }
// }
// }
}
.tips {
font-size: 1.6rem;
font-family: 'AlibabaPuHuiTiRegular';
text-align: center;
color: #b1e3ff;
margin-top: 40vh;
}
}
}
/*滚动条整体部分*/
.tableGrid ::-webkit-scrollbar {
width: 8px;
height: 8px;
}
/*滚动条的轨道*/
.tableGrid ::-webkit-scrollbar-track {
background-color: transparent;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
}
/*滚动条里面的小方块,能向上向下移动*/
.tableGrid ::-webkit-scrollbar-thumb {
background-color: rgb(147, 147, 153, 0.5);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
}
.tableGrid ::-webkit-scrollbar-thumb:hover {
background-color: #a8a8a8;
}
.tableGrid :-webkit-scrollbar-thumb:active {
background-color: #787878;
}
/*边角,即两个滚动条的交汇处*/
.tableGrid ::-webkit-scrollbar-corner {
background-color: transparent;
}
}
.copyright {
height: 25px;
line-height: 25px;
text-align: center;
color: #9ca3af;
font-family: Arial;
font-size: 12px;
letter-spacing: 1px;
margin-top: 5px;
}
}
.dark {
.devicemanage {
background-color: rgba(29, 30, 31, 0.8);
background-blend-mode: multiply;
.layout {
.sidebar {
background-color: rgba(29, 30, 31, 0.8);
}
.main {
background-color: rgba(29, 30, 31, 0.8);
.devicePrt {
:deep(.devicInfo) {
.infoPanel {
.item {
background: -webkit-linear-gradient(top, rgba(29, 30, 31, 0.8) 0%, rgba(28, 32, 37, 0.8) 100%);
}
}
}
}
}
}
}
}

67
src/views/monitoring/equipment/index.vue

@ -0,0 +1,67 @@
<template>
<div ref="screenRef" class="devicemanage">
<section ref="titleRef" class="header">
<Header
:titleData="titleData"
:settingShow="false"
@returnClick="returnClick"
/>
</section>
<section class="layout">
<div ref="sidebar" class="sidebar">
<Menu menuType="2" @tableMenuData="tableMenuData" />
</div>
<div class="main">
<Main :sidebarHeight="sidebarHeight" />
</div>
</section>
<!-- <div class="copyright">
Copyright © {{ $t("copyright.year") }} {{ $t("copyright.abbr") }}
{{ $t("copyright.document") }}
</div> -->
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { useRoute, useRouter } from "vue-router";
import Header from "./components/header.vue";
import Menu from "./components/menu.vue";
import Main from "./components/main.vue";
// import screenfull from 'screenfull'
const titleRef = ref();
const sidebar = ref();
const screenRef = ref();
const sidebarHeight = ref();
const titleData = ref("");
const route = useRoute();
const router = useRouter();
onMounted(() => {
console.log(sidebar.value);
sidebarHeight.value = sidebar.value?.offsetHeight; //
console.log("sidebar:", sidebar.value?.offsetHeight);
});
window.addEventListener("resize", () => {
//
sidebarHeight.value = sidebar.value?.offsetHeight; //
console.log("监听sidebar:", sidebar.value?.offsetHeight);
});
function tableMenuData(data) {
//
titleData.value = data[0].deptName;
}
function returnClick() {
//
router.go(-1);
}
// function screenClick() {
// if (screenfull.isEnabled) {
// //
// screenfull.toggle(screenRef.value)
// }
// }
</script>
<style lang="scss" scoped>
@import "./index.scss";
</style>

300
src/views/monitoring/graph/index.scss

@ -0,0 +1,300 @@
@import url('@/assets/fonts/font.css');
.details {
padding: 15px 15px 0 15px;
.search {
position: relative;
margin-bottom: 15px;
overflow: visible;
:deep(.el-card__header) {
padding: 10px;
}
:deep(.el-card__body) {
padding: 0 20px;
}
.cardHeader {
display: flex;
justify-content: center;
align-items: center;
line-height: 25px;
position: relative;
span {
font-size: 24px;
font-family: 'PangMenZhengDaoBiao';
color: var(--el-menu-active-color);
}
.tooltips {
position: absolute;
top: -5px;
right: 10px;
width: 36px;
height: 36px;
border-radius: 0px 0px 0px 0px;
opacity: 1;
}
}
.searchForm {
.item {
margin: 20px 0;
.searchCheckbox {
margin-right: 30px;
}
}
.formBtn {
margin: 20px;
}
}
.searchTips {
position: absolute;
bottom: 0;
right: 30px;
cursor: pointer;
}
.searchTips.isShow {
bottom: -15px;
}
.searchTips.isHide::after {
content: '隐藏';
position: absolute;
top: -130%;
left: 50%;
transform: translateX(-50%);
width: 40px;
height: fit-content;
background-color: var(--el-menu-active-color);
padding: 4px 8px;
border-radius: 5px;
transition: 0.2s linear;
transition-delay: 0.2s;
color: white;
// text-transform: uppercase;
font-size: 12px;
opacity: 0;
// visibility: hidden;
}
.searchTips.isShow::after {
content: '显示';
position: absolute;
top: -130%;
left: 50%;
transform: translateX(-50%);
width: 40px;
height: fit-content;
background-color: var(--el-menu-active-color);
padding: 4px 8px;
border-radius: 5px;
transition: 0.2s linear;
transition-delay: 0.2s;
color: white;
// text-transform: uppercase;
font-size: 12px;
opacity: 0;
// visibility: hidden;
}
.icon {
transform: scale(1.2);
transition: 0.2s linear;
}
.searchTips:hover > .icon {
transform: scale(1.5);
}
.searchTips:hover > .icon path {
fill: var(--el-menu-active-color);
}
.searchTips:hover::after {
visibility: visible;
opacity: 1;
top: -160%;
}
}
.echart {
:deep(.el-card__body) {
display: flex;
padding: 15px;
.sidebar {
width: 200px;
border: 1px solid #e8eaec;
height: calc(100vh - 150px - 30px - 40px - 2px);
h3 {
height: 25px;
line-height: 25px;
margin: 15px 0;
font-size: 22px;
font-family: 'PangMenZhengDaoBiao';
color: var(--el-menu-active-color);
text-align: center;
}
.deviceMenu {
height: calc(100vh - 150px - 30px - 40px - 55px - 4px);
border-right: none;
overflow: auto;
.el-menu-item {
display: block;
width: 100%;
height: 45px;
line-height: 45px;
padding: 0 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
.iconfont {
margin-right: 6px;
}
}
.el-menu-item.weather {
.icon-weather {
font-size: 16px;
color: var(--el-menu-active-color);
}
span {
font-size: 16px;
color: var(--el-menu-active-color);
}
}
}
.paramList {
// height: calc(100vh - 150px - 7.5rem);
padding: 20px 10px;
overflow: auto;
.item {
font-size: 14px;
padding: 10px 0;
line-height: 30px;
border-bottom: 1px dashed #cacaca;
.name {
display: flex;
align-items: center;
i {
width: 12px;
height: 12px;
border-radius: 10px;
margin-right: 5px;
}
}
}
}
/*滚动条整体部分*/
.deviceMenu::-webkit-scrollbar,
.paramList::-webkit-scrollbar {
width: 5px;
height: 8px;
}
/*滚动条的轨道*/
.deviceMenu::-webkit-scrollbar-track,
.paramList::-webkit-scrollbar-track {
background-color: transparent;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
}
/*滚动条里面的小方块,能向上向下移动*/
.deviceMenu::-webkit-scrollbar-thumb,
.paramList::-webkit-scrollbar-thumb {
background-color: rgb(147, 147, 153, 0.5);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
}
.deviceMenu::-webkit-scrollbar-thumb:hover,
.paramList::-webkit-scrollbar-thumb:hover {
background-color: #a8a8a8;
}
.deviceMenu:-webkit-scrollbar-thumb:active,
.paramList:-webkit-scrollbar-thumb:active {
background-color: #787878;
}
/*边角,即两个滚动条的交汇处*/
.deviceMenu::-webkit-scrollbar-corner,
.paramList::-webkit-scrollbar-corner {
background-color: transparent;
}
}
.comparisonInfo {
flex: 1;
margin: 0 15px;
.stackedLine {
width: 100%;
height: calc(100vh - 150px - 30px - 40px - 2px);
line-height: calc(100vh - 150px - 30px - 40px - 2px);
font-size: 1.4rem;
text-align: center;
color: #606266;
}
}
}
}
.echart.echartHide {
:deep(.el-card__body) {
.sidebar {
height: calc(100vh - 78px - 30px - 40px - 2px);
.deviceMenu {
height: calc(100vh - 78px - 30px - 40px - 55px - 4px);
}
}
.comparisonInfo {
.stackedLine {
height: calc(100vh - 78px - 30px - 40px - 2px);
line-height: calc(100vh - 78px - 30px - 40px - 2px);
}
}
}
}
.copyright {
height: 40px;
line-height: 40px;
text-align: center;
color: #9ca3af;
font-family: Arial;
font-size: 12px;
letter-spacing: 1px;
}
}
/** pc **/
@media only screen and (min-width: 768px) and (max-width: 1680px) {
.echart {
:deep(.el-card__body) {
.sidebar {
height: calc(100vh - 222px - 30px - 40px - 2px) !important;
.deviceMenu {
height: calc(100vh - 222px - 30px - 40px - 55px - 4px) !important;
}
}
.comparisonInfo {
.stackedLine {
height: calc(100vh - 222px - 30px - 40px - 2px) !important;
line-height: calc(100vh - 222px - 30px - 40px - 2px) !important;
}
}
}
}
.echart.echartHide {
:deep(.el-card__body) {
.sidebar {
height: calc(100vh - 78px - 30px - 40px - 2px) !important;
.deviceMenu {
height: calc(100vh - 78px - 30px - 40px - 55px - 4px) !important;
}
}
.comparisonInfo {
.stackedLine {
height: calc(100vh - 78px - 30px - 40px - 2px) !important;
line-height: calc(100vh - 78px - 30px - 40px - 2px) !important;
}
}
}
}
}

1228
src/views/monitoring/graph/index.vue

File diff suppressed because it is too large

162
src/views/monitoring/station/components/bar - 副本.vue

@ -1,162 +0,0 @@
<template>
<div class="electricityInfo">
<div ref="electricityRef" class="electricityLine" />
</div>
</template>
<script lang="ts" setup>
import * as echarts from 'echarts';
import { Ref } from 'vue';
import { powerLostRate } from '@/api/data/index';
import useCounter from '@/store/modules/date';
const counterStore = useCounter();
const yearMonthDay = ref();
const electricityRef: Ref<HTMLElement | any> = ref(null);
const options = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
top: 10,
right: 10,
itemWidth: 11,
itemHeight: 11,
textStyle: {
color: '#fff',
fontSize: 14
}
},
grid: {
top: '20%',
left: '0',
right: '0',
bottom: '0',
containLabel: true
},
dataset: {
source: [
['name', '合力供热站', '浑南热力', '国润低碳', '新环保', '节能环保'],
['计划数', 41.1, 30.4, 65.1, 53.3, 69],
['实际数', 35.5, 92.1, 85.7, 83.1, 72]
]
},
xAxis: {
type: 'category',
axisLabel: {
show: true,
color: '#99CFFF'
},
axisLine: {
lineStyle: {
color: '#546778'
}
}
},
yAxis: [
{
type: 'value',
name: '单位',
nameTextStyle: {
color: '#546778',
fontSize: 12,
padding: [0, 0, 0, 0] //name
},
axisTick: {
//
show: false
},
axisLabel: {
show: true,
color: '#546778'
},
splitLine: {
// 线
show: true,
lineStyle: {
//线
color: '#306269',
width: 1,
opacity: 0.2
}
},
}
],
series: [
{
type: 'bar',
seriesLayoutBy: 'row',
barWidth: 15, //
itemStyle: {
//
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#61B9FF' },
{ offset: 0.5, color: '#4263DF' },
{ offset: 1, color: '#2106BD' }
])
}
},
{
type: 'bar',
seriesLayoutBy: 'row',
barWidth: 15, //
itemStyle: {
//
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#F2DE28' },
{ offset: 0.5, color: '#F5A113' },
{ offset: 1, color: '#F96800' }
])
}
}
]
};
onMounted(() => {
//
const chart = echarts.init(electricityRef.value);
chart.setOption(options);
// getElect();
//
window.addEventListener('resize', () => {
chart.resize();
});
});
watchEffect(() => {
const dataStr = counterStore.dateStr;
if (dataStr != '') {
yearMonthDay.value = counterStore.dateStr.split('-');
// getElect();
}
});
function getElect() {
//
const params = {
orgId: 206,
dateYear: yearMonthDay.value[0],
dateMonth: yearMonthDay.value[1],
dateDay: yearMonthDay.value[2]
};
powerLostRate(params).then((res: any) => {
if (res.code === 200 && Object.keys(res.data).length != 0) {
options.dataset.source = res.data.source;
options.yAxis[0].name = `单位(${res.data.unit})`;
const chart = echarts.init(electricityRef.value);
chart.setOption(options);
}
});
}
</script>
<style lang="scss" scoped>
.electricityInfo {
width: 100%;
height: 318px;
.electricityLine {
width: 100%;
height: 318px;
}
}
</style>

154
src/views/monitoring/station/components/boxPlot - 副本.vue

@ -1,154 +0,0 @@
<template>
<div class="boxPlotInfo">
<div ref="boxPlotRef" class="electricityLine" />
</div>
</template>
<script lang="ts" setup>
import * as echarts from 'echarts';
import { Ref } from 'vue';
import { powerLostRate } from '@/api/data/index';
import useCounter from '@/store/modules/date';
const counterStore = useCounter();
const yearMonthDay = ref();
const boxPlotRef: Ref<HTMLElement | any> = ref(null);
const options = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
top: 10,
right: 10,
itemWidth: 11,
itemHeight: 2,
textStyle: {
color: '#fff',
fontSize: 14
}
},
grid: {
top: '20%',
left: '0',
right: '0',
bottom: '0',
containLabel: true
},
dataset: {
source: [
['name', '合力供热站', '浑南热力', '国润低碳', '新环保', '节能环保'],
['一网进温', 35.5, 92.1, 85.7, 83.1, 72],
['一网回温', 41.1, 50.4, 65.1, 53.3, 69]
]
},
xAxis: {
type: 'category',
axisLabel: {
show: true,
color: '#fff'
}
},
yAxis: [
{
type: 'value',
name: '单位',
scale: true, //
nameTextStyle: {
color: '#fff',
fontSize: 12,
padding: [0, 0, 0, 0] //name
},
axisTick: {
//
show: false
},
axisLabel: {
show: true,
color: '#fff'
},
splitLine: {
// 线
show: true,
lineStyle: {
//线
color: '#306269',
width: 1,
opacity: 0.2
}
}
}
],
series: [
{
type: 'bar',
seriesLayoutBy: 'row',
barWidth: 15, //
itemStyle: {
//
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#2850F2' },
{ offset: 0.5, color: '#1390F9' },
{ offset: 1, color: '#00CBFF' }
])
}
},
{
type: 'line',
seriesLayoutBy: 'row',
barWidth: 15, //
itemStyle: {
color: '#FFEB6B', //
borderWidth: 1, //
borderColor: '#FFEB6B' //
}
}
]
};
onMounted(() => {
//
const chart = echarts.init(boxPlotRef.value);
chart.setOption(options);
// getElect();
//
window.addEventListener('resize', () => {
chart.resize();
});
});
watchEffect(() => {
const dataStr = counterStore.dateStr;
if (dataStr != '') {
yearMonthDay.value = counterStore.dateStr.split('-');
// getElect();
}
});
function getElect() {
//
const params = {
orgId: 206,
dateYear: yearMonthDay.value[0],
dateMonth: yearMonthDay.value[1],
dateDay: yearMonthDay.value[2]
};
powerLostRate(params).then((res: any) => {
if (res.code === 200 && Object.keys(res.data).length != 0) {
const chart = echarts.init(boxPlotRef.value);
chart.setOption(options);
}
});
}
</script>
<style lang="scss" scoped>
.boxPlotInfo {
width: 100%;
height: 318px;
.electricityLine {
width: 100%;
height: 318px;
}
}
</style>

142
src/views/monitoring/station/components/table - 副本.vue

@ -1,142 +0,0 @@
<template>
<div class="tableInfo">
<el-table
class="tableClass"
:data="tableData"
header-row-class-name="headerRow"
header-cell-class-name="headerCell"
row-class-name="rowClass"
cell-class-name="cellClass"
stripe
>
<el-table-column prop="id" label="序号" align="center" width="80" />
<el-table-column prop="name" label="换热站" align="center" width="180" show-overflow-tooltip />
<el-table-column prop="date" label="Date" align="center" />
<el-table-column prop="name" label="Name" align="center" />
<el-table-column prop="address" label="Address" align="center" />
</el-table>
</div>
</template>
<script lang="ts" setup>
const tableData = [
{
id: '1',
date: '2016-05-03',
name: '大唐管井',
address: 'No. 189, Grove St, Los Angeles'
},
{
id: '11',
date: '2016-05-02',
name: '汪家鑫城二期',
address: 'No. 189, Grove St, Los Angeles'
},
{
id: '12',
date: '2016-05-04',
name: '东湖紫东苑(兆城紫东苑)',
address: 'No. 189, Grove St, Los Angeles'
},
{
id: '22',
date: '2016-05-01',
name: '汪家鑫城一期B区A区C区',
address: 'No. 189, Grove St, Los Angeles'
},
{
id: '1',
date: '2016-05-03',
name: '大唐管井',
address: 'No. 189, Grove St, Los Angeles'
},
{
id: '11',
date: '2016-05-02',
name: '汪家鑫城二期',
address: 'No. 189, Grove St, Los Angeles'
},
{
id: '12',
date: '2016-05-04',
name: '东湖紫东苑(兆城紫东苑)',
address: 'No. 189, Grove St, Los Angeles'
},
{
id: '22',
date: '2016-05-01',
name: '汪家鑫城一期B区A区C区',
address: 'No. 189, Grove St, Los Angeles'
},
{
id: '1',
date: '2016-05-03',
name: '大唐管井',
address: 'No. 189, Grove St, Los Angeles'
},
{
id: '11',
date: '2016-05-02',
name: '汪家鑫城二期',
address: 'No. 189, Grove St, Los Angeles'
},
{
id: '12',
date: '2016-05-04',
name: '东湖紫东苑(兆城紫东苑)',
address: 'No. 189, Grove St, Los Angeles'
},
{
id: '22',
date: '2016-05-01',
name: '汪家鑫城一期B区A区C区',
address: 'No. 189, Grove St, Los Angeles'
}
];
</script>
<style lang="scss" scoped>
.tableInfo {
height: 378px;
margin-top: 20px;
overflow: hidden;
:deep(.tableClass) {
height: 376px;
font-size: 18px;
--el-table-border: none;
--el-table-text-color: #d2def6;
--el-table-header-text-color: #d2def6;
--el-table-row-hover-bg-color: none;
--el-table-header-bg-color: #0d1015;
--el-table-tr-bg-color: #0d1b35;
--el-fill-color-lighter: #0d1015;
.headerCell,.cellClass{
padding: 12px 0;
}
.el-table__inner-wrapper::before {
content: none;
}
.el-table__inner-wrapper {
.cellClass:hover {
background-color: transparent;
}
}
// .headerRow {
// .headerCell {
// border-bottom: none;
// background-color: #0d1015;
// }
// }
// .rowClass {
// background-color: #0d1b35;
// .cellClass {
// border-bottom: none;
// background-color: #0d1b35;
// }
// }
// .rowClass.el-table__row--striped {
// .cellClass {
// background-color: #0d1015;
// }
// }
}
}
</style>

2
src/views/monitoring/station/components/table.vue

@ -119,7 +119,7 @@ const handlePageChange = ({ currentPage, pageSize }) => {
tablePage.pageSize = pageSize;
sessionStorageIns.setUseStorage("currentPage", currentPage);
sessionStorageIns.setUseStorage("pageSize", pageSize);
tableDatas();
// tableDatas();
};
function tableHeader() {

715
src/views/system/menu/index.vue

@ -1,289 +1,408 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
<el-form-item label="菜单名称" prop="menuName">
<el-input
v-model="queryParams.menuName"
placeholder="请输入菜单名称"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="菜单状态" clearable style="width: 240px">
<el-option
v-for="dict in sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</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>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryRef"
:inline="true"
v-show="showSearch"
>
<el-form-item label="菜单名称" prop="menuName">
<el-input
v-model="queryParams.menuName"
placeholder="请输入菜单名称"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="菜单状态"
clearable
style="width: 240px"
>
<el-option
v-for="dict in sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</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-col :span="1.5">
<el-button
type="info"
plain
icon="Sort"
@click="toggleExpandAll"
>展开/折叠</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<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-col :span="1.5">
<el-button type="info" plain icon="Sort" @click="toggleExpandAll"
>展开/折叠</el-button
>
</el-col>
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<el-table
v-if="refreshTable"
v-loading="loading"
:data="menuList"
row-key="menuId"
:default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
<el-table
v-if="refreshTable"
v-loading="loading"
:data="menuList"
row-key="menuId"
:default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column
prop="menuName"
label="菜单名称"
:show-overflow-tooltip="true"
width="280"
></el-table-column>
<el-table-column prop="icon" label="图标" align="center" width="100">
<template #default="scope">
<svg-icon :icon-class="scope.row.icon" />
</template>
</el-table-column>
<el-table-column
prop="orderNum"
label="排序"
width="60"
></el-table-column>
<el-table-column
prop="perms"
label="权限标识"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
prop="component"
label="组件路径"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column prop="status" label="状态" width="80">
<template #default="scope">
<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
width="160"
prop="createTime"
>
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="210"
class-name="small-padding fixed-width"
>
<el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" width="280"></el-table-column>
<el-table-column prop="icon" label="图标" align="center" width="100">
<template #default="scope">
<svg-icon :icon-class="scope.row.icon" />
</template>
</el-table-column>
<el-table-column prop="orderNum" label="排序" width="60"></el-table-column>
<el-table-column prop="perms" label="权限标识" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="component" label="组件路径" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="status" label="状态" width="80">
<template #default="scope">
<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" width="160" prop="createTime">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="210" 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="Plus" @click="handleAdd(scope.row)">新增</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<template #default="scope">
<el-button
link
type="primary"
icon="Edit"
@click="handleUpdate(scope.row)"
>修改</el-button
>
<el-button
link
type="primary"
icon="Plus"
@click="handleAdd(scope.row)"
>新增</el-button
>
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改菜单对话框 -->
<el-dialog :title="title" v-model="open" width="680px" append-to-body draggable>
<el-form ref="menuRef" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :span="24">
<el-form-item label="上级菜单">
<el-tree-select
v-model="form.parentId"
:data="menuOptions"
:props="{ value: 'menuId', label: 'menuName', children: 'children' }"
value-key="menuId"
placeholder="选择上级菜单"
check-strictly
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="菜单类型" prop="menuType">
<el-radio-group v-model="form.menuType">
<el-radio label="M">目录</el-radio>
<el-radio label="C">菜单</el-radio>
<el-radio label="F">按钮</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24" v-if="form.menuType != 'F'">
<el-form-item label="菜单图标" prop="icon">
<el-popover
placement="bottom-start"
:width="540"
v-model:visible="showChooseIcon"
trigger="click"
@show="showSelectIcon"
>
<template #reference>
<el-input v-model="form.icon" placeholder="点击选择图标" @blur="showSelectIcon" v-click-outside="hideSelectIcon" readonly>
<template #prefix>
<svg-icon
v-if="form.icon"
:icon-class="form.icon"
class="el-input__icon"
style="height: 32px;width: 16px;"
/>
<el-icon v-else style="height: 32px;width: 16px;"><search /></el-icon>
</template>
</el-input>
</template>
<icon-select ref="iconSelectRef" @selected="selected" />
</el-popover>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="菜单名称" prop="menuName">
<el-input v-model="form.menuName" placeholder="请输入菜单名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="显示排序" prop="orderNum">
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item>
<template #label>
<span>
<el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
<el-icon><question-filled /></el-icon>
</el-tooltip>
</span>
</template>
<el-radio-group v-model="form.isFrame">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item prop="path">
<template #label>
<span>
<el-tooltip content="访问的路由地址,如:`user`,如外网地址需内链访问则以`http(s)://`开头" placement="top">
<el-icon><question-filled /></el-icon>
</el-tooltip>
路由地址
</span>
</template>
<el-input v-model="form.path" placeholder="请输入路由地址" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType == 'C'">
<el-form-item prop="component">
<template #label>
<span>
<el-tooltip content="访问的组件路径,如:`system/user/index`,默认在`views`目录下" placement="top">
<el-icon><question-filled /></el-icon>
</el-tooltip>
组件路径
</span>
</template>
<el-input v-model="form.component" placeholder="请输入组件路径" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType != 'M'">
<el-form-item>
<el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" />
<template #label>
<span>
<el-tooltip content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top">
<el-icon><question-filled /></el-icon>
</el-tooltip>
权限字符
</span>
</template>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType == 'C'">
<el-form-item>
<el-input v-model="form.query" placeholder="请输入路由参数" maxlength="255" />
<template #label>
<span>
<el-tooltip content='访问路由的默认传递参数,如:`{"id": 1, "name": "ry"}`' placement="top">
<el-icon><question-filled /></el-icon>
</el-tooltip>
路由参数
</span>
</template>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType == 'C'">
<el-form-item>
<template #label>
<span>
<el-tooltip content="选择是则会被`keep-alive`缓存,需要匹配组件的`name`和地址保持一致" placement="top">
<el-icon><question-filled /></el-icon>
</el-tooltip>
是否缓存
</span>
</template>
<el-radio-group v-model="form.isCache">
<el-radio label="0">缓存</el-radio>
<el-radio label="1">不缓存</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item>
<template #label>
<span>
<el-tooltip content="选择隐藏则路由将不会出现在侧边栏,但仍然可以访问" placement="top">
<el-icon><question-filled /></el-icon>
</el-tooltip>
显示状态
</span>
</template>
<el-radio-group v-model="form.visible">
<el-radio
v-for="dict in sys_show_hide"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item>
<template #label>
<span>
<el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top">
<el-icon><question-filled /></el-icon>
</el-tooltip>
菜单状态
</span>
</template>
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</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>
<!-- 添加或修改菜单对话框 -->
<el-dialog
:title="title"
v-model="open"
width="680px"
append-to-body
draggable
>
<el-form ref="menuRef" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :span="24">
<el-form-item label="上级菜单">
<el-tree-select
v-model="form.parentId"
:data="menuOptions"
:props="{
value: 'menuId',
label: 'menuName',
children: 'children',
}"
value-key="menuId"
placeholder="选择上级菜单"
check-strictly
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="菜单类型" prop="menuType">
<el-radio-group v-model="form.menuType">
<el-radio label="M">目录</el-radio>
<el-radio label="C">菜单</el-radio>
<el-radio label="F">按钮</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24" v-if="form.menuType != 'F'">
<el-form-item label="菜单图标" prop="icon">
<el-popover
placement="bottom-start"
:width="540"
v-model:visible="showChooseIcon"
trigger="click"
@show="showSelectIcon"
>
<template #reference>
<el-input
v-model="form.icon"
placeholder="点击选择图标"
@blur="showSelectIcon"
v-click-outside="hideSelectIcon"
readonly
>
<template #prefix>
<svg-icon
v-if="form.icon"
:icon-class="form.icon"
class="el-input__icon"
style="height: 32px; width: 16px"
/>
<el-icon v-else style="height: 32px; width: 16px"
><search
/></el-icon>
</template>
</el-input>
</template>
<icon-select ref="iconSelectRef" @selected="selected" />
</el-popover>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="菜单名称" prop="menuName">
<el-input v-model="form.menuName" placeholder="请输入菜单名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="显示排序" prop="orderNum">
<el-input-number
v-model="form.orderNum"
controls-position="right"
:min="0"
/>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item>
<template #label>
<span>
<el-tooltip
content="选择是外链则路由地址需要以`http(s)://`开头"
placement="top"
>
<el-icon><question-filled /></el-icon> </el-tooltip
>是否外链
</span>
</template>
<el-radio-group v-model="form.isFrame">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item prop="path">
<template #label>
<span>
<el-tooltip
content="访问的路由地址,如:`user`,如外网地址需内链访问则以`http(s)://`开头"
placement="top"
>
<el-icon><question-filled /></el-icon>
</el-tooltip>
路由地址
</span>
</template>
<el-input v-model="form.path" placeholder="请输入路由地址" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType == 'C'">
<el-form-item prop="component">
<template #label>
<span>
<el-tooltip
content="访问的组件路径,如:`system/user/index`,默认在`views`目录下"
placement="top"
>
<el-icon><question-filled /></el-icon>
</el-tooltip>
组件路径
</span>
</template>
<el-input v-model="form.component" placeholder="请输入组件路径" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType != 'M'">
<el-form-item>
<el-input
v-model="form.perms"
placeholder="请输入权限标识"
maxlength="100"
/>
<template #label>
<span>
<el-tooltip
content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasPermi('system:user:list')`)"
placement="top"
>
<el-icon><question-filled /></el-icon>
</el-tooltip>
权限字符
</span>
</template>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType == 'C'">
<el-form-item>
<el-input
v-model="form.query"
placeholder="请输入路由参数"
maxlength="255"
/>
<template #label>
<span>
<el-tooltip
content='访问路由的默认传递参数,如:`{"id": 1, "name": "ry"}`'
placement="top"
>
<el-icon><question-filled /></el-icon>
</el-tooltip>
路由参数
</span>
</template>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType == 'C'">
<el-form-item>
<template #label>
<span>
<el-tooltip
content="选择是则会被`keep-alive`缓存,需要匹配组件的`name`和地址保持一致"
placement="top"
>
<el-icon><question-filled /></el-icon>
</el-tooltip>
是否缓存
</span>
</template>
<el-radio-group v-model="form.isCache">
<el-radio label="0">缓存</el-radio>
<el-radio label="1">不缓存</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item>
<template #label>
<span>
<el-tooltip
content="选择隐藏则路由将不会出现在侧边栏,但仍然可以访问"
placement="top"
>
<el-icon><question-filled /></el-icon>
</el-tooltip>
显示状态
</span>
</template>
<el-radio-group v-model="form.visible">
<el-radio
v-for="dict in sys_show_hide"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item>
<template #label>
<span>
<el-tooltip
content="选择停用则路由将不会出现在侧边栏,也不能被访问"
placement="top"
>
<el-icon><question-filled /></el-icon>
</el-tooltip>
菜单状态
</span>
</template>
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</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 { addMenu, delMenu, getMenu, listMenu, updateMenu } from "@/api/system/menu";
import {
addMenu,
delMenu,
getMenu,
listMenu,
updateMenu,
} from "@/api/system/menu";
import SvgIcon from "@/components/SvgIcon";
import IconSelect from "@/components/IconSelect";
import { ClickOutside as vClickOutside } from 'element-plus'
import { ClickOutside as vClickOutside } from "element-plus";
const { proxy } = getCurrentInstance();
const { sys_show_hide, sys_normal_disable } = proxy.useDict("sys_show_hide", "sys_normal_disable");
const { sys_show_hide, sys_normal_disable } = proxy.useDict(
"sys_show_hide",
"sys_normal_disable"
);
const menuList = ref([]);
const open = ref(false);
@ -300,12 +419,16 @@ const data = reactive({
form: {},
queryParams: {
menuName: undefined,
visible: undefined
visible: undefined,
},
rules: {
menuName: [{ required: true, message: "菜单名称不能为空", trigger: "blur" }],
orderNum: [{ required: true, message: "菜单顺序不能为空", trigger: "blur" }],
path: [{ required: true, message: "路由地址不能为空", trigger: "blur" }]
menuName: [
{ required: true, message: "菜单名称不能为空", trigger: "blur" },
],
orderNum: [
{ required: true, message: "菜单顺序不能为空", trigger: "blur" },
],
path: [{ required: true, message: "路由地址不能为空", trigger: "blur" }],
},
});
@ -314,7 +437,7 @@ const { queryParams, form, rules } = toRefs(data);
/** 查询菜单列表 */
function getList() {
loading.value = true;
listMenu(queryParams.value).then(response => {
listMenu(queryParams.value).then((response) => {
menuList.value = proxy.handleTree(response.data, "menuId");
loading.value = false;
});
@ -322,7 +445,7 @@ function getList() {
/** 查询菜单下拉树结构 */
function getTreeselect() {
menuOptions.value = [];
listMenu().then(response => {
listMenu().then((response) => {
const menu = { menuId: 0, menuName: "主类目", children: [] };
menu.children = proxy.handleTree(response.data, "menuId");
menuOptions.value.push(menu);
@ -345,7 +468,7 @@ function reset() {
isFrame: "1",
isCache: "0",
visible: "0",
status: "0"
status: "0",
};
proxy.resetForm("menuRef");
}
@ -361,7 +484,11 @@ function selected(name) {
}
/** 图标外层点击隐藏下拉列表 */
function hideSelectIcon(event) {
var elem = event.relatedTarget || event.srcElement || event.target || event.currentTarget;
var elem =
event.relatedTarget ||
event.srcElement ||
event.target ||
event.currentTarget;
var className = elem.className;
if (className !== "el-input__inner") {
showChooseIcon.value = false;
@ -400,7 +527,7 @@ function toggleExpandAll() {
async function handleUpdate(row) {
reset();
await getTreeselect();
getMenu(row.menuId).then(response => {
getMenu(row.menuId).then((response) => {
form.value = response.data;
open.value = true;
title.value = "修改菜单";
@ -408,16 +535,16 @@ async function handleUpdate(row) {
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["menuRef"].validate(valid => {
proxy.$refs["menuRef"].validate((valid) => {
if (valid) {
if (form.value.menuId != undefined) {
updateMenu(form.value).then(response => {
updateMenu(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addMenu(form.value).then(response => {
addMenu(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
@ -428,12 +555,16 @@ function submitForm() {
}
/** 删除按钮操作 */
function handleDelete(row) {
proxy.$modal.confirm('是否确认删除名称为"' + row.menuName + '"的数据项?').then(function() {
return delMenu(row.menuId);
}).then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
}).catch(() => {});
proxy.$modal
.confirm('是否确认删除名称为"' + row.menuName + '"的数据项?')
.then(function () {
return delMenu(row.menuId);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
}
getList();

14
vite/plugins/auto-import.js

@ -1,12 +1,8 @@
import autoImport from 'unplugin-auto-import/vite'
import autoImport from "unplugin-auto-import/vite";
export default function createAutoImport() {
return autoImport({
imports: [
'vue',
'vue-router',
'pinia'
],
dts: false
})
return autoImport({
imports: ["vue", "vue-router", "pinia"],
dts: false,
});
}

22
vite/plugins/index.js

@ -1,15 +1,15 @@
import vue from '@vitejs/plugin-vue'
import vue from "@vitejs/plugin-vue";
import createAutoImport from './auto-import'
import createSvgIcon from './svg-icon'
import createCompression from './compression'
import createSetupExtend from './setup-extend'
import createAutoImport from "./auto-import";
import createSvgIcon from "./svg-icon";
import createCompression from "./compression";
import createSetupExtend from "./setup-extend";
export default function createVitePlugins(viteEnv, isBuild = false) {
const vitePlugins = [vue()]
vitePlugins.push(createAutoImport())
vitePlugins.push(createSetupExtend())
vitePlugins.push(createSvgIcon(isBuild))
isBuild && vitePlugins.push(...createCompression(viteEnv))
return vitePlugins
const vitePlugins = [vue()];
vitePlugins.push(createAutoImport());
vitePlugins.push(createSetupExtend());
vitePlugins.push(createSvgIcon(isBuild));
isBuild && vitePlugins.push(...createCompression(viteEnv));
return vitePlugins;
}

Loading…
Cancel
Save