7 changed files with 578 additions and 259 deletions
-
2.env
-
9src/services/globalCmd/globalCmd.ts
-
8src/services/txn.ts
-
50src/views/graphite/components/AddLiquid.vue
-
48src/views/graphite/components/HeatPosition.vue
-
2src/views/graphite/components/mock.ts
-
718src/views/graphite/index.vue
@ -1,3 +1,3 @@ |
|||
VITE_API_HOST=127.0.0.1 |
|||
VITE_API_HOST=192.168.1.119 |
|||
VITE_API_PORT=8080 |
|||
VITE_WS_PATH=/ws |
@ -1,5 +1,5 @@ |
|||
export const graphiteMock = { |
|||
|
|||
heatAreaStatus : [true, false,true, false,true, false],//加热区状态
|
|||
heatAreaStatus : [true, true,true, true,true, true],//加热区状态
|
|||
|
|||
} |
@ -1,271 +1,577 @@ |
|||
<template> |
|||
<div class="graphite_home component-page overflow-auto" id="heatArea"> |
|||
<div class="heat_area" > |
|||
<div v-for="(item, index) in heatList" :key="item"> |
|||
<HeatPosition :heatInfo="{...item, index}" :tubeIndex="index + 1" @onSelectedTray="onSelectedTray"></HeatPosition> |
|||
</div> |
|||
<!--执行中状态的遮罩层--> |
|||
</div> |
|||
<!--拍照区--> |
|||
<div class="picture_area"> |
|||
<TakePickture></TakePickture> |
|||
<!--操作区--> |
|||
<div class="graphite_btn_container"> |
|||
<van-button size="large" class="btn_size op_open_door">开门</van-button> |
|||
<van-button size="large" class="btn_size op_start_task">开始实验</van-button> |
|||
<van-button size="large" class="btn_size op_stop_task">结束实验</van-button> |
|||
<van-button size="large" class="btn_size op_select_craft" @click="onChooseCaft">选择工艺</van-button> |
|||
<van-button size="large" class="btn_size op_exec_craft">执行工艺</van-button> |
|||
<van-button size="large" class="btn_size op_add_liquid" @click="onAddLiquid">添加溶液</van-button> |
|||
<van-button size="large" class="btn_size op_shake_up">摇匀</van-button> |
|||
<van-button size="large" class="btn_size op_move_heat" @click="onMoveToHeat">移至加热</van-button> |
|||
<van-button size="large" class="btn_size op_move_act">移至加液</van-button> |
|||
<van-button size="large" class="btn_size op_move_exception">移至特殊</van-button> |
|||
<van-button size="large" class="btn_size op_start_heat">开始加热</van-button> |
|||
<van-button size="large" class="btn_size op_up_tray">抬起托盘</van-button> |
|||
</div> |
|||
</div> |
|||
<van-overlay :show="liquidVisible" style="z-index: 9999"> |
|||
<div class="liquid"> |
|||
<div class="addLiquid"> |
|||
<AddLiquid @cancel="liquidVisible = false"></AddLiquid> |
|||
</div> |
|||
</div> |
|||
</van-overlay> |
|||
<!--选择工艺--> |
|||
<OverlayModal :visible="craftVisible"> |
|||
<CraftList @changeVisible="changeVisible"></CraftList> |
|||
</OverlayModal> |
|||
</div> |
|||
<div class="graphite_home component-page overflow-auto" id="heatArea"> |
|||
<div class="heat_area"> |
|||
<div v-for="(item, index) in heatList" :key="item.id"> |
|||
<HeatPosition |
|||
:heatInfo="{ ...item, index }" |
|||
:tubeIndex="index + 1" |
|||
@onSelectedTray="onSelectedTray" |
|||
@onSetHeatAreaTemp = "onSetHeatAreaTemp" |
|||
></HeatPosition> |
|||
</div> |
|||
<!--执行中状态的遮罩层--> |
|||
</div> |
|||
<!--拍照区--> |
|||
<div class="picture_area"> |
|||
<!--加液区和拍照区可切换--> |
|||
<div style="display: flex; justify-content: center; align-items: center"> |
|||
<div style="font-size: 1rem; margin-left: 0.3rem">加液区</div> |
|||
<van-switch |
|||
v-model="switchModule" |
|||
size="1rem" |
|||
active-color="#ee0a24" |
|||
inactive-color="green" |
|||
/> |
|||
<div style="font-size: 1rem; margin-left: 0.3rem">拍照区</div> |
|||
</div> |
|||
|
|||
<TakePickture v-if="switchModule"></TakePickture> |
|||
<div v-else class="home_tube"> |
|||
<div |
|||
class="inner-circle" |
|||
v-for="(tubeItem, index) in tubeList" |
|||
:key="index" |
|||
:style="{ background: tubeItem.color }" |
|||
@click="onChooseTube(tubeItem, index)" |
|||
></div> |
|||
</div> |
|||
<!--操作区--> |
|||
<div class="graphite_btn_container"> |
|||
<van-button size="large" class="btn_size op_open_door" @click="onOPen" |
|||
>开门</van-button |
|||
> |
|||
<van-button size="large" class="btn_size op_start_task" |
|||
>开始实验</van-button |
|||
> |
|||
<van-button size="large" class="btn_size op_stop_task" |
|||
>结束实验</van-button |
|||
> |
|||
<van-button |
|||
size="large" |
|||
class="btn_size op_select_craft" |
|||
@click="onChooseCaft" |
|||
>选择工艺</van-button |
|||
> |
|||
<van-button size="large" class="btn_size op_exec_craft" |
|||
>执行工艺</van-button |
|||
> |
|||
<van-button |
|||
size="large" |
|||
class="btn_size op_add_liquid" |
|||
@click="onAddLiquid" |
|||
>添加溶液</van-button |
|||
> |
|||
<van-button size="large" class="btn_size op_shake_up">摇匀</van-button> |
|||
<van-button |
|||
size="large" |
|||
class="btn_size op_move_heat" |
|||
@click="onMoveToHeat" |
|||
>移至加热</van-button |
|||
> |
|||
<van-button size="large" class="btn_size op_move_act" @click="onMoveToOperationArea" |
|||
>移至加液</van-button |
|||
> |
|||
<van-button size="large" class="btn_size op_move_exception" |
|||
>移至特殊</van-button |
|||
> |
|||
<van-button size="large" class="btn_size op_start_heat" @click="onStartHeat" |
|||
>开始加热</van-button |
|||
> |
|||
<van-button size="large" class="btn_size op_up_tray" |
|||
>抬起托盘</van-button |
|||
> |
|||
</div> |
|||
</div> |
|||
<van-overlay :show="liquidVisible" style="z-index: 9999"> |
|||
<div class="liquid"> |
|||
<div class="addLiquid"> |
|||
<AddLiquid |
|||
@cancel="liquidVisible = false" |
|||
@onAddSolution="onAddSolution" |
|||
></AddLiquid> |
|||
</div> |
|||
</div> |
|||
</van-overlay> |
|||
<!--选择工艺--> |
|||
<OverlayModal :visible="craftVisible"> |
|||
<CraftList @changeVisible="changeVisible"></CraftList> |
|||
</OverlayModal> |
|||
</div> |
|||
</template> |
|||
<script lang="ts" setup> |
|||
import { ref, onMounted } from "vue"; |
|||
import { ref, reactive, onMounted, onUnmounted, watch } from "vue"; |
|||
//@ts-ignore |
|||
import { ElMessage } from "element-plus"; |
|||
import { createWebSocket, sharedWsUrl } from "@/services/socket"; |
|||
import { HeatPosition, TakePickture, AddLiquid } from "./components"; |
|||
import OverlayModal from "@/components/OverlayModal.vue"; |
|||
import CraftList from "@/views/graphite/components/CraftList.vue"; |
|||
import { graphiteMock } from './components/mock' |
|||
import { graphiteMock } from "./components/mock"; |
|||
import { useStatusStore } from "@/stores/status"; |
|||
import { getConfig } from "@/services/sysConfig/sysConfig"; |
|||
import { |
|||
CmdDescMap, |
|||
taskCmd, |
|||
type OperationCmd, |
|||
} from "@/services/globalCmd/globalCmd"; |
|||
import { getTxnRecord } from "@/services/txn"; |
|||
import { useSettingStore } from "@/stores/setting"; |
|||
|
|||
const settingStore = useSettingStore(); |
|||
console.log('settingStore---', settingStore.heatAreaConfig) |
|||
|
|||
//设备的全局状态 |
|||
const useStatus = useStatusStore() |
|||
const statusStore = useStatusStore(); |
|||
const heatList: any = ref([]); |
|||
const craftVisible = ref(false); |
|||
const tubeRackList = ['A-1','A-2', 'A-3','A-4','A-5','A-5'] |
|||
const switchModule = ref(false); |
|||
let tubeList = reactive<any>([]); |
|||
const selectedColor = "#4F85FB"; |
|||
const emptyColor = "#FFFFFF"; |
|||
const defaultColor = "#189952"; |
|||
onMounted(() => { |
|||
//6个加热区数据 |
|||
heatList.value = settingStore.heatAreaConfig |
|||
//6个加热区数据 |
|||
heatList.value = settingStore.heatAreaConfig; |
|||
//设备16个试管的基础数据 |
|||
tubeBaseConfig(); |
|||
//连接socket |
|||
const wsClient = createWebSocket(sharedWsUrl); |
|||
const subscription = wsClient.dataOb.subscribe((data) => { |
|||
if (data.type === "cmd") { |
|||
const cmdInfo = getTxnRecord(data.data.commandId, "task"); |
|||
if (cmdInfo) { |
|||
const cmdName = CmdDescMap[cmdInfo.command]; |
|||
const result = data.data.success |
|||
? "执行完毕" |
|||
: `执行失败 ${data.data.message}`; |
|||
ElMessage({ |
|||
message: `${cmdName} ${result}`, |
|||
type: data.data.success ? "success" : "error", |
|||
}); |
|||
} |
|||
} else if (data.type === "status") { |
|||
statusStore.setStatus(data.data); |
|||
} else if (data.type === "warn") { |
|||
ElMessage({ |
|||
message: data.data.message, |
|||
type: "warning", |
|||
}); |
|||
} |
|||
}); |
|||
wsClient.connect(); |
|||
|
|||
onUnmounted(() => { |
|||
subscription.unsubscribe(); |
|||
}); |
|||
}); |
|||
|
|||
//选择的托盘 |
|||
const selectedTrayList = ref<any>([]); |
|||
const currentIndex = ref(); |
|||
const selectedTrayObj:any = {} |
|||
const onSelectedTray = (data:any) => { |
|||
if(selectedTrayObj[data.id]){ |
|||
delete selectedTrayObj[data.id] |
|||
}else { |
|||
selectedTrayObj[data.id] = data |
|||
const selectedTrayObj: any = {}; |
|||
const onSelectedTray = (data: any) => { |
|||
console.log("data==操作加热区:=", data); |
|||
if (!data.isSelect) { |
|||
delete selectedTrayObj[data.id]; |
|||
} else { |
|||
selectedTrayObj[data.id] = data; |
|||
} |
|||
selectedTrayList.value = Object.values(selectedTrayObj) |
|||
console.log('data==操作加热区:=', data) |
|||
selectedTrayList.value = Object.values(selectedTrayObj); |
|||
|
|||
}; |
|||
|
|||
//设置加热区温度 |
|||
const onSetHeatAreaTemp = (dataInfo:any) => { |
|||
selectedTrayObj[dataInfo.id] = dataInfo; |
|||
selectedTrayList.value = Object.values(selectedTrayObj); |
|||
} |
|||
|
|||
const tubeBaseConfig = () => { |
|||
//默认为16个 |
|||
for (let i = 0; i < 16; i++) { |
|||
tubeList.push({ |
|||
id: i + 1, |
|||
color: "rgb(212, 212, 212)", |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
//添加溶液 |
|||
const liquidVisible = ref(false); |
|||
const onAddLiquid = () => { |
|||
liquidVisible.value = true; |
|||
//检查加液区是否有试管。但是现在没有这个状态,暂时不考虑。 |
|||
liquidVisible.value = true; |
|||
}; |
|||
|
|||
const onAddSolution = (data: any) => { |
|||
let ids = data.map((item: any) => item.id); |
|||
tubeList.forEach((item: any) => { |
|||
if (ids.includes(item.id)) { |
|||
item.default = defaultColor; |
|||
item.color = defaultColor; |
|||
item.isSelected = true; |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
const changeVisible = () => { |
|||
craftVisible.value = false; |
|||
craftVisible.value = false; |
|||
}; |
|||
|
|||
//选择工艺 |
|||
const onChooseCaft = () => { |
|||
craftVisible.value = true; |
|||
craftVisible.value = true; |
|||
}; |
|||
|
|||
const onChooseTube = (tubeItem: any, index: any) => { |
|||
if (!tubeItem.id) return; |
|||
//@ts-ignore |
|||
let list = [...tubeList]; |
|||
for (let i = 0; i < list.length; i++) { |
|||
let item = list[i]; |
|||
if (index == i) { |
|||
item.color = selectedColor; |
|||
item.isSelected = true; |
|||
} else { |
|||
item.color = item.default ? item.default : emptyColor; |
|||
item.isSelected = false; |
|||
} |
|||
} |
|||
tubeList = [...list]; |
|||
}; |
|||
|
|||
//移至加热 |
|||
const onMoveToHeat = () => { |
|||
//1、是否选择了加热区,且只能选择一个加热区 |
|||
if(selectedTrayList.value.length != 1){ |
|||
ElMessage.error('只能选择一个加热区') |
|||
//1、是否选择了加热区 |
|||
if (!selectedTrayList.value.length) { |
|||
ElMessage.error("请选择目标加热区"); |
|||
return; |
|||
} |
|||
//2、只能选择一个加热区 |
|||
if (selectedTrayList.value.length != 1) { |
|||
ElMessage.error("只能选择一个加热区"); |
|||
return; |
|||
} |
|||
|
|||
let selectedDataItem = selectedTrayList.value[0]; |
|||
//2、判断选择的加热区是否已经有了试管架 |
|||
let heatAearStatus: any = statusStore.status?.trayStatus || graphiteMock.heatAreaStatus; |
|||
if (!heatAearStatus[selectedDataItem.index]) { |
|||
ElMessage.error("选择的加热区已有试管架,重新选择加热区"); |
|||
return; |
|||
} |
|||
|
|||
//调用移至加热接口 |
|||
const params = { |
|||
areaId: selectedDataItem.id, |
|||
}; |
|||
const command: OperationCmd = "moveToHeatArea"; |
|||
taskCmd({ command, params }).then((res) => { |
|||
if (res.success) { |
|||
ElMessage.success("指令已发送,请稍等"); |
|||
} else { |
|||
ElMessage.error(res.msg); |
|||
} |
|||
}); |
|||
|
|||
//指令完成成更新UI |
|||
let list = [...heatList.value]; |
|||
list.forEach((item: any) => { |
|||
if (item.id == selectedDataItem.id) { |
|||
item.tubeList = JSON.parse(JSON.stringify(tubeList)); |
|||
|
|||
selectedTrayObj[item.id] = item; |
|||
selectedTrayList.value = Object.values(selectedTrayObj); |
|||
} |
|||
}); |
|||
tubeList.forEach((item:any) => { |
|||
item.color = ''; |
|||
item.default = '' |
|||
}); |
|||
heatList.value = [...list]; |
|||
}; |
|||
|
|||
//移至加液区(操作区) |
|||
const onMoveToOperationArea = () => { |
|||
//1、判断加液区是否有试管架(暂时获取不到这个状态) |
|||
//1、是否选择了试管架/加热区 |
|||
if (!selectedTrayList.value.length) { |
|||
ElMessage.error("请选择试管架"); |
|||
return; |
|||
} |
|||
//2、只能选择一个试管架/加热区 |
|||
if (selectedTrayList.value.length != 1) { |
|||
ElMessage.error("只能选择一个试管架"); |
|||
return; |
|||
} |
|||
let selectedData = selectedTrayList.value[0] |
|||
let selectedDataItem = selectedTrayList.value[0]; |
|||
selectedDataItem.isSelect = false |
|||
//3、选择的加热区有没有试管架 |
|||
if(!selectedDataItem.tubeList || !selectedDataItem.tubeList.length){ |
|||
ElMessage.error("选择的加热区没有试管架"); |
|||
return; |
|||
} |
|||
|
|||
//4、发送移至加液区指令 |
|||
const params = { |
|||
areaId: selectedDataItem.id |
|||
} |
|||
onSendCmd('moveToActionArea', params) |
|||
//更新UI |
|||
heatList.value.forEach((item:any) => { |
|||
if(item.id == selectedDataItem.id){ |
|||
tubeList = [...item.tubeList] |
|||
item.tubeList = null; |
|||
|
|||
} |
|||
}) |
|||
onSelectedTray(selectedDataItem) |
|||
} |
|||
|
|||
|
|||
//开门 |
|||
const onOPen = () => { |
|||
const params = {}; |
|||
const command: OperationCmd = "openDoor"; |
|||
taskCmd({ command, params }).then((res) => { |
|||
if (res.success) { |
|||
ElMessage.success("指令已发送,请稍等"); |
|||
} else { |
|||
ElMessage.error(res.msg); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
//2、判断加液区是否有试管 |
|||
let heatAearStatus:any = useStatus.status || graphiteMock.heatAreaStatus |
|||
if(!heatAearStatus[selectedData.index]){ |
|||
ElMessage.error('选择的加热区已有试管架,重新选择加热区') |
|||
//开始加热 |
|||
const onStartHeat = () => { |
|||
//选择的加热区 |
|||
if (!selectedTrayList.value.length) { |
|||
ElMessage.error("请选择目标加热区"); |
|||
return; |
|||
} |
|||
//调用移至加热接口 |
|||
//判断选中的加热区是否有试管架 |
|||
let existTubeRack = true; |
|||
//加热区是否设置了加热温度 |
|||
let hasSetTemp = true; |
|||
selectedTrayList.value.forEach((item:any) => { |
|||
let tubeList = item.tubeList; |
|||
if(!tubeList || !tubeList.length){ |
|||
|
|||
existTubeRack = false; |
|||
} |
|||
if(!item.temperature){ |
|||
hasSetTemp = false; |
|||
} |
|||
}) |
|||
|
|||
if(!existTubeRack){ |
|||
ElMessage.error("选择的加热区未放置试管架,请重新选择") |
|||
return; |
|||
} |
|||
if(!hasSetTemp){ |
|||
ElMessage.error("选择的加热区未设置温度,请设置温度") |
|||
return; |
|||
} |
|||
|
|||
//后台批量发送指令 |
|||
|
|||
const cmdList:any = [] |
|||
selectedTrayList.value.forEach((heatArea:any) => { |
|||
cmdList.push({ |
|||
command:'startHeat', |
|||
params:{ |
|||
areaId : heatArea.id |
|||
} |
|||
}) |
|||
}) |
|||
console.log('cmdList---', cmdList) |
|||
onSendCmd("startHeat", cmdList) |
|||
} |
|||
|
|||
const onSendCmd = (command:OperationCmd,params:any)=> { |
|||
//发送加热指令 |
|||
taskCmd({ command, params }).then((res) => { |
|||
if (res.success) { |
|||
ElMessage.success("指令已发送,请稍等"); |
|||
} else { |
|||
ElMessage.error(res.msg); |
|||
} |
|||
}); |
|||
} |
|||
</script> |
|||
<style lang="scss" scoped> |
|||
@use "@/assets/style/mixin.scss" as *; |
|||
|
|||
.graphite_home { |
|||
background: #f6f6f6; |
|||
display: flex; |
|||
gap: 1rem; |
|||
// @media (min-width: $md) { |
|||
flex-direction: column; |
|||
align-items: stretch; |
|||
// } |
|||
.picture_area { |
|||
display: flex; |
|||
flex-direction: column-reverse; |
|||
} |
|||
@media (min-width: $lg) { |
|||
flex-direction: row; |
|||
align-items: start; |
|||
.picture_area { |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 47.5rem; |
|||
} |
|||
} |
|||
background: #f6f6f6; |
|||
display: flex; |
|||
gap: 1rem; |
|||
// @media (min-width: $md) { |
|||
flex-direction: column; |
|||
align-items: stretch; |
|||
// } |
|||
.picture_area { |
|||
display: flex; |
|||
flex-direction: column-reverse; |
|||
} |
|||
@media (min-width: $lg) { |
|||
flex-direction: row; |
|||
align-items: start; |
|||
.picture_area { |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 47.5rem; |
|||
} |
|||
} |
|||
} |
|||
.heat_area { |
|||
margin: 5px 0; |
|||
|
|||
background: #ffffff; |
|||
border-radius: 20px; |
|||
|
|||
column-gap: 8px; |
|||
row-gap: 10px; |
|||
padding: 1.5rem 0.5rem; |
|||
min-width: 600px; |
|||
flex: 1 1 auto; |
|||
display: grid; |
|||
grid-template-columns: repeat(3, 1fr); |
|||
> * { |
|||
justify-self: center; |
|||
align-self: center; |
|||
} |
|||
margin: 5px 0; |
|||
|
|||
@media (min-width: $md) { |
|||
column-gap: 12px; |
|||
row-gap: 20px; |
|||
height: 47.5rem; |
|||
} |
|||
background: #ffffff; |
|||
border-radius: 20px; |
|||
|
|||
@media (min-width: $xl) { |
|||
padding: 4.5rem 1rem; |
|||
} |
|||
column-gap: 8px; |
|||
row-gap: 10px; |
|||
padding: 1.5rem 0.5rem; |
|||
min-width: 600px; |
|||
flex: 1 1 auto; |
|||
display: grid; |
|||
grid-template-columns: repeat(3, 1fr); |
|||
> * { |
|||
justify-self: center; |
|||
align-self: center; |
|||
} |
|||
|
|||
.craft_executing_modal { |
|||
position: absolute; |
|||
width: 10.5rem; |
|||
height: 18rem; |
|||
background: rgb(230, 230, 230); |
|||
opacity: 0.5; |
|||
z-index: 9999; |
|||
} |
|||
@media (min-width: $md) { |
|||
column-gap: 12px; |
|||
row-gap: 20px; |
|||
height: 47.5rem; |
|||
} |
|||
|
|||
@media (min-width: $xl) { |
|||
padding: 4.5rem 1rem; |
|||
} |
|||
|
|||
.craft_executing_modal { |
|||
position: absolute; |
|||
width: 10.5rem; |
|||
height: 18rem; |
|||
background: rgb(230, 230, 230); |
|||
opacity: 0.5; |
|||
z-index: 9999; |
|||
} |
|||
} |
|||
|
|||
.picture_area { |
|||
display: flex; |
|||
flex-direction: column; |
|||
margin: 5px; |
|||
// margin-left: 1.25rem; |
|||
background: #ffffff; |
|||
border-radius: 20px; |
|||
padding: 0 1.5rem; |
|||
@media (min-width: $lg) { |
|||
flex: 1 1 180px; |
|||
} |
|||
@media (min-width: $xl) { |
|||
flex: 0 0 auto; |
|||
width: 27rem; |
|||
} |
|||
display: flex; |
|||
flex-direction: column; |
|||
margin: 5px; |
|||
// margin-left: 1.25rem; |
|||
background: #ffffff; |
|||
border-radius: 20px; |
|||
padding: 0 1.5rem; |
|||
@media (min-width: $lg) { |
|||
flex: 1 1 180px; |
|||
} |
|||
@media (min-width: $xl) { |
|||
flex: 0 0 auto; |
|||
width: 27rem; |
|||
} |
|||
|
|||
.graphite_btn_container { |
|||
margin: 2rem 0; |
|||
gap: 0.625rem; |
|||
display: grid; |
|||
@media (max-width: calc($md - 0.1px)) { |
|||
grid-template-columns: repeat(2, 1fr); |
|||
.op_open_door { |
|||
grid-column: 1/-1; |
|||
} |
|||
.op_up_tray { |
|||
grid-column: 1/-1; |
|||
} |
|||
} |
|||
@media (min-width: $md) and (max-width: calc($lg - 0.1px)) { |
|||
grid-template-columns: repeat(6, 1fr); |
|||
> * { |
|||
grid-column: span 3; |
|||
} |
|||
.op_open_door { |
|||
grid-column: 1/-1; |
|||
} |
|||
.op_move_heat { |
|||
grid-column: span 2; |
|||
} |
|||
.op_move_act { |
|||
grid-column: span 2; |
|||
} |
|||
.op_move_exception { |
|||
grid-column: span 2; |
|||
} |
|||
} |
|||
@media (min-width: $lg) and (max-width: calc($xl - 0.1px)) { |
|||
grid-template-columns: repeat(2, 1fr); |
|||
.op_open_door { |
|||
grid-column: 1/-1; |
|||
} |
|||
.op_up_tray { |
|||
grid-column: 1/-1; |
|||
} |
|||
} |
|||
@media (min-width: $xl) { |
|||
grid-template-columns: repeat(6, 1fr); |
|||
> * { |
|||
grid-column: span 3; |
|||
} |
|||
.op_open_door { |
|||
grid-column: 1/-1; |
|||
} |
|||
.op_move_heat { |
|||
grid-column: span 2; |
|||
} |
|||
.op_move_act { |
|||
grid-column: span 2; |
|||
} |
|||
.op_move_exception { |
|||
grid-column: span 2; |
|||
} |
|||
} |
|||
} |
|||
.graphite_btn_container { |
|||
margin: 2rem 0; |
|||
gap: 0.625rem; |
|||
display: grid; |
|||
@media (max-width: calc($md - 0.1px)) { |
|||
grid-template-columns: repeat(2, 1fr); |
|||
.op_open_door { |
|||
grid-column: 1/-1; |
|||
} |
|||
.op_up_tray { |
|||
grid-column: 1/-1; |
|||
} |
|||
} |
|||
@media (min-width: $md) and (max-width: calc($lg - 0.1px)) { |
|||
grid-template-columns: repeat(6, 1fr); |
|||
> * { |
|||
grid-column: span 3; |
|||
} |
|||
.op_open_door { |
|||
grid-column: 1/-1; |
|||
} |
|||
.op_move_heat { |
|||
grid-column: span 2; |
|||
} |
|||
.op_move_act { |
|||
grid-column: span 2; |
|||
} |
|||
.op_move_exception { |
|||
grid-column: span 2; |
|||
} |
|||
} |
|||
@media (min-width: $lg) and (max-width: calc($xl - 0.1px)) { |
|||
grid-template-columns: repeat(2, 1fr); |
|||
.op_open_door { |
|||
grid-column: 1/-1; |
|||
} |
|||
.op_up_tray { |
|||
grid-column: 1/-1; |
|||
} |
|||
} |
|||
@media (min-width: $xl) { |
|||
grid-template-columns: repeat(6, 1fr); |
|||
> * { |
|||
grid-column: span 3; |
|||
} |
|||
.op_open_door { |
|||
grid-column: 1/-1; |
|||
} |
|||
.op_move_heat { |
|||
grid-column: span 2; |
|||
} |
|||
.op_move_act { |
|||
grid-column: span 2; |
|||
} |
|||
.op_move_exception { |
|||
grid-column: span 2; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.btn_size { |
|||
height: 2.75rem; |
|||
color: #1989fa; |
|||
border: 1px solid #1989fa; |
|||
font-size: 1.25rem; |
|||
height: 2.75rem; |
|||
color: #1989fa; |
|||
border: 1px solid #1989fa; |
|||
font-size: 1.25rem; |
|||
} |
|||
|
|||
.liquid { |
|||
display: flex; |
|||
justify-content: center; |
|||
width: 100%; |
|||
height: 100%; |
|||
align-items: center; |
|||
.addLiquid { |
|||
width: 70.375rem; |
|||
height: 52rem; |
|||
background: #ffffff; |
|||
} |
|||
display: flex; |
|||
justify-content: center; |
|||
width: 100%; |
|||
height: 100%; |
|||
align-items: center; |
|||
.addLiquid { |
|||
width: 70.375rem; |
|||
height: 52rem; |
|||
background: #ffffff; |
|||
} |
|||
} |
|||
|
|||
.home_tube { |
|||
height: 12rem; |
|||
background: #384d5d; |
|||
opacity: 1; |
|||
margin-top: 0.5rem; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
gap: 0.5rem; |
|||
padding-left: 0.4rem; |
|||
padding-top: 0.2rem; |
|||
border-radius: 1.5rem; |
|||
.inner-circle { |
|||
border-radius: 50%; |
|||
width: 2.5rem; |
|||
height: 2.5rem; |
|||
background-color: rgb(212, 212, 212); |
|||
} |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue