Browse Source

完善加液,移至加热,移至加液功能

feature/layout_0214^2
LiLongLong 6 months ago
parent
commit
3a7066418c
  1. 2
      .env
  2. 9
      src/services/globalCmd/globalCmd.ts
  3. 8
      src/services/txn.ts
  4. 50
      src/views/graphite/components/AddLiquid.vue
  5. 48
      src/views/graphite/components/HeatPosition.vue
  6. 2
      src/views/graphite/components/mock.ts
  7. 718
      src/views/graphite/index.vue

2
.env

@ -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

9
src/services/globalCmd/globalCmd.ts

@ -40,9 +40,16 @@ export type OperationCmd =
| "openClaw" // 张开夹爪
| "closeClaw" // 收合夹爪
| "moveMachineArm" // 移动机械臂
| "moveTube"; // 移动试管
| "moveTube" // 移动试管
| 'openDoor' //开门
| 'closeDoor' //关门
export function debugCmd(params: { command: OperationCmd; params: Record<string, any> }) {
const commandId = addTxnRecord({ ...params, category: "debug" });
return httpRequest<BaseResponse<string>>({ url: "/api/cmd/", params: { ...params, commandId }, method: "POST" });
}
export function taskCmd(params: { command: OperationCmd; params: Record<string, any> }) {
const commandId = addTxnRecord({ ...params, category: "task" });
return httpRequest<BaseResponse<string>>({ url: "/api/cmd/", params: { ...params, commandId }, method: "POST" });
}

8
src/services/txn.ts

@ -22,7 +22,13 @@ type DebugCmdRecord = {
params: Record<string, any>;
};
type TxnRecord = DebugCmdRecord; // | xxxRecord
type TaskCmdRecord = {
category: "task";
command: OperationCmd;
params: Record<string, any>;
}
type TxnRecord = DebugCmdRecord | TaskCmdRecord
const txnCmdMap: Record<string, TxnRecord> = {};

50
src/views/graphite/components/AddLiquid.vue

@ -14,6 +14,7 @@
</div>
<div class="tube_num">已选择{{ selectedTubeList.length }}个试管</div>
</div>
<div class="liquid_main">
<div class="liquid_area" v-for="(solution, index) in solutionList" :key="index">
<!--左溶液瓶区-->
@ -60,7 +61,7 @@
<script setup>
import AddSvg from '@/assets/add.svg'
import { ref, onMounted, computed } from 'vue'
const emits = defineEmits(['cancel'])
const emits = defineEmits(['cancel', 'onAddSolution'])
const solutionData = {
solutionNum:null
};
@ -73,51 +74,47 @@
const selectedTubeList = ref([])
const tubeQueue = ref([])
const selectedColor = '#4F85FB'
const defaultColor = '#26D574'
const emptyColor = '#FFFFFF'
const defualtTube = {
color:emptyColor
}
const tubeList = ref([{
id: 1,
color: defaultColor
},{
id: 2,
color: defaultColor
},{
id: 3,
color: defaultColor
},{
id: 4,
color: defaultColor
}])
const tubeList = ref([])
const onConfirm = () => {
//
console.log('tubeQueue---', tubeQueue.value)
emits('onAddSolution', selectedTubeList.value)
onCancel()
}
onMounted(()=>{
while(tubeList.value.length != 16){
tubeList.value.push(defualtTube)
}
tubeBaseConfig();
while(solutionList.value.length != 8){
solutionList.value.push({id:solutionList.value.length + 1})
}
})
function tubeBaseConfig(){
//16
for(let i = 0; i < 16; i++){
tubeList.value.push({
id: i + 1,
color:emptyColor
})
}
}
const onChooseTube = (tubeItem, index) => {
if(!tubeItem.id)return
//
if(tubeItem.isSelected){//
tubeItem.color = defaultColor
tubeItem.color = emptyColor
selectedTubeList.value = selectedTubeList.value.filter(item => item.id != tubeItem.id)
}else{//
tubeItem.color = selectedColor
selectedTubeList.value.push(tubeItem)
}
tubeItem.isSelected = !tubeItem.isSelected;
}
const onCancel = () => {
@ -126,7 +123,7 @@
//
const delQueueSolution = (data) => {
console.log('data===', data)
tubeQueue.value = tubeQueue.value.filter(item => (data.tubeId != item.tubeId || data.solutionId != item.solutionId) )
}
//
@ -135,9 +132,10 @@
//
selectedTubeList.value.forEach(item => {
tubeQueue.value.push({
tubeId: item.id,
solutionId,
solutionNum,
solutionName
solutionName,
})
})
@ -176,7 +174,7 @@
display: flex;
flex-wrap: wrap;
gap: 0.7rem;
padding-left: 0.6rem;
padding: 0.6rem;
border-radius: 1.5rem;
.inner-circle {
border-radius: 50%;

48
src/views/graphite/components/HeatPosition.vue

@ -2,27 +2,27 @@
<div
class="heat_main"
:style="`${
tubeIndex === currentIndex && isSelect
trayInfo.isSelect
? 'border:4px solid rgb(66 215 76)'
: 'border:4px solid #ffffff'
}`"
>
<section class="heat_pos_text">
<div class="pos_text">{{ `A-${tubeIndex || ""}` }}</div>
<div class="pos_text">{{ trayInfo.name }}</div>
<div class="pos_text pos_state">已放置</div>
</section>
<section
class="heat_pos"
:style="`background:${trayInfo?.id ? '#384D5D' : ''}`"
:style="`background:${trayInfo?.id ? '' : ''}`"
@click="onSelectTray"
>
<div
v-for="(tube, index) in tubeList"
v-for="(tube, index) in trayInfo.tubeList || tubeList"
:key="index"
class="inner-circle"
@click.stop="onHandleTube(tube)"
:style="{ background: trayInfo?.id ? '#F2652D' : '' }"
:style="{ background: tube.color || 'rgb(212, 212, 212)' }"
></div>
<!--执行中状态的遮罩层-->
<div class="craft_executing_modal" v-if="trayInfo.state == 1">
@ -37,7 +37,7 @@
<section class="heat_footer">
<div class="heat_temperature" @click="setTemperature">
<template v-if="trayInfo?.id">
<div class="target_temp">目标温度: {{ trayInfo.trayTempVale }}</div>
<div class="target_temp">目标温度: {{ trayInfo.temperature }}</div>
<div class="heating">加热中</div>
</template>
<template v-else>
@ -60,14 +60,14 @@
</div>
</section>
<OverlayModal :visible="tempVisivle">
<OverlayModal :visible="tempVisible">
<div class="set_temp_modal_content">
<h3 class="set_temp_title">设定温度</h3>
<section class="temp_label">
<div class="text-xl">
目标温度<input
type="number"
v-model="trayTempVale"
v-model="heatAreaTemperature"
class="temp_input"
placeholder="请输入温度"
/>
@ -91,7 +91,7 @@
<button class="btn-dark px-10 py-2 w-15" @click="onConfirm">
确定
</button>
<button class="btn-light px-10 py-2" @click="tempVisivle = false">
<button class="btn-light px-10 py-2" @click="tempVisible = false">
取消
</button>
</footer>
@ -114,7 +114,7 @@ const props = defineProps({
heatInfo: Object,
tubeIndex: Number,
});
const emits = defineEmits(["onSelectedTray"]);
const emits = defineEmits(["onSelectedTray", "onSetHeatAreaTemp"]);
onMounted(() => {});
@ -122,42 +122,44 @@ const craftVisible = ref(false);
//
const trayTempType = ref(false);
const tempVisivle = ref(false);
const tempVisible = ref(false);
//
const trayInfo = ref(props.heatInfo || {});
const trayTempVale = ref(trayInfo.value.trayTempVale || "");
const formulaList: any = ref([]);
let trayInfo = ref<any>(props.heatInfo || {});
watch(()=>props.heatInfo, (newVal)=>{
trayInfo.value = newVal
})
const heatAreaTemperature = ref(trayInfo.value.temperature || "");
//
const isSelect = ref(false);
const currentIndex = ref();
const selectedTrayList = ref<any>([]);
const onSelectTray = () => {
if (currentIndex.value !== props.tubeIndex) {
isSelect.value = true;
trayInfo.value.isSelect = true;
} else {
isSelect.value = !isSelect.value;
trayInfo.value.isSelect = !trayInfo.value.isSelect;
}
currentIndex.value = props.tubeIndex;
emits("onSelectedTray", props.heatInfo);
emits("onSelectedTray", trayInfo.value);
};
const changeVisible = () => {
craftVisible.value = false;
};
//
const onChooseCraft = () => {
craftVisible.value = true;
};
const setTemperature = () => {
tempVisivle.value = true;
tempVisible.value = true;
};
const onConfirm = () => {
trayInfo.value.id = 3;
trayInfo.value.trayTempVale = trayTempVale;
tempVisivle.value = false;
trayInfo.value.temperature = heatAreaTemperature.value;
tempVisible.value = false;
//
emits("onSetHeatAreaTemp", trayInfo.value);
};
//

2
src/views/graphite/components/mock.ts

@ -1,5 +1,5 @@
export const graphiteMock = {
heatAreaStatus : [true, false,true, false,true, false],//加热区状态
heatAreaStatus : [true, true,true, true,true, true],//加热区状态
}

718
src/views/graphite/index.vue

@ -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>
Loading…
Cancel
Save