更新 #36

Merged
zwq merged 1 commits from zwq into develop 2022-03-07 09:17:50 +08:00
11 changed files with 716 additions and 17 deletions

View File

@ -747,6 +747,10 @@ export default {
HistoricalTask: { HistoricalTask: {
zh: '历史任务', zh: '历史任务',
en: 'Historical Task' en: 'Historical Task'
},
ProcessStorageManagement: {
zh: '工序存储区域管理',
en: 'Process Storage Management'
} }
}, },
order: { order: {

View File

@ -1,8 +1,8 @@
/* /*
* @Author: gtz * @Author: gtz
* @Date: 2021-03-08 09:45:54 * @Date: 2021-03-08 09:45:54
* @LastEditors: gtz * @LastEditors: zwq
* @LastEditTime: 2021-04-15 19:34:46 * @LastEditTime: 2022-03-04 15:07:12
* @Description: file content * @Description: file content
*/ */
@ -47,6 +47,7 @@ export default {
sameEqError: 'Can not choice same equipment!', sameEqError: 'Can not choice same equipment!',
processList: { processList: {
processName: 'Process Step Name', processName: 'Process Step Name',
processCode: 'process Code',
processEq: 'Process Step Equipment', processEq: 'Process Step Equipment',
description: 'Description', description: 'Description',
addProcess: 'Add a Process Step', addProcess: 'Add a Process Step',

View File

@ -2,7 +2,7 @@
* @Author: gtz * @Author: gtz
* @Date: 2021-03-04 16:13:51 * @Date: 2021-03-04 16:13:51
* @LastEditors: zwq * @LastEditors: zwq
* @LastEditTime: 2022-03-04 10:13:58 * @LastEditTime: 2022-03-04 15:24:39
* @Description: file content * @Description: file content
*/ */
export default { export default {
@ -287,6 +287,7 @@ export default {
BoxStatus: 'Box Status', BoxStatus: 'Box Status',
BoxNumber: 'Box Number', BoxNumber: 'Box Number',
PreviousOperation: 'Previous Operation', PreviousOperation: 'Previous Operation',
ExecutionOperation: 'Execution Operation',
NextOperation: 'Next Operation', NextOperation: 'Next Operation',
CompletionTime: 'Completion Time', CompletionTime: 'Completion Time',
StartLocation: 'Start Location', StartLocation: 'Start Location',
@ -315,6 +316,8 @@ export default {
IsEmpty: 'Is Empty', IsEmpty: 'Is Empty',
IsEmptyBox: 'Is Empty Box', IsEmptyBox: 'Is Empty Box',
LocationName: 'Location Name', LocationName: 'Location Name',
LocationCode: 'Location Code' LocationCode: 'Location Code',
PerformTaskManual: 'Perform Task Manual',
processStorageLink: 'Process Storage Link'
} }
} }

View File

@ -1,8 +1,8 @@
/* /*
* @Author: gtz * @Author: gtz
* @Date: 2021-03-08 09:46:00 * @Date: 2021-03-08 09:46:00
* @LastEditors: gtz * @LastEditors: zwq
* @LastEditTime: 2021-04-15 19:35:00 * @LastEditTime: 2022-03-04 15:07:02
* @Description: file content * @Description: file content
*/ */
@ -47,6 +47,7 @@ export default {
sameEqError: '不能选择相同的设备!', sameEqError: '不能选择相同的设备!',
processList: { processList: {
processName: '工序名称', processName: '工序名称',
processCode: '工序编码',
processEq: '工序设备', processEq: '工序设备',
description: '描述', description: '描述',
addProcess: '添加一道工序', addProcess: '添加一道工序',

View File

@ -1,14 +1,8 @@
/* /*
* @Author: gtz * @Author: gtz
* @Date: 2021-03-04 16:13:51 * @Date: 2021-03-04 16:13:51
<<<<<<< HEAD
* @LastEditors: fzq
* @LastEditTime: 2022-03-06 19:53:27
=======
* @LastEditors: zwq * @LastEditors: zwq
* @LastEditTime: 2022-03-04 10:13:41 * @LastEditTime: 2022-03-07 09:14:33
>>>>>>> develop
* @Description: file content
*/ */
export default { export default {
visual: { visual: {
@ -307,6 +301,7 @@ export default {
BoxStatus: '箱状态', BoxStatus: '箱状态',
BoxNumber: '箱号', BoxNumber: '箱号',
PreviousOperation: '上一个工序', PreviousOperation: '上一个工序',
ExecutionOperation: '执行工序',
NextOperation: '下一个工序', NextOperation: '下一个工序',
CompletionTime: '完成时间', CompletionTime: '完成时间',
StartLocation: '开始库位', StartLocation: '开始库位',
@ -335,7 +330,8 @@ export default {
IsEmpty: '是否有基板', IsEmpty: '是否有基板',
IsEmptyBox: '是否空箱', IsEmptyBox: '是否空箱',
LocationName: '库位名', LocationName: '库位名',
LocationCode: '库位编码' LocationCode: '库位编码',
PerformTaskManual: '手动执行任务',
processStorageLink: '工序关联库位'
} }
} }

View File

@ -298,6 +298,21 @@ export const constantRoutes = [
import('@/views/basicData/Warehouse/HistoricalTask'), import('@/views/basicData/Warehouse/HistoricalTask'),
name: 'HistoricalTask', name: 'HistoricalTask',
meta: { title: routerTitle.Warehouse.HistoricalTask?.[language] || routerTitle.Warehouse.HistoricalTask.en, icon: 'form', affix: true, required: true, requireToken: true } meta: { title: routerTitle.Warehouse.HistoricalTask?.[language] || routerTitle.Warehouse.HistoricalTask.en, icon: 'form', affix: true, required: true, requireToken: true }
},
{
path: '/ProcessStorageManagement',
component: () =>
import('@/views/basicData/Warehouse/ProcessStorageManagement'),
name: 'ProcessStorageManagement',
meta: { title: routerTitle.Warehouse.ProcessStorageManagement?.[language] || routerTitle.Warehouse.ProcessStorageManagement.en, icon: 'form', affix: true, required: true, requireToken: true }
},
{
path: '/ProcessStorageManagementInfo',
hidden: true,
component: () =>
import('@/views/basicData/Warehouse/components/ProcessStorageManagement-info'),
name: 'ProcessStorageManagementInfo',
meta: { title: routerTitle.Warehouse.ProcessStorageManagement?.[language] || routerTitle.Warehouse.ProcessStorageManagement.en, icon: 'form', affix: true, required: true, requireToken: true }
} }
] ]
}, },

View File

@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2020-12-29 15:41:11 * @Date: 2020-12-29 15:41:11
* @LastEditors: zwq * @LastEditors: zwq
* @LastEditTime: 2022-01-14 15:54:12 * @LastEditTime: 2022-03-04 10:56:41
* @Description: * @Description:
--> -->
<template> <template>
@ -46,6 +46,7 @@
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="getList()"> {{ 'btn.search' | i18nFilter }} </el-button> <el-button type="primary" @click="getList()"> {{ 'btn.search' | i18nFilter }} </el-button>
<el-button type="primary" @click="manualTask()"> {{ $t('module.basicData.Warehouse.PerformTaskManual') | i18nFilter }} </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<base-table <base-table
@ -70,12 +71,14 @@
@pagination="getList()" @pagination="getList()"
/> />
<current-task-info v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getList" /> <current-task-info v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getList" />
<current-task-add v-if="manualTaskVisible" ref="manualTaskRef" @refreshDataList="getList" />
</div> </div>
</template> </template>
<script> <script>
import { CurrentTaskList } from '@/api/basicData/Warehouse/HistoricalTask' import { CurrentTaskList } from '@/api/basicData/Warehouse/HistoricalTask'
import CurrentTaskInfo from './components/CurrentTaskInfo.vue' import CurrentTaskInfo from './components/CurrentTaskInfo.vue'
import CurrentTaskAdd from './components/CurrentTask-add.vue'
import i18n from '@/lang' import i18n from '@/lang'
import BaseTable from '@/components/BaseTable' import BaseTable from '@/components/BaseTable'
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
@ -168,11 +171,12 @@ const tableProps = [
export default { export default {
name: 'ScrapInfo', name: 'ScrapInfo',
components: { Pagination, BaseTable, MethodBtn, CurrentTaskInfo }, components: { Pagination, BaseTable, MethodBtn, CurrentTaskInfo, CurrentTaskAdd },
data() { data() {
return { return {
trueWidth: 100, trueWidth: 100,
addOrUpdateVisible: false, addOrUpdateVisible: false,
manualTaskVisible: false,
tableProps, tableProps,
tableBtn, tableBtn,
list: [], list: [],
@ -237,6 +241,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.addOrUpdate.init(id) this.$refs.addOrUpdate.init(id)
}) })
},
//
manualTask() {
this.manualTaskVisible = true
this.$nextTick(() => {
this.$refs.manualTaskRef.init()
})
} }
} }
} }

View File

@ -0,0 +1,202 @@
<!--
* @Author: zwq
* @Date: 2020-12-29 15:41:11
* @LastEditors: zwq
* @LastEditTime: 2022-03-04 15:45:23
* @Description:
-->
<template>
<div class="app-container">
<el-form
ref="formData"
:rules="rules"
:model="listQuery"
:inline="true"
size="medium"
label-width="100px"
>
<el-form-item :label="$t('module.art.processList.processName')" prop="processId">
<el-select
v-model="listQuery.processId"
:placeholder="$i18nForm(['placeholder.input', $t('module.art.processList.processName')])"
clearable
filterable
:style="{width: '100%'}"
>
<el-option
v-for="(item, index) in processArr"
:key="index"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getList()"> {{ 'btn.search' | i18nFilter }} </el-button>
</el-form-item>
</el-form>
<base-table
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="list"
:is-loading="listLoading"
>
<method-btn
slot="handleBtn"
:width="trueWidth"
:method-list="tableBtn"
@clickBtn="handleClick"
/>
</base-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.current"
:limit.sync="listQuery.size"
@pagination="getList()"
/>
</div>
</template>
<script>
import { list } from '@/api/art-manage/process'
import BaseTable from '@/components/BaseTable'
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import { timeFormatter } from '@/filters'
import i18n from '@/lang'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableBtn = [
{
type: 'see',
btnName: i18n.t('module.basicData.Warehouse.processStorageLink')
}
]
const tableProps = [
{
prop: 'code',
label: i18n.t('module.art.processList.processCode'),
align: 'center'
},
{
prop: 'name',
label: i18n.t('module.art.processList.processName'),
align: 'center'
},
{
prop: 'createTime',
label: i18n.t('module.art.eqName'),
filter: timeFormatter,
align: 'center'
}
]
export default {
name: 'ExecutionInfo',
components: { Pagination, BaseTable, MethodBtn },
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'info',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
tableBtn,
trueWidth: 200,
tableProps,
list: [],
processArr: [],
total: 0,
listLoading: true,
rules: {},
listQuery: {
current: 1,
size: 10,
processId: ''
}
}
},
created() {
this.getList()
this.init()
},
methods: {
handleClick(raw) {
this.addNew(raw.data.id)
},
init() {
const lparams = {
current: 1,
size: 999
}
list(lparams).then(response => {
if (response.data.records) {
this.processArr = response.data.records
} else {
this.processArr.splice(0, this.list.length)
}
this.total = response.data.total
})
},
getList() {
// this.listLoading = true
// ExecutionInfoList(this.listQuery).then(response => {
// if (response.data.records) {
// this.list = response.data.records
// } else {
// this.list.splice(0, this.list.length)
// }
// this.total = response.data.total
this.list = [
{
code: 11,
name: '11'
}
]
this.listLoading = false
// })
},
// /
addNew(id) {
this.$router.push({
name: 'ProcessStorageManagementInfo',
query: {
dictTypeId: id
}
})
}
}
}
</script>
<style scoped>
.edit-input {
padding-right: 100px;
}
.cancel-btn {
position: absolute;
right: 15px;
top: 10px;
}
</style>

View File

@ -0,0 +1,125 @@
<!--
* @Author: zwq
* @Date: 2020-12-29 16:37:56
* @LastEditors: zwq
* @LastEditTime: 2022-03-04 11:05:23
* @Description:
-->
<template>
<el-dialog
:title="'btn.see' | i18nFilter"
:visible.sync="visible"
>
<el-row :gutter="10">
<el-form
ref="dataForm"
:model="dataForm"
size="medium"
label-width="110px"
label-position="left"
>
<el-col :span="12">
<el-row>
<el-col :span="24">
<el-form-item :label="$t('module.basicData.Warehouse.TaskBoxNumber')" prop="taskCode">
<el-input v-model="dataForm.taskCode" readonly :style="{width: '100%'}" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.basicData.Warehouse.FullBoxNumber')" prop="orderName">
<el-input v-model="dataForm.orderName" readonly :style="{width: '100%'}" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.basicData.Warehouse.ExecutionOperation')" prop="fullCode">
<el-input v-model="dataForm.fullCode" readonly :style="{width: '100%'}" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.basicData.Warehouse.TaskStatus')" prop="name">
<el-input v-model="dataForm.name" readonly :style="{width: '100%'}" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.basicData.ScrapInfo.remark')" prop="remark">
<el-input v-model="dataForm.remark" readonly :style="{width: '100%'}" />
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="12">
<el-row>
<el-col :span="24">
<el-form-item :label="$t('module.basicData.Warehouse.TaskLocation')" prop="createTime">
<el-input v-model="dataForm.createTime" readonly :style="{width: '100%'}" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.basicData.Warehouse.FullBoxStartLocation')" prop="taskType">
<el-input v-model="dataForm.taskType" readonly :style="{width: '100%'}" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.basicData.Warehouse.Priority')" prop="emptyCode">
<el-input v-model="dataForm.emptyCode" readonly :style="{width: '100%'}" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :label="$t('module.basicData.Warehouse.NextOperation')" prop="anotherCurrLocation">
<el-input
v-model="dataForm.anotherCurrLocation"
readonly
:style="{width: '100%'}"
/>
</el-form-item>
</el-col>
</el-row>
</el-col>
</el-form>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="visible = false">{{ $t('module.basicData.Warehouse.PerformTaskManual') | i18nFilter }} </el-button>
</span>
</el-dialog>
</template>
<script>
// import { CurrentTaskDetail } from '@/api/basicData/Warehouse/HistoricalTask'
export default {
data() {
return {
visible: false,
dataForm: {
id: '',
taskCode: undefined,
orderName: undefined,
fullCode: undefined,
name: undefined,
remark: undefined,
field119: undefined,
createTime: undefined,
taskType: undefined,
emptyCode: undefined,
anotherCurrLocation: undefined,
field121: undefined,
taskSource: undefined,
anotherCurrProcessCode: undefined,
anotherNextProcessCode: undefined,
anotherTargetLocation: undefined,
field126: undefined
}
}
},
methods: {
init(id) {
this.dataForm.id = id
this.visible = true
this.$nextTick(() => {
this.$refs['dataForm'].resetFields()
})
}
}
}
</script>

