12 changed files with 799 additions and 851 deletions
-
5eslint.config.js
-
7package.json
-
81src/components/common/FTChart/index.vue
-
1src/layouts/default.vue
-
2src/main.ts
-
43src/stores/debugStore.ts
-
73src/types/debug.d.ts
-
777src/views/debug/index.vue
-
642src/views/home/index.vue
-
2src/views/login/index.vue
-
5tsconfig.json
-
12vite.config.ts
@ -0,0 +1,81 @@ |
|||||
|
<script lang="ts" setup> |
||||
|
import type { EChartsOption } from 'echarts/types/dist/shared' |
||||
|
import * as echarts from 'echarts' |
||||
|
import { markRaw, nextTick, onMounted, ref, watch } from 'vue' |
||||
|
|
||||
|
interface Props { |
||||
|
option?: EChartsOption |
||||
|
} |
||||
|
const props = withDefaults(defineProps<Props>(), { |
||||
|
option: undefined, |
||||
|
}) |
||||
|
|
||||
|
const emits = defineEmits(['onClick', 'getInstance']) |
||||
|
|
||||
|
const chart = ref() |
||||
|
let myChart: undefined | echarts.ECharts |
||||
|
onMounted(() => { |
||||
|
setOption() |
||||
|
window.addEventListener('resize', () => { |
||||
|
resize() |
||||
|
}) |
||||
|
}) |
||||
|
const setOption = () => { |
||||
|
myChart = echarts.getInstanceByDom(chart.value as HTMLElement) |
||||
|
if (!myChart) { |
||||
|
myChart = markRaw(echarts.init(chart.value as HTMLElement, null, { renderer: 'svg' })) |
||||
|
} |
||||
|
const series = myChart?.getOption()?.series |
||||
|
myChart.clear() |
||||
|
if (props.option) { |
||||
|
const option = markRaw(props.option) |
||||
|
if (series && series?.length > 0) { |
||||
|
option.series = series |
||||
|
} |
||||
|
myChart?.setOption(option, true) |
||||
|
setTimeout(() => { |
||||
|
resize() |
||||
|
}, 100) |
||||
|
} |
||||
|
myChart.on('click', (params) => { |
||||
|
emits('onClick', params) |
||||
|
}) |
||||
|
emits('getInstance', myChart) |
||||
|
} |
||||
|
|
||||
|
const updateOption = (data: any) => { |
||||
|
myChart?.setOption(data) |
||||
|
} |
||||
|
const resize = () => { |
||||
|
nextTick(() => { |
||||
|
const option = myChart?.getOption() |
||||
|
option && myChart?.setOption(option, { notMerge: true }) |
||||
|
myChart?.resize() |
||||
|
}) |
||||
|
} |
||||
|
watch( |
||||
|
() => props.option, |
||||
|
() => |
||||
|
|
||||
|
nextTick(() => { |
||||
|
console.log('有变化了', props.option) |
||||
|
setOption() |
||||
|
}), |
||||
|
{ deep: true }, |
||||
|
) |
||||
|
defineExpose({ |
||||
|
resize, |
||||
|
updateOption, |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<div ref="chart" class="my-chart" /> |
||||
|
</template> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.my-chart { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
</style> |
@ -1,418 +1,252 @@ |
|||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||
import { trayIn } from 'apis/home' |
|
||||
import AddLiquid from 'components/home/AddLiquid/index.vue' |
|
||||
import CheckCraft from 'components/home/CheckCraft/index.vue' |
|
||||
import ExecuteCraft from 'components/home/ExecuteCraft/index.vue' |
|
||||
import ExtractLiquid from 'components/home/ExtractLiquid/index.vue' |
|
||||
import FillSolution from 'components/home/FillSolution/index.vue' |
|
||||
import SetTemperature from 'components/home/SetTemperature/index.vue' |
|
||||
|
|
||||
import StartClean from 'components/home/StartClean/index.vue' |
|
||||
import StartExperiment from 'components/home/StartExperiment/index.vue' |
|
||||
import Tube from 'components/home/Tube/index.vue' |
|
||||
import { ElMessageBox } from 'element-plus' |
|
||||
import { FtMessage } from 'libs/message' |
|
||||
import { socket } from 'libs/socket' |
|
||||
import { cmdNameMap, formatDateTime } from 'libs/utils' |
|
||||
import { useHomeStore } from 'stores/homeStore' |
|
||||
import { useSystemStore } from 'stores/systemStore' |
import { useSystemStore } from 'stores/systemStore' |
||||
import { computed, onMounted, onUnmounted, provide, ref } from 'vue' |
|
||||
|
|
||||
const homeStore = useHomeStore() |
|
||||
const systemStore = useSystemStore() |
|
||||
|
|
||||
onMounted(() => { |
|
||||
socket.init(receiveMessage, 'cmd_debug') |
|
||||
socket.init(receiveMessage, 'cmd_response') |
|
||||
}) |
|
||||
|
|
||||
onUnmounted(() => { |
|
||||
socket.unregisterCallback(receiveMessage, 'cmd_debug') |
|
||||
socket.unregisterCallback(receiveMessage, 'cmd_response') |
|
||||
|
import { watch } from 'vue' |
||||
|
|
||||
|
const option = ref({ |
||||
|
grid: { |
||||
|
left: '5%', |
||||
|
right: '5%', |
||||
|
top: '5%', |
||||
|
bottom: '20%', |
||||
|
}, |
||||
|
xAxis: { |
||||
|
type: 'category', |
||||
|
}, |
||||
|
yAxis: { |
||||
|
type: 'value', |
||||
|
}, |
||||
|
series: [ |
||||
|
{ |
||||
|
data: [150, 230, 224, 218, 135, 147, 260], |
||||
|
type: 'line', |
||||
|
showSymbol: true, |
||||
|
symbolSize: 10, |
||||
|
}, |
||||
|
], |
||||
}) |
}) |
||||
|
|
||||
let currentCommandId = '' |
|
||||
const receiveMessage = (data: Socket.cmdData) => { |
|
||||
data.commandId === currentCommandId && systemStore.pushSystemList(data) |
|
||||
if (['start', 'success', 'fail'].includes(data.status)) { |
|
||||
const cmdName = cmdNameMap[data.command as keyof typeof cmdNameMap] || data.command |
|
||||
systemStore.insertLog({ cmdName, status: data.status as System.SystemLog['status'], time: formatDateTime() }) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
const selectedHeatArea = computed(() => { |
|
||||
return homeStore.heatAreaList.find(item => item.selected) |
|
||||
}) |
|
||||
|
const list = [ |
||||
|
'2025年7月23 14:12:00 1号滴定位开始执行.....', |
||||
|
'2025年7月23 14:12:00 1号滴定位开始执行.....', |
||||
|
'2025年7月23 14:12:00 1号滴定位开始执行.....', |
||||
|
'2025年7月23 14:12:00 1号滴定位开始执行.....', |
||||
|
'2025年7月23 14:12:00 1号滴定位开始执行.....', |
||||
|
'2025年7月23 14:12:00 1号滴定位开始执行.....', |
||||
|
'2025年7月23 14:12:00 1号滴定位开始执行.....', |
||||
|
'2025年7月23 14:12:00 1号滴定位开始执行.....', |
||||
|
'2025年7月23 14:12:00 1号滴定位开始执行.....', |
||||
|
'2025年7月23 14:12:00 1号滴定位开始执行.....', |
||||
|
|
||||
const startVisible = ref(false) |
|
||||
|
] |
||||
|
|
||||
const selectCraftVisible = ref(false) |
|
||||
|
const chartBox = ref(null) |
||||
|
|
||||
const executeCraftHandle = async () => { |
|
||||
selectCraftVisible.value = true |
|
||||
} |
|
||||
|
const systemStore = useSystemStore() |
||||
|
|
||||
const setTemperatureVisible = ref(false) |
|
||||
const currentTemperatureData = ref<{ id: string, label: string | undefined }>({ |
|
||||
id: '', |
|
||||
label: 'A-1', |
|
||||
|
watch(() => systemStore.menuExpand, () => { |
||||
|
chartBox.value.resize() |
||||
}) |
}) |
||||
provide('currentTemperatureData', currentTemperatureData) |
|
||||
const setTemperature = (data: System.HeatArea) => { |
|
||||
const craft = systemStore.systemStatus.trays?.find(item => item.heatModuleCode === data.moduleCode)?.crafts |
|
||||
if (craft?.craft) { |
|
||||
FtMessage.warning(`当前加热区已绑定工艺`) |
|
||||
return |
|
||||
} |
|
||||
currentTemperatureData.value = { |
|
||||
id: data.moduleCode, |
|
||||
label: homeStore.heatAreaList.find(item => item.value === data.moduleCode)?.label, |
|
||||
} |
|
||||
setTemperatureVisible.value = true |
|
||||
} |
|
||||
|
|
||||
const fillSolutionVisible = ref(false) |
|
||||
|
|
||||
const addLiquidVisible = ref(false) |
|
||||
|
|
||||
const cleanVisible = ref(false) |
|
||||
|
|
||||
const extractLiquidVisible = ref(false) |
|
||||
|
|
||||
const commandHandle = async (command: string, params?: unknown) => { |
|
||||
currentCommandId = Date.now().toString() |
|
||||
const data = { |
|
||||
commandId: currentCommandId, |
|
||||
command, |
|
||||
params, |
|
||||
} |
|
||||
await homeStore.sendControl(data) |
|
||||
} |
|
||||
|
|
||||
const move_to_liquid_area = async () => { |
|
||||
if (!selectedHeatArea.value?.value) { |
|
||||
await ElMessageBox.confirm( |
|
||||
'是否要将上料区托盘移至加液位? ', |
|
||||
'提示', |
|
||||
{ |
|
||||
confirmButtonText: '确认', |
|
||||
showClose: false, |
|
||||
closeOnClickModal: false, |
|
||||
closeOnPressEscape: false, |
|
||||
type: 'warning', |
|
||||
customClass: 'init-message', |
|
||||
}, |
|
||||
) |
|
||||
} |
|
||||
await commandHandle('move_to_liquid_area', { heatModuleCode: selectedHeatArea.value?.value }) |
|
||||
} |
|
||||
|
|
||||
const move_to_feed_area = async () => { |
|
||||
if (!selectedHeatArea.value?.value) { |
|
||||
await ElMessageBox.confirm( |
|
||||
'是否要将加液位托盘移至上料区? ', |
|
||||
'提示', |
|
||||
{ |
|
||||
confirmButtonText: '确认', |
|
||||
showClose: false, |
|
||||
closeOnClickModal: false, |
|
||||
closeOnPressEscape: false, |
|
||||
type: 'warning', |
|
||||
customClass: 'init-message', |
|
||||
}, |
|
||||
) |
|
||||
} |
|
||||
await commandHandle('move_to_feed_area', { heatModuleCode: selectedHeatArea.value?.value }) |
|
||||
} |
|
||||
|
|
||||
const move_to_anneal_area = async () => { |
|
||||
if (!selectedHeatArea.value?.value) { |
|
||||
await ElMessageBox.confirm( |
|
||||
'是否要将加液位或上料区的托盘移至退火区? ', |
|
||||
'提示', |
|
||||
{ |
|
||||
confirmButtonText: '确认', |
|
||||
showClose: false, |
|
||||
closeOnClickModal: false, |
|
||||
closeOnPressEscape: false, |
|
||||
type: 'warning', |
|
||||
customClass: 'init-message', |
|
||||
}, |
|
||||
) |
|
||||
} |
|
||||
await commandHandle('move_to_anneal_area', { heatModuleCode: selectedHeatArea.value?.value }) |
|
||||
} |
|
||||
|
|
||||
const trayInHandle = async () => { |
|
||||
await trayIn() |
|
||||
FtMessage.success('设置放入托盘成功') |
|
||||
} |
|
||||
|
|
||||
// const trayOutHandle = async () => { |
|
||||
// await trayOut() |
|
||||
// } |
|
||||
|
|
||||
const checkCraftVisible = ref(false) |
|
||||
|
|
||||
const moreVisible = ref(false) |
|
||||
|
|
||||
const cleanHandle = async () => { |
|
||||
await ElMessageBox.confirm( |
|
||||
'请确认已把托盘放至上料位或移至加液位? ', |
|
||||
'提示', |
|
||||
{ |
|
||||
confirmButtonText: '确认', |
|
||||
showClose: false, |
|
||||
closeOnClickModal: false, |
|
||||
closeOnPressEscape: false, |
|
||||
type: 'warning', |
|
||||
customClass: 'init-message', |
|
||||
}, |
|
||||
) |
|
||||
cleanVisible.value = true |
|
||||
} |
|
||||
|
|
||||
const addLiquidHandle = async () => { |
|
||||
await ElMessageBox.confirm( |
|
||||
'请确认已把托盘放至上料位或移至加液位? ', |
|
||||
'提示', |
|
||||
{ |
|
||||
confirmButtonText: '确认', |
|
||||
showClose: false, |
|
||||
closeOnClickModal: false, |
|
||||
closeOnPressEscape: false, |
|
||||
type: 'warning', |
|
||||
customClass: 'init-message', |
|
||||
}, |
|
||||
) |
|
||||
addLiquidVisible.value = true |
|
||||
} |
|
||||
|
|
||||
const extractLiquidHandle = async () => { |
|
||||
await ElMessageBox.confirm( |
|
||||
'请确认已把托盘放至上料位或移至加液位? ', |
|
||||
'提示', |
|
||||
{ |
|
||||
confirmButtonText: '确认', |
|
||||
showClose: false, |
|
||||
closeOnClickModal: false, |
|
||||
closeOnPressEscape: false, |
|
||||
type: 'warning', |
|
||||
customClass: 'init-message', |
|
||||
}, |
|
||||
) |
|
||||
extractLiquidVisible.value = true |
|
||||
} |
|
||||
</script> |
</script> |
||||
|
|
||||
<template> |
|
||||
<div class="home-page"> |
|
||||
<div class="page-top"> |
|
||||
<Tube |
|
||||
v-for="(item, index) in systemStore.systemStatus.heatModule" |
|
||||
:key="item.moduleCode" |
|
||||
:data="item" |
|
||||
@select-change="homeStore.selectChange(index)" |
|
||||
@set-temperature="setTemperature(item)" |
|
||||
/> |
|
||||
</div> |
|
||||
<div class="button-box"> |
|
||||
<el-row style="width: 100%; height: 100%" :gutter="20"> |
|
||||
<el-col :span="24"> |
|
||||
<div style="padding: 30px 0;display: grid; gap: 20px; grid-template-columns: repeat(4, 1fr);grid-template-rows: repeat(1, 1fr);height: 100%"> |
|
||||
<el-card> |
|
||||
<ft-button type="primary" size="large" :disabled="!systemStore.systemStatus.doorModule.actionable" :click-handle="() => commandHandle('door_open')"> |
|
||||
开门 |
|
||||
</ft-button> |
|
||||
<ft-button type="primary" size="large" :disabled="!systemStore.systemStatus.doorModule.actionable" :click-handle="() => commandHandle('door_close')"> |
|
||||
关门 |
|
||||
</ft-button> |
|
||||
</el-card> |
|
||||
|
|
||||
<el-card> |
|
||||
<ft-button type="primary" size="large" :click-handle="trayInHandle"> |
|
||||
放入托盘 |
|
||||
</ft-button> |
|
||||
<ft-button type="primary" size="large" :click-handle="() => commandHandle('out_tray', { heatModuleCode: selectedHeatArea!.value })" :disabled="!selectedHeatArea"> |
|
||||
取出托盘 |
|
||||
</ft-button> |
|
||||
</el-card> |
|
||||
<el-card> |
|
||||
<ft-button type="primary" style="margin: auto 0;" class="manual-button" size="large" :click-handle="executeCraftHandle"> |
|
||||
执行工艺 |
|
||||
</ft-button> |
|
||||
<!-- <ft-button type="primary" size="large" :click-handle="() => checkCraftVisible = true"> --> |
|
||||
<!-- <el-icon v-if="systemStore.errorCraft" color="#DF1515" size="15" style="margin-right: 5px"> --> |
|
||||
<!-- <WarningFilled /> --> |
|
||||
<!-- </el-icon> --> |
|
||||
<!-- 异常工艺 --> |
|
||||
<!-- </ft-button> --> |
|
||||
</el-card> |
|
||||
<el-card> |
|
||||
<el-popover |
|
||||
:visible="moreVisible" |
|
||||
placement="left-start" |
|
||||
width="auto" |
|
||||
trigger="click" |
|
||||
popper-class="button-popper" |
|
||||
> |
|
||||
<template #reference> |
|
||||
<ft-button type="primary" size="large" style="margin: auto 0;" class="manual-button" @click="moreVisible = !moreVisible"> |
|
||||
手动操作 |
|
||||
</ft-button> |
|
||||
</template> |
|
||||
<template #default> |
|
||||
<div class="container-box"> |
|
||||
<ft-button type="primary" size="large" :disabled="!selectedHeatArea" :click-handle="() => commandHandle('heater_start', { heatModuleCode: selectedHeatArea!.value })"> |
|
||||
开始加热 |
|
||||
</ft-button> |
|
||||
<ft-button type="primary" size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('dry_start', { heatModuleCode: selectedHeatArea!.value })"> |
|
||||
开始烘干 |
|
||||
</ft-button> |
|
||||
|
|
||||
<ft-button type="primary" size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label !== '退火区'" :click-handle="() => commandHandle('anneal_start', { heatModuleCode: selectedHeatArea!.value })"> |
|
||||
开始退火 |
|
||||
</ft-button> |
|
||||
|
|
||||
<ft-button type="primary" size="large" :disabled="!selectedHeatArea" :click-handle="() => commandHandle('heater_stop', { heatModuleCode: selectedHeatArea!.value })"> |
|
||||
停止加热 |
|
||||
</ft-button> |
|
||||
|
|
||||
<ft-button type="primary" size="large" :disabled="!selectedHeatArea" :click-handle="() => commandHandle('fan_start', { heatModuleCode: selectedHeatArea!.value })"> |
|
||||
开始降温 |
|
||||
</ft-button> |
|
||||
|
|
||||
<ft-button type="primary" size="large" :disabled="!selectedHeatArea" :click-handle="() => commandHandle('fan_stop', { heatModuleCode: selectedHeatArea!.value })"> |
|
||||
停止降温 |
|
||||
</ft-button> |
|
||||
|
|
||||
<ft-button type="primary" size="large" :click-handle="() => commandHandle('move_to_heat_area', { heatModuleCode: selectedHeatArea!.value })" :disabled="!selectedHeatArea"> |
|
||||
移至加热位 |
|
||||
</ft-button> |
|
||||
|
|
||||
<ft-button type="primary" size="large" :click-handle="move_to_liquid_area"> |
|
||||
移至加液位 |
|
||||
</ft-button> |
|
||||
<ft-button type="primary" size="large" :click-handle="move_to_feed_area"> |
|
||||
移至上料区 |
|
||||
</ft-button> |
|
||||
<ft-button type="primary" size="large" :click-handle="move_to_anneal_area"> |
|
||||
移至退火位 |
|
||||
</ft-button> |
|
||||
<ft-button type="primary" size="large" @click="cleanHandle"> |
|
||||
开始清洗 |
|
||||
</ft-button> |
|
||||
|
|
||||
<ft-button type="primary" size="large" @click=" fillSolutionVisible = true"> |
|
||||
预充管路 |
|
||||
</ft-button> |
|
||||
|
|
||||
<ft-button type="primary" size="large" @click="addLiquidHandle"> |
|
||||
添加溶液 |
|
||||
</ft-button> |
|
||||
|
|
||||
<ft-button type="primary" size="large" @click="extractLiquidHandle"> |
|
||||
抽取溶液 |
|
||||
</ft-button> |
|
||||
<ft-button type="primary" size="large" :click-handle="() => commandHandle('drain_liquid')"> |
|
||||
关机排空 |
|
||||
</ft-button> |
|
||||
<ft-button type="primary" size="large" :click-handle="() => commandHandle('liquid_motor_origin')"> |
|
||||
加液臂回原点 |
|
||||
</ft-button> |
|
||||
<ft-button type="primary" size="large" :click-handle="() => commandHandle('z_origin')"> |
|
||||
z轴回原点 |
|
||||
</ft-button> |
|
||||
<ft-button type="primary" size="large" :click-handle="() => commandHandle('x_origin')"> |
|
||||
x轴回原点 |
|
||||
</ft-button> |
|
||||
</div> |
|
||||
</template> |
|
||||
</el-popover> |
|
||||
</el-card> |
|
||||
</div> |
|
||||
</el-col> |
|
||||
</el-row> |
|
||||
</div> |
|
||||
<CheckCraft v-if="checkCraftVisible" @close="checkCraftVisible = false" /> |
|
||||
<StartExperiment v-if="startVisible" @ok="startVisible = false" @cancel="startVisible = false" /> |
|
||||
<StartClean v-if="cleanVisible" @ok="cleanVisible = false" @cancel="cleanVisible = false" /> |
|
||||
<ExecuteCraft v-if="selectCraftVisible" @ok="selectCraftVisible = false" @cancel="selectCraftVisible = false" /> |
|
||||
<SetTemperature v-if="setTemperatureVisible" @ok="setTemperatureVisible = false" @cancel="setTemperatureVisible = false" /> |
|
||||
<AddLiquid v-if="addLiquidVisible" @ok="addLiquidVisible = false" @cancel="addLiquidVisible = false" /> |
|
||||
<ExtractLiquid v-if="extractLiquidVisible" @ok="extractLiquidVisible = false" @cancel="extractLiquidVisible = false" /> |
|
||||
<FillSolution v-if="fillSolutionVisible" @ok="fillSolutionVisible = false" @cancel="fillSolutionVisible = false" /> |
|
||||
</div> |
|
||||
|
<template lang="pug"> |
||||
|
div.home-container |
||||
|
el-row(:gutter="15") |
||||
|
el-col(:span="18") |
||||
|
div.home-left |
||||
|
div.left-top |
||||
|
el-card |
||||
|
div.tube-box(v-for="item in 16" :key="item") |
||||
|
span.serial-number {{item.toString().padStart(2, '0')}} |
||||
|
span 体积: 000000 |
||||
|
span 结果: 00.00% |
||||
|
el-card |
||||
|
div.tube-box(v-for="item in 16" :key="item",class="tube-box-success") |
||||
|
span.serial-number {{(item+16).toString().padStart(2, '0')}} |
||||
|
span 体积: 00000 |
||||
|
span 结果: 00.00% |
||||
|
div.left-bottom |
||||
|
el-card |
||||
|
div.home-chart |
||||
|
ft-chart(:option="option" ref="chartBox") |
||||
|
div.home-log |
||||
|
div.log-box |
||||
|
p.log-text(v-for="item in list" :key="item") {{item}} |
||||
|
el-col(:span="6") |
||||
|
div.home-right |
||||
|
div.right-photo |
||||
|
el-card |
||||
|
div.img-box |
||||
|
el-image(src="https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg" ) |
||||
|
el-image(src="https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg" ) |
||||
|
div.right-heat |
||||
|
el-card |
||||
|
template(#header) |
||||
|
span 加热位 |
||||
|
div.content-box |
||||
|
div.heat-box |
||||
|
p.title 加热位1 |
||||
|
div.heat-box |
||||
|
p.title 加热位2 |
||||
|
div.right-titration |
||||
|
el-card |
||||
|
template(#header) |
||||
|
span 滴定位 |
||||
|
div.content-box |
||||
|
div.titration-box |
||||
|
p.title 滴定位1 |
||||
|
div.titration-box |
||||
|
p.title 滴定位2 |
||||
|
div.right-button |
||||
|
ft-button 手动滴定 |
||||
|
ft-button 预充管路 |
||||
|
ft-button 自动滴定 |
||||
|
ft-button 清洗管路 |
||||
|
ft-button 排空管路 |
||||
</template> |
</template> |
||||
|
|
||||
<style scoped lang="scss"> |
|
||||
.home-page { |
|
||||
.page-top{ |
|
||||
height: 65%; |
|
||||
border-radius: 8px; |
|
||||
padding: 0 10px 10px; |
|
||||
display: grid; |
|
||||
grid-template-columns: repeat(4, 1fr); /* 创建3列等宽轨道 */ |
|
||||
grid-template-rows: repeat(1, auto); /* 创建2行自动高度 */ |
|
||||
gap: 10px; |
|
||||
justify-content: center; /* 水平居中 */ |
|
||||
align-items: center; |
|
||||
} |
|
||||
.button-box { |
|
||||
height: 35%; |
|
||||
//display: grid; |
|
||||
//grid-template-columns: repeat(6, 1fr); /* 创建3列等宽轨道 */ |
|
||||
//grid-template-rows: repeat(4, 1fr); /* 创建2行自动高度 */ |
|
||||
//gap: 10px 20px; |
|
||||
.ft-button { |
|
||||
//width: 100px; |
|
||||
font-weight: bold; |
|
||||
margin-right: 0; |
|
||||
|
|
||||
.my-button { |
|
||||
padding: 0 !important; |
|
||||
border: 3px solid #1989fa !important; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
.el-col { |
|
||||
height: 100%; |
|
||||
} |
|
||||
.manual-box { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
} |
|
||||
.container-box { |
|
||||
width: 600px; |
|
||||
display: grid; |
|
||||
grid-template-columns: repeat(4, 1fr); |
|
||||
grid-template-rows: repeat(2, 1fr); |
|
||||
gap: 10px; |
|
||||
|
|
||||
} |
|
||||
.manual-button { |
|
||||
height: 80px; |
|
||||
line-height: 80px; |
|
||||
text-align: center; |
|
||||
border-radius: 10px; |
|
||||
:deep(.my-button) { |
|
||||
height: 100%; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
:deep(.el-card__body){ |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
justify-content: space-between; |
|
||||
.ft-button { |
|
||||
box-shadow: 0 0 25px rgba(0,0,0,0.2); |
|
||||
} |
|
||||
} |
|
||||
|
<style scoped lang="stylus"> |
||||
|
.home-container |
||||
|
background-color #F6F6F6 !important |
||||
|
padding 0 |
||||
|
.el-row |
||||
|
height 100% |
||||
|
.el-col |
||||
|
height 100% |
||||
|
.home-left, .home-right |
||||
|
border-radius 10px |
||||
|
height 100% |
||||
|
background-color #fff |
||||
|
padding 10px |
||||
|
.home-left |
||||
|
display flex |
||||
|
flex-direction column |
||||
|
justify-content space-between |
||||
|
.left-top |
||||
|
height calc(50% - 5px) |
||||
|
display flex |
||||
|
justify-content space-between |
||||
|
.el-card |
||||
|
width calc(50% - 5px) |
||||
|
height 100% |
||||
|
background #F7F7F7 |
||||
|
border-radius 10px !important |
||||
|
box-shadow none |
||||
|
border none |
||||
|
:deep(.el-card__body) |
||||
|
background #F7F7F7 |
||||
|
border-radius 10px!important |
||||
|
padding 10px |
||||
|
display grid |
||||
|
grid-template-columns repeat(4, 1fr) |
||||
|
grid-template-rows repeat(4, 1fr) |
||||
|
grid-gap 4px |
||||
|
height 100% |
||||
|
.tube-box-success |
||||
|
background #12C290 !important |
||||
|
color #fff !important |
||||
|
.tube-box |
||||
|
font-size 10px |
||||
|
display flex |
||||
|
flex-direction column |
||||
|
justify-content space-between |
||||
|
background #EBEFF4 |
||||
|
border-radius: 10px |
||||
|
padding 5px 2px |
||||
|
color #606266 |
||||
|
border 2px solid #ffffff |
||||
|
.serial-number |
||||
|
font-size 14px |
||||
|
font-weight 900 |
||||
|
.left-bottom |
||||
|
height calc(50% - 5px) |
||||
|
.el-card |
||||
|
width 100% |
||||
|
height 100% |
||||
|
:deep(.el-card__body) |
||||
|
height 100% |
||||
|
padding 10px |
||||
|
overflow hidden |
||||
|
.home-chart |
||||
|
height 50% |
||||
|
width 100% |
||||
|
.home-log |
||||
|
height 50% |
||||
|
padding 10px |
||||
|
width 100% |
||||
|
background #F7F7F7 |
||||
|
border-radius 5px |
||||
|
.log-box |
||||
|
height 100% |
||||
|
overflow-y auto |
||||
|
.log-text |
||||
|
font-size 12px |
||||
|
color #606266 |
||||
|
//margin-bottom 5px |
||||
|
.log-text |
||||
|
font-size 10px |
||||
|
color #606266 |
||||
|
margin-bottom 5px |
||||
|
.home-right |
||||
|
display grid |
||||
|
grid-template-rows repeat(4, 1fr) |
||||
|
grid-gap 10px |
||||
|
.right-button |
||||
|
display grid |
||||
|
grid-template-columns repeat(2, 1fr) |
||||
|
grid-template-rows repeat(3, 1fr) |
||||
|
gap 5px |
||||
|
:deep(.ft-button) |
||||
|
margin 0 !important |
||||
|
.my-button |
||||
|
padding 5px 10px |
||||
|
.el-card |
||||
|
width 100% |
||||
|
height 100% |
||||
|
background #F7F7F7 |
||||
|
border-radius 10px !important |
||||
|
box-shadow none |
||||
|
border none |
||||
|
display flex |
||||
|
flex-direction column |
||||
|
:deep(.el-card__header) |
||||
|
background rgba(0, 38, 77, 0.102); |
||||
|
padding 5px 20px |
||||
|
color #393F46 |
||||
|
font-size 12px |
||||
|
font-weight 600 |
||||
|
:deep(.el-card__body) |
||||
|
flex 1 |
||||
|
padding 10px |
||||
|
overflow hidden |
||||
|
//display flex |
||||
|
.img-box |
||||
|
width 100% |
||||
|
height 100% |
||||
|
display flex |
||||
|
gap 10px |
||||
|
.content-box |
||||
|
//flex 1 |
||||
|
height 100% |
||||
|
width 100% |
||||
|
display flex |
||||
|
justify-content space-between |
||||
|
align-items center |
||||
|
.heat-box, .titration-box |
||||
|
height 80px |
||||
|
width 80px |
||||
|
background: #EBEFF4 |
||||
|
border-radius 50% |
||||
|
border: 1px solid #fff |
||||
|
position relative |
||||
|
overflow hidden |
||||
|
.title |
||||
|
position absolute |
||||
|
bottom 0 |
||||
|
left 0 |
||||
|
width 100% |
||||
|
height 25px |
||||
|
line-height 25px |
||||
|
font-size 10px |
||||
|
text-align center |
||||
|
background: rgba(0, 38, 77, 0.1) |
||||
</style> |
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue