Browse Source

v1.1

master
wally 4 years ago
parent
commit
6ccfd6bca5
  1. 27
      .idea/workspace.xml
  2. BIN
      assets/images/farm-top.png
  3. 56
      components/Common/Weather.vue
  4. 18
      components/DataCenter/Address.vue
  5. 5
      components/DataCenter/FarmList.vue
  6. 11
      components/DataCenter/FarmTab.vue
  7. 4
      components/DataCenter/Left.vue
  8. 4
      components/DataCenter/Right.vue
  9. 94
      components/DataFarm/Humidity.vue
  10. 91
      components/DataFarm/SoilHumidity.vue
  11. 92
      components/DataFarm/Temperature.vue
  12. 13
      components/Page/Buttons.vue
  13. 30
      components/Page/Header.vue
  14. 16
      components/Page/Modal.vue
  15. 119
      config/layout/dataFarmBody.js
  16. 18
      hooks/useLayoutConfig.js
  17. 4
      layouts/default.vue
  18. 41
      layouts/farm.vue
  19. 9
      pages/farm.vue
  20. 28
      pages/index.vue
  21. 10
      server/api/weather.ts

27
.idea/workspace.xml

@ -6,15 +6,16 @@
<component name="ChangeListManager">
<list default="true" id="83558921-0a42-4f39-ab1d-d218d98a0f1e" name="变更" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app.vue" beforeDir="false" afterPath="$PROJECT_DIR$/app.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/Common/Monitor.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/Common/Monitor.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/DataCenter/ComplexChart.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/DataCenter/ComplexChart.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/DataCenter/Tall.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/DataCenter/Tall.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/DataCenter/YieldChart.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/DataCenter/YieldChart.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/DataCenter/Address.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/DataCenter/Address.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/DataCenter/FarmList.vue" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/components/DataCenter/FarmTab.vue" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/components/DataCenter/Left.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/DataCenter/Left.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/DataCenter/Right.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/DataCenter/Right.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/Page/Buttons.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/Page/Buttons.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/Page/Header.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/Page/Header.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/Page/Modal.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/Page/Modal.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/layouts/default.vue" beforeDir="false" afterPath="$PROJECT_DIR$/layouts/default.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/utils/complexChart.js" beforeDir="false" afterPath="$PROJECT_DIR$/utils/complexChart.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/utils/complexConfig.js" beforeDir="false" afterPath="$PROJECT_DIR$/utils/complexConfig.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pages/index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/pages/index.vue" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -24,9 +25,9 @@
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="TypeScript File" />
<option value="Vue Single File Component" />
<option value="JavaScript File" />
<option value="Vue Single File Component" />
<option value="TypeScript File" />
</list>
</option>
</component>
@ -56,7 +57,7 @@
<property name="ASKED_ADD_EXTERNAL_FILES" value="true" />
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/server" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/config/layout" />
<property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.detected.package.tslint" value="true" />
<property name="node.js.selected.package.eslint" value="(autodetect)" />
@ -64,11 +65,12 @@
<property name="nodejs_package_manager_path" value="yarn" />
<property name="prettierjs.PrettierConfiguration.Package" value="D:\Demo\vue3\nuxt3-app\node_modules\prettier" />
<property name="settings.editor.selected.configurable" value="xyz.sleipnir.codeminimap.config.ConfigEntry" />
<property name="ts.external.directory.path" value="C:\Users\Administrator\AppData\Local\JetBrains\Toolbox\apps\WebStorm\ch-1\213.5449.31\plugins\JavaScriptLanguage\jsLanguageServicesImpl\external" />
<property name="ts.external.directory.path" value="C:\Users\Administrator\AppData\Local\JetBrains\Toolbox\apps\WebStorm\ch-1\213.5744.224\plugins\JavaScriptLanguage\jsLanguageServicesImpl\external" />
<property name="vue.rearranger.settings.migration" value="true" />
</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="D:\Demo\vue3\nuxt3-app\config\layout" />
<recent name="D:\Demo\vue3\nuxt3-app\server" />
<recent name="D:\Demo\vue3\nuxt3-app\components\DataCenter" />
</key>
@ -99,6 +101,9 @@
<workItem from="1638145763343" duration="1269000" />
<workItem from="1638147052619" duration="213000" />
<workItem from="1638147277058" duration="16639000" />
<workItem from="1638339993712" duration="26000" />
<workItem from="1638493797139" duration="837000" />
<workItem from="1638494995524" duration="14445000" />
</task>
<servers />
</component>

BIN
assets/images/farm-top.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

56
components/Common/Weather.vue

@ -0,0 +1,56 @@
<template>
<div class="weather-container" v-if="weather">
今日天气
<i :class="[`qi-${weather.icon}`, 'icon']"></i>
<span class="text">{{ weather.text }}</span>
<span class="temp">{{ weather.temp }}</span>
</div>
</template>
<script setup>
import { ref } from 'vue';
const weather = ref(null);
async function getData() {
try {
const { data: rawData } = await useFetch('/api/weather');
const { code, now } = rawData.value.data;
if (+code !== 200) {
throw new Error(code);
} else {
weather.value = now;
}
} catch (error) {
console.error(error);
}
}
getData();
</script>
<style scoped>
.weather-container {
position: absolute;
right: 20rem;
top: 10rem;
color: #fff;
display: flex;
align-items: center;
}
.temp {
font-size: 25rem;
color: #fff;
font-family: impact;
margin-left: 14rem;
}
.text {
margin-left: 14rem;
}
.icon {
margin-left: 10rem;
color: #fff100;
font-size: 26rem;
font-weight: bolder;
}
</style>

18
components/DataCenter/Address.vue

@ -1,14 +1,22 @@
<template>
<div class="address-container">
<img src="../../assets/images/icon-location.png" alt="" />
我的位置山西省 > 太原市 > 晋祠农场
我的位置山西省 > 太原市 > {{ address }}
</div>
</template>
<script>
export default {
name: 'Address',
};
<script setup>
import { inject, computed } from 'vue';
const scene = inject('scene');
const address = computed(() => {
if (scene === 'farm') {
return '大井生态园';
} else {
return '山西省农科院';
}
});
</script>
<style scoped>

5
components/DataCenter/FarmList.vue

@ -1,5 +0,0 @@
<template>1</template>
<script setup></script>
<style scoped></style>

11
components/DataCenter/FarmTab.vue

@ -1,11 +0,0 @@
<template>
<div class="tab-container" v-show="show"></div>
</template>
<script setup>
import { ref } from 'vue';
const show = ref(false);
</script>
<style scoped></style>

4
components/DataCenter/Left.vue

@ -21,7 +21,9 @@
</template>
<script setup>
import { body } from '@/config/layout/dataCenterBody';
import useLayoutConfig from '@/hooks/useLayoutConfig';
const body = useLayoutConfig();
</script>
<style scoped>

4
components/DataCenter/Right.vue

@ -21,7 +21,9 @@
</template>
<script setup>
import { body } from '@/config/layout/dataCenterBody';
import useLayoutConfig from '@/hooks/useLayoutConfig';
const body = useLayoutConfig();
</script>
<style scoped>

94
components/DataFarm/Humidity.vue

@ -0,0 +1,94 @@
<template>
<div id="humidity-container"></div>
</template>
<script setup>
import { nextTick } from 'vue';
async function getData() {
try {
const { data: rawData } = await useFetch('/api/datas');
const { code, msg, data } = rawData.value;
if (code === 200) {
await nextTick();
initChart(data);
} else {
throw new Error(msg);
}
} catch (error) {
console.error(error);
}
}
getData();
//
function initChart(data) {
const chartDom = document.getElementById('humidity-container');
const option = initOption(data);
const myChart = echarts.init(chartDom);
myChart.setOption(option);
}
function initData(data) {
console.log('data1: ', data);
const result = { times: [], roomH: [], outH: [] };
data.forEach(item => {
result.times.push(item.time);
result.roomH.push(item.roomH);
result.outH.push(item.outH);
});
return result;
}
function initOption(data) {
const { time, roomH, outH } = initData(data);
return {
tooltip: {
trigger: 'axis',
},
grid: {
left: 5,
right: 5,
top: 30,
bottom: 30,
},
darkMode: true,
legend: { show: true, textStyle: { color: '#fff' } },
xAxis: {
type: 'category',
boundaryGap: false,
data: time,
axisTick: { alignWithLabel: true },
axisLabel: { color: '#fff' },
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value} °C',
},
},
series: [
{
name: '室内湿度',
type: 'line',
data: roomH,
smooth: true,
},
{
name: '室外湿度',
type: 'line',
data: outH,
smooth: true,
},
],
};
}
</script>
<style scoped>
#humidity-container {
width: 100%;
height: 100%;
}
</style>

91
components/DataFarm/SoilHumidity.vue

@ -0,0 +1,91 @@
<template>
<div id="soil-humidity-container"></div>
</template>
<script setup>
import { nextTick } from 'vue';
async function getData() {
try {
const { data: rawData } = await useFetch('/api/datas');
const { code, msg, data } = rawData.value;
if (code === 200) {
await nextTick();
initChart(data);
} else {
throw new Error(msg);
}
} catch (error) {
console.error(error);
}
}
getData();
//
function initChart(data) {
const chartDom = document.getElementById('soil-humidity-container');
const option = initOption(data);
const myChart = echarts.init(chartDom);
myChart.setOption(option);
}
function initData(data) {
const result = { times: [], soilH: [] };
data.forEach(item => {
result.times.push(item.time);
result.soilH.push(item.soilH);
});
return result;
}
function initOption(data) {
const { time, soilH, outH } = initData(data);
return {
tooltip: {
trigger: 'axis',
},
grid: {
left: 5,
right: 5,
top: 30,
bottom: 30,
},
darkMode: true,
legend: { show: true, textStyle: { color: '#fff' } },
xAxis: {
type: 'category',
boundaryGap: false,
data: time,
axisTick: { alignWithLabel: true },
axisLabel: { color: '#fff' },
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value} °C',
},
},
visualMap: {
show: false,
inRange: {
color: ['#65B581', '#FFCE34', '#FD665F'],
},
},
series: [
{
name: '土壤湿度',
type: 'bar',
data: soilH,
},
],
};
}
</script>
<style scoped>
#soil-humidity-container {
width: 100%;
height: 100%;
}
</style>

92
components/DataFarm/Temperature.vue

@ -0,0 +1,92 @@
<template>
<div id="temperature-container"></div>
</template>
<script setup>
import { nextTick } from 'vue';
async function getData() {
try {
const { data: rawData } = await useFetch('/api/datas');
const { code, msg, data } = rawData.value;
if (code === 200) {
await nextTick();
initChart(data);
} else {
throw new Error(msg);
}
} catch (error) {
console.error(error);
}
}
getData();
//
function initChart(data) {
const chartDom = document.getElementById('temperature-container');
const option = initOption(data);
const myChart = echarts.init(chartDom);
myChart.setOption(option);
}
function initData(data) {
console.log('data1: ', data);
const result = { times: [], roomT: [], outT: [] };
data.forEach(item => {
result.times.push(item.time);
result.roomT.push(item.roomT);
result.outT.push(item.outT);
});
return result;
}
function initOption(data) {
const { time, roomT, outT } = initData(data);
return {
tooltip: {
trigger: 'axis',
},
grid: {
left: 5,
right: 5,
top: 30,
bottom: 30,
},
darkMode: true,
legend: { show: true, textStyle: { color: '#fff' } },
xAxis: {
type: 'category',
boundaryGap: false,
data: time,
axisTick: { alignWithLabel: true },
axisLabel: { color: '#fff' },
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value} °C',
},
},
series: [
{
name: '室内温度',
type: 'line',
data: roomT,
},
{
name: '室外温度',
type: 'line',
data: outT,
},
],
};
}
</script>
<style scoped>
#temperature-container {
width: 100%;
height: 100%;
}
</style>

13
components/Page/Buttons.vue

@ -12,10 +12,19 @@
</template>
<script setup>
import { defineEmits } from 'vue';
import { defineEmits, computed, inject } from 'vue';
const scene = inject('scene');
const buttons = ['农场连线', '时物链', '数据监控', '导出统计'];
defineEmits(['click-btn']);
const buttons = computed(() => {
if (scene === 'center') {
return ['农场连线', '时物链', '数据监控', '导出统计'];
} else {
return ['专家连线', '时物链', '系统总览', '导出统计'];
}
});
</script>
<style scoped>

30
components/Page/Header.vue

@ -1,32 +1,52 @@
<template>
<header class="page-header">
<header
:class="{ 'bg-center': scene === 'center', 'bg-farm': scene === 'farm' }"
>
<!-- 时间-->
<PageTime></PageTime>
<!-- 按钮组-->
<PageButtons @click-btn="onClickBtn"></PageButtons>
<CommonWeather></CommonWeather>
</header>
</template>
<script setup>
import { inject } from 'vue';
import { useRouter } from 'vue-router';
const scene = inject('scene');
const modalDisplay = useModal(); // modal
const monitorDisplay = useMonitor(); // video
const router = useRouter();
function onClickBtn({ index: btnIndex, item }) {
console.log('btnIndex: ', btnIndex);
if (btnIndex === 0) {
modalDisplay.value = !modalDisplay.value;
} else if (btnIndex === 2) {
monitorDisplay.value = !monitorDisplay.value;
// monitorDisplay.value = !monitorDisplay.value;
if (scene === 'farm') {
// /
router.push('/');
} else {
// /farm
router.push('/farm');
}
}
}
</script>
<style scoped>
.page-header {
.bg-center {
position: relative;
height: 115rem;
background: url('@/assets/images/top.png') no-repeat center;
background-size: 100% 114rem;
}
.bg-farm {
position: relative;
height: 115rem;
background: url('@/assets/images/farm-top.png') no-repeat center;
background-size: 100% 114rem;
}
</style>

16
components/Page/Modal.vue

@ -1,14 +1,10 @@
<template>
<div class="modal-container" v-show="modalDisplay">
<!-- 标题-->
<DataCenterTitle :item="modalItem"></DataCenterTitle>
<!-- tab-->
<DataCenterFarmTab></DataCenterFarmTab>
<!-- 列表list-->
<DataCenterFarmList></DataCenterFarmList>
</div>
<iframe
class="modal-container"
v-show="modalDisplay"
src="https://www.tall.wiki/wl/7/#/center"
frameborder="0"
></iframe>
</template>
<script setup>

119
config/layout/dataFarmBody.js

@ -0,0 +1,119 @@
export const body = {
left: {
width: '480rem',
data: [
{
width: '480rem',
height: '308rem',
background: {
image: 'assets/images/border-1.png',
},
title: {
text: '室内/外温度折线',
color: '#fff',
size: '18rem',
align: 'center',
height: '40rem',
},
component: 'DataFarmTemperature',
},
{
width: '480rem',
height: '308rem',
background: {
image: 'assets/images/border-1.png',
},
title: {
text: '室内/外湿度折线',
color: '#fff',
size: '18rem',
align: 'center',
height: '40rem',
},
component: 'DataFarmHumidity',
},
{
width: '480rem',
height: '308rem',
background: {
image: 'assets/images/border-1.png',
},
title: {
text: '土壤湿度',
color: '#fff',
size: '18rem',
align: 'center',
height: '40rem',
},
component: 'DataFarmSoilHumidity',
},
],
},
middle: {
width: '920rem',
data: [
{
width: '920rem',
height: '626rem',
background: {
image: 'assets/images/border-main.png',
},
title: {
hide: true,
text: '3D地图',
},
component: 'DataCenterMapContainer',
},
{
width: '920rem',
height: '300rem',
background: {
image: 'assets/images/border-3.png',
},
title: {
text: '综合曲线',
color: '#fff',
size: '18rem',
align: 'center',
height: '40rem',
},
component: 'DataCenterComplexChart',
},
],
},
right: {
width: '480rem',
data: [
{
width: '480rem',
height: '618rem',
background: {
image: 'assets/images/border-2.png',
},
title: {
text: '时物链',
color: '#fff',
size: '18rem',
align: 'center',
height: '40rem',
},
component: 'DataCenterTall',
},
{
width: '480rem',
height: '300rem',
background: {
image: 'assets/images/border-1.png',
},
title: {
text: '实时报警',
color: '#fff',
size: '18rem',
align: 'center',
height: '40rem',
},
component: 'DataCenterFaultChart',
},
],
},
};

18
hooks/useLayoutConfig.js

@ -0,0 +1,18 @@
import { body as centerBody } from '@/config/layout/dataCenterBody';
import { body as farmBody } from '@/config/layout/dataFarmBody';
import { inject, computed } from 'vue';
export default function useLayoutConfig() {
const scene = inject('scene');
const body = computed(() => {
if (scene === 'farm') {
return farmBody;
} else {
return centerBody;
}
});
return body;
}

4
layouts/default.vue

@ -9,7 +9,9 @@
</template>
<script setup>
import { onMounted } from 'vue';
import { onMounted, provide } from 'vue';
provide('scene', 'center');
function setRem(html) {
const winWidth = html.clientWidth;

41
layouts/farm.vue

@ -0,0 +1,41 @@
<template>
<div class="page">
<PageHeader></PageHeader>
<PageMain></PageMain>
<PageFooter></PageFooter>
<PageModal></PageModal>
</div>
</template>
<script setup>
import { onMounted, provide } from 'vue';
provide('scene', 'farm');
function setRem(html) {
const winWidth = html.clientWidth;
html.style.fontSize = winWidth / 1920 + 'px';
}
onMounted(() => {
const html = document.documentElement;
setRem(html);
window.addEventListener(
'resize',
() => {
setRem(html);
},
false,
);
});
</script>
<style scoped>
.page {
width: 100%;
height: 100%;
background: url('@/assets/images/bg.png') no-repeat center center;
background-size: cover;
}
</style>

9
pages/farm.vue

@ -0,0 +1,9 @@
<template>
<div></div>
</template>
<script>
export default {
layout: 'farm',
};
</script>

28
pages/index.vue

@ -1,19 +1,9 @@
<template>
hello index
{{ data.code }}
</template>
<script setup>
const { data } = await useFetch('/api/hello');
console.log('res: ', data);
</script>
<script>
export default {
layout: "default"
}
</script>
<style scoped>
</style>
<template>
<div></div>
</template>
<script>
export default {
layout: 'default',
};
</script>

10
server/api/weather.ts

@ -0,0 +1,10 @@
import type { IncomingMessage, ServerResponse } from 'http';
import axios from 'axios';
export default async (req: IncomingMessage, res: ServerResponse) => {
const { data } = await axios.get(
'https://devapi.qweather.com/v7/weather/now?key=9764d65c999349a9b42c42a8f1052a81&location=112.48699,37.94036&lang =zh',
);
console.log('res: ', data);
return { code: 200, msg: 'ok', data };
};
Loading…
Cancel
Save