View File

@ -0,0 +1,166 @@
<!--
* @Author: zwq
* @Date: 2020-12-29 15:41:11
* @LastEditors: zwq
* @LastEditTime: 2022-03-04 16:01:28
* @Description:
-->
<template>
<div class="app-container">
<div style="margin:10px 50px">
<el-button type="success" @click="goback()">{{ 'btn.back' | i18nFilter }}</el-button>
<el-button type="primary" @click="addNew()">{{ 'btn.add' | i18nFilter }}</el-button>
</div>
<base-table
:page="listQuery.current"
:limit="listQuery.size"
:table-config="tableProps"
:table-data="list"
:is-loading="listLoading"
>
<method-btn
slot="handleBtn"
:width="trueWidth"
:method-list="tableBtn"
@clickBtn="handleClick"
/>
</base-table>
<processStorage-link v-if="addOrUpdateVisible" ref="addOrUpdate" :area-id="listQuery.areaId" @refreshDataList="getList" />
</div>
</template>
<script>
import i18n from '@/lang'
import processStorageLink from './processStorageLink.vue'
import BaseTable from '@/components/BaseTable'
import MethodBtn from '@/components/BaseTable/subcomponents/MethodBtn'
import { timeFormatter } from '@/filters'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
const tableBtn = [
{
type: 'delete',
btnName: 'btn.delete'
}
]
const tableProps = [
{
prop: 'code',
label: i18n.t('module.basicData.cache.LocationCode'),
filter: timeFormatter,
align: 'center'
},
{
prop: 'name',
label: i18n.t('module.basicData.cache.LocationName'),
align: 'center'
},
{
prop: 'shelfName',
label: i18n.t('module.basicData.cache.locationType'),
align: 'center'
}
]
export default {
name: 'Shelf',
components: { BaseTable, MethodBtn, processStorageLink },
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'info',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
addOrUpdateVisible: false,
tableBtn,
trueWidth: 200,
tableProps,
list: [],
listLoading: true,
listQuery: {
current: 1,
size: 990,
areaId: ''
}
}
},
created() {
this.listQuery.areaId = this.$route.query.id
this.getList()
},
methods: {
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(`${this.$t('module.basicData.visual.TipsBefore')}[${raw.data.name}]?`, this.$t('module.basicData.visual.Tips'), {
confirmButtonText: this.$t('module.basicData.visual.confirmButtonText'),
cancelButtonText: this.$t('module.basicData.visual.cancelButtonText'),
type: 'warning'
}).then(() => {
// shelfDelete(raw.data.id).then(response => {
// this.$message({
// message: this.$t('module.basicData.visual.success'),
// type: 'success',
// duration: 1500,
// onClose: () => {
// this.getList()
// }
// })
// })
}).catch(() => {})
}
},
getList(key) {
this.listLoading = true
// shelfList(this.listQuery).then(response => {
// if (response.data.records) {
// this.list = response.data.records
// } else {
// this.list.splice(0, this.list.length)
// }
this.listLoading = false
// })
},
// /
addNew(id) {
this.addOrUpdateVisible = true
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id)
})
},
goback() {
this.$router.go(-1)
}
}
}
</script>
<style scoped>
.edit-input {
padding-right: 100px;
}
.cancel-btn {
position: absolute;
right: 15px;
top: 10px;
}
</style>

View File

@ -0,0 +1,175 @@
<!--
* @Author: zwq
* @Date: 2020-12-29 16:37:56
* @LastEditors: zwq
* @LastEditTime: 2022-03-04 16:54:51
* @Description:
-->
<template>
<el-dialog
:title="$t('module.basicData.visual.stock') | i18nFilter"
:visible.sync="visible"
top="5vh"
>
<div>
<div class="mainDiv" style="margin:10px 0 100px">
<div class="title">货架一</div>
<div class="flexDiv">
<div
v-for="count in 5"
:key="count"
class="wareBox"
:class="[
count > Math.round(Math.random() * 10) ? 'enableBox' : 'disableBox',
{ active: count === isActive }
]"
@click="selectBox(count)"
>
<div class="plat">库位{{ count }}</div>
</div>
</div>
<div class="flexDiv">
<div
v-for="count in 5"
:key="count"
class="wareBox"
:class="[
count > Math.round(Math.random() * 10) ? 'enableBox' : 'disableBox',
{ active: count + 5 === isActive }
]"
@click="selectBox(count + 5)"
>
<div class="plat">库位{{ count + 5 }}</div>
</div>
</div>
</div>
<div class="line" />
<div class="mainDiv" style="margin:100px 0 10px">
<div class="title">货架二</div>
<div class="flexDiv">
<div
v-for="count in 5"
:key="count"
class="wareBox"
:class="[
count > Math.round(Math.random() * 10) ? 'enableBox' : 'disableBox',
{ active: count+10 === isActive }
]"
@click="selectBox(count+10)"
>
<div class="plat">库位{{ count+10 }}</div>
</div>
</div>
<div class="flexDiv">
<div
v-for="count in 5"
:key="count"
class="wareBox"
:class="[
count > Math.round(Math.random() * 10) ? 'enableBox' : 'disableBox',
{ active: count+15 === isActive }
]"
@click="selectBox(count+15)"
>
<div class="plat">库位{{ count+15 }}</div>
</div>
</div>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">{{ 'btn.cancel' | i18nFilter }}</el-button>
<el-button type="primary" @click="dataFormSubmit()">{{ 'btn.confirm' | i18nFilter }}</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
data() {
return {
visible: false,
isActiveArr: []
}
},
methods: {
init() {
this.visible = true
},
selectBox(count) {
this.isActive.push(count)
},
//
dataFormSubmit() {
this.visible = false
}
}
}
</script>
<style scoped>
.mainDiv {
border: 2px solid rgb(145, 174, 255);
padding: 20px 0;
}
.flexDiv {
display: -webkit-flex;
display: flex;
-webkit-justify-content: space-around;
justify-content: space-around;
}
.title {
float: left;
width: 50px;
font-size: 40px;
line-height: 45px;
}
/* 边框特效 */
.wareBox:hover {
background: linear-gradient(to left, deepskyblue, deepskyblue) left top
no-repeat,
linear-gradient(to bottom, deepskyblue, deepskyblue) left top no-repeat,
linear-gradient(to left, deepskyblue, deepskyblue) right top no-repeat,
linear-gradient(to bottom, deepskyblue, deepskyblue) right top no-repeat,
linear-gradient(to left, deepskyblue, deepskyblue) left bottom no-repeat,
linear-gradient(to bottom, deepskyblue, deepskyblue) left bottom no-repeat,
linear-gradient(to left, deepskyblue, deepskyblue) right bottom no-repeat,
linear-gradient(to left, deepskyblue, deepskyblue) right bottom no-repeat;
background-size: 5px 30px, 30px 5px;
color: black;
border-radius: 5px;
background-color: rgb(190, 224, 241);
}
.wareBox {
cursor: pointer;
margin: 10px;
height: 80px;
line-height: 70px;
text-align: center;
border: 2px solid #cdcdc5;
border-radius: 5px;
}
.plat {
min-width: 80px;
}
.line {
margin: 20px 0;
height: 2px;
background-color: gray;
border-left: 200px solid #ddd;
border-right: 200px solid #ddd;
}
.enableBox {
background: rgb(0, 189, 16);
}
.disableBox {
background: #ddd;
cursor: not-allowed;
}
.end-plat {
background-color: rgb(195, 246, 255);
}
.active {
border: 2px solid red;
}
</style>