Procházet zdrojové kódy

fix: 优化项目概览

yanglzh před 9 měsíci
rodič
revize
48ef901c8e

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 1
src/assets/project/project-icon7.svg


+ 100 - 96
src/components/chart/index.vue

@@ -3,129 +3,133 @@
 </template>
 
 <script setup lang="ts">
-import * as echarts from 'echarts'
-import { onMounted, ref, watch } from 'vue'
+import * as echarts from "echarts";
+import { onMounted, ref, watch } from "vue";
 // import * as chartOptions from './options.js'
-import { useStore } from '/@/store/index'
-const store = useStore()
+import { useStore } from "/@/store/index";
+const store = useStore();
 
 const loadingOption = {
-	// maskColor: 'rgba(255, 255, 255, 0.1)'
-	maskColor: 'rgba(255, 255, 255, 0)',
-	text: '',
-	color: '#409eff',
-	// textColor: '#000',
-	// zlevel: 0,
-	// fontSize: 12,
-	// showSpinner: true,
-	spinnerRadius: 18,
-	lineWidth: 2,
-	// fontWeight: 'normal',
-	// fontStyle: 'normal',
-	// fontFamily: 'sans-serif'
-}
+  // maskColor: 'rgba(255, 255, 255, 0.1)'
+  maskColor: "rgba(255, 255, 255, 0)",
+  text: "",
+  color: "#409eff",
+  // textColor: '#000',
+  // zlevel: 0,
+  // fontSize: 12,
+  // showSpinner: true,
+  spinnerRadius: 18,
+  lineWidth: 2,
+  // fontWeight: 'normal',
+  // fontStyle: 'normal',
+  // fontFamily: 'sans-serif'
+};
 
 const props = defineProps({
-	bg: Boolean,
-	noPadding: Boolean,
-	auto: {
-		type: Boolean,
-		default: false,
-	},
-	autoLoading: {
-		type: Boolean,
-		default: true ,
-	},
-	height: {
-		type: String,
-		default: '100%',
-	},
-	type: {
-		type: String,
-		default: 'Bar',
-	},
-	option: {
-		type: Object,
-		default: () => {
-			return {}
-		},
-	},
-})
+  bg: Boolean,
+  noPadding: Boolean,
+  auto: {
+    type: Boolean,
+    default: false,
+  },
+  autoLoading: {
+    type: Boolean,
+    default: true,
+  },
+  height: {
+    type: String,
+    default: "100%",
+  },
+  type: {
+    type: String,
+    default: "Bar",
+  },
+  option: {
+    type: Object,
+    default: () => {
+      return {};
+    },
+  },
+});
 
-let myChart: any = null
-let optionCache: any = null
-const chart = ref()
+let myChart: any = null;
+let optionCache: any = null;
+const chart = ref();
 
 // 绘制图形
 const draw = (option?: object) => {
-	myChart && myChart.dispose()
-	myChart = echarts.init(chart.value)
-	myChart.hideLoading()
-	if (option) {
-		optionCache = option
-		myChart.setOption(option)
-	} else {
-		// myChart.setOption(chartOptions[`get${props.type}Option`]({ ...props.option }))
-	}
-}
+  myChart && myChart.dispose();
+  myChart = echarts.init(chart.value);
+  myChart.hideLoading();
+  if (option) {
+    optionCache = option;
+    myChart.setOption(option);
+  } else {
+    // myChart.setOption(chartOptions[`get${props.type}Option`]({ ...props.option }))
+  }
+};
 
 const loading = () => {
-	myChart?.setOption({}, { notMerge: true })
-	myChart?.showLoading(loadingOption)
-}
+  myChart?.setOption({}, { notMerge: true });
+  myChart?.showLoading(loadingOption);
+};
+
+const hideLoading = () => {
+  myChart?.hideLoading();
+};
 
 const getChart = () => {
-	return myChart
-}
+  return myChart;
+};
 
-const download = (name: string = 'chart picture') => {
-	const picInfo = myChart.getDataURL({
-		type: 'png',
-		pixelRatio: 2,
-		backgroundColor: '#fff',
-	})
-	let elink = document.createElement('a')
-	elink.download = name
-	elink.style.display = 'none'
-	elink.href = picInfo
-	document.body.appendChild(elink)
-	elink.click()
-	URL.revokeObjectURL(elink.href)
-	document.body.removeChild(elink)
-}
+const download = (name: string = "chart picture") => {
+  const picInfo = myChart.getDataURL({
+    type: "png",
+    pixelRatio: 2,
+    backgroundColor: "#fff",
+  });
+  let elink = document.createElement("a");
+  elink.download = name;
+  elink.style.display = "none";
+  elink.href = picInfo;
+  document.body.appendChild(elink);
+  elink.click();
+  URL.revokeObjectURL(elink.href);
+  document.body.removeChild(elink);
+};
 
 // 配置变化 重绘
 watch(
-	() => props.option,
-	() => {
-		draw()
-	}
-)
+  () => props.option,
+  () => {
+    draw();
+  }
+);
 watch(
-	() => store.state.global.resize,
-	() => {
-		draw(optionCache)
-	}
-)
+  () => store.state.global.resize,
+  () => {
+    draw(optionCache);
+  }
+);
 
 onMounted(() => {
-	myChart = echarts.init(chart.value)
-	props.autoLoading && loading()
-	props.auto && draw()
-})
+  myChart = echarts.init(chart.value);
+  props.autoLoading && loading();
+  props.auto && draw();
+});
 
-defineExpose({ draw, loading, download, getChart })
+defineExpose({ draw, loading, download, getChart, hideLoading });
 </script>
 
 <style scoped lang="scss">
 .echart {
-	height: 100%;
-	width: 100%;
-	// margin: 1vh 0;
-	padding: 2px;
+  height: 100%;
+  width: 100%;
+  // margin: 1vh 0;
+  padding: 2px;
 }
 
 .bg {
-	background: #444;
+  background: #444;
 }
 </style>

+ 123 - 123
src/views/iot/projects/screen/BaseinfoVue.vue

@@ -1,157 +1,157 @@
 <template>
-	<div class="project-card">
-		<div class="select-device title flex-row">
-			<div class="flex">
-				<img src="/@/assets/project/project-icon2.svg" class="icon" />
-				基本信息
-			</div>
-			<el-select style="width: 15vw" v-model="deviceKey" @change="deviceChnage" placeholder="请选择">
-				<el-option v-for="row in deviceList" :key="row.key" :label="row.name" :value="row.key"></el-option>
-			</el-select>
-		</div>
-		<div class="baseinfo-wrapper" v-loading="loading">
-			<section class="baseinfo">
-				<div class="flex-item" v-for="row in propertiyList" :key="row.devicePropertiyKey">
-					<div class="label">{{ row.devicePropertiyName }}</div>
-					<div class="val">
-						{{ row.devicePropertiyValue }}
-						<span class="unit" v-if="row.devicePropertiyUnit">{{ row.devicePropertiyUnit }}</span>
-					</div>
-				</div>
-				<template v-if="propertiyList.length % 3">
-					<div class="flex-item space" v-for="i in 3 - (propertiyList.length % 3)" :key="i"></div>
-				</template>
-			</section>
-		</div>
-	</div>
+  <div class="project-card">
+    <div class="select-device title flex-row">
+      <div class="flex">
+        <img src="/@/assets/project/project-icon2.svg" class="icon" />
+        基本信息
+      </div>
+      <el-select style="width: 15vw" v-model="deviceKey" @change="deviceChnage" placeholder="请选择">
+        <el-option v-for="row in deviceList" :key="row.key" :label="row.name" :value="row.key"></el-option>
+      </el-select>
+    </div>
+    <div class="baseinfo-wrapper" v-loading="loading">
+      <section class="baseinfo">
+        <div class="flex-item" v-for="row in propertiyList" :key="row.devicePropertiyKey">
+          <div class="label">{{ row.devicePropertiyName }}</div>
+          <div class="val">
+            {{ row.devicePropertiyValue }}
+            <span class="unit" v-if="row.devicePropertiyUnit">{{ row.devicePropertiyUnit }}</span>
+          </div>
+        </div>
+        <template v-if="propertiyList.length % 3">
+          <div class="flex-item space" v-for="i in 3 - (propertiyList.length % 3)" :key="i"></div>
+        </template>
+      </section>
+    </div>
+  </div>
 </template>
 <script setup lang="ts">
-import { ref, inject, watch, Ref } from 'vue'
-import api from '/@/api/projects'
+import { ref, inject, watch, Ref } from "vue";
+import api from "/@/api/projects";
 
-const emit = defineEmits(['change'])
+const emit = defineEmits(["change"]);
 
-const projectCode = inject<Ref<string>>('projectCode', ref(''))
+const projectCode = inject<Ref<string>>("projectCode", ref(""));
 
-const loading = ref(true)
-const deviceKey = ref('')
-const deviceList = ref<any[]>([])
-const propertiyList = ref<any[]>([])
+const loading = ref(false);
+const deviceKey = ref("");
+const deviceList = ref<any[]>([]);
+const propertiyList = ref<any[]>([]);
 
-watch(() => projectCode.value, getData)
+watch(() => projectCode.value, getData);
 
 function getData(code: string) {
-	if (!code) return
+  if (!code) return;
 
-	loading.value = true
+  loading.value = true;
 
-	deviceKey.value = ''
-	deviceList.value = []
-	propertiyList.value = []
+  deviceKey.value = "";
+  deviceList.value = [];
+  propertiyList.value = [];
 
-	api.screen.projectDevices(code).then((res: any) => {
-		if (!res?.length) return (loading.value = false)
+  api.screen.projectDevices(code).then((res: any) => {
+    if (!res?.length) return (loading.value = false);
 
-		const keys = (res || []).filter((row: any) => row.resourcesTypes === 1).map((item: any) => item.resourcesKey)
+    const keys = (res || []).filter((row: any) => row.resourcesTypes === 1).map((item: any) => item.resourcesKey);
 
-		loading.value = true
-		api.screen.projectDevicesList(keys).then((res: any) => {
-			const list = res.device || []
+    loading.value = true;
+    api.screen.projectDevicesList(keys).then((res: any) => {
+      const list = res.device || [];
 
-			deviceList.value = list
+      deviceList.value = list;
 
-			if (list.length) {
-				deviceKey.value = list[0].key
-				deviceChnage()
-			} else {
-				emit('change', '')
-				loading.value = false
-			}
-		})
-	})
+      if (list.length) {
+        deviceKey.value = list[0].key;
+        deviceChnage();
+      } else {
+        emit("change", "");
+        loading.value = false;
+      }
+    });
+  });
 }
 
 function deviceChnage() {
-	emit('change', deviceKey.value)
-
-	loading.value = true
-	api.screen
-		.propertyListValue(projectCode.value, deviceKey.value)
-		.then((res: any) => {
-			propertiyList.value = res || []
-		})
-		.finally(() => (loading.value = false))
+  emit("change", deviceKey.value);
+
+  loading.value = true;
+  api.screen
+    .propertyListValue(projectCode.value, deviceKey.value)
+    .then((res: any) => {
+      propertiyList.value = res || [];
+    })
+    .finally(() => (loading.value = false));
 }
 </script>
 
 <style lang="scss" scoped>
 .project-card {
-	flex: 1;
-	display: flex;
-	flex-direction: column;
-	overflow: hidden;
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
 }
 
 .select-device {
-	display: flex;
-	align-items: center;
+  display: flex;
+  align-items: center;
 }
 .baseinfo-wrapper {
-	flex: 1;
-	overflow-y: auto;
+  flex: 1;
+  overflow-y: auto;
 }
 .baseinfo {
-	display: flex;
-	flex-flow: row wrap;
-	justify-content: space-between;
-	gap: 10px;
-
-	.flex-item {
-		display: flex;
-		align-items: center;
-		justify-content: space-between;
-		flex: 1;
-		height: 40px;
-		max-width: 33%;
-		min-width: 30%;
-		font-size: 12px;
-		white-space: nowrap;
-		overflow: hidden;
-		border-radius: 4px;
-		border: 1px solid #e0e7ff;
-		font-weight: 500;
-		padding: 0 3%;
-
-		&.space {
-			background: none;
-		}
-
-		.label {
-			color: #2e384d;
-		}
-
-		.val {
-			font-size: 15px;
-			font-weight: bold;
-			color: #8798ad;
-
-			.unit {
-				font-weight: normal;
-				font-size: 12px;
-			}
-		}
-	}
+  display: flex;
+  flex-flow: row wrap;
+  justify-content: space-between;
+  gap: 10px;
+
+  .flex-item {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    flex: 1;
+    height: 40px;
+    max-width: 33%;
+    min-width: 30%;
+    font-size: 12px;
+    white-space: nowrap;
+    overflow: hidden;
+    border-radius: 4px;
+    border: 1px solid #e0e7ff;
+    font-weight: 500;
+    padding: 0 3%;
+
+    &.space {
+      background: none;
+    }
+
+    .label {
+      color: #2e384d;
+    }
+
+    .val {
+      font-size: 15px;
+      font-weight: bold;
+      color: #8798ad;
+
+      .unit {
+        font-weight: normal;
+        font-size: 12px;
+      }
+    }
+  }
 }
-[data-theme='dark'] {
-	.flex-item {
-		border: 1px solid #717171;
-	}
-	.label {
-		color: #a4a6ad !important;
-	}
-
-	.val {
-		color: #4285f5 !important;
-	}
+[data-theme="dark"] {
+  .flex-item {
+    border: 1px solid #717171;
+  }
+  .label {
+    color: #a4a6ad !important;
+  }
+
+  .val {
+    color: #4285f5 !important;
+  }
 }
 </style>

+ 98 - 98
src/views/iot/projects/screen/InfoVue.vue

@@ -1,127 +1,127 @@
 <template>
-	<div class="project-card">
-		<div class="title flex-row">
-			<div class="flex">
-				<img src="/@/assets/project/project-icon1.svg" class="icon" />
-				项目信息
-			</div>
-			<el-select style="width: 15vw" v-model="project" @change="projectChange" placeholder="请选择">
-				<el-option v-for="row in projectList" :key="row.id" :label="row.name" :value="row.code"></el-option>
-			</el-select>
-		</div>
-		<div class="flex-row">
-			<div class="flex">
-				<div class="label">项目名称:</div>
-				<div class="val">{{ projectData?.name }}</div>
-			</div>
-			<div class="flex">
-				<div class="label">项目地址:</div>
-				<div class="val">{{ projectData?.addressDetail }}</div>
-			</div>
-		</div>
-		<section class="info">
-			<div class="info-content">
-				<div class="count-card">
-					<img src="/@/assets/project/project-icon7.svg" class="icon" />
-					<div class="count">{{ projectData?.heatingArea }} <span class="unit">m²</span></div>
-					<div class="text">供热面积</div>
-				</div>
-				<div class="count-card">
-					<img src="/@/assets/project/project-icon8.svg" class="icon" />
-					<div class="count">{{ projectData?.deviceCount }} <span class="unit">台</span></div>
-					<div class="text">设备台数</div>
-				</div>
-				<div class="count-card">
-					<img src="/@/assets/project/project-icon9.svg" class="icon" />
-					<div class="count">{{ projectData?.repairMobile || '-' }}</div>
-					<div class="text">维保电话</div>
-				</div>
-			</div>
-		</section>
-	</div>
+  <div class="project-card">
+    <div class="title flex-row">
+      <div class="flex">
+        <img src="/@/assets/project/project-icon1.svg" class="icon" />
+        项目信息
+      </div>
+      <el-select style="width: 15vw" v-model="project" @change="projectChange" placeholder="请选择">
+        <el-option v-for="row in projectList" :key="row.id" :label="row.name" :value="row.code"></el-option>
+      </el-select>
+    </div>
+    <div class="flex-row">
+      <div class="flex">
+        <div class="label">项目名称:</div>
+        <div class="val">{{ projectData?.name }}</div>
+      </div>
+      <div class="flex">
+        <div class="label">项目地址:</div>
+        <div class="val">{{ projectData?.addressDetail }}</div>
+      </div>
+    </div>
+    <section class="info">
+      <div class="info-content">
+        <div class="count-card">
+          <img src="/@/assets/project/project-icon7.svg" class="icon" />
+          <div class="count">{{ projectData?.heatingArea }} <span class="unit">m²</span></div>
+          <div class="text">覆盖面积</div>
+        </div>
+        <div class="count-card">
+          <img src="/@/assets/project/project-icon8.svg" class="icon" />
+          <div class="count">{{ projectData?.deviceCount }} <span class="unit">台</span></div>
+          <div class="text">设备台数</div>
+        </div>
+        <div class="count-card">
+          <img src="/@/assets/project/project-icon9.svg" class="icon" />
+          <div class="count">{{ projectData?.repairMobile || "-" }}</div>
+          <div class="text">维保电话</div>
+        </div>
+      </div>
+    </section>
+  </div>
 </template>
 <script setup lang="ts">
-import { reactive, ref, inject, watch, Ref } from 'vue'
+import { reactive, ref, inject, watch, Ref } from "vue";
 
-const emit = defineEmits(['change'])
+const emit = defineEmits(["change"]);
 
-const props = defineProps(['projectList'])
-const projectCode = inject<Ref<string>>('projectCode', ref(''))
+const props = defineProps(["projectList"]);
+const projectCode = inject<Ref<string>>("projectCode", ref(""));
 
-const project = ref(projectCode)
-const projectData = ref<any>({})
+const project = ref(projectCode);
+const projectData = ref<any>({});
 
-watch(() => projectCode.value, projectChange)
+watch(() => projectCode.value, projectChange);
 
 function projectChange(code: string) {
-	project.value = code
-	emit('change', code)
-	projectData.value = props.projectList.find((row: any) => row.code === code) || {}
+  project.value = code;
+  emit("change", code);
+  projectData.value = props.projectList.find((row: any) => row.code === code) || {};
 }
 </script>
 
 <style lang="scss" scoped>
 .label {
-	color: var(--primary-color);
+  color: var(--primary-color);
 }
 
 .val {
-	color: #8798ad;
+  color: #8798ad;
 }
 
 .info {
-	margin-top: 10px;
-	.info-content {
-		display: flex;
-		justify-content: space-between;
-		gap: 20px;
+  margin-top: 10px;
+  .info-content {
+    display: flex;
+    justify-content: space-between;
+    gap: 20px;
 
-		.count-card {
-			padding: 2vh;
-			flex: 1;
-			.icon {
-				height: 5vh;
-			}
+    .count-card {
+      padding: 2vh;
+      flex: 1;
+      .icon {
+        height: 5vh;
+      }
 
-			.label {
-				color: var(--primary-color);
-			}
+      .label {
+        color: var(--primary-color);
+      }
 
-			.count {
-				color: #2e384d;
-				font-size: 22px;
-				margin: 4px 0;
-			}
-			.text {
-				color: #8798ad;
-				font-size: 12px;
-			}
-			.unit {
-				font-size: 12px;
-			}
-		}
-	}
+      .count {
+        color: #2e384d;
+        font-size: 22px;
+        margin: 4px 0;
+      }
+      .text {
+        color: #8798ad;
+        font-size: 12px;
+      }
+      .unit {
+        font-size: 12px;
+      }
+    }
+  }
 }
 .count-card {
-	background: #ffffff;
-	border-radius: 1px;
-	border: 1px solid rgba(46, 91, 255, 0.08);
-	box-shadow: 0px 10px 20px 0px rgba(46, 91, 255, 0.07);
+  background: #ffffff;
+  border-radius: 1px;
+  border: 1px solid rgba(46, 91, 255, 0.08);
+  box-shadow: 0px 10px 20px 0px rgba(46, 91, 255, 0.07);
 }
-[data-theme='dark'] {
-	.count-card {
-		background: #1f1f1f;
-		border: 1px solid rgba(255, 255, 255, 0.02);
-	}
-	.count {
-		color: #3d7ade !important;
-	}
-	.label {
-		color: #8B8D92;
-	}
+[data-theme="dark"] {
+  .count-card {
+    background: #1f1f1f;
+    border: 1px solid rgba(255, 255, 255, 0.02);
+  }
+  .count {
+    color: #3d7ade !important;
+  }
+  .label {
+    color: #8b8d92;
+  }
 
-	.val {
-		color: #4285F5;
-	}
+  .val {
+    color: #4285f5;
+  }
 }
 </style>

+ 116 - 115
src/views/iot/projects/screen/LineChart.vue

@@ -1,144 +1,145 @@
 <template>
-	<div class="project-card">
-		<div class="select-device title">
-			<div class="flex">
-				<img src="/@/assets/project/project-icon4.svg" v-if="index" class="icon" />
-				<img src="/@/assets/project/project-icon3.svg" v-else class="icon" />
-				设备状态
-			</div>
-			<div class="flex">
-				<el-date-picker
-					class="date-picker-wrap"
-					v-model="params.timeRange"
-					:clearable="false"
-					type="datetimerange"
-					range-separator="至"
-					start-placeholder="开始时间"
-					end-placeholder="结束时间"
-					format="MM-DD HH:mm"
-					value-format="YYYY-MM-DD HH:mm:00"
-					date-format="YYYY/MM/DD"
-					time-format="hh:mm"
-					@change="getChartData"
-					style="width: 230px; margin-right: 10px"
-				/>
-				<el-select style="width: 150px" v-model="params.properties" multiple collapse-tags @change="getChartData" placeholder="请选择">
-					<el-option v-for="row in options" :key="row.key" :label="row.name" :value="row.key"></el-option>
-				</el-select>
-			</div>
-		</div>
-		<section class="line">
-			<Chart height="22.5vh" ref="chartRef"></Chart>
-		</section>
-	</div>
+  <div class="project-card">
+    <div class="select-device title">
+      <div class="flex">
+        <img src="/@/assets/project/project-icon4.svg" v-if="index" class="icon" />
+        <img src="/@/assets/project/project-icon3.svg" v-else class="icon" />
+        设备状态
+      </div>
+      <div class="flex">
+        <el-date-picker
+          class="date-picker-wrap"
+          v-model="params.timeRange"
+          :clearable="false"
+          type="datetimerange"
+          range-separator="至"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+          format="MM-DD HH:mm"
+          value-format="YYYY-MM-DD HH:mm:00"
+          date-format="YYYY/MM/DD"
+          time-format="hh:mm"
+          @change="getChartData"
+          style="width: 230px; margin-right: 10px"
+        />
+        <el-select style="width: 150px" v-model="params.properties" multiple collapse-tags @change="getChartData" placeholder="请选择">
+          <el-option v-for="row in options" :key="row.key" :label="row.name" :value="row.key"></el-option>
+        </el-select>
+      </div>
+    </div>
+    <section class="line">
+      <Chart height="22.5vh" ref="chartRef"></Chart>
+    </section>
+  </div>
 </template>
 <script setup lang="ts">
-import { onMounted, reactive, ref, watch } from 'vue'
-import { getLineMultiOption } from '/@/components/chart/options'
-import Chart from '/@/components/chart/index.vue'
-import api from '/@/api/projects'
-import { dayjs } from 'element-plus'
-import { useStore } from '/@/store/index'
-const store = useStore()
+import { onMounted, reactive, ref, watch } from "vue";
+import { getLineMultiOption } from "/@/components/chart/options";
+import Chart from "/@/components/chart/index.vue";
+import api from "/@/api/projects";
+import { dayjs } from "element-plus";
+import { useStore } from "/@/store/index";
+const store = useStore();
 
 const props = defineProps({
-	index: {
-		type: [String, Number],
-		dafault: 0,
-	},
-	deviceKey: {
-		type: String,
-		dafault: '',
-	},
-})
-
-let deviceCode = ''
-const chartRef = ref()
-const theme = ref('light')
-const options = ref<any[]>([])
+  index: {
+    type: [String, Number],
+    dafault: 0,
+  },
+  deviceKey: {
+    type: String,
+    dafault: "",
+  },
+});
+
+let deviceCode = "";
+const chartRef = ref();
+const theme = ref("light");
+const options = ref<any[]>([]);
 const params = reactive({
-	timeRange: [dayjs().subtract(1, 'hour').format('YYYY-MM-DD HH:mm:00'), dayjs().format('YYYY-MM-DD HH:mm:00')],
-	properties: [] as string[],
-})
+  timeRange: [dayjs().subtract(1, "hour").format("YYYY-MM-DD HH:mm:00"), dayjs().format("YYYY-MM-DD HH:mm:00")],
+  properties: [] as string[],
+});
 
 watch(
-	() => store.state.themeConfig.themeConfig.isIsDark,
-	(isIsDark) => {
-		theme.value = isIsDark ? 'dark' : 'light'
-		if (params.properties.length) getChartData()
-	},
-	{
-		immediate: true,
-	}
-)
-
-watch(() => props.deviceKey!, getData)
+  () => store.state.themeConfig.themeConfig.isIsDark,
+  (isIsDark) => {
+    theme.value = isIsDark ? "dark" : "light";
+    if (params.properties.length) getChartData();
+  },
+  {
+    immediate: true,
+  }
+);
+
+watch(() => props.deviceKey!, getData);
 
 onMounted(() => {
-	chartRef.value?.loading()
-})
+  chartRef.value?.hideLoading();
+});
 
 function getData(code: string) {
-	params.properties = []
-	options.value = []
+  params.properties = [];
+  options.value = [];
 
-	deviceCode = code
+  deviceCode = code;
+  console.log(code);
 
-	if (!code) return chartRef.value.draw()
+  if (!code) return chartRef.value.draw();
 
-	chartRef.value?.loading()
+  chartRef.value?.loading();
 
-	api.screen.propertyList(code).then((res: any) => {
-		const list = res?.Data || []
-		options.value = list
+  api.screen.propertyList(code).then((res: any) => {
+    const list = res?.Data || [];
+    options.value = list;
 
-		if (!list.length) return chartRef.value.draw()
+    if (!list.length) return chartRef.value.draw();
 
-		const i = Number(props.index)
-		if (list[i]) {
-			params.properties = [list[i].key]
-		} else {
-			params.properties = [list[0].key]
-		}
-		getChartData()
-	})
+    const i = Number(props.index);
+    if (list[i]) {
+      params.properties = [list[i].key];
+    } else {
+      params.properties = [list[0].key];
+    }
+    getChartData();
+  });
 }
 
 function getChartData() {
-	chartRef.value.loading()
-	if (!params.properties.length) return chartRef.value.draw()
-	api.screen
-		.chartData({
-			deviceKey: deviceCode,
-			dateRange: params.timeRange,
-			properties: params.properties,
-		})
-		.then((res: any) => {
-			if (!res) return chartRef.value.draw()
-
-			const values = Object.values(res) as any[]
-
-			const legend = Object.keys(res).map((key) => options.value.find((item) => item.key === key)?.name)
-
-			chartRef.value?.draw(
-				getLineMultiOption({
-					datas: values.map((arr: any) => (arr || []).map((item: any) => item.dataValue)),
-					legend,
-					xAxis: (values[0] || []).map((item: any) => item.dataTime),
-					theme: theme.value,
-				})
-			)
-		})
+  chartRef.value.loading();
+  if (!params.properties.length) return chartRef.value.draw();
+  api.screen
+    .chartData({
+      deviceKey: deviceCode,
+      dateRange: params.timeRange,
+      properties: params.properties,
+    })
+    .then((res: any) => {
+      if (!res) return chartRef.value.draw();
+
+      const values = Object.values(res) as any[];
+
+      const legend = Object.keys(res).map((key) => options.value.find((item) => item.key === key)?.name);
+
+      chartRef.value?.draw(
+        getLineMultiOption({
+          datas: values.map((arr: any) => (arr || []).map((item: any) => item.dataValue)),
+          legend,
+          xAxis: (values[0] || []).map((item: any) => item.dataTime),
+          theme: theme.value,
+        })
+      );
+    });
 }
 </script>
 
 <style lang="scss" scoped>
 .select-device {
-	color: var(--primary-color);
-	display: flex;
-	align-items: center;
-	white-space: nowrap;
-	justify-content: space-between;
+  color: var(--primary-color);
+  display: flex;
+  align-items: center;
+  white-space: nowrap;
+  justify-content: space-between;
 }
 
 .line {

+ 76 - 76
src/views/iot/projects/screen/VideoVue.vue

@@ -1,106 +1,106 @@
 <template>
-	<div class="project-card">
-		<section class="video" v-loading="loading">
-			<div class="title">
-				<el-select v-model="params.project" @change="projectChange" placeholder="选择项目" style="width: 300px">
-					<el-option v-for="row in projectList" :key="row.id" :label="row.name" :value="row.code"></el-option>
-				</el-select>
-				<!-- <el-select v-model="params.type" placeholder="" style="width: 9vw; margin-left: 1.6vw">
+  <div class="project-card">
+    <section class="video" v-loading="loading">
+      <div class="title">
+        <el-select v-model="params.project" @change="projectChange" placeholder="选择项目" style="width: 300px">
+          <el-option v-for="row in projectList" :key="row.id" :label="row.name" :value="row.code"></el-option>
+        </el-select>
+        <!-- <el-select v-model="params.type" placeholder="" style="width: 9vw; margin-left: 1.6vw">
 				<el-option label="视频监控" value="1"></el-option>
 				<el-option label="组态" value="2"></el-option>
 			</el-select> -->
-				<div class="full-screent-icon" @click="fullScreen = true">
-					<el-icon color="#409eff" size="18px"><ele-FullScreen /></el-icon>
-					<!-- <img src="/@/assets//project/full-screen.svg" style="height: 32px;" /> -->
-				</div>
-			</div>
-			<div class="video-content">
-				<template v-if="params.type === '2' && topoSrc">
-					<iframe :src="topoSrc" frameborder="0"></iframe>
-				</template>
-			</div>
-			<el-dialog v-model="fullScreen" class="video-screen-dialog" fullscreen append-to-body>
-				<iframe v-if="fullScreen" :src="topoSrc" frameborder="0" style="height: calc(100vh - 75px)"></iframe>
-			</el-dialog>
-		</section>
-	</div>
+        <div class="full-screent-icon" @click="fullScreen = true">
+          <el-icon color="#409eff" size="18px"><ele-FullScreen /></el-icon>
+          <!-- <img src="/@/assets//project/full-screen.svg" style="height: 32px;" /> -->
+        </div>
+      </div>
+      <div class="video-content">
+        <template v-if="params.type === '2' && topoSrc">
+          <iframe :src="topoSrc" frameborder="0"></iframe>
+        </template>
+      </div>
+      <el-dialog v-model="fullScreen" class="video-screen-dialog" fullscreen append-to-body>
+        <iframe v-if="fullScreen" :src="topoSrc" frameborder="0" style="height: calc(100vh - 75px)"></iframe>
+      </el-dialog>
+    </section>
+  </div>
 </template>
 
 <script setup lang="ts">
-import { reactive, ref, inject, watch, Ref } from 'vue'
-import api from '/@/api/projects'
+import { reactive, ref, inject, watch, Ref } from "vue";
+import api from "/@/api/projects";
 
-const emit = defineEmits(['change'])
+const emit = defineEmits(["change"]);
 
-const { projectList } = defineProps(['projectList'])
-const projectCode = inject<Ref<string>>('projectCode', ref(''))
-const fullScreen = ref(false)
-const loading = ref(false)
-const topoSrc = ref('')
+const { projectList } = defineProps(["projectList"]);
+const projectCode = inject<Ref<string>>("projectCode", ref(""));
+const fullScreen = ref(false);
+const loading = ref(false);
+const topoSrc = ref("");
 
-watch(() => projectCode.value, projectChange)
+watch(() => projectCode.value, projectChange);
 
 const params = reactive({
-	project: projectCode,
-	type: '2',
-})
+  project: projectCode,
+  type: "2",
+});
 
 function projectChange(code: string) {
-	topoSrc.value = ''
-	loading.value = true
+  topoSrc.value = "";
+  loading.value = true;
 
-	emit('change', code)
+  emit("change", code);
 
-	api.screen
-		.projectDevices(code)
-		.then((res: any) => {
-			const topoKey = (res || []).find((row: any) => row.resourcesTypes === 2)?.resourcesKey
-			// topoSrc.value = topoKey ? '/plugin/topo/#/show/' + topoKey : ''
-			topoSrc.value = topoKey ? 'https://zhgy.sagoo.cn/plugin/topo/index.html#/show/' + topoKey : ''
-		})
-		.finally(() => (loading.value = false))
+  api.screen
+    .projectDevices(code)
+    .then((res: any) => {
+      const topoKey = (res || []).find((row: any) => row.resourcesTypes === 2)?.resourcesKey;
+      topoSrc.value = topoKey ? "/plugin/topo/#/show/" + topoKey : "";
+      // topoSrc.value = topoKey ? 'https://zhgy.sagoo.cn/plugin/topo/index.html#/show/' + topoKey : ''
+    })
+    .finally(() => (loading.value = false));
 }
 </script>
 <style lang="scss" scoped>
 iframe {
-	width: 100%;
-	height: 100%;
-	padding: 0;
-	overflow: hidden;
+  width: 100%;
+  height: 100%;
+  padding: 0;
+  overflow: hidden;
 }
 .project-card {
-	flex: 1;
+  flex: 1;
 }
 
 .video {
-	height: 100%;
-	pointer-events: all;
-	background-size: 100% 100%;
-	background-repeat: no-repeat;
-	background-position: center;
-	display: flex;
-	flex-direction: column;
+  height: 100%;
+  pointer-events: all;
+  background-size: 100% 100%;
+  background-repeat: no-repeat;
+  background-position: center;
+  display: flex;
+  flex-direction: column;
 
-	.video-content {
-		width: 100%;
-		flex: 1;
-		padding: 0 2px;
-		position: relative;
-	}
+  .video-content {
+    width: 100%;
+    flex: 1;
+    padding: 0 2px;
+    position: relative;
+  }
 
-	.title {
-		color: var(--primary-color);
-		display: flex;
-		align-items: center;
-		justify-content: space-between;
+  .title {
+    color: var(--primary-color);
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
 
-		.full-screent-icon {
-			color: var(--primary-color);
-			cursor: pointer;
-		}
-		.label {
-			font-weight: 500;
-		}
-	}
+    .full-screent-icon {
+      color: var(--primary-color);
+      cursor: pointer;
+    }
+    .label {
+      font-weight: 500;
+    }
+  }
 }
 </style>

