Files
SoonWorkerD/src/renderer/views/dashboard/index.vue
T
2024-11-30 17:29:57 +08:00

1350 lines
46 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="container_box">
<!-- 头部 -->
<div class="flex_box flex_row_between top_box">
<div class="flex_box top_left">
<div @click="showWork" class="flex_box flex_row_center top_btn1">
<img src="@/assets/images/Plus1_icon.png" />
<div>新建作业</div>
</div>
<div @click="openWork" class="flex_box flex_row_center top_btn2">
<img src="@/assets/images/Search_icon.png" />
<div>打开作业文件</div>
</div>
<div @click="goSet('/manage')" class="flex_box flex_row_center top_btn2">
<img src="@/assets/images/Setting_icon.png" />
<div>系统设置</div>
</div>
<div class="top_left_line"></div>
<el-tooltip :content="workStatus?'关闭服务':'打开服务'" placement="bottom">
<div class="flex_box flex_row_center top_left_status_box">
<el-switch :disabled="!serviceStatus" @change="serviceChange" class="top_left_status" v-model="workStatus" active-color="#07C160" inactive-color="#aaa"> </el-switch>
</div>
</el-tooltip>
<div class="flex_box top_left_option">
<div class="top_left_text">完成拷贝数:</div>
<div class="top_left_num">{{ task_list.length }}</div>
</div>
<div class="flex_box top_left_option">
<div class="top_left_text">废弃拷贝数:</div>
<div class="top_left_num top_left_num1">0</div>
</div>
<div class="flex_box top_left_option">
<div class="top_left_text">错误:</div>
<div class="top_left_num">0</div>
</div>
<div class="top_left_line"></div>
</div>
<user-info></user-info>
</div>
<div class="content_body">
<!-- 设备 -->
<div class="flex_box device_box">
<!-- 左侧 -->
<div class="device_left">
<div class="flex_box device_left_top">
<img v-if="!printer_info.cover_flag" class="flex_shrink device_img" src="@/assets/images/device.png" />
<img v-else class="flex_shrink device_img" src="@/assets/images/device-open.png" />
<div class="flex_box flex_row_between device_info">
<div class="device_info_box">
<div class="device_info_main" :class="{ device_info_main1: infoStatus === 1 }">
<div class="device_info_item">
<div class="device_info_title">卡树光盘刻录一体机{{ printer_info.printer_name }}</div>
<div class="device_info_sure">
<div v-if="currentRunVal === 6" class="flex_box flex_row_between device_info_sure_box">
<div class="device_info_sure_text">{{ sureText }}</div>
<el-button @click="sureCD" class="device_info_sure_btn" type="primary">确定</el-button>
</div>
</div>
<div class="flex_box device_info_options">
<div class="device_info_option">
<div class="device_info_option_box">
<img src="@/assets/images/device4.png" />
<div class="device_info_option_cap">
<div
class="device_info_option_cap_box"
:class="{ 'device_info_option_cap_box1': printer_info.strongList[2].cd_num < 30, 'device_info_option_cap_box2': printer_info.strongList[2].cd_num < 10 }"
:style="{ height: $accDiv(printer_info.strongList[2].cd_num, 50) * 100 + '%' }"
></div>
</div>
</div>
<div class="flex_box flex_row_center">
<el-dropdown trigger="click" :disabled="currentRunVal !== 6" @command="(e) => handleCommandCD(e, 2)">
<div class="el-dropdown-link flex_box flex_row_center device_info_option_b">
<div class="device_info_option_b_text">{{ CDTypes[printer_info.strongList[2].cd_type] }} {{ printer_info.strongList[2].cd_num }}</div>
<i v-if="currentRunVal === 6" class="el-icon-caret-bottom"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="(item, index) in CDTypes" :key="index" :command="index"><span :style="{'color': index === printer_info.strongList[2].cd_type ? '#409EFF' : '#000', 'font-weight': index === printer_info.strongList[2].cd_type ? '600' : '400' }">{{ item }}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
<div class="device_info_option">
<div class="device_info_option_box">
<img src="@/assets/images/device4.png" />
<div class="device_info_option_cap">
<div
class="device_info_option_cap_box"
:class="{ 'device_info_option_cap_box1': printer_info.strongList[1].cd_num < 30, 'device_info_option_cap_box2': printer_info.strongList[1].cd_num < 10 }"
:style="{ height: $accDiv(printer_info.strongList[1].cd_num, 50) * 100 + '%' }"
></div>
</div>
</div>
<div class="flex_box flex_row_center">
<el-dropdown trigger="click" :disabled="currentRunVal !== 6" @command="(e) => handleCommandCD(e, 1)">
<div class="el-dropdown-link flex_box flex_row_center device_info_option_b">
<div class="device_info_option_b_text">{{ CDTypes[printer_info.strongList[1].cd_type] }} {{ printer_info.strongList[1].cd_num }}</div>
<i v-if="currentRunVal === 6" class="el-icon-caret-bottom"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="(item, index) in CDTypes" :key="index" :command="index"><span :style="{'color': index === printer_info.strongList[1].cd_type ? '#409EFF' : '#000', 'font-weight': index === printer_info.strongList[1].cd_type ? '600' : '400' }">{{ item }}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
<div class="device_info_option">
<div class="flex_box flex_row_between device_info_option_list">
<div class="device_info_option_item device_info_option_blue">
<div :style="{ height: parseInt(printer_info.blue_last) + '%' }" class="device_info_option_content"></div>
</div>
<div class="device_info_option_item device_info_option_red">
<div :style="{ height: parseInt(printer_info.red_last) + '%' }" class="device_info_option_content"></div>
</div>
<div class="device_info_option_item device_info_option_yellow">
<div :style="{ height: parseInt(printer_info.yellow_last) + '%' }" class="device_info_option_content"></div>
</div>
</div>
<div v-if="!isLast" @click="isLast = true" class="flex_box flex_row_between device_info_option_b">
<div class="device_info_option_b_text device_info_option_b_text1">{{ parseInt(printer_info.blue_last) }}%</div>
<div class="device_info_option_b_text device_info_option_b_text1">{{ parseInt(printer_info.red_last) }}%</div>
<div class="device_info_option_b_text device_info_option_b_text1">{{ parseInt(printer_info.yellow_last) }}%</div>
</div>
<div v-if="isLast" @click="isLast = false" class="flex_box flex_row_center device_info_option_b">
<div class="device_info_option_b_text device_info_option_b_text1">{{ $accDiv($accAdd($accAdd(printer_info.blue_last,printer_info.red_last),printer_info.yellow_last),3).toFixed(2) }}%</div>
</div>
</div>
</div>
</div>
<div class="device_info_item">
<div class="device_info_text">系统序列号</div>
<div class="device_info_text">主机名{{ printer_info.system_name }}</div>
<div class="device_info_text">主机IP{{ printer_info.system_ip }}</div>
<div class="device_info_text">缓存空间0G共0G</div>
</div>
</div>
</div>
<div class="device_info_right">
<div v-if="infoStatus === 1" @click="infoStatus = 0" class="device_info_right_item">
<img src="@/assets/images/Arrow_right1_icon.png" />
</div>
<div v-if="infoStatus === 0" @click="infoStatus = 1" class="device_info_right_item">
<img src="@/assets/images/Arrow_left1_icon.png" />
</div>
</div>
</div>
</div>
<!-- <div class="flex_box device_status" :class="`flex_box device_status device_status${printer_info.printer_status} device_status${printer_info.cover_flag}`"> -->
<div class="flex_box device_status" :class="{ 'device_status1': printer_info.printer_status === 'I', 'device_status2': printer_info.printer_status === 'B' || printer_info.printer_status === 'P', 'device_status3': printer_info.cover_flag || printer_info.calibration_flag || !isConnect || !serviceStatus }">
<div class="device_status_dot"></div>
<div class="device_status_text">{{ runText }}</div>
</div>
<div class="flex_box device_run">
<div class="flex_box device_run_input">
<el-select v-model="runVal" placeholder="请选择">
<el-option v-for="item in runList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</div>
<el-button @click="handleRun" type="primary" class="device_run_btn">执行</el-button>
</div>
</div>
<!-- 右侧 -->
<div class="device_right">
<div class="flex_box device_right_top">
<div class="flex_box flex_row_between device_right_top_item">
<div class="device_right_top_img">
<img v-if="cd_list[0].cd_status == 4" src="@/assets/images/device3.png" />
<img v-if="cd_list[0].cd_status != 4" src="@/assets/images/device2.png" />
<div class="device_right_top_img_text" v-if="cd_list[0].cd_status != 4">{{ diskTypes[cd_list[0].dev_type] }}</div>
<div class="device_right_top_img_text device_right_top_img_text1" v-if="cd_list[0].cd_status == 4">{{ CDTypes[cd_list[0].cd_type] }}</div>
</div>
<div class="device_right_top_content">
<div class="device_right_top_title">{{ cd_list[0].dev_path || '' }}({{ $store.state.chat.CDName[cd_list[0].cd_pos] }})</div>
<template v-if="cd_list[0].copy_scheduler > 0">
<div class="flex_box device_right_top_progress">
<div class="device_right_top_progress_box" :style="{ 'width': cd_list[0].copy_scheduler + '%' }"></div>
</div>
<div class="device_right_top_text">已刻录{{ $filterSize(cd_list[0].use_size) }}{{ $filterSize(cd_list[0].total_size) }}<span v-if="cd_list[0].burn_speed">速度{{ cd_list[0].burn_speed.toFixed(2) }}X</span></div>
</template>
<div class="device_right_top_text">状态{{ $store.state.chat.CDStatus[cd_list[0].cd_status] }}</div>
<div class="device_right_top_text">任务{{ cd_list[0].cd_taskid && cd_list[0].copy_scheduler ? cd_list[0].cd_taskid : '' }}</div>
<div class="device_right_top_text">光盘{{ cd_list[0].cd_assid && cd_list[0].copy_scheduler ? cd_list[0].cd_assid : '' }}</div>
</div>
</div>
<div class="device_right_top_line"></div>
<div class="flex_box flex_row_between device_right_top_item">
<div class="device_right_top_img">
<img v-if="cd_list[1].cd_status == 4" src="@/assets/images/device3.png" />
<img v-if="cd_list[1].cd_status != 4" src="@/assets/images/device2.png" />
<div class="device_right_top_img_text" v-if="cd_list[1].cd_status != 4">{{ diskTypes[cd_list[1].dev_type] }}</div>
<div class="device_right_top_img_text device_right_top_img_text1" v-if="cd_list[1].cd_status == 4">{{ CDTypes[cd_list[1].cd_type] }}</div>
</div>
<div class="device_right_top_content">
<div class="device_right_top_title">{{ cd_list[1].dev_path || '' }}({{ $store.state.chat.CDName[cd_list[1].cd_pos] }})</div>
<template v-if="cd_list[1].copy_scheduler">
<div class="flex_box device_right_top_progress">
<div class="device_right_top_progress_box" :style="{ 'width': cd_list[1].copy_scheduler + '%' }"></div>
</div>
<div class="device_right_top_text">已刻录{{ $filterSize(cd_list[1].use_size) }}{{ $filterSize(cd_list[1].total_size) }}<span v-if="cd_list[1].burn_speed">速度{{ cd_list[1].burn_speed.toFixed(2) }}X</span></div>
</template>
<div class="device_right_top_text">状态{{ $store.state.chat.CDStatus[cd_list[1].cd_status] }}</div>
<div class="device_right_top_text">任务{{ cd_list[1].cd_taskid && cd_list[1].copy_scheduler ? cd_list[1].cd_taskid : '' }}</div>
<div class="device_right_top_text">光盘{{ cd_list[1].cd_assid && cd_list[1].copy_scheduler ? cd_list[1].cd_assid : '' }}</div>
</div>
</div>
</div>
<div class="notice_box">
<div class="flex_box flex_row_between notice_top">
<div class="flex_box notice_title">
<img src="@/assets/images/inform1_icon.png" />
<div>动态</div>
</div>
<div @click="noticeChange" class="flex_box notice_all">
<img src="@/assets/images/Calendar_icon.png" />
<div>{{ showAll ? '最新日志' : '全部日志' }}</div>
</div>
</div>
<div class="notice_list">
<template v-if="!showAll">
<div v-for="(item, index) in logList" :key="index" :class="`flex_box flex_row_between notice_item notice_${item.status}`">
<div class="notice_content">
<span>{{ index + 1 }}</span
>[{{ item.status }}]{{ item.text }}
</div>
<div class="notice_time">{{ item.time }}</div>
</div>
</template>
<template v-if="showAll">
<div v-for="(item, index) in allLogList" :key="index" :class="`flex_box flex_row_between notice_item notice_${item.status}`">
<div class="notice_content">
<span>{{ index + 1 }}</span
>[{{ item.status }}]{{ item.text }}
</div>
<div class="notice_time">{{ item.time }}</div>
</div>
</template>
</div>
</div>
</div>
</div>
<!-- 作业队列 -->
<div class="work_box">
<div class="flex_box work_top">
<div class="work_top_text">作业列表</div>
</div>
<el-table row-key="task_uuid" default-expand-all class="work_table" :data="task_list" empty-text="暂无作业列表" :tree-props="{children: 'ass_task', hasChildren: 'hasChildren'}">
<!-- <el-table-column type="index" width="80" label="序号"></el-table-column> -->
<el-table-column prop="task_uuid" label="作业ID"></el-table-column>
<el-table-column prop="task_name" label="任务名称"></el-table-column>
<!-- <el-table-column prop="DataSource" label="来源"></el-table-column> -->
<el-table-column label="类型">
<template slot-scope="scope">
<div>{{ scope.row.ass_task&&scope.row.ass_task[0]&&CDTypes[scope.row.ass_task[0].cd_type] }}</div>
</template>
</el-table-column>
<el-table-column prop="task_size" label="大小">
<template slot-scope="scope">
<div>{{ $filterSize(scope.row.task_size) }}</div>
</template>
</el-table-column>
<el-table-column prop="start_time" label="开始时间"></el-table-column>
<el-table-column prop="finish_time" label="结束时间"></el-table-column>
<el-table-column label="完成">
<template slot-scope="scope">
<div>{{ scope.row.finish_freq }}/{{ scope.row.total_freq }}</div>
</template>
</el-table-column>
<el-table-column prop="task_status" label="状态">
<template slot-scope="scope">
<div class="flex_box work_status_box">
<div>{{ statusList[scope.row.task_status] }}</div>
<!-- <i class="el-icon-caret-bottom"></i> -->
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
<!-- 底部 -->
<div class="flex_box flex_row_center footer_box">
<div>Copyright @ 2023 CARDSOON Corporation</div>
<div class="footer_line"></div>
<div class="footer_text">帮助</div>
<div class="footer_line"></div>
<div class="footer_text">关于我们</div>
</div>
<!-- 新建作业 -->
<work-add v-if="workShow" @close="workShow=false" ref="workAdd"></work-add>
</div>
</template>
<script>
let that
let outTimer
import { mapGetters } from 'vuex'
import UserInfo from '@/components/userInfo/userInfo.vue'
import WorkAdd from '@/components/workAdd/workAdd.vue'
export default {
name: 'dashboard',
components: { UserInfo, WorkAdd },
data() {
return {
// 服务状态
isConnect: false,
serviceStatus: false,
// 工作状态
infoStatus: 0,
// 运行选项
runVal: '',
currentRunVal: '',
sureText: '请设置左右盘仓类型并按确定键',
sureTime: 0,
runList: [
{
value: 1,
label: '重启打印机'
},
{
value: 2,
label: '清除错误'
},
{
value: 3,
label: '校准盘仓'
},
{
value: 4,
label: '校准打印机'
},
{
value: 5,
label: '自动匹配光驱'
},
{
value: 6,
label: '设置左右盘仓'
},
{
value: 7,
label: '进入运输模式'
}
],
// 剩余容量
progressW: 75,
// 作业列表
task_list: [],
statusList: {
0: '新建中',
1: '准备中',
2: '等待中',
3: '正在拷贝',
4: '正在打印',
5: '已失败',
6: '运行中',
100: '已完成'
},
// 设备信息
printer_info: {},
isLast: false,
// 光盘信息
default_cd: {},
diskTypes: {},
CDTypes: {},
cd_list: [],
// 光盘更换命令
changeCD: {
req_name: 'setCDStrong',
req_type: 2,
req_info: {
strong_list: [
{
strong_pos: 1,
strong_type: 1
},
{
strong_pos: 2,
strong_type: 1
}
]
}
},
// 日志信息
logList: [],
allLogList: [],
showAll: false,
workShow: false
}
},
watch: {
'$store.state.chat.task_list': {
handler(val) {
if (val && val.length) {
let tasks = [...val]
let list = []
tasks.forEach((item, index) => {
if (item.ass_task&&item.ass_task.length) {
let task_size = 0
item.ass_task.forEach((item2, idx) => {
item2.task_uuid = item.task_uuid+'_'+(idx+1)
item2.task_name = item.task_name+'_'+(idx+1)
task_size = this.$accAdd(task_size, item2.task_size)
})
item.task_size = task_size
}
list.push(item)
})
this.task_list = list
}
},
deep: true,
immediate: true
},
'$store.state.chat.printer_info': {
handler(val) {
this.default_cd = val.strongList
this.printer_info = { ...val }
},
deep: true,
immediate: true
},
'$store.state.chat.diskTypes': {
handler(val) {
this.diskTypes = { ...val }
},
deep: true,
immediate: true
},
'$store.state.chat.CDTypes': {
handler(val) {
this.CDTypes = { ...val }
},
deep: true,
immediate: true
},
'$store.state.chat.cd_list': {
handler(val) {
this.cd_list = [...val]
},
deep: true,
immediate: true
},
'$store.state.chat.logList': {
handler(val) {
this.logList = [...val]
},
deep: true,
immediate: true
},
'$store.state.chat.allLogList': {
handler(val) {
this.allLogList = [...val]
},
deep: true,
immediate: true
},
'$store.state.chat.isConnect': {
handler(val) {
this.isConnect = val
},
deep: true,
immediate: true
},
'$store.state.chat.serviceStatus': {
handler(val) {
this.serviceStatus = val
},
deep: true,
immediate: true
}
},
computed: {
...mapGetters(['name', 'roles']),
runText() {
let text = this.$store.state.chat.PrinterStatus[this.printer_info.printer_status]
if (this.printer_info.cover_flag) {
text = '设备门盖被打开,请关闭门盖。'
}
if (this.printer_info.calibration_flag) {
text = '请先校准打印机'
this.runVal = 4
}
if (!this.isConnect) {
text = '服务已关闭'
}
if (!this.serviceStatus) {
text = '正在连接服务器,请检查服务器是否正常'
}
return text
},
workStatus() {
return this.isConnect&&this.serviceStatus
},
},
mounted() {
that = this
},
methods: {
// 服务打开/关闭
serviceChange(e) {
if (!that.serviceStatus) {
return
}
if (e) {
that.store.commit('setData', { name: 'workStatus', data: true })
setTimeout(() => {
that.$store.dispatch('chat/initWebSocket')
}, 500);
} else {
that.store.commit('setData', { name: 'workStatus', data: false })
setTimeout(() => {
that.$store.dispatch('chat/closeWebsocket')
}, 500);
}
},
// 执行
handleRun() {
if (!that.workStatus) {
that.$message({
message: '请先连接服务',
type: 'warning'
})
return
}
if (!that.runVal) {
that.$message({
message: '请先选择需要执行的操作',
type: 'warning'
})
return
}
// that.$message({
// message: that.runList[index].label,
// type: 'success'
// })
clearTimeout(outTimer)
switch (that.runVal) {
case 1:
// 重启打印机
that.$store.dispatch('chat/websocketsend', {
req_name: 'resetPrinter',
req_type: 1,
req_info: {}
}).then(() => {
that.$message({
message: '重启设备执行成功',
type: 'success'
})
}).catch(() => {
that.$message({
message: '重启设备执行失败,请重新尝试',
type: 'error'
})
})
break;
case 2:
// 清除错误
that.$store.dispatch('chat/websocketsend', {
req_name: 'cleanError',
req_type: 1,
req_info: {}
}).then(() => {
that.$message({
message: '清除错误执行成功',
type: 'success'
})
}).catch(() => {
that.$message({
message: '清除错误执行失败,请重新尝试',
type: 'error'
})
})
break;
case 3:
// 校准盘仓
that.$store.dispatch('chat/websocketsend', {
req_name: 'CaliCDStone',
req_type: 1,
req_info: {}
}).then(() => {
that.$message({
message: '校准盘仓执行成功',
type: 'success'
})
}).catch(() => {
that.$message({
message: '校准盘仓执行失败,请重新尝试',
type: 'error'
})
})
break;
case 4:
// 校准打印机
that.$store.dispatch('chat/websocketsend', {
req_name: 'CaliPrinter',
req_type: 1,
req_info: {}
}).then(() => {
that.$message({
message: '校准打印机执行成功',
type: 'success'
})
}).catch(() => {
that.$message({
message: '校准打印机执行失败,请重新尝试',
type: 'error'
})
})
break;
case 5:
// 自动匹配光驱
that.$store.dispatch('chat/websocketsend', {
req_name: 'autoSetCDDev',
req_type: 1,
req_info: {}
}).then(() => {
that.$message({
message: '自动匹配光驱执行成功',
type: 'success'
})
}).catch(() => {
that.$message({
message: '自动匹配光驱执行失败,请重新尝试',
type: 'error'
})
})
break;
case 6:
outTimer = setTimeout(() => {
that.currentRunVal = 0
that.printer_info.strongList = that.default_cd
}, 120000);
break;
}
that.currentRunVal = that.runVal
},
// 更换左右磁盘类型
handleCommandCD(e, type) {
that.printer_info.strongList[type].cd_type = e
that.changeCD.req_info.strong_list[type-1].strong_type = e
},
sureCD() {
that.$store.dispatch('chat/websocketsend', that.changeCD).then(() => {
clearTimeout(outTimer)
that.currentRunVal = 0
}).catch(() => {
clearTimeout(outTimer)
that.currentRunVal = 0
})
},
// 新建作业
showWork() {
if (!that.workStatus) {
that.$message({
message: '请先连接服务',
type: 'warning'
})
return
}
that.workShow = true
that.$nextTick(() => {
that.$refs.workAdd.show()
})
},
// 打开作业文件
openWork() {
if (!that.workStatus) {
that.$message({
message: '请先连接服务',
type: 'warning'
})
return
}
},
// 显示日志
noticeChange() {
if (!that.workStatus) {
that.$message({
message: '请先连接服务',
type: 'warning'
})
return
}
that.showAll = !that.showAll
},
// 跳转设置
goSet(e) {
that.$router.push({ path: e })
},
// 退出登录
goOut() {
this.$store.dispatch('FedLogOut').then(() => {
location.reload()
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
$green: #00c325;
$yellow: #f5a623;
$red: #ff0000;
.container_box {
height: 100vh;
.top_box {
height: 78px;
padding: 0 32px;
background-color: #ffffff;
.top_left {
.top_btn1 {
cursor: pointer;
padding: 0 16px;
height: 40px;
background: #00c325;
border-radius: 6px;
margin-right: 16px;
font-weight: 500;
font-size: 18px;
color: #ffffff;
img {
width: 18px;
height: 18px;
margin-right: 8px;
}
}
.top_btn2 {
cursor: pointer;
padding: 0 16px;
height: 40px;
background: rgba(0, 195, 37, 0.12);
border: 2px solid rgba(0, 195, 37, 0.32);
border-radius: 6px;
margin-right: 16px;
font-weight: 500;
font-size: 18px;
color: #00c325;
img {
width: 18px;
height: 18px;
margin-right: 8px;
}
}
.top_left_line {
width: 2px;
height: 40px;
background: #e0e0e0;
margin: 0 16px;
}
.top_left_status_box {
width: 90px;
.top_left_status {
padding: 0 16px;
zoom: 1.3;
}
}
.top_left_option {
margin-left: 16px;
.top_left_text {
font-weight: 500;
font-size: 18px;
color: #000000;
text-decoration: underline;
}
.top_left_num {
padding: 0 10px;
height: 28px;
background: #00c325;
border-radius: 6px;
font-weight: 500;
font-size: 18px;
color: #ffffff;
line-height: 28px;
margin-left: 12px;
}
.top_left_num1 {
background: #b8b8b8;
}
}
}
}
.content_body {
background-color: #f8f8f8;
padding: 0 100px;
}
.device_box {
padding: 16px 0;
background-color: #f8f8f8;
.device_left {
width: 50%;
padding: 0 45px;
.device_left_top {
margin-bottom: 24px;
.device_img {
width: 255px;
margin-right: 35px;
}
.device_info {
width: calc(100% - 290px);
.device_info_box {
width: calc(100% - 40px);
overflow: hidden;
.device_info_main {
white-space: nowrap;
transition: all 0.5s;
.device_info_item {
width: 100%;
display: inline-block;
.device_info_text {
font-weight: 500;
font-size: 19px;
color: #000000;
line-height: 38px;
}
.device_info_title {
font-weight: bold;
font-size: 25px;
color: #000000;
line-height: 38px;
}
.device_info_sure {
height: 42px;
.device_info_sure_box {
width: 100%;
height: 100%;
}
.device_info_sure_text {
font-size: 15px;
color: $green;
}
.device_info_sure_btn {
width: 80px;
height: 30px;
line-height: 30px;
padding: 0;
background: #00bcc3;
border-radius: 6px;
font-weight: 500;
font-size: 16px;
margin: 0;
color: #ffffff;
}
}
.device_info_options {
.device_info_option {
padding: 0 10px;
margin-right: 40px;
&:last-child {
margin-right: 0;
}
.device_info_option_box {
width: 84px;
height: 67px;
margin: 0 auto;
position: relative;
img {
width: 100%;
}
.device_info_option_cap {
position: absolute;
left: 20px;
bottom: 20px;
width: 42px;
height: 47px;
z-index: 3;
.device_info_option_cap_box {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 0;
background-color: $green;
border-radius: 4px;
z-index: 4;
}
.device_info_option_cap_box1 {
background-color: $yellow;
}
.device_info_option_cap_box2 {
background-color: $red;
}
}
}
.device_info_option_img {
width: 118px;
height: 67px;
}
.device_info_option_b {
height: 30px;
padding-top: 10px;
font-size: 24px;
cursor: pointer;
.device_info_option_b_text {
font-weight: 500;
font-size: 18px;
color: #000000;
}
.device_info_option_b_text1 {
width: 36px;
text-align: center;
font-size: 16px;
}
.el-icon-caret-bottom {
transition: all 0.5s;
}
}
.device_info_option_b1 {
.el-icon-caret-bottom {
transform: rotate(90deg);
}
}
.device_info_option_list {
width: 130px;
.device_info_option_item {
width: 36px;
height: 67px;
border-radius: 2px;
background: linear-gradient(270deg, #e1fbfe 0%, #ffffff 50%, #e5f9ff 100%);
border: 1px solid #b1cdd0;
position: relative;
.device_info_option_content {
position: absolute;
bottom: 0;
left: 0;
width: 34px;
height: 32px;
}
}
.device_info_option_blue {
background: linear-gradient(270deg, #e1fbfe 0%, #ffffff 50%, #e5f9ff 100%);
border: 1px solid #b1cdd0;
.device_info_option_content {
background: linear-gradient(90deg, #279fd0 0%, #80e1f7 48%, #2fb0e0 100%);
}
}
.device_info_option_red {
background: linear-gradient(270deg, #fbe5f7 0%, #ffffff 50%, #f6e1f1 100%);
border: 1px solid #e6bcd6;
.device_info_option_content {
background: linear-gradient(90deg, #d02886 0%, #f56abe 48%, #d02991 100%);
}
}
.device_info_option_yellow {
background: linear-gradient(270deg, #fefdc5 0%, #ffffff 50%, #fefdc5 100%);
border: 1px solid #eaecc6;
.device_info_option_content {
background: linear-gradient(90deg, #f7ea32 0%, #fefaaa 48%, #f8e94b 100%);
}
}
}
}
}
}
}
.device_info_main1 {
transform: translateX(-100%);
}
}
.device_info_right {
.device_info_right_item {
width: 28px;
padding: 8px 0;
cursor: pointer;
img {
width: 28px;
height: 28px;
}
}
}
}
}
.device_status {
height: 44px;
background: #ffffff;
border-radius: 4px;
margin-bottom: 24px;
padding: 0 18px;
.device_status_dot {
width: 22px;
height: 22px;
border-radius: 50%;
background: #e54d4d;
margin-right: 18px;
}
.device_status_text {
font-weight: 500;
font-size: 19px;
color: #e54d4d;
line-height: 30px;
}
}
.device_status1 {
.device_status_dot {
background-color: $green;
}
.device_status_text {
color: $green;
}
}
.device_status2 {
.device_status_dot {
background-color: $yellow;
}
.device_status_text {
color: $yellow;
}
}
.device_status3 {
.device_status_dot {
background-color: $red;
}
.device_status_text {
color: $red;
}
}
.device_run {
width: 100%;
height: 44px;
overflow: hidden;
background: #ffffff;
box-shadow: 0px 5 9px 2px rgba(102, 102, 102, 0.18);
border-radius: 6px;
.device_run_input {
width: calc(100% - 140px);
height: 44px;
border: 2px solid #00bcc3;
overflow: hidden;
border-radius: 6px 0 0 6px;
.el-select {
width: 100%;
padding-left: 10px;
::v-deep {
.el-input__inner {
border: none;
font-weight: 500;
background-color: transparent;
font-size: 20px;
height: 40px;
line-height: 40px;
color: #000000;
}
.el-input__icon {
height: 40px;
font-size: 20px;
line-height: 40px;
font-weight: bold;
color: #000;
}
}
}
}
.device_run_btn {
width: 140px;
height: 44px;
background: #00bcc3;
border-radius: 0px 6px 6px 0px;
font-weight: 500;
font-size: 19px;
margin: 0;
color: #ffffff;
}
}
}
.device_right {
width: 50%;
.device_right_top {
height: 200px;
background: #ffffff;
border-radius: 4px;
margin-bottom: 18px;
padding: 0 24px;
.device_right_top_item {
width: calc(50% - 25px);
.device_right_top_img {
width: 120px;
height: 120px;
position: relative;
img {
width: 100%;
height: 100%;
}
.device_right_top_img_text {
position: absolute;
background: #000;
border-radius: 4px;
padding: 4px 10px;
font-size: 18px;
font-weight: 500;
color: #fff;
text-align: center;
left: 15px;
bottom: 45px;
}
.device_right_top_img_text1 {
left: 0;
bottom: 0;
padding: 6px;
font-size: 18px;
width: 100%;
}
}
.device_right_top_content {
width: calc(100% - 136px);
.device_right_top_title {
font-weight: 500;
font-size: 19px;
color: #000000;
line-height: 34px;
}
.device_right_top_text {
font-weight: 500;
font-size: 16px;
color: #666666;
line-height: 30px;
}
.device_right_top_progress {
height: 18px;
background: #ffffff;
border-radius: 3px;
border: 2px solid #707070;
margin: 2px 0 2px;
.device_right_top_progress_box {
width: 0;
height: 15px;
background: #00c325;
transition: all 0.5s;
}
}
}
}
.device_right_top_line {
width: 2px;
height: 150px;
background: #e1f5e5;
margin: 0 24px;
}
}
.notice_box {
background: #ffffff;
border-radius: 6px;
.notice_top {
height: 75px;
padding: 0 30px;
border-bottom: 2px solid #e1f5e5;
.notice_title {
font-weight: 500;
font-size: 19px;
color: #000000;
img {
width: 28px;
height: 28px;
margin-right: 18px;
}
}
.notice_all {
font-weight: 500;
font-size: 19px;
color: #00c325;
cursor: pointer;
img {
width: 28px;
height: 28px;
margin-right: 18px;
}
}
}
.notice_list {
height: 200px;
overflow-y: scroll;
padding: 6px;
::-webkit-scrollbar {
width: 6px; /* 设置滚动条的宽度 */
height: 6px;
}
/* 滚动条滑块样式 */
::-webkit-scrollbar-thumb {
background-color: #b5b5b5; /* 设置滑块背景颜色 */
}
/* 滚动条轨道hover状态样式 */
::-webkit-scrollbar-track:hover {
background-color: #efefef; /* 设置轨道hover状态时的背景颜色 */
}
/* 滚动条滑块hover状态样式 */
::-webkit-scrollbar-thumb:hover {
background-color: #b5b5b5; /* 设置滑块hover状态时的背景颜色 */
}
.notice_item {
height: 42px;
background-color: #f8f8f8;
margin-bottom: 3px;
cursor: pointer;
.notice_content {
width: calc(100% - 108px);
font-size: 16px;
color: #000000;
line-height: 24px;
span {
display: inline-block;
width: 42px;
text-align: center;
}
}
.notice_time {
width: 160px;
text-align: center;
font-size: 14px;
color: #000000;
line-height: 24px;
}
}
.notice_INFO {
.notice_content,
.notice_time {
color: $green;
}
}
.notice_DEBUG {
.notice_content,
.notice_time {
color: $yellow;
}
}
.notice_ERROR {
.notice_content,
.notice_time {
color: $red;
}
}
}
}
}
}
.work_box {
height: calc(100vh - 640px);
::-webkit-scrollbar {
width: 0; /* 设置滚动条的宽度 */
height: 0;
}
.el-table.work_table {
height: calc(100vh - 720px) !important;
::v-deep .el-table__body-wrapper {
height: calc(100% - 48px) !important;
overflow: scroll!important;
}
}
.work_top {
background-color: #fff;
height: 72px;
.work_top_text {
width: 132px;
height: 72px;
background: linear-gradient(180deg, #c1ffcd 0%, #ffffff 100%);
font-weight: bold;
font-size: 19px;
color: #00c325;
line-height: 72px;
text-align: center;
}
}
.work_table {
background-color: #ffffff;
&::before {
height: 0;
}
::v-deep {
tr {
background-color: #ffffff;
}
td.el-table__cell {
background-color: #ffffff;
border-bottom: 2px solid #f8f8f8;
}
th.el-table__cell {
background-color: #f2f9f4;
border-bottom: 2px solid #f8f8f8;
}
.el-table__cell {
padding: 6px 0;
}
.cell {
line-height: 28px;
font-size: 16px;
color: #000000;
}
}
.work_progress {
width: 80%;
::v-deep {
.el-progress-bar__outer {
height: 16px !important;
line-height: 16px !important;
.el-progress-bar__innerText {
font-size: 12px !important;
color: #fff !important;
}
}
}
}
.work_status_box {
font-weight: 500;
font-size: 14px;
color: #000000;
height: 30px;
}
}
.child_table {
&::before {
height: 0;
}
::v-deep {
td.el-table__cell {
border-bottom: 2px solid #f8f8f8;
}
tr {
&:last-child {
td.el-table__cell {
border-bottom: none;
}
}
}
th.el-table__cell {
border-bottom: 2px solid #f8f8f8;
}
}
}
}
.footer_box {
height: 36px;
background: #dcf5e1;
font-weight: 500;
font-size: 14px;
color: #666666;
.footer_line {
width: 2px;
height: 14px;
background-color: #666666;
margin: 0 20px;
}
.footer_text {
cursor: pointer;
&:hover {
color: #00c325;
}
}
}
}
</style>