Browse Source

细节控制

master
wally 4 years ago
parent
commit
b297312cf3
  1. 22
      .idea/workspace.xml
  2. 2
      app.vue
  3. 8
      components/Common/Monitor.vue
  4. 8
      components/DataCenter/ComplexChart.vue
  5. 5
      components/DataCenter/FarmList.vue
  6. 11
      components/DataCenter/FarmTab.vue
  7. 48
      components/DataCenter/Tall.vue
  8. 5
      components/DataCenter/YieldChart.vue
  9. 10
      components/Page/Header.vue
  10. 46
      components/Page/Modal.vue
  11. 35
      components/Tall/Roles.vue
  12. 176
      components/Tall/Tasks.vue
  13. 5
      composables/useModal.js
  14. 5
      composables/useMonitor.js
  15. 74
      layouts/default.vue
  16. 12
      server/api/roles.ts
  17. 8
      utils/complexChart.js
  18. 18
      utils/complexConfig.js

22
.idea/workspace.xml

@ -6,15 +6,15 @@
<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$/components/Common/Map.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/Common/Map.vue" 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/MapContainer.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/DataCenter/MapContainer.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/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$/config/layout/dataCenterBody.js" beforeDir="false" afterPath="$PROJECT_DIR$/config/layout/dataCenterBody.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/utils/map.js" beforeDir="false" afterPath="$PROJECT_DIR$/utils/map.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/yarn.lock" beforeDir="false" afterPath="$PROJECT_DIR$/yarn.lock" 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$/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" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -24,8 +24,8 @@
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Vue Single File Component" />
<option value="TypeScript File" />
<option value="Vue Single File Component" />
<option value="JavaScript File" />
</list>
</option>
@ -63,7 +63,7 @@
<property name="node.js.selected.package.tslint" value="(autodetect)" />
<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="editor.preferences.fonts.default" />
<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="vue.rearranger.settings.migration" value="true" />
</component>
@ -73,6 +73,7 @@
<recent name="D:\Demo\vue3\nuxt3-app\components\DataCenter" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="D:\Demo\vue3\nuxt3-app\components\Page" />
<recent name="D:\Demo\vue3\nuxt3-app\components\DataCenter" />
<recent name="D:\Demo\vue3\nuxt3-app\server" />
<recent name="D:\Demo\vue3\nuxt3-app" />
@ -95,6 +96,9 @@
<workItem from="1637883404061" duration="1422000" />
<workItem from="1637887980805" duration="16198000" />
<workItem from="1637918094972" duration="756000" />
<workItem from="1638145763343" duration="1269000" />
<workItem from="1638147052619" duration="213000" />
<workItem from="1638147277058" duration="16639000" />
</task>
<servers />
</component>

2
app.vue

@ -12,7 +12,7 @@ body,
}
.clear:after {
content: '';
diosplay: block;
display: block;
height: 0;
visibility: hidden;
clear: both;

8
components/Common/Monitor.vue

@ -1,5 +1,5 @@
<template>
<div class="frame-container">
<div class="frame-container" v-show="monitorDisplay">
<iframe
src="https://www.tall.wiki/kangfu/v1/?key=230659446"
frameborder="0"
@ -7,10 +7,8 @@
</div>
</template>
<script>
export default {
name: 'Monitor',
};
<script setup>
const monitorDisplay = useMonitor();
</script>
<style scoped>

8
components/DataCenter/ComplexChart.vue

@ -11,12 +11,12 @@ let data = [];
let defaultSelectedLegend = {
'室内温度(℃)': true,
'室外温度(℃)': true,
'土壤温度(℃)': true,
'土壤温度(℃)': false,
'室内湿度(RH%)': true,
'室外湿度(RH%)': true,
'土壤湿度(RH%)': true,
'风速(m/s)': true,
'CO2(%)': true,
'土壤湿度(RH%)': false,
'风速(m/s)': false,
'CO2(%)': false,
'光照(klux)': true,
};

5
components/DataCenter/FarmList.vue

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

11
components/DataCenter/FarmTab.vue

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

48
components/DataCenter/Tall.vue

@ -1,9 +1,45 @@
<template>Tall</template>
<template>
<div class="tall-container">
<!-- 角色-->
<TallRoles
:roles="roles"
:role-id="roleId"
@change="onChangeRole"
></TallRoles>
<!-- 任务-->
<TallTasks :role-id="roleId"></TallTasks>
</div>
</template>
<script>
export default {
name: 'Tall',
};
<script setup>
import { ref } from 'vue';
const roles = ref([]);
const tasks = ref([]);
const roleId = ref('');
//
async function getRoles() {
const { data: rawData } = await useFetch('/api/roles');
console.log('data:', rawData.value.data);
roles.value = rawData.value.data;
roleId.value = roles.value[0].id;
}
function onChangeRole(clickRoleId) {
console.log('roleId: ', clickRoleId);
roleId.value = clickRoleId;
}
getRoles();
</script>
<style scoped></style>
<style scoped>
.tall-container {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
</style>

5
components/DataCenter/YieldChart.vue

@ -13,7 +13,7 @@ onMounted(() => {
});
function initOptions() {
const option = {
return {
darkMode: true,
grid: {
top: 20,
@ -23,9 +23,11 @@ function initOptions() {
type: 'category',
boundaryGap: false,
data: ['2017', '2018', '2019', '2020', '2021'],
axisLabel: { color: '#fff' },
},
yAxis: {
type: 'value',
axisLabel: { color: '#fff' },
},
series: [
{
@ -35,7 +37,6 @@ function initOptions() {
},
],
};
return option;
}
</script>

10
components/Page/Header.vue

@ -9,8 +9,16 @@
</template>
<script setup>
const modalDisplay = useModal(); // modal
const monitorDisplay = useMonitor(); // video
function onClickBtn({ index: btnIndex, item }) {
console.log('btnIndex: ', btnIndex, item);
console.log('btnIndex: ', btnIndex);
if (btnIndex === 0) {
modalDisplay.value = !modalDisplay.value;
} else if (btnIndex === 2) {
monitorDisplay.value = !monitorDisplay.value;
}
}
</script>

46
components/Page/Modal.vue

@ -0,0 +1,46 @@
<template>
<div class="modal-container" v-show="modalDisplay">
<!-- 标题-->
<DataCenterTitle :item="modalItem"></DataCenterTitle>
<!-- tab-->
<DataCenterFarmTab></DataCenterFarmTab>
<!-- 列表list-->
<DataCenterFarmList></DataCenterFarmList>
</div>
</template>
<script setup>
const modalItem = {
width: '676rem',
height: '510rem',
background: {
image: 'assets/images/modal-bg.png',
},
title: {
text: '农场列表',
color: '#fff',
size: '18rem',
align: 'center',
height: '40rem',
},
component: 'DataCenterFarms',
};
const modalDisplay = useModal(); // modal
</script>
<style scoped>
.modal-container {
z-index: 9999;
position: absolute;
left: 50%;
top: 50%;
width: 676rem;
height: 510rem;
transform: translate3d(-50%, -50%, 0);
background: url(assets/images/modal-bg.png) no-repeat center center;
background-size: 100%;
}
</style>

35
components/Tall/Roles.vue

@ -0,0 +1,35 @@
<template>
<div class="role-container clear">
<div
v-for="item in roles"
:key="item"
class="role-item"
:class="{ active: roleId === item.id }"
@click="$emit('change', item.id)"
>
{{ item.name }}
</div>
</div>
</template>
<script setup>
defineProps({ roles: Object, roleId: String });
defineEmits(['change']);
</script>
<style scoped>
.role-item {
float: left;
padding: 8rem 2rem;
margin-left: 4rem;
margin-right: 4rem;
font-size: 16rem;
color: #fff;
cursor: pointer;
}
.role-item.active {
border-bottom: 2rem solid #00d9ff;
color: #00d9ff;
font-weight: 600;
}
</style>

176
components/Tall/Tasks.vue

@ -0,0 +1,176 @@
<template>
<div class="task-container">
<div v-for="(roleTasks, keyRoleId) in tasks" :key="keyRoleId">
<div
class="task-item"
v-for="item in roleTasks"
:key="item.id"
v-show="keyRoleId === roleId"
>
<div class="task-item-header">
<div class="task-item-icon"></div>
<div class="task-item-time flex-1">{{ item.beginTime }}</div>
</div>
<div class="task-item-content">
<div class="line"></div>
<div class="content">
{{ item.name }}
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import dayjs from 'dayjs';
defineProps({ roleId: String });
/**
* 计算转换开始时间
* @param {number} delta 当前时间的差值
*/
function computeBeginTime(delta) {
return dayjs().add(delta, 'hour').format('YYYY-MM-DD HH:00');
}
const tasks = {
111: [
{
id: 111,
name: '周会',
beginTime: computeBeginTime(0),
duration: 5,
role: { id: '111', name: '专家' },
},
{
id: 112,
name: '专家会诊',
beginTime: computeBeginTime(1),
duration: 60,
role: { id: '111', name: '专家' },
},
{
id: 113,
name: '生态园远程会诊',
beginTime: computeBeginTime(3),
duration: 90,
role: { id: '111', name: '专家' },
},
{
id: 114,
name: '生态园实地考察',
beginTime: computeBeginTime(6),
duration: 120,
role: { id: '111', name: '专家' },
},
{
id: 115,
name: '智慧农业专项会议',
beginTime: computeBeginTime(10),
duration: 100,
role: { id: '111', name: '专家' },
},
{
id: 116,
name: '数据报表导出统计分析',
beginTime: computeBeginTime(10),
duration: 100,
role: { id: '111', name: '专家' },
},
{
id: 117,
name: '生态园巡查',
beginTime: computeBeginTime(10),
duration: 100,
role: { id: '111', name: '专家' },
},
{
id: 117,
name: '智慧农业论坛',
beginTime: computeBeginTime(10),
duration: 100,
role: { id: '111', name: '专家' },
},
],
112: [
{
id: 211,
name: '周会',
beginTime: computeBeginTime(0),
duration: 5,
role: { id: '112', name: '农场' },
},
{
id: 212,
name: '浇水',
beginTime: computeBeginTime(1),
duration: 60,
role: { id: '112', name: '农场' },
},
{
id: 213,
name: '专家远程会诊',
beginTime: computeBeginTime(3),
duration: 90,
role: { id: '112', name: '农场' },
},
{
id: 214,
name: '专家考察',
beginTime: computeBeginTime(6),
duration: 120,
role: { id: '112', name: '农场' },
},
{
id: 215,
name: '施肥',
beginTime: computeBeginTime(10),
duration: 100,
role: { id: '112', name: '农场' },
},
],
};
</script>
<style scoped>
.task-container {
padding: 10rem;
overflow-y: auto;
height: 100%;
}
::-webkit-scrollbar {
display: none;
}
.task-item {
color: #fff;
}
.task-item-header {
display: flex;
align-items: center;
}
.task-item-icon {
width: 24rem;
height: 24rem;
background: url('assets/images/icon-play.png') no-repeat center center;
background-size: 100%;
margin-right: 10rem;
margin-top: 10rem;
margin-bottom: 10rem;
}
.task-item-content {
display: flex;
}
.line {
width: 2rem;
margin-left: 11rem;
margin-right: 21rem;
background-color: #00d9ff;
}
.task-item-content .content {
flex: 1;
box-shadow: 0 0 9rem #00d9ff inset;
padding: 16rem;
font-size: 18rem;
}
</style>

5
composables/useModal.js

@ -0,0 +1,5 @@
import { useState } from '#app';
export const useModal = () => {
return useState('modalDisplay', () => false);
};

5
composables/useMonitor.js

@ -0,0 +1,5 @@
import { useState } from '#app';
export const useMonitor = () => {
return useState('monitorDisplay', () => true);
};

74
layouts/default.vue

@ -1,35 +1,39 @@
<template>
<div class="page">
<PageHeader></PageHeader>
<PageMain></PageMain>
<PageFooter></PageFooter>
</div>
</template>
<script setup>
import { onMounted } from 'vue';
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>
<template>
<div class="page">
<PageHeader></PageHeader>
<PageMain></PageMain>
<PageFooter></PageFooter>
<PageModal></PageModal>
</div>
</template>
<script setup>
import { onMounted } from 'vue';
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>

12
server/api/roles.ts

@ -0,0 +1,12 @@
import type { IncomingMessage, ServerResponse } from 'http';
export default async (req: IncomingMessage, res: ServerResponse) => {
return {
code: 200,
msg: 'ok',
data: [
{ id: '111', name: '专家' },
{ id: '112', name: '农场' },
],
};
};

8
utils/complexChart.js

@ -147,7 +147,7 @@ export function generateChartOption(rawData, selected) {
const yAxis = generateYAxis(selected);
const series = generateSeries(data, yAxis);
const grid = generateGrid(yAxis);
const option = {
return {
color: colors,
darkMode: true,
tooltip: {
@ -160,6 +160,10 @@ export function generateChartOption(rawData, selected) {
grid,
legend: {
type: 'scroll',
textStyle: { color: '#fff' },
pageTextStyle: { color: '#fff' },
pageIconColor: '#cacaca',
pageIconInactiveColor: '#999',
selected,
data: legendData,
},
@ -168,10 +172,10 @@ export function generateChartOption(rawData, selected) {
type: 'category',
axisTick: { alignWithLabel: true },
data: data.time,
axisLabel: { color: '#fff' },
},
],
yAxis,
series,
};
return option;
}

18
utils/complexConfig.js

@ -1,14 +1,14 @@
/* eslint-disable max-len */
export const colors = [
'#EAB308',
'#F97316',
'#EC4899',
'#F43F5E',
'#D946EF',
'#06B6D4',
'#B45309',
'#1E40AF',
'#166534',
'#FCD34D',
'#FDBA74',
'#F9A8D4',
'#FDA4AF',
'#F0ABFC',
'#67E8F9',
'#FCD34D',
'#93C5FD',
'#86EFAC',
];
export const itemColor = {

Loading…
Cancel
Save