+ 63 - 63
src/views/iot/projects/screen/index.vue

@@ -1,78 +1,78 @@
 <script setup lang="ts">
-import LineChart from './LineChart.vue'
-import VideoVue from './VideoVue.vue'
-import InfoVue from './InfoVue.vue'
-import BaseinfoVue from './BaseinfoVue.vue'
-import { provide, ref } from 'vue'
-import api from '/@/api/projects'
+import LineChart from "./LineChart.vue";
+import VideoVue from "./VideoVue.vue";
+import InfoVue from "./InfoVue.vue";
+import BaseinfoVue from "./BaseinfoVue.vue";
+import { provide, ref } from "vue";
+import api from "/@/api/projects";
 
-const projectCode = ref('')
-const deviceKey = ref('')
-const projectList = ref<any[]>([])
+const projectCode = ref("");
+const deviceKey = ref("");
+const projectList = ref<any[]>([]);
 
-provide('projectCode', projectCode)
+provide("projectCode", projectCode);
 
 api.screen
-	.projects({
-		pageNum: 1,
-		pageSize: 500,
-		status: 1,
-	})
-	.then(({ list }: { list: any[] }) => {
-		projectList.value = list || []
-		if (list?.length) {
-			setTimeout(() => {
-				projectCode.value = list[0].code
-			}, 1000)
-		}
-	})
+  .projects({
+    pageNum: 1,
+    pageSize: 500,
+    status: 1,
+  })
+  .then(({ list }: { list: any[] }) => {
+    projectList.value = list || [];
+    if (list?.length) {
+      setTimeout(() => {
+        projectCode.value = list[0].code;
+      }, 1000);
+    }
+  });
 </script>
 
 <template>
-	<el-form class="container" size="small">
-		<div class="part">
-			<VideoVue :projectList="projectList" @change="projectCode = $event"></VideoVue>
-			<LineChart :deviceKey="deviceKey" :index="0"></LineChart>
-		</div>
-		<div class="part">
-			<InfoVue :projectList="projectList" @change="projectCode = $event"></InfoVue>
-			<BaseinfoVue @change="deviceKey = $event"></BaseinfoVue>
-			<LineChart :deviceKey="deviceKey" :index="1"></LineChart>
-		</div>
-	</el-form>
+  <el-form class="container" size="small">
+    <div class="part">
+      <VideoVue :projectList="projectList" @change="projectCode = $event"></VideoVue>
+      <LineChart :deviceKey="deviceKey" :index="0"></LineChart>
+    </div>
+    <div class="part">
+      <InfoVue :projectList="projectList" @change="projectCode = $event"></InfoVue>
+      <BaseinfoVue @change="deviceKey = $event"></BaseinfoVue>
+      <LineChart :deviceKey="deviceKey" :index="1"></LineChart>
+    </div>
+  </el-form>
 </template>
 
 <style lang="scss" scoped>
 .container {
-	width: 100%;
-	display: flex;
-	justify-content: space-between;
-	height: 100%;
-	overflow: hidden;
-	gap: 15px;
-	::v-deep(.project-card) {
-		background-color: var(--el-color-white) !important;
-		padding: 15px 20px;
-		border-radius: 6px;
-		.title {
-			font-size: 14px;
-			font-weight: 500;
-			margin-bottom: 12px;
-			.icon {
-				height: 28px;
-				margin-right: 8px;
-			}
-		}
-	}
+  width: 100%;
+  display: flex;
+  justify-content: space-between;
+  height: 100%;
+  overflow: hidden;
+  gap: 15px;
+  ::v-deep(.project-card) {
+    background-color: var(--el-color-white) !important;
+    padding: 15px 20px;
+    border-radius: 6px;
+    .title {
+      font-size: 14px;
+      font-weight: 500;
+      margin-bottom: 12px;
+      .icon {
+        height: 28px;
+        margin-right: 8px;
+      }
+    }
+  }
 
-	.part {
-		flex: 1;
-		display: flex;
-		flex-flow: column nowrap;
-		justify-content: space-between;
-		z-index: 10;
-		overflow: hidden;
-		gap: 15px;
-	}
+  .part {
+    flex: 1;
+    display: flex;
+    flex-flow: column nowrap;
+    justify-content: space-between;
+    z-index: 10;
+    overflow: hidden;
+    gap: 15px;
+  }
 }
 </style>

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů