This commit is contained in:
DESKTOP-FUDKNA8\znjsz
2024-01-16 17:02:53 +08:00
commit 9d48e56dd0
50 changed files with 3533 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
<script setup>
import Icon from './Icon.vue';
import Corner from './Corner.vue';
const props = defineProps({
title: {
type: String,
default: 'Default title',
},
icon: {
type: String,
default: 'icon',
},
corner: {
type: Array,
default: ['tl', 'tr', 'bl', 'br'], //'trbl', // top right bottom left
},
cubeCorner: {
type: String,
default: 'bl',
validator: (value, props) => {
return ['bl', 'br'].includes(value);
},
},
});
</script>
<template>
<div class="container-border">
<Corner
v-if="corner.indexOf('tl') !== -1"
position="top-left"
key="top-left"
/>
<Corner
v-if="corner.indexOf('tr') !== -1"
position="top-right"
key="top-right"
/>
<Corner
v-if="corner.indexOf('bl') !== -1"
position="bottom-left"
key="bottom-left"
/>
<Corner
v-if="corner.indexOf('br') !== -1"
position="bottom-right"
key="bottom-right"
/>
<div class="container">
<div class="cube" :class="[`cube-${cubeCorner}`]"></div>
<div class="container-header">
<Icon :name="icon" />
<span>{{ title }}</span>
</div>
<div class="container-body">
<slot />
</div>
</div>
</div>
</template>
<style scoped>
.container-border {
position: relative;
display: flex;
}
.cube {
width: 26px;
height: 26px;
background: #1f8fff;
position: absolute;
z-index: 1;
}
.cube-bl {
transform: rotate(45deg);
bottom: -13px;
left: -13px;
}
.cube-br {
transform: rotate(45deg);
bottom: -13px;
right: -13px;
}
.container {
flex: 1;
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
color: #fff;
}
.container-header {
background: #006acd66;
backdrop-filter: blur(2px);
color: #fff;
display: flex;
align-items: center;
gap: 12px;
padding: 8px 12px;
}
.container-body {
background: #ffffff33;
backdrop-filter: blur(1px);
flex: 1;
padding: 20px;
}
</style>

View File

@@ -0,0 +1,62 @@
<script setup>
import { ref, computed } from 'vue';
const props = defineProps({
position: {
type: String,
default: 'bottom-left',
},
});
const styles = computed(() => {
switch (props.position) {
case 'top-left':
return {
transform: 'rotate(90deg)',
top: 0,
left: 0,
bottom: 'unset',
right: 'unset',
};
case 'top-right':
return {
transform: 'rotate(180deg)',
top: 0,
left: 'unset',
bottom: 'unset',
right: 0,
};
case 'bottom-left':
return {
transform: 'rotate(0deg)',
bottom: 0,
left: 0,
right: 'unset',
top: 'unset',
};
case 'bottom-right':
return {
transform: 'rotate(-90deg)',
top: 'unset',
left: 'unset',
bottom: 0,
right: 0,
};
}
});
</script>
<template>
<div class="corner" :style="styles"></div>
</template>
<style scoped>
.corner {
position: absolute;
width: 16px;
height: 16px;
border-left: 2px solid #0078e4;
border-bottom: 2px solid #0078e4;
z-index: 2;
}
</style>

View File

@@ -0,0 +1,37 @@
<script setup>
import { ref, computed } from 'vue';
</script>
<template>
<header class="header">
<div>
<Icon htmlRole="logo" icon="logo" />
<h1 class="header__title">郴州旗滨光伏光电玻璃有限公司</h1>
</div>
</header>
</template>
<style scoped>
.header {
position: relative;
height: 90px;
background: url(../../assets/header-bg@2x.png) 100% / 100% no-repeat;
}
.header > div {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
/** width: 520px; **/
width: 480px;
top: 20px;
}
.header__title {
font-weight: 400;
letter-spacing: 2px;
color: #fff;
user-select: none;
}
</style>

View File

@@ -0,0 +1,51 @@
<script setup>
// import icons
import checkIcon from '../../assets/svg/check.svg';
import cubeIcon from '../../assets/svg/cube.svg';
import cube2Icon from '../../assets/svg/cube-twice.svg';
import stackIcon from '../../assets/svg/stack.svg';
import { ref, computed } from 'vue';
const props = defineProps({
name: {
type: String,
default: 'icon',
},
htmlRole: {
type: String,
default: 'icon', // 'icon' | 'logo'
},
});
const icon = computed(() => {
switch (props.name) {
case 'icon':
case 'cube':
return cubeIcon;
case 'cube-2':
return cube2Icon;
case 'stack':
return stackIcon;
case 'check':
return checkIcon;
}
});
</script>
<template>
<div class="icon">
<img :src="icon" :class="icon" />
</div>
</template>
<style scoped>
.icon {
height: 16px;
width: 16px;
background: #fff3;
display: flex;
justify-content: center;
align-items: center;
}
</style>

View File

@@ -0,0 +1,54 @@
<script setup>
import './style.css';
import { Close } from '@element-plus/icons-vue';
import { ref, onMounted, onBeforeUnmount } from 'vue';
const contentVisible = ref(false);
const emit = defineEmits(['close']);
onMounted(() => {
setTimeout(() => {
contentVisible.value = true;
}, 100);
});
onBeforeUnmount(() => {});
function close() {
contentVisible.value = false;
setTimeout(() => {
emit('close');
}, 150);
}
</script>
<template>
<div class="modal">
<div class="dribbble-dialog pop-out" :class="{ visible: contentVisible }">
<div class="logo"></div>
<div class="left"></div>
<div class="right"></div>
<div class="content-text">
<p>Advance your career with a</p>
<p>Professional Diploma in UX Design</p>
<button>Learn More</button>
</div>
<el-button
:icon="Close"
size="small"
circle
style="
background: #eeeb;
color: #000;
border: none;
position: absolute;
top: -3px;
right: 8px;
z-index: -10;
"
@click="close"
></el-button>
</div>
</div>
</template>
i

View File

@@ -0,0 +1,105 @@
.modal {
background: #0003;
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: grid;
place-items: center;
color: #000;
}
.dribbble-dialog {
position: relative;
margin: 12px;
background: #fff;
border-radius: 18px;
box-shadow: 0 0 32px 2px #0001;
overflow-x: hidden;
height: auto;
padding: 20px;
transition: all 0.1s cubic-bezier(0, 0.48, 0, 1.18);
}
.content-text {
margin: 56px 56px 32px;
text-align: center;
font-weight: 700;
line-height: 1;
}
p {
margin: 10px 0;
user-select: none;
}
button {
border: none;
outline: none;
appearance: none;
padding: 12px 24px;
border-radius: 20px;
background: #000;
color: #fff;
margin-top: 12px;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.5px;
text-transform: uppercase;
transition: all 0.1s ease-out;
}
button:hover {
cursor: pointer;
background: #000b;
}
.logo {
width: 128px;
height: 40px;
position: absolute;
top: 20px;
left: 20px;
background: url(../../assets/logo@2x.png) center / contain no-repeat;
}
.left {
width: 160px;
height: 80px;
position: absolute;
bottom: 0;
left: 0;
background: url(../../assets/leftcorner@2x.png) center / 100% 100% no-repeat;
z-index: -100;
}
.right {
width: 100px;
height: 118px;
position: absolute;
z-index: -100;
top: -2px;
right: 0;
background: url(../../assets/rightcorner@2x.png) center / 100% 100% no-repeat;
}
.fade-in {
opacity: 0;
transform: translateY(-56px);
}
.fade-in.visible {
transform: translateY(0);
opacity: 1;
}
.pop-out {
opacity: 0;
transform: scale(0);
}
.pop-out.visible {
opacity: 1;
transform: scale(1);
}

View File

@@ -0,0 +1,52 @@
<script setup>
import { ref, onMounted } from 'vue';
import * as echarts from 'echarts';
import Container from './Base/Container.vue';
const chartChart = ref(null);
onMounted(() => {
chartChart.value.classList.add('h-full');
const mc = echarts.init(chartChart.value);
mc.setOption({
grid: {
top: 24,
bottom: 24,
left: 24,
right: 24,
},
tooltip: {},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
},
],
});
});
</script>
<template>
<Container class="chart" title="小时数据" icon="cube">
<div ref="chartChart" class="chart-chart"></div>
</Container>
</template>
<style scoped>
.chart {
height: 300px;
}
.chart-inner {
background: #0f0;
}
.chart-chart {
height: 100%;
}
</style>

View File

@@ -0,0 +1,55 @@
<script setup>
import { ref } from 'vue';
const emit = defineEmits(['change']);
const handleClick = (page) => {
emit('change', page);
};
</script>
<template>
<nav class="nav-menu">
<ul>
<li><button @click="(e) => handleClick('3d')">三维界面</button></li>
<li><button @click="(e) => handleClick('data')">数据界面</button></li>
<li><button @click="(e) => handleClick('realtime')">实时数据</button></li>
<li><button @click="(e) => handleClick('alert')">报警列表</button></li>
<li>
<button @click="(e) => handleClick('announcement')">公告页面</button>
</li>
</ul>
</nav>
</template>
<style scoped>
.nav-menu {
width: 480px;
padding: 12px;
background: #0006;
color: #fff;
/**
position: fixed;
top: 45%;
left: 10px;
*/
}
button {
appearance: none;
border: none;
outline: none;
background: #7777;
color: #fff;
cursor: pointer;
}
button:hover {
background: #ccc;
}
ul,
li {
margin: 0;
padding: 0;
list-style: none;
}
</style>

View File

@@ -0,0 +1,56 @@
<!-- 货物情况 -->
<script setup>
import { ref, onMounted } from 'vue';
import * as echarts from 'echarts';
import Container from './Base/Container.vue';
const cargoChart = ref(null);
onMounted(() => {
cargoChart.value.classList.add('h-full');
const mc = echarts.init(cargoChart.value);
mc.setOption({
grid: {
top: 24,
bottom: 24,
left: 24,
right: 24,
},
tooltip: {},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
},
],
});
});
</script>
<template>
<Container class="cargo" title="实时数据" icon="cube">
<div ref="cargoChart" class="cargo-chart"></div>
</Container>
</template>
<style scoped>
.cargo {
height: 640px;
width: 80%;
align-self: self-end;
}
.cargo-inner {
background: #0f0;
}
.cargo-chart {
height: 100%;
}
</style>

View File

@@ -0,0 +1,49 @@
<!-- 实时数据表格 -->
<script setup>
const tableData = [
{ productLine: '00A', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
{ productLine: '00B', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
{ productLine: '00C', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
{ productLine: '00D', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
{ productLine: '00E', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
{ productLine: '00F', mbt: '---', mbb: '---', dkt: '---', dkb: '---', dmt: '---', dmb: '---', syt: '---', syb: '---', ght: '---', ghb: '---', gh1: '---', gh2: '---', bzt: '---', bzb: '---' },
]
</script>
<template>
<div class="realtime-table">
<el-table class="dark-table" :data="tableData" :show-overflow-tooltip="true" row-class-name="dark-row"
header-row-class-name="dark-header">
<el-table-column prop="productLine" label="产线"></el-table-column>
<el-table-column prop="mbt" label="磨边上"></el-table-column>
<el-table-column prop="mbb" label="磨边下"></el-table-column>
<el-table-column prop="dkt" label="打孔上"></el-table-column>
<el-table-column prop="dkb" label="打孔下"></el-table-column>
<el-table-column prop="dmt" label="镀膜上"></el-table-column>
<el-table-column prop="dmb" label="镀膜下"></el-table-column>
<el-table-column prop="syt" label="丝印上"></el-table-column>
<el-table-column prop="syb" label="丝印下"></el-table-column>
<el-table-column prop="ght" label="固化上"></el-table-column>
<el-table-column prop="ghb" label="固化下"></el-table-column>
<el-table-column prop="gh1" label="钢化上"></el-table-column>
<el-table-column prop="gh2" label="钢化下"></el-table-column>
<el-table-column prop="bzt" label="包装上"></el-table-column>
<el-table-column prop="bzb" label="包装下"></el-table-column>
</el-table>
</div>
</template>
<style scoped>
.realtime-table {
background: #00f3;
height: 240px;
width: 80%;
align-self: self-start;
}
.dark-table {
height: 100%;
}
</style>

65
src/components/Slider.vue Normal file
View File

@@ -0,0 +1,65 @@
<script setup>
import { ref, watch, onMounted } from 'vue';
const emit = defineEmits(['size-change']);
const size = ref(100);
const slider = ref(null);
// watchers
watch(size, (value) => {
if (value == null) return;
emit('size-change', value);
});
// handlers
function keydownHandler(e) {
if (e.shiftKey && e.key === 'L') {
if (slider.value) {
slider.value.classList.toggle('show');
}
}
}
// hooks
onMounted(() => {
document.addEventListener('keydown', keydownHandler);
});
</script>
<template>
<div ref="slider" class="slider">
<input type="range" min="0" max="100" v-model="size" />
</div>
</template>
<style scoped>
.slider {
height: 5vh;
width: 20vw;
border-radius: 88px;
box-shadow: 0 0 68px 8px rgba(0, 0, 0, 0.3);
padding: 32px;
display: grid;
place-items: center;
background: #fff;
position: fixed;
z-index: 1000;
bottom: -5vh;
opacity: 0;
left: 50%;
transform: translateX(-50%);
transition: opacity 0.3s ease-out, bottom 0.3s ease-out;
}
.slider input {
width: 100%;
transform: translateY(-7px);
color: #0b58ff;
background: #fcc;
}
.slider.show {
opacity: 1;
bottom: 64px;
}
</style>

View File

@@ -0,0 +1,52 @@
<script setup>
import { ref, onMounted } from 'vue';
import * as echarts from 'echarts';
import Container from './Base/Container.vue';
const chartChart = ref(null);
onMounted(() => {
chartChart.value.classList.add('h-full');
const mc = echarts.init(chartChart.value);
mc.setOption({
grid: {
top: 24,
bottom: 24,
left: 24,
right: 24,
},
tooltip: {},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
},
],
});
});
</script>
<template>
<Container class="chart" title="本日班组情况" icon="cube">
<div ref="chartChart" class="chart-chart"></div>
</Container>
</template>
<style scoped>
.chart {
height: 300px;
}
.chart-inner {
background: #0f0;
}
.chart-chart {
height: 100%;
}
</style>

View File

@@ -0,0 +1,52 @@
<script setup>
import { ref, onMounted } from 'vue';
import * as echarts from 'echarts';
import Container from './Base/Container.vue';
const chartChart = ref(null);
onMounted(() => {
chartChart.value.classList.add('h-full');
const mc = echarts.init(chartChart.value);
mc.setOption({
grid: {
top: 24,
bottom: 24,
left: 24,
right: 24,
},
tooltip: {},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
},
],
});
});
</script>
<template>
<Container class="chart" title="本月班组情况" icon="cube">
<div ref="chartChart" class="chart-chart"></div>
</Container>
</template>
<style scoped>
.chart {
height: 300px;
}
.chart-inner {
background: #0f0;
}
.chart-chart {
height: 100%;
}
</style>

21
src/components/Tools.vue Normal file
View File

@@ -0,0 +1,21 @@
<script setup>
import { ref, watch, onMounted } from 'vue';
</script>
<template>
<div class="tools">
<button>Home</button>
<button>Settings</button>
<button>AutoScroll</button>
</div>
</template>
<style scoped>
.tools {
background: #00f;
padding: 8px;
position: absolute;
bottom: 24px;
left: 24px;
}
</style>

11
src/components/data.json Normal file
View File

@@ -0,0 +1,11 @@
{
"code": 0,
"data": [
{ "date": "2023-01-01", "检测项目": "光刻胶&显影", "光刻胶残留": "1" },
{ "date": "2023-01-01", "检测项目": "激光一", "磨面擦伤": "1" },
{ "date": "2023-01-01", "检测项目": "激光二", "刻线宽度不良": "1" },
{ "date": "2023-01-02", "检测项目": "光刻胶&显影", "光刻胶残留": "2" },
{ "date": "2023-01-02", "检测项目": "激光一", "刻线宽度不良": "2" },
{ "date": "2023-01-03", "检测项目": "激光二", "擦伤": "3" }
]
}