Compare commits
3 Commits
8a0327b63e
...
30c319694c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30c319694c | ||
|
|
a038261888 | ||
|
|
7f98f145d4 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,6 +4,8 @@
|
||||
node_modules
|
||||
.pnp
|
||||
.pnp.js
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
# Turbo
|
||||
.turbo
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// 应用全局配置
|
||||
module.exports = {
|
||||
baseUrl: 'http://192.168.31.116:8080',
|
||||
// baseUrl: 'http://140.143.206.120:8080',
|
||||
// baseUrl: 'http://192.168.31.116:8080',
|
||||
baseUrl: 'http://140.143.206.120:8080',
|
||||
// baseUrl: 'http://localhost:8080',
|
||||
// 应用信息
|
||||
appInfo: {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"name" : "科伦普",
|
||||
"appid" : "__UNI__E781B49",
|
||||
"description" : "",
|
||||
"versionName" : "1.2.0",
|
||||
"versionCode" : "100",
|
||||
"versionName" : "3.4",
|
||||
"versionCode" : 1,
|
||||
"transformPx" : false,
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "首页",
|
||||
"path" : "pages/easycode/easycode",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : "扫码",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login",
|
||||
@@ -13,6 +14,13 @@
|
||||
"navigationBarTitleText": "登录"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "首页",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "pages/mine/index",
|
||||
@@ -91,28 +99,28 @@
|
||||
"navigationBarTitleText": "RuoYi",
|
||||
"navigationBarBackgroundColor": "#FFFFFF"
|
||||
},
|
||||
"tabBar": {
|
||||
"list": [
|
||||
{
|
||||
"text": "产线",
|
||||
"pagePath": "pages/index",
|
||||
"selectedIconPath": "/static/images/tabbar/home_.png",
|
||||
"iconPath": "/static/images/tabbar/home.png"
|
||||
},
|
||||
{
|
||||
"text": "扫码",
|
||||
"pagePath": "pages/code/code",
|
||||
"selectedIconPath": "/static/images/tabbar/work_.png",
|
||||
"iconPath": "/static/images/tabbar/work.png"
|
||||
},
|
||||
{
|
||||
"text": "我的",
|
||||
"pagePath": "pages/mine/index",
|
||||
"selectedIconPath": "/static/images/tabbar/mine_.png",
|
||||
"iconPath": "/static/images/tabbar/mine.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
// "tabBar": {
|
||||
// "list": [
|
||||
// {
|
||||
// "text": "产线",
|
||||
// "pagePath": "pages/index",
|
||||
// "selectedIconPath": "/static/images/tabbar/home_.png",
|
||||
// "iconPath": "/static/images/tabbar/home.png"
|
||||
// },
|
||||
// {
|
||||
// "text": "扫码",
|
||||
// "pagePath": "pages/code/code",
|
||||
// "selectedIconPath": "/static/images/tabbar/work_.png",
|
||||
// "iconPath": "/static/images/tabbar/work.png"
|
||||
// },
|
||||
// {
|
||||
// "text": "我的",
|
||||
// "pagePath": "pages/mine/index",
|
||||
// "selectedIconPath": "/static/images/tabbar/mine_.png",
|
||||
// "iconPath": "/static/images/tabbar/mine.png"
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
"easycom": {
|
||||
"autoscan": true,
|
||||
"custom": {
|
||||
|
||||
60
apps/hand-factory/pages/easycode/easycode.vue
Normal file
60
apps/hand-factory/pages/easycode/easycode.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<view>
|
||||
<button v-for='item in types' @click="handleScan(item.dictValue)">
|
||||
{{ item.dictLabel }}
|
||||
</button>
|
||||
|
||||
<button @click='handleLogout'>
|
||||
退出登录
|
||||
</button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getDicts } from '@/api/system/dict/data.js'
|
||||
import { getGenerateRecord } from '@/api/wms/code.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
types: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleLogout() {
|
||||
this.$modal.confirm('确定注销并退出系统吗?').then(() => {
|
||||
this.$store.dispatch('LogOut').then(() => {}).finally(() => {
|
||||
this.$tab.reLaunch('/pages/login')
|
||||
})
|
||||
})
|
||||
},
|
||||
handleScan(type) {
|
||||
// 1. 扫码
|
||||
uni.scanCode({
|
||||
success(res) {
|
||||
const result = res.result;
|
||||
// 2. 解析二维码的content,获取enter_coil_no、current_coil_no和coil_id
|
||||
const qrcodeRecord = qrcodeRes.data;
|
||||
const content = JSON.parse(qrcodeRecord.content);
|
||||
const enterCoilNo = content.enter_coil_no;
|
||||
const currentCoilNo = content.current_coil_no;
|
||||
const coilId = content.coil_id && content.coil_id !== 'null' ? content.coil_id : null;
|
||||
|
||||
// 3. 调用创建待操作记录的API
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 获取字典
|
||||
getDicts('easycode_type').then(res => {
|
||||
console.log(res)
|
||||
this.types = res.data
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -64,7 +64,7 @@
|
||||
onLoad() {
|
||||
//#ifdef H5
|
||||
if (getToken()) {
|
||||
this.$tab.reLaunch('/pages/index')
|
||||
this.$tab.reLaunch('/pages/easycode/easycode')
|
||||
}
|
||||
//#endif
|
||||
},
|
||||
@@ -122,7 +122,7 @@
|
||||
loginSuccess(result) {
|
||||
// 设置用户信息
|
||||
this.$store.dispatch('GetInfo').then(res => {
|
||||
this.$tab.reLaunch('/pages/index')
|
||||
this.$tab.reLaunch('/pages/easycode/easycode')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,9 +103,9 @@
|
||||
},
|
||||
handleLogout() {
|
||||
this.$modal.confirm('确定注销并退出系统吗?').then(() => {
|
||||
// this.$store.dispatch('LogOut').then(() => {}).finally(() => {
|
||||
this.$store.dispatch('LogOut').then(() => {}).finally(() => {
|
||||
this.$tab.reLaunch('/pages/login')
|
||||
// })
|
||||
})
|
||||
})
|
||||
},
|
||||
handleToEditInfo() {
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
@include colorBtn($yellow)
|
||||
}
|
||||
|
||||
.pan-btn {
|
||||
.el-button.pan-btn {
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
padding: 14px 36px;
|
||||
border-radius: 8px;
|
||||
padding: 4px !important;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
outline: none;
|
||||
transition: 600ms ease all;
|
||||
@@ -81,7 +81,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.custom-button {
|
||||
.el-button.custom-button {
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
@@ -93,7 +93,21 @@
|
||||
box-sizing: border-box;
|
||||
outline: 0;
|
||||
margin: 0;
|
||||
padding: 10px 15px;
|
||||
padding: 2px !important;
|
||||
font-size: 14px;
|
||||
border-radius: 4px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
|
||||
.el-table__cell {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.el-table__cell .el-button {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.el-table__cell + .el-button {
|
||||
margin-left: 4px !important;
|
||||
padding: 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,8 @@
|
||||
**/
|
||||
|
||||
/* theme color */
|
||||
$--color-primary: #647b98;
|
||||
$--color-primary: #5F7BA0;
|
||||
// $--color-primary: #2bf;
|
||||
$--color-success: #13ce66;
|
||||
$--color-warning: #ffba00;
|
||||
$--color-danger: #ff4949;
|
||||
@@ -26,6 +27,6 @@ $--font-path: '~element-ui/lib/theme-chalk/fonts';
|
||||
|
||||
// the :export directive is the magic sauce for webpack
|
||||
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
|
||||
:export {
|
||||
theme: $--color-primary;
|
||||
}
|
||||
// :export {
|
||||
// theme: $--color-primary;
|
||||
// }
|
||||
|
||||
@@ -10,7 +10,6 @@ body {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
background-color: #a1a6ac;
|
||||
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
291
apps/l2/src/assets/styles/klp.scss
Normal file
291
apps/l2/src/assets/styles/klp.scss
Normal file
@@ -0,0 +1,291 @@
|
||||
/**
|
||||
* 通用css样式布局处理
|
||||
* Copyright (c) 2019 klp
|
||||
*/
|
||||
|
||||
/** 基础通用 **/
|
||||
.pt5 {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.pr5 {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.pb5 {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.mt5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.mr5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.mb5 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ml5 {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.mr10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.mb10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.mr20 {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.ml20 {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.el-message-box__status + .el-message-box__message{
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.el-dialog:not(.is-fullscreen) {
|
||||
margin-top: 6vh !important;
|
||||
}
|
||||
|
||||
.el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body {
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
max-height: 70vh;
|
||||
padding: 10px 20px 0;
|
||||
}
|
||||
|
||||
// .el-table {
|
||||
// .el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
||||
// th {
|
||||
// word-break: break-word;
|
||||
// background-color: #f8f8f9;
|
||||
// color: #515a6e;
|
||||
// height: 40px;
|
||||
// font-size: 13px;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .el-table__body-wrapper {
|
||||
// .el-button [class*="el-icon-"] + span {
|
||||
// margin-left: 1px;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/** 表单布局 **/
|
||||
// .form-header {
|
||||
// font-size: 15px;
|
||||
// color: #6379bb;
|
||||
// border-bottom: 1px solid #ddd;
|
||||
// margin: 8px 10px 25px 10px;
|
||||
// padding-bottom: 5px
|
||||
// }
|
||||
|
||||
// /** 表格布局 **/
|
||||
// .pagination-container {
|
||||
// position: relative;
|
||||
// height: 25px;
|
||||
// margin-bottom: 10px;
|
||||
// margin-top: 15px;
|
||||
// padding: 10px 20px !important;
|
||||
// }
|
||||
|
||||
/* tree border */
|
||||
// .tree-border {
|
||||
// margin-top: 5px;
|
||||
// border: 1px solid #e5e6e7;
|
||||
// background: #FFFFFF none;
|
||||
// border-radius: 4px;
|
||||
// }
|
||||
|
||||
// .pagination-container .el-pagination {
|
||||
// right: 0;
|
||||
// position: absolute;
|
||||
// }
|
||||
|
||||
// @media (max-width: 768px) {
|
||||
// .pagination-container .el-pagination > .el-pagination__jump {
|
||||
// display: none !important;
|
||||
// }
|
||||
// .pagination-container .el-pagination > .el-pagination__sizes {
|
||||
// display: none !important;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .el-table .fixed-width .el-button--mini {
|
||||
// padding-left: 0;
|
||||
// padding-right: 0;
|
||||
// width: inherit;
|
||||
// }
|
||||
|
||||
// /** 表格更多操作下拉样式 */
|
||||
// .el-table .el-dropdown-link,.el-table .el-dropdown-selfdefine {
|
||||
// cursor: pointer;
|
||||
// margin-left: 5px;
|
||||
// }
|
||||
|
||||
// .el-table .el-dropdown, .el-icon-arrow-down {
|
||||
// font-size: 12px;
|
||||
// }
|
||||
|
||||
// .el-tree-node__content > .el-checkbox {
|
||||
// margin-right: 8px;
|
||||
// }
|
||||
|
||||
.list-group-striped > .list-group-item {
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-radius: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
padding-left: 0px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
border-bottom: 1px solid #e7eaec;
|
||||
border-top: 1px solid #e7eaec;
|
||||
margin-bottom: -1px;
|
||||
padding: 11px 0px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.pull-right {
|
||||
float: right !important;
|
||||
}
|
||||
|
||||
.el-card__header {
|
||||
padding: 14px 15px 7px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.el-card__body {
|
||||
padding: 15px 20px 20px 20px;
|
||||
}
|
||||
|
||||
.card-box {
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* button color */
|
||||
.el-button--cyan.is-active,
|
||||
.el-button--cyan:active {
|
||||
background: #20B2AA;
|
||||
border-color: #20B2AA;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.el-button--cyan:focus,
|
||||
.el-button--cyan:hover {
|
||||
background: #48D1CC;
|
||||
border-color: #48D1CC;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.el-button--cyan {
|
||||
background-color: #20B2AA;
|
||||
border-color: #20B2AA;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* text color */
|
||||
.text-navy {
|
||||
color: #1ab394;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: #1c84c6;
|
||||
}
|
||||
|
||||
.text-info {
|
||||
color: #23c6c8;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
color: #f8ac59;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: #ed5565;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
/* image */
|
||||
.img-circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.img-lg {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.avatar-upload-preview {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 拖拽列样式 */
|
||||
.sortable-ghost {
|
||||
opacity: .8;
|
||||
color: #fff !important;
|
||||
background: #42b983 !important;
|
||||
}
|
||||
|
||||
.top-right-btn {
|
||||
position: relative;
|
||||
float: right;
|
||||
}
|
||||
@@ -1,415 +0,0 @@
|
||||
/**
|
||||
* 通用css样式布局处理
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
|
||||
/** 基础通用 **/
|
||||
.pt5 {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.pr5 {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.pb5 {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.mt5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.mr5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.mb5 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ml5 {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.mr10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.mb10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.mr20 {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.ml20 {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.el-message-box__status + .el-message-box__message{
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.el-dialog:not(.is-fullscreen) {
|
||||
margin-top: 6vh !important;
|
||||
}
|
||||
|
||||
.el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body {
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
max-height: 70vh;
|
||||
padding: 10px 20px 0;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
/* 固定列表格容器背景与分割线 */
|
||||
.el-table__fixed,
|
||||
.el-table__fixed-left,
|
||||
.el-table__fixed-right {
|
||||
background: transparent; /* 让内部单元格背景生效 */
|
||||
}
|
||||
|
||||
.el-table__fixed::before,
|
||||
.el-table__fixed-left::before,
|
||||
.el-table__fixed-right::before {
|
||||
/* 顶部那条细线颜色 */
|
||||
background-color: #444A52;
|
||||
}
|
||||
|
||||
/* 固定列表头 */
|
||||
.el-table__fixed-header-wrapper th,
|
||||
.el-table__fixed-left .el-table__fixed-header-wrapper th,
|
||||
.el-table__fixed-right .el-table__fixed-header-wrapper th {
|
||||
background: #1F2227 !important; /* 与主表头一致的深灰 */
|
||||
color: #FFFFFF !important; /* 白字 */
|
||||
border-bottom: 1px solid #444A52 !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 固定列表体单元格(奇偶行) */
|
||||
.el-table__fixed-body-wrapper .el-table__row:nth-child(odd) .el-table__cell,
|
||||
.el-table__fixed-left .el-table__fixed-body-wrapper .el-table__row:nth-child(odd) .el-table__cell,
|
||||
.el-table__fixed-right .el-table__fixed-body-wrapper .el-table__row:nth-child(odd) .el-table__cell {
|
||||
background: #2F3339 !important; /* 中深灰 */
|
||||
color: #EAEAEA !important; /* 浅灰白字 */
|
||||
border-bottom: 1px solid #444A52 !important;
|
||||
}
|
||||
|
||||
.el-table__fixed-body-wrapper .el-table__row:nth-child(even) .el-table__cell,
|
||||
.el-table__fixed-left .el-table__fixed-body-wrapper .el-table__row:nth-child(even) .el-table__cell,
|
||||
.el-table__fixed-right .el-table__fixed-body-wrapper .el-table__row:nth-child(even) .el-table__cell {
|
||||
background: #353A40 !important; /* 稍亮一档 */
|
||||
color: #EAEAEA !important;
|
||||
border-bottom: 1px solid #444A52 !important;
|
||||
}
|
||||
|
||||
/* 固定列 hover / current-row 同步 */
|
||||
.el-table__fixed-body-wrapper .el-table__row:hover .el-table__cell,
|
||||
.el-table__fixed-left .el-table__fixed-body-wrapper .el-table__row:hover .el-table__cell,
|
||||
.el-table__fixed-right .el-table__fixed-body-wrapper .el-table__row:hover .el-table__cell {
|
||||
background: rgba(95, 123, 160, 0.25) !important; /* 工业蓝 hover */
|
||||
color: #FFFFFF !important;
|
||||
}
|
||||
|
||||
.el-table__fixed-body-wrapper .el-table__row.current-row .el-table__cell,
|
||||
.el-table__fixed-left .el-table__fixed-body-wrapper .el-table__row.current-row .el-table__cell,
|
||||
.el-table__fixed-right .el-table__fixed-body-wrapper .el-table__row.current-row .el-table__cell {
|
||||
background: rgba(95, 123, 160, 0.35) !important; /* current-row 更明显 */
|
||||
color: #FFFFFF !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 固定列滚动条(可选) */
|
||||
.el-table__fixed-body-wrapper::-webkit-scrollbar,
|
||||
.el-table__fixed-left .el-table__fixed-body-wrapper::-webkit-scrollbar,
|
||||
.el-table__fixed-right .el-table__fixed-body-wrapper::-webkit-scrollbar {
|
||||
width: 8px; height: 8px;
|
||||
}
|
||||
.el-table__fixed-body-wrapper::-webkit-scrollbar-thumb,
|
||||
.el-table__fixed-left .el-table__fixed-body-wrapper::-webkit-scrollbar-thumb,
|
||||
.el-table__fixed-right .el-table__fixed-body-wrapper::-webkit-scrollbar-thumb {
|
||||
background: #4A525B; border-radius: 6px;
|
||||
}
|
||||
}
|
||||
/* =========================
|
||||
Splitpanes 工业风深色主题
|
||||
仍保留 default-theme 类名
|
||||
========================= */
|
||||
|
||||
/* 根容器:与页面主背景统一,去掉默认白底 */
|
||||
.splitpanes.default-theme {
|
||||
background: #2B2F36; /* 页面主底色 */
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* pane:统一深灰金属风,提供一致的内边距 */
|
||||
.splitpanes.default-theme .splitpanes__pane {
|
||||
background: linear-gradient(145deg, #1F242A, #21262D) !important; /* 深灰渐变 */
|
||||
color: #EAEAEA !important;
|
||||
padding: 12px 12px; /* 两侧内容留白一致 */
|
||||
box-sizing: border-box;
|
||||
overflow: hidden; /* 保持干净 */
|
||||
}
|
||||
|
||||
/* 左/右外侧圆角,仅在最外侧边缘展示,避免中缝突兀 */
|
||||
.splitpanes.default-theme .splitpanes__pane:first-child {
|
||||
border-radius: 8px 0 0 8px;
|
||||
}
|
||||
.splitpanes.default-theme .splitpanes__pane:last-child {
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
|
||||
/* 分隔条(splitter):工业灰,hover 工业蓝,带内嵌“握把” */
|
||||
.splitpanes.default-theme .splitpanes__splitter {
|
||||
position: relative;
|
||||
background: #39414A !important; /* 静态 */
|
||||
transition: background .2s ease;
|
||||
}
|
||||
.splitpanes.default-theme .splitpanes__splitter:hover {
|
||||
background: #46505A !important; /* 悬停稍亮 */
|
||||
}
|
||||
/* 把握把做成中线,水平/垂直两种方向都美观 */
|
||||
.splitpanes.default-theme .splitpanes__splitter::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
border-radius: 2px;
|
||||
background: #4A525B;
|
||||
}
|
||||
.splitpanes.default-theme.splitpanes--vertical .splitpanes__splitter::before {
|
||||
width: 2px; height: 60%;
|
||||
}
|
||||
.splitpanes.default-theme.splitpanes--horizontal .splitpanes__splitter::before {
|
||||
height: 2px; width: 60%;
|
||||
}
|
||||
|
||||
/* pane 内滚动条(如果有)与全站一致 */
|
||||
.splitpanes.default-theme .splitpanes__pane::-webkit-scrollbar { width: 8px; height: 8px; }
|
||||
.splitpanes.default-theme .splitpanes__pane::-webkit-scrollbar-thumb {
|
||||
background: #4A525B; border-radius: 6px;
|
||||
}
|
||||
.splitpanes.default-theme .splitpanes__pane::-webkit-scrollbar-track { background: transparent; }
|
||||
|
||||
/* 可选:让右侧主区域看起来像一张卡片(若你的右 pane 是内容主区) */
|
||||
.splitpanes.default-theme .splitpanes__pane:last-child {
|
||||
box-shadow: 0 12px 24px rgba(0,0,0,.25) inset,
|
||||
0 1px 0 rgba(255,255,255,.04) inset;
|
||||
}
|
||||
|
||||
/* 可选:在窄屏时减小 pane 内边距,避免拥挤 */
|
||||
@media (max-width: 992px) {
|
||||
.splitpanes.default-theme .splitpanes__pane { padding: 8px; }
|
||||
}
|
||||
|
||||
/** 表单布局 **/
|
||||
.form-header {
|
||||
font-size: 15px;
|
||||
color: #6379bb;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 8px 10px 25px 10px;
|
||||
padding-bottom: 5px
|
||||
}
|
||||
|
||||
/** 表格布局 **/
|
||||
.pagination-container {
|
||||
position: relative;
|
||||
height: 25px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 15px;
|
||||
padding: 10px 20px !important;
|
||||
}
|
||||
|
||||
/* tree border */
|
||||
.tree-border {
|
||||
margin-top: 5px;
|
||||
border: 1px solid #e5e6e7;
|
||||
background: #FFFFFF none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.pagination-container .el-pagination {
|
||||
right: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.pagination-container .el-pagination > .el-pagination__jump {
|
||||
display: none !important;
|
||||
}
|
||||
.pagination-container .el-pagination > .el-pagination__sizes {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table .fixed-width .el-button--mini {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
/** 表格更多操作下拉样式 */
|
||||
.el-table .el-dropdown-link,.el-table .el-dropdown-selfdefine {
|
||||
cursor: pointer;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.el-table .el-dropdown, .el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.el-tree-node__content > .el-checkbox {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.list-group-striped > .list-group-item {
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-radius: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
padding-left: 0px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
border-bottom: 1px solid #e7eaec;
|
||||
border-top: 1px solid #e7eaec;
|
||||
margin-bottom: -1px;
|
||||
padding: 11px 0px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.pull-right {
|
||||
float: right !important;
|
||||
}
|
||||
|
||||
.el-card__header {
|
||||
padding: 14px 15px 7px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.el-card__body {
|
||||
padding: 15px 20px 20px 20px;
|
||||
}
|
||||
|
||||
.card-box {
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* button color */
|
||||
.el-button--cyan.is-active,
|
||||
.el-button--cyan:active {
|
||||
background: #20B2AA;
|
||||
border-color: #20B2AA;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.el-button--cyan:focus,
|
||||
.el-button--cyan:hover {
|
||||
background: #48D1CC;
|
||||
border-color: #48D1CC;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.el-button--cyan {
|
||||
background-color: #20B2AA;
|
||||
border-color: #20B2AA;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* text color */
|
||||
.text-navy {
|
||||
color: #1ab394;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: #1c84c6;
|
||||
}
|
||||
|
||||
.text-info {
|
||||
color: #23c6c8;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
color: #f8ac59;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: #ed5565;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
/* image */
|
||||
.img-circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.img-lg {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.avatar-upload-preview {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 拖拽列样式 */
|
||||
.sortable-ghost {
|
||||
opacity: .8;
|
||||
color: #fff !important;
|
||||
background: #42b983 !important;
|
||||
}
|
||||
|
||||
.top-right-btn {
|
||||
position: relative;
|
||||
float: right;
|
||||
}
|
||||
@@ -4,24 +4,25 @@
|
||||
--text-regular: #333333;
|
||||
--text-secondary: #555555;
|
||||
--text-placeholder: #777777;
|
||||
--background-color: #fff;
|
||||
|
||||
.main-container {
|
||||
height: 100%;
|
||||
transition: margin-left .28s, box-shadow .3s ease;
|
||||
margin-left: $base-sidebar-width;
|
||||
position: relative;
|
||||
background: #3f4449; // 金属浅色渐变
|
||||
// background: #1E2227; // 金属浅色渐变
|
||||
}
|
||||
|
||||
.sidebarHide {
|
||||
margin-left: 0!important;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
.sidebar-container {
|
||||
-webkit-transition: width .28s, background .3s ease;
|
||||
transition: width 0.28s, background .3s ease;
|
||||
width: $base-sidebar-width !important;
|
||||
background: #3f4449; // 金属深色渐变
|
||||
background: var(--background-color); // 金属深色渐变
|
||||
border-right: 1px solid #8d939b;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
@@ -44,11 +45,12 @@
|
||||
|
||||
.el-scrollbar__bar.is-vertical {
|
||||
right: 0px;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
background: #2Bf;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.el-scrollbar__thumb {
|
||||
background: #1E2227;
|
||||
background: var(--background-color);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
@@ -86,7 +88,8 @@
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.el-menu-item, .el-submenu__title {
|
||||
.el-menu-item,
|
||||
.el-submenu__title {
|
||||
// 明确默认状态样式(关键修复)
|
||||
background: transparent !important;
|
||||
box-shadow: none !important;
|
||||
@@ -96,7 +99,7 @@
|
||||
white-space: nowrap !important;
|
||||
color: var(--text-regular); // 菜单项文本偏黑
|
||||
border-radius: 4px;
|
||||
margin: 0 6px;
|
||||
margin: 0;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
@@ -107,17 +110,10 @@
|
||||
background: rgba(255, 255, 255, 0.1) !important;
|
||||
color: var(--text-primary) !important; // hover时文本更深
|
||||
box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.1),
|
||||
inset -1px -1px 2px rgba(255, 255, 255, 0.05);
|
||||
inset -1px -1px 2px rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
// 深色主题下子菜单选中高亮
|
||||
& .theme-dark .is-active > .el-submenu__title {
|
||||
color: #fff !important; // 选中时文字纯白
|
||||
// background-color: rgba(95, 123, 160, 0.25) !important; // 工业蓝浅高亮
|
||||
// border-left: 3px solid #5F7BA0; // 左边高亮条
|
||||
}
|
||||
|
||||
// & .nest-menu .el-submenu>.el-submenu__title,
|
||||
& .el-submenu .el-menu-item {
|
||||
// 子菜单默认样式
|
||||
@@ -145,13 +141,20 @@
|
||||
|
||||
&.is-active {
|
||||
background: rgba(95, 123, 160, 0.28) !important; // 激活背景
|
||||
color: #fff !important; // 激活文字白色
|
||||
color: #000 !important; // 激活文字白色
|
||||
font-weight: 600;
|
||||
border-left: 3px solid #5F7BA0; // 左边高亮条
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-menu-item.is-active.submenu-title-noDropdown {
|
||||
background: #657b96; // 激活背景
|
||||
color: #000; // 激活文字白色
|
||||
font-weight: 600;
|
||||
border-left: 3px solid #657b96; // 左边高亮条
|
||||
}
|
||||
|
||||
.hideSidebar {
|
||||
.sidebar-container {
|
||||
width: 54px !important;
|
||||
@@ -205,6 +208,10 @@
|
||||
min-width: $base-sidebar-width !important;
|
||||
}
|
||||
|
||||
.el-submenu .el-menu {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
// mobile responsive
|
||||
.mobile {
|
||||
.main-container {
|
||||
@@ -227,6 +234,7 @@
|
||||
}
|
||||
|
||||
.withoutAnimation {
|
||||
|
||||
.main-container,
|
||||
.sidebar-container {
|
||||
transition: none;
|
||||
@@ -234,7 +242,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// when menu collapsed
|
||||
// 收起状态下的菜单
|
||||
.el-menu--vertical {
|
||||
&>.el-menu {
|
||||
.svg-icon {
|
||||
@@ -252,7 +260,7 @@
|
||||
background: rgba(255, 255, 255, 0.1) !important;
|
||||
color: var(--text-primary) !important;
|
||||
box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.1),
|
||||
inset -1px -1px 2px rgba(255, 255, 255, 0.05);
|
||||
inset -1px -1px 2px rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
::v-deep &.is-active {
|
||||
@@ -261,7 +269,7 @@
|
||||
font-weight: 600;
|
||||
border-left: 3px solid #5F7BA0;
|
||||
box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.15),
|
||||
inset -1px -1px 2px rgba(255, 255, 255, 0.08);
|
||||
inset -1px -1px 2px rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
::v-deep .el-menu-item.is-active span,
|
||||
@@ -293,7 +301,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
#app .sidebar-container .el-menu-item,
|
||||
#app .sidebar-container .el-submenu__title {
|
||||
margin: 0;
|
||||
#app .sidebar-container .nest-menu .el-submenu .el-submenu__title {
|
||||
margin: 0 4px;
|
||||
}
|
||||
@@ -1,38 +1,45 @@
|
||||
// 基础金属色调
|
||||
$metal-dark: #637994; // 主色调1 - 深金属色
|
||||
$metal-light: #bec3c9; // 主色调2 - 浅金属色
|
||||
$metal-bg: #a1a6ac; // 背景主色调
|
||||
$metal-highlight: #d0d5db; // 金属高光色
|
||||
$metal-shadow: #8c949d; // 金属阴影色
|
||||
// base color
|
||||
$blue:#324157;
|
||||
$light-blue:#3A71A8;
|
||||
$red:#C03639;
|
||||
$pink: #E65D6E;
|
||||
$green: #30B08F;
|
||||
$tiffany: #4AB7BD;
|
||||
$yellow:#FEC171;
|
||||
$panGreen: #30B08F;
|
||||
|
||||
// 功能色(保持原有,但调整为金属质感)
|
||||
$blue: mix($metal-dark, #324157, 30%);
|
||||
$light-blue: mix($metal-light, #3A71A8, 30%);
|
||||
$red: mix($metal-light, #C03639, 20%);
|
||||
$pink: mix($metal-light, #E65D6E, 20%);
|
||||
$green: mix($metal-light, #30B08F, 20%);
|
||||
$tiffany: mix($metal-light, #4AB7BD, 20%);
|
||||
$yellow: mix($metal-light, #FEC171, 20%);
|
||||
$panGreen: mix($metal-light, #30B08F, 20%);
|
||||
// 默认菜单主题风格
|
||||
$base-menu-color:#bfcbd9;
|
||||
$base-menu-color-active:#f4f4f5;
|
||||
$base-menu-background:#304156;
|
||||
$base-logo-title-color: #ffffff;
|
||||
|
||||
// 金属风格菜单主题
|
||||
$base-menu-color: mix($metal-light, rgba(255, 255, 255, 0.7), 60%); // 菜单文字色
|
||||
$base-menu-color-active: #ffffff; // 激活菜单文字色
|
||||
$base-menu-background: linear-gradient(145deg, darken($metal-bg, 3%), $metal-bg); // 菜单背景
|
||||
$base-logo-title-color: $metal-highlight; // Logo文字色
|
||||
$base-menu-light-color:rgba(0,0,0,.70);
|
||||
$base-menu-light-background:#ffffff;
|
||||
$base-logo-light-title-color: #001529;
|
||||
|
||||
// 浅色金属菜单风格
|
||||
$base-menu-light-color: mix($metal-dark, rgba(0, 0, 0, 0.7), 70%); // 浅色菜单文字色
|
||||
$base-menu-light-background: linear-gradient(145deg, $metal-bg, lighten($metal-bg, 3%)); // 浅色菜单背景
|
||||
$base-logo-light-title-color: $metal-dark; // 浅色Logo文字色
|
||||
$base-sub-menu-background:#1f2d3d;
|
||||
$base-sub-menu-hover:#001528;
|
||||
|
||||
// 子菜单样式
|
||||
$base-sub-menu-background: darken($metal-bg, 5%); // 子菜单背景
|
||||
$base-sub-menu-hover: linear-gradient(145deg, $metal-bg, $metal-dark); // 子菜单悬停背景
|
||||
// 自定义暗色菜单风格
|
||||
/**
|
||||
$base-menu-color:hsla(0,0%,100%,.65);
|
||||
$base-menu-color-active:#fff;
|
||||
$base-menu-background:#001529;
|
||||
$base-logo-title-color: #ffffff;
|
||||
|
||||
$base-sidebar-width: 200px; // 侧边栏宽度
|
||||
$base-menu-light-color:rgba(0,0,0,.70);
|
||||
$base-menu-light-background:#ffffff;
|
||||
$base-logo-light-title-color: #001529;
|
||||
|
||||
// 导出变量供JS使用
|
||||
$base-sub-menu-background:#000c17;
|
||||
$base-sub-menu-hover:#001528;
|
||||
*/
|
||||
|
||||
$base-sidebar-width: 200px;
|
||||
|
||||
// the :export directive is the magic sauce for webpack
|
||||
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
|
||||
:export {
|
||||
menuColor: $base-menu-color;
|
||||
menuLightColor: $base-menu-light-color;
|
||||
@@ -43,9 +50,5 @@ $base-sidebar-width: 200px; // 侧边栏宽度
|
||||
subMenuHover: $base-sub-menu-hover;
|
||||
sideBarWidth: $base-sidebar-width;
|
||||
logoTitleColor: $base-logo-title-color;
|
||||
logoLightTitleColor: $base-logo-light-title-color;
|
||||
// 导出金属主题基础色供全局使用
|
||||
metalDark: $metal-dark;
|
||||
metalLight: $metal-light;
|
||||
metalBg: $metal-bg;
|
||||
logoLightTitleColor: $base-logo-light-title-color
|
||||
}
|
||||
@@ -93,9 +93,9 @@ export default {
|
||||
.app-breadcrumb.el-breadcrumb {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 50px;
|
||||
line-height: 40px;
|
||||
margin-left: 8px;
|
||||
color: #fff;
|
||||
color: #111;
|
||||
.no-redirect {
|
||||
color: #ddd;
|
||||
cursor: text;
|
||||
@@ -103,6 +103,6 @@ export default {
|
||||
}
|
||||
|
||||
.el-breadcrumb__inner.is-link, .el-breadcrumb__inner a {
|
||||
color: #fff;
|
||||
color: #111;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -43,6 +43,6 @@ export default {
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: #fff;
|
||||
fill: #111;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -65,7 +65,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<!-- <style lang="scss" scoped>
|
||||
/* 工业风:石墨灰体系,深色背景适配。无蓝色。 */
|
||||
.pagination-container {
|
||||
background: transparent; /* 不要白底 */
|
||||
@@ -93,9 +93,9 @@ export default {
|
||||
|
||||
/* sizes 选择器(下拉的输入框外观) */
|
||||
.el-pagination__sizes .el-select .el-input .el-input__inner {
|
||||
background: var(--pg-bg);
|
||||
border-color: var(--pg-border);
|
||||
color: var(--pg-text);
|
||||
// background: var(--pg-bg);
|
||||
// border-color: var(--pg-border);
|
||||
// color: var(--pg-text);
|
||||
}
|
||||
.el-pagination__sizes .el-select .el-input .el-input__inner:hover {
|
||||
background: var(--pg-bg-hover);
|
||||
@@ -183,4 +183,4 @@ export default {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style> -->
|
||||
|
||||
489
apps/l2/src/components/TrackMeasure/index.vue
Normal file
489
apps/l2/src/components/TrackMeasure/index.vue
Normal file
@@ -0,0 +1,489 @@
|
||||
<template>
|
||||
<div class="process-monitor">
|
||||
<!-- 控制区 -->
|
||||
<div class="control-bar">
|
||||
<div class="chart-selector">
|
||||
<label>图表视图:</label>
|
||||
<select v-model="currentChart" @change="handleChartChange">
|
||||
<option v-for="chart in chartTypes" :key="chart.value" :value="chart.value">
|
||||
{{ chart.label }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="connection-status" :class="{ connected: isConnected }">
|
||||
连接状态:{{ isConnected ? '已连接' : '连接中...' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图表展示区 -->
|
||||
<div class="chart-container">
|
||||
<h3 class="chart-title">{{ currentChartLabel }}</h3>
|
||||
<div ref="chartDom" class="chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
export default {
|
||||
name: 'ProcessTrackMonitor',
|
||||
data() {
|
||||
return {
|
||||
// WebSocket相关(固定为track_measure)
|
||||
socket: null,
|
||||
isConnected: false,
|
||||
|
||||
// 图表相关
|
||||
chartTypes: [
|
||||
{ value: 'entry', label: '入口数据监控' },
|
||||
{ value: 'furnace', label: '炉温数据监控' },
|
||||
{ value: 'coat', label: '涂层数据监控' },
|
||||
{ value: 'exit', label: '出口数据监控' }
|
||||
],
|
||||
currentChart: 'entry', // 默认显示入口数据图表
|
||||
chartInstance: null, // 当前图表实例
|
||||
|
||||
// 图表数据存储
|
||||
chartData: {
|
||||
entry: {
|
||||
time: [],
|
||||
tensionPorBr1: [],
|
||||
tensionBr1Br2: [],
|
||||
tensionBr2Br3: [],
|
||||
stripSpeed: []
|
||||
},
|
||||
furnace: {
|
||||
time: [],
|
||||
phFurnaceTemperatureActual: [],
|
||||
nof1FurnaceTemperatureActual: [],
|
||||
nof1FurnaceTemperatureSet: []
|
||||
},
|
||||
coat: {
|
||||
time: [],
|
||||
avrCoatingWeightTop: [],
|
||||
avrCoatingWeightBottom: [],
|
||||
airKnifePressure: [],
|
||||
stripSpeedTmExit: []
|
||||
},
|
||||
exit: {
|
||||
time: [],
|
||||
tensionBr8Br9: [],
|
||||
tensionBr9Tr: [],
|
||||
speedExitSection: []
|
||||
}
|
||||
},
|
||||
maxDataPoints: 30 // 最多显示的数据点数量
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 当前图表标题
|
||||
currentChartLabel() {
|
||||
const chart = this.chartTypes.find(item => item.value === this.currentChart);
|
||||
return chart ? chart.label : '';
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 初始化图表
|
||||
this.initChart();
|
||||
// 建立WebSocket连接(固定为track_measure)
|
||||
this.connectWebSocket();
|
||||
// 监听窗口大小变化
|
||||
window.addEventListener('resize', this.handleWindowResize);
|
||||
},
|
||||
unmounted() {
|
||||
// 清理资源
|
||||
this.disconnectWebSocket();
|
||||
this.destroyChart();
|
||||
window.removeEventListener('resize', this.handleWindowResize);
|
||||
},
|
||||
methods: {
|
||||
// 初始化当前图表
|
||||
initChart() {
|
||||
// 先销毁已有实例
|
||||
this.destroyChart();
|
||||
|
||||
// 初始化新图表
|
||||
if (this.$refs.chartDom) {
|
||||
this.chartInstance = echarts.init(this.$refs.chartDom);
|
||||
this.chartInstance.setOption(this.getChartOption());
|
||||
}
|
||||
},
|
||||
|
||||
// 根据当前图表类型获取配置
|
||||
getChartOption() {
|
||||
const baseOption = {
|
||||
backgroundColor: 'transparent',
|
||||
tooltip: { trigger: 'axis' },
|
||||
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: this.chartData[this.currentChart].time,
|
||||
axisLine: { lineStyle: { color: '#666' } },
|
||||
axisLabel: { color: '#b0b0b0' }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#666' } },
|
||||
axisLabel: { color: '#b0b0b0' },
|
||||
splitLine: { lineStyle: { color: 'rgba(255, 255, 255, 0.1)' } }
|
||||
}
|
||||
};
|
||||
|
||||
// 不同图表的系列配置
|
||||
switch (this.currentChart) {
|
||||
case 'entry':
|
||||
return {
|
||||
...baseOption,
|
||||
legend: {
|
||||
data: ['入口张力1', '入口张力2', '入口张力3', '带钢速度'],
|
||||
textStyle: { color: '#e0e0e0' }
|
||||
},
|
||||
series: [
|
||||
{ name: '入口张力1', type: 'line', data: this.chartData.entry.tensionPorBr1, smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '入口张力2', type: 'line', data: this.chartData.entry.tensionBr1Br2, smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '入口张力3', type: 'line', data: this.chartData.entry.tensionBr2Br3, smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '带钢速度', type: 'line', data: this.chartData.entry.stripSpeed, smooth: true, lineStyle: { width: 2 } }
|
||||
]
|
||||
};
|
||||
|
||||
case 'furnace':
|
||||
return {
|
||||
...baseOption,
|
||||
legend: {
|
||||
data: ['PH炉实际温度', 'NOF1炉实际温度', 'NOF1炉设定温度'],
|
||||
textStyle: { color: '#e0e0e0' }
|
||||
},
|
||||
series: [
|
||||
{ name: 'PH炉实际温度', type: 'line', data: this.chartData.furnace.phFurnaceTemperatureActual, smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: 'NOF1炉实际温度', type: 'line', data: this.chartData.furnace.nof1FurnaceTemperatureActual, smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: 'NOF1炉设定温度', type: 'line', data: this.chartData.furnace.nof1FurnaceTemperatureSet, smooth: true, lineStyle: { width: 2, type: 'dashed' } }
|
||||
]
|
||||
};
|
||||
|
||||
case 'coat':
|
||||
return {
|
||||
...baseOption,
|
||||
legend: {
|
||||
data: ['顶部平均涂层重量', '底部平均涂层重量', '气刀压力', '出口速度'],
|
||||
textStyle: { color: '#e0e0e0' }
|
||||
},
|
||||
series: [
|
||||
{ name: '顶部平均涂层重量', type: 'line', data: this.chartData.coat.avrCoatingWeightTop, smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '底部平均涂层重量', type: 'line', data: this.chartData.coat.avrCoatingWeightBottom, smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '气刀压力', type: 'line', data: this.chartData.coat.airKnifePressure, smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '出口速度', type: 'line', data: this.chartData.coat.stripSpeedTmExit, smooth: true, lineStyle: { width: 2 } }
|
||||
]
|
||||
};
|
||||
|
||||
case 'exit':
|
||||
return {
|
||||
...baseOption,
|
||||
legend: {
|
||||
data: ['出口张力1', '出口张力2', '出口速度'],
|
||||
textStyle: { color: '#e0e0e0' }
|
||||
},
|
||||
series: [
|
||||
{ name: '出口张力1', type: 'line', data: this.chartData.exit.tensionBr8Br9, smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '出口张力2', type: 'line', data: this.chartData.exit.tensionBr9Tr, smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '出口速度', type: 'line', data: this.chartData.exit.speedExitSection, smooth: true, lineStyle: { width: 2 } }
|
||||
]
|
||||
};
|
||||
|
||||
default:
|
||||
return baseOption;
|
||||
}
|
||||
},
|
||||
|
||||
// 处理窗口大小变化
|
||||
handleWindowResize() {
|
||||
if (this.chartInstance) {
|
||||
this.chartInstance.resize();
|
||||
}
|
||||
},
|
||||
|
||||
// 销毁当前图表
|
||||
destroyChart() {
|
||||
if (this.chartInstance) {
|
||||
this.chartInstance.dispose();
|
||||
this.chartInstance = null;
|
||||
}
|
||||
},
|
||||
|
||||
// 建立WebSocket连接(固定连接track_measure)
|
||||
connectWebSocket() {
|
||||
// 先断开现有连接
|
||||
this.disconnectWebSocket();
|
||||
|
||||
this.isConnected = false;
|
||||
const url = 'ws://140.143.206.120:18081/websocket?type=track_measure';
|
||||
|
||||
try {
|
||||
this.socket = new WebSocket(url);
|
||||
|
||||
this.socket.onopen = () => {
|
||||
console.log('WebSocket连接已建立(track_measure)');
|
||||
this.isConnected = true;
|
||||
};
|
||||
|
||||
this.socket.onmessage = (event) => {
|
||||
this.processData(event.data);
|
||||
};
|
||||
|
||||
this.socket.onerror = (error) => {
|
||||
console.error('WebSocket错误:', error);
|
||||
this.isConnected = false;
|
||||
};
|
||||
|
||||
this.socket.onclose = (event) => {
|
||||
console.log(`WebSocket连接已关闭: ${event.code} - ${event.reason}`);
|
||||
this.isConnected = false;
|
||||
|
||||
// 自动重连(非主动关闭)
|
||||
if (event.code !== 1000) {
|
||||
setTimeout(() => this.connectWebSocket(), 3000);
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('建立WebSocket连接失败:', error);
|
||||
setTimeout(() => this.connectWebSocket(), 3000);
|
||||
}
|
||||
},
|
||||
|
||||
// 断开WebSocket连接
|
||||
disconnectWebSocket() {
|
||||
if (this.socket) {
|
||||
this.socket.close(1000, '主动关闭');
|
||||
this.socket = null;
|
||||
}
|
||||
},
|
||||
|
||||
// 处理图表切换
|
||||
handleChartChange() {
|
||||
this.initChart();
|
||||
},
|
||||
|
||||
// 处理接收到的数据
|
||||
processData(data) {
|
||||
try {
|
||||
const parsedData = JSON.parse(data);
|
||||
this.processTrackMeasureData(parsedData);
|
||||
} catch (error) {
|
||||
console.error('数据解析错误:', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 处理track_measure类型数据
|
||||
processTrackMeasureData(data) {
|
||||
// 获取当前时间标签(分:秒.毫秒)
|
||||
const now = new Date();
|
||||
const timeLabel = `${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}.${now.getMilliseconds().toString().slice(0, 2)}`;
|
||||
|
||||
// 处理入口数据
|
||||
if (data.appMeasureEntryMessage) {
|
||||
this.addDataPoint('entry', timeLabel, {
|
||||
tensionPorBr1: data.appMeasureEntryMessage.tensionPorBr1,
|
||||
tensionBr1Br2: data.appMeasureEntryMessage.tensionBr1Br2,
|
||||
tensionBr2Br3: data.appMeasureEntryMessage.tensionBr2Br3,
|
||||
stripSpeed: data.appMeasureEntryMessage.stripSpeed
|
||||
});
|
||||
}
|
||||
|
||||
// 处理炉温数据
|
||||
if (data.appMeasureFurnaceMessage) {
|
||||
this.addDataPoint('furnace', timeLabel, {
|
||||
phFurnaceTemperatureActual: data.appMeasureFurnaceMessage.phFurnaceTemperatureActual,
|
||||
nof1FurnaceTemperatureActual: data.appMeasureFurnaceMessage.nof1FurnaceTemperatureActual,
|
||||
nof1FurnaceTemperatureSet: data.appMeasureFurnaceMessage.nof1FurnaceTemperatureSet
|
||||
});
|
||||
}
|
||||
|
||||
// 处理涂层数据
|
||||
if (data.appMeasureCoatMessage) {
|
||||
this.addDataPoint('coat', timeLabel, {
|
||||
avrCoatingWeightTop: data.appMeasureCoatMessage.avrCoatingWeightTop,
|
||||
avrCoatingWeightBottom: data.appMeasureCoatMessage.avrCoatingWeightBottom,
|
||||
airKnifePressure: data.appMeasureCoatMessage.airKnifePressure,
|
||||
stripSpeedTmExit: data.appMeasureCoatMessage.stripSpeedTmExit
|
||||
});
|
||||
}
|
||||
|
||||
// 处理出口数据
|
||||
if (data.appMeasureExitMessage) {
|
||||
this.addDataPoint('exit', timeLabel, {
|
||||
tensionBr8Br9: data.appMeasureExitMessage.tensionBr8Br9,
|
||||
tensionBr9Tr: data.appMeasureExitMessage.tensionBr9Tr,
|
||||
speedExitSection: data.appMeasureExitMessage.speedExitSection
|
||||
});
|
||||
}
|
||||
|
||||
// 更新当前显示的图表
|
||||
this.updateCurrentChart();
|
||||
},
|
||||
|
||||
// 添加数据点到对应图表数据
|
||||
addDataPoint(chartType, time, values) {
|
||||
// 添加时间标签
|
||||
this.chartData[chartType].time.push(time);
|
||||
|
||||
// 添加各项数据
|
||||
Object.keys(values).forEach(key => {
|
||||
if (this.chartData[chartType][key] !== undefined) {
|
||||
this.chartData[chartType][key].push(values[key]);
|
||||
}
|
||||
});
|
||||
|
||||
// 保持数据点数量在maxDataPoints以内
|
||||
if (this.chartData[chartType].time.length > this.maxDataPoints) {
|
||||
this.chartData[chartType].time.shift();
|
||||
|
||||
Object.keys(values).forEach(key => {
|
||||
if (this.chartData[chartType][key] !== undefined) {
|
||||
this.chartData[chartType][key].shift();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 更新当前显示的图表
|
||||
updateCurrentChart() {
|
||||
if (this.chartInstance) {
|
||||
this.chartInstance.setOption({
|
||||
xAxis: { data: this.chartData[this.currentChart].time },
|
||||
series: this.getSeriesData()
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 获取当前图表的系列数据
|
||||
getSeriesData() {
|
||||
switch (this.currentChart) {
|
||||
case 'entry':
|
||||
return [
|
||||
{ data: this.chartData.entry.tensionPorBr1 },
|
||||
{ data: this.chartData.entry.tensionBr1Br2 },
|
||||
{ data: this.chartData.entry.tensionBr2Br3 },
|
||||
{ data: this.chartData.entry.stripSpeed }
|
||||
];
|
||||
|
||||
case 'furnace':
|
||||
return [
|
||||
{ data: this.chartData.furnace.phFurnaceTemperatureActual },
|
||||
{ data: this.chartData.furnace.nof1FurnaceTemperatureActual },
|
||||
{ data: this.chartData.furnace.nof1FurnaceTemperatureSet }
|
||||
];
|
||||
|
||||
case 'coat':
|
||||
return [
|
||||
{ data: this.chartData.coat.avrCoatingWeightTop },
|
||||
{ data: this.chartData.coat.avrCoatingWeightBottom },
|
||||
{ data: this.chartData.coat.airKnifePressure },
|
||||
{ data: this.chartData.coat.stripSpeedTmExit }
|
||||
];
|
||||
|
||||
case 'exit':
|
||||
return [
|
||||
{ data: this.chartData.exit.tensionBr8Br9 },
|
||||
{ data: this.chartData.exit.tensionBr9Tr },
|
||||
{ data: this.chartData.exit.speedExitSection }
|
||||
];
|
||||
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.process-monitor {
|
||||
padding: 20px;
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #3f4449;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.control-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.chart-selector {
|
||||
padding: 10px;
|
||||
background-color: #4a4f55;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.chart-selector label {
|
||||
margin-right: 10px;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.chart-selector select {
|
||||
padding: 5px 10px;
|
||||
border: 1px solid #5d6268;
|
||||
border-radius: 4px;
|
||||
background-color: #555a60;
|
||||
color: #e0e0e0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.connection-status {
|
||||
padding: 8px 10px;
|
||||
border-radius: 4px;
|
||||
background-color: #4a4f55;
|
||||
color: #ffd700;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.connection-status.connected {
|
||||
color: #32cd32;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
background-color: #4a4f55;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
margin-top: 0;
|
||||
color: #f0f0f0;
|
||||
font-size: 18px;
|
||||
border-bottom: 1px solid #5d6268;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
height: 400px; /* 增大图表高度提升可读性 */
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
.control-bar {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.connection-status {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.chart {
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -30,7 +30,7 @@ export default {
|
||||
.app-main {
|
||||
/* 50= navbar 50 */
|
||||
min-height: calc(100vh - 50px);
|
||||
background-color: #3f4449;
|
||||
// background-color: #3f4449;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -104,7 +104,7 @@ export default {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
// 金属质感渐变背景
|
||||
background: #454c51;
|
||||
// background: #454c51;
|
||||
border-bottom: 1px solid #8d939b;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1),
|
||||
0 1px 1px rgba(255, 255, 255, 0.08) inset;
|
||||
@@ -156,7 +156,7 @@ export default {
|
||||
height: 100%;
|
||||
font-size: 18px;
|
||||
// 金属风格文字色
|
||||
color: #ddd;
|
||||
color: #111;
|
||||
vertical-align: text-bottom;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
<logo v-if="showLogo" :collapse="isCollapse" />
|
||||
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
|
||||
<el-menu
|
||||
active-text-color="#fff"
|
||||
active-text-color="#000"
|
||||
:default-active="activeMenu"
|
||||
:collapse="isCollapse"
|
||||
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
|
||||
:text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
|
||||
text-color="#111"
|
||||
:unique-opened="true"
|
||||
:collapse-transition="false"
|
||||
mode="vertical"
|
||||
|
||||
@@ -242,7 +242,7 @@ export default {
|
||||
height: 34px;
|
||||
width: 100%;
|
||||
// 金属浅色渐变背景(直接写死渐变值)
|
||||
background: #454c51;
|
||||
// background: #454c51;
|
||||
border-bottom: 1px solid #a0a6ad;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(255, 255, 255, 0.05) inset;
|
||||
|
||||
@@ -254,9 +254,9 @@ export default {
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
border: 1px solid #a0a6ad;
|
||||
color: #fff;
|
||||
// color: #fff;
|
||||
// 标签金属渐变背景
|
||||
background: #454c51;
|
||||
// background: #454c51;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
margin-left: 5px;
|
||||
|
||||
@@ -76,7 +76,6 @@ export default {
|
||||
}
|
||||
|
||||
.drawer-bg {
|
||||
background: #000;
|
||||
opacity: 0.3;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
|
||||
@@ -7,7 +7,7 @@ import Element from 'element-ui'
|
||||
import './assets/styles/element-variables.scss'
|
||||
|
||||
import '@/assets/styles/index.scss' // global css
|
||||
import '@/assets/styles/ruoyi.scss' // ruoyi css
|
||||
// import '@/assets/styles/ruoyi.scss' // ruoyi css
|
||||
import App from './App'
|
||||
import store from './store'
|
||||
import router from './router'
|
||||
|
||||
@@ -7,7 +7,7 @@ module.exports = {
|
||||
/**
|
||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||
*/
|
||||
sideTheme: 'theme-dark',
|
||||
sideTheme: 'theme-light',
|
||||
|
||||
/**
|
||||
* 系统布局配置
|
||||
|
||||
@@ -47,6 +47,17 @@
|
||||
/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-card>
|
||||
<div slot="header"><span>过程跟踪</span></div>
|
||||
<TrackMeasure
|
||||
v-loading="measureLoading"
|
||||
:columns="measureColumns"
|
||||
:data="measureData"
|
||||
tableHeight="300px"
|
||||
/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
@@ -59,10 +70,11 @@ import MiniTable from "./components/MiniTable.vue";
|
||||
import { getLogDataPage } from "@/api/l2/log";
|
||||
import { getRollHistorytList } from '@/api/l2/roller'
|
||||
import { listPlan } from "@/api/l2/plan";
|
||||
import TrackMeasure from "@/components/TrackMeasure/index.vue";
|
||||
|
||||
export default {
|
||||
name: "Index",
|
||||
components: { CurrentTime, HomeMain, MiniTable },
|
||||
components: { CurrentTime, HomeMain, MiniTable, TrackMeasure },
|
||||
data() {
|
||||
return {
|
||||
featureCards: [
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
<Pagination
|
||||
v-show="pagination.total>0"
|
||||
:total="pagination.total"
|
||||
v-model:page="pagination.currentPage"
|
||||
v-model:limit="pagination.pageSize"
|
||||
:page.sync="pagination.currentPage"
|
||||
:limit.sync="pagination.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
@@ -175,7 +175,7 @@ export default {
|
||||
// 从父组件调用的查询方法
|
||||
getList(params) {
|
||||
console.log('接收到父组件的搜索参数:', params)
|
||||
this.pagination.currentPage = 1
|
||||
// this.pagination.currentPage = 1
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<el-table-column prop="rolledLength" label="长度" width="70" />
|
||||
<el-table-column prop="rolledWeight" label="重量" width="70" />
|
||||
<el-table-column prop="rolledCount" label="轧制数量" width="75" />
|
||||
<el-table-column prop="instalTime" label="装机时间" width="133" />
|
||||
<el-table-column prop="instalTime" label="装机时间" width="160" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
637
apps/l2/src/views/l2/socket/index.vue
Normal file
637
apps/l2/src/views/l2/socket/index.vue
Normal file
@@ -0,0 +1,637 @@
|
||||
<template>
|
||||
<div class="socket-monitor">
|
||||
<!-- 类型选择器 -->
|
||||
<div class="type-selector">
|
||||
<label>数据类型:</label>
|
||||
<select v-model="currentType" @change="handleTypeChange">
|
||||
<option v-for="type in types" :key="type" :value="type">{{ type }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- 连接状态指示 -->
|
||||
<div class="connection-status" :class="{ connected: isConnected }">
|
||||
连接状态:{{ isConnected ? '已连接' : '连接中...' }}
|
||||
</div>
|
||||
|
||||
<!-- 图表区域 - 仅在track_measure类型时显示 -->
|
||||
<div v-if="currentType === 'track_measure'" class="charts-container">
|
||||
<div class="chart-group">
|
||||
<h3>入口数据监控</h3>
|
||||
<div ref="entryChart" class="chart"></div>
|
||||
</div>
|
||||
|
||||
<div class="chart-group">
|
||||
<h3>炉温数据监控</h3>
|
||||
<div ref="furnaceChart" class="chart"></div>
|
||||
</div>
|
||||
|
||||
<div class="chart-group">
|
||||
<h3>涂层数据监控</h3>
|
||||
<div ref="coatChart" class="chart"></div>
|
||||
</div>
|
||||
|
||||
<div class="chart-group">
|
||||
<h3>出口数据监控</h3>
|
||||
<div ref="exitChart" class="chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 其他类型提示 -->
|
||||
<div v-else class="other-type-info">
|
||||
选择 "track_measure" 类型以查看数据图表
|
||||
</div>
|
||||
|
||||
<!-- 原始数据展示区 -->
|
||||
<div class="raw-data">
|
||||
<h3>原始数据</h3>
|
||||
<pre>{{ formattedRawData }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
export default {
|
||||
name: 'SocketMonitor',
|
||||
data() {
|
||||
return {
|
||||
socket: null,
|
||||
types: [
|
||||
'alarm',
|
||||
'track_position',
|
||||
'calc_setup_result',
|
||||
'track_measure',
|
||||
'track_signal',
|
||||
'track_matmap'
|
||||
],
|
||||
currentType: 'track_measure',
|
||||
isConnected: false,
|
||||
rawData: null,
|
||||
// 图表实例
|
||||
entryChart: null,
|
||||
furnaceChart: null,
|
||||
coatChart: null,
|
||||
exitChart: null,
|
||||
// 图表数据存储
|
||||
chartData: {
|
||||
entry: {
|
||||
time: [],
|
||||
tensionPorBr1: [],
|
||||
tensionBr1Br2: [],
|
||||
tensionBr2Br3: [],
|
||||
stripSpeed: []
|
||||
},
|
||||
furnace: {
|
||||
time: [],
|
||||
phFurnaceTemperatureActual: [],
|
||||
nof1FurnaceTemperatureActual: [],
|
||||
nof1FurnaceTemperatureSet: []
|
||||
},
|
||||
coat: {
|
||||
time: [],
|
||||
avrCoatingWeightTop: [],
|
||||
avrCoatingWeightBottom: [],
|
||||
airKnifePressure: [],
|
||||
stripSpeedTmExit: []
|
||||
},
|
||||
exit: {
|
||||
time: [],
|
||||
tensionBr8Br9: [],
|
||||
tensionBr9Tr: [],
|
||||
speedExitSection: []
|
||||
}
|
||||
},
|
||||
// 最多显示的数据点数量
|
||||
maxDataPoints: 30
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
formattedRawData() {
|
||||
if (!this.rawData) return '等待接收数据...';
|
||||
try {
|
||||
return JSON.stringify(JSON.parse(this.rawData), null, 2);
|
||||
} catch (e) {
|
||||
return this.rawData;
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 初始化为track_measure时直接初始化图表
|
||||
if (this.currentType === 'track_measure') {
|
||||
this.initCharts();
|
||||
}
|
||||
this.connectWebSocket();
|
||||
window.addEventListener('resize', this.handleWindowResize);
|
||||
},
|
||||
updated() {
|
||||
// 当组件更新且类型为track_measure时,确保图表已初始化
|
||||
if (this.currentType === 'track_measure' && !this.entryChart) {
|
||||
this.initCharts();
|
||||
}
|
||||
},
|
||||
unmounted() {
|
||||
this.disconnectWebSocket();
|
||||
this.destroyCharts();
|
||||
window.removeEventListener('resize', this.handleWindowResize);
|
||||
},
|
||||
methods: {
|
||||
// 初始化所有图表
|
||||
initCharts() {
|
||||
// 先销毁可能存在的旧实例
|
||||
this.destroyCharts();
|
||||
|
||||
// 确保DOM元素存在再初始化
|
||||
if (this.$refs.entryChart) {
|
||||
this.entryChart = echarts.init(this.$refs.entryChart);
|
||||
this.entryChart.setOption(this.getEntryChartOption());
|
||||
}
|
||||
|
||||
if (this.$refs.furnaceChart) {
|
||||
this.furnaceChart = echarts.init(this.$refs.furnaceChart);
|
||||
this.furnaceChart.setOption(this.getFurnaceChartOption());
|
||||
}
|
||||
|
||||
if (this.$refs.coatChart) {
|
||||
this.coatChart = echarts.init(this.$refs.coatChart);
|
||||
this.coatChart.setOption(this.getCoatChartOption());
|
||||
}
|
||||
|
||||
if (this.$refs.exitChart) {
|
||||
this.exitChart = echarts.init(this.$refs.exitChart);
|
||||
this.exitChart.setOption(this.getExitChartOption());
|
||||
}
|
||||
},
|
||||
|
||||
// 入口数据图表配置
|
||||
getEntryChartOption() {
|
||||
return {
|
||||
backgroundColor: 'transparent',
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: {
|
||||
data: ['入口张力1', '入口张力2', '入口张力3', '带钢速度'],
|
||||
textStyle: { color: '#e0e0e0' }
|
||||
},
|
||||
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: [],
|
||||
axisLine: { lineStyle: { color: '#666' } },
|
||||
axisLabel: { color: '#b0b0b0' }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#666' } },
|
||||
axisLabel: { color: '#b0b0b0' },
|
||||
splitLine: { lineStyle: { color: 'rgba(255, 255, 255, 0.1)' } }
|
||||
},
|
||||
series: [
|
||||
{ name: '入口张力1', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '入口张力2', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '入口张力3', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '带钢速度', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } }
|
||||
]
|
||||
};
|
||||
},
|
||||
|
||||
// 炉温数据图表配置
|
||||
getFurnaceChartOption() {
|
||||
return {
|
||||
backgroundColor: 'transparent',
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: {
|
||||
data: ['PH炉实际温度', 'NOF1炉实际温度', 'NOF1炉设定温度'],
|
||||
textStyle: { color: '#e0e0e0' }
|
||||
},
|
||||
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: [],
|
||||
axisLine: { lineStyle: { color: '#666' } },
|
||||
axisLabel: { color: '#b0b0b0' }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#666' } },
|
||||
axisLabel: { color: '#b0b0b0' },
|
||||
splitLine: { lineStyle: { color: 'rgba(255, 255, 255, 0.1)' } }
|
||||
},
|
||||
series: [
|
||||
{ name: 'PH炉实际温度', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: 'NOF1炉实际温度', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: 'NOF1炉设定温度', type: 'line', data: [], smooth: true, lineStyle: { width: 2, type: 'dashed' } }
|
||||
]
|
||||
};
|
||||
},
|
||||
|
||||
// 涂层数据图表配置
|
||||
getCoatChartOption() {
|
||||
return {
|
||||
backgroundColor: 'transparent',
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: {
|
||||
data: ['顶部平均涂层重量', '底部平均涂层重量', '气刀压力', '出口速度'],
|
||||
textStyle: { color: '#e0e0e0' }
|
||||
},
|
||||
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: [],
|
||||
axisLine: { lineStyle: { color: '#666' } },
|
||||
axisLabel: { color: '#b0b0b0' }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#666' } },
|
||||
axisLabel: { color: '#b0b0b0' },
|
||||
splitLine: { lineStyle: { color: 'rgba(255, 255, 255, 0.1)' } }
|
||||
},
|
||||
series: [
|
||||
{ name: '顶部平均涂层重量', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '底部平均涂层重量', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '气刀压力', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '出口速度', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } }
|
||||
]
|
||||
};
|
||||
},
|
||||
|
||||
// 出口数据图表配置
|
||||
getExitChartOption() {
|
||||
return {
|
||||
backgroundColor: 'transparent',
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: {
|
||||
data: ['出口张力1', '出口张力2', '出口速度'],
|
||||
textStyle: { color: '#e0e0e0' }
|
||||
},
|
||||
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: [],
|
||||
axisLine: { lineStyle: { color: '#666' } },
|
||||
axisLabel: { color: '#b0b0b0' }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#666' } },
|
||||
axisLabel: { color: '#b0b0b0' },
|
||||
splitLine: { lineStyle: { color: 'rgba(255, 255, 255, 0.1)' } }
|
||||
},
|
||||
series: [
|
||||
{ name: '出口张力1', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '出口张力2', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } },
|
||||
{ name: '出口速度', type: 'line', data: [], smooth: true, lineStyle: { width: 2 } }
|
||||
]
|
||||
};
|
||||
},
|
||||
|
||||
handleWindowResize() {
|
||||
if (this.entryChart) this.entryChart.resize();
|
||||
if (this.furnaceChart) this.furnaceChart.resize();
|
||||
if (this.coatChart) this.coatChart.resize();
|
||||
if (this.exitChart) this.exitChart.resize();
|
||||
},
|
||||
|
||||
destroyCharts() {
|
||||
if (this.entryChart) {
|
||||
this.entryChart.dispose();
|
||||
this.entryChart = null;
|
||||
}
|
||||
if (this.furnaceChart) {
|
||||
this.furnaceChart.dispose();
|
||||
this.furnaceChart = null;
|
||||
}
|
||||
if (this.coatChart) {
|
||||
this.coatChart.dispose();
|
||||
this.coatChart = null;
|
||||
}
|
||||
if (this.exitChart) {
|
||||
this.exitChart.dispose();
|
||||
this.exitChart = null;
|
||||
}
|
||||
},
|
||||
|
||||
connectWebSocket() {
|
||||
this.disconnectWebSocket();
|
||||
|
||||
this.isConnected = false;
|
||||
const url = `ws://140.143.206.120:18081/websocket?type=${this.currentType}`;
|
||||
|
||||
try {
|
||||
this.socket = new WebSocket(url);
|
||||
|
||||
this.socket.onopen = () => {
|
||||
console.log('WebSocket连接已建立');
|
||||
this.isConnected = true;
|
||||
};
|
||||
|
||||
this.socket.onmessage = (event) => {
|
||||
this.rawData = event.data;
|
||||
this.processData(event.data);
|
||||
};
|
||||
|
||||
this.socket.onerror = (error) => {
|
||||
console.error('WebSocket错误:', error);
|
||||
this.isConnected = false;
|
||||
};
|
||||
|
||||
this.socket.onclose = (event) => {
|
||||
console.log(`WebSocket连接已关闭: ${event.code} - ${event.reason}`);
|
||||
this.isConnected = false;
|
||||
|
||||
if (event.code !== 1000) {
|
||||
setTimeout(() => this.connectWebSocket(), 3000);
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('建立WebSocket连接失败:', error);
|
||||
setTimeout(() => this.connectWebSocket(), 3000);
|
||||
}
|
||||
},
|
||||
|
||||
disconnectWebSocket() {
|
||||
if (this.socket) {
|
||||
this.socket.close(1000, '主动关闭');
|
||||
this.socket = null;
|
||||
}
|
||||
},
|
||||
|
||||
// 修复核心:切换类型时重新初始化图表
|
||||
handleTypeChange() {
|
||||
this.rawData = null;
|
||||
this.resetChartData();
|
||||
|
||||
// 如果切换到track_measure类型,需要重新初始化图表
|
||||
if (this.currentType === 'track_measure') {
|
||||
// 确保DOM更新后再初始化图表(使用$nextTick)
|
||||
this.$nextTick(() => {
|
||||
this.initCharts();
|
||||
});
|
||||
} else {
|
||||
// 切换到其他类型时销毁图表
|
||||
this.destroyCharts();
|
||||
}
|
||||
|
||||
this.connectWebSocket();
|
||||
},
|
||||
|
||||
resetChartData() {
|
||||
this.chartData = {
|
||||
entry: { time: [], tensionPorBr1: [], tensionBr1Br2: [], tensionBr2Br3: [], stripSpeed: [] },
|
||||
furnace: { time: [], phFurnaceTemperatureActual: [], nof1FurnaceTemperatureActual: [], nof1FurnaceTemperatureSet: [] },
|
||||
coat: { time: [], avrCoatingWeightTop: [], avrCoatingWeightBottom: [], airKnifePressure: [], stripSpeedTmExit: [] },
|
||||
exit: { time: [], tensionBr8Br9: [], tensionBr9Tr: [], speedExitSection: [] }
|
||||
};
|
||||
|
||||
this.updateCharts();
|
||||
},
|
||||
|
||||
processData(data) {
|
||||
try {
|
||||
const parsedData = JSON.parse(data);
|
||||
|
||||
if (this.currentType === 'track_measure') {
|
||||
this.processTrackMeasureData(parsedData);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('数据解析错误:', error);
|
||||
}
|
||||
},
|
||||
|
||||
processTrackMeasureData(data) {
|
||||
const now = new Date();
|
||||
const timeLabel = `${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}.${now.getMilliseconds().toString().slice(0, 2)}`;
|
||||
|
||||
if (data.appMeasureEntryMessage) {
|
||||
this.addDataPoint('entry', timeLabel, {
|
||||
tensionPorBr1: data.appMeasureEntryMessage.tensionPorBr1,
|
||||
tensionBr1Br2: data.appMeasureEntryMessage.tensionBr1Br2,
|
||||
tensionBr2Br3: data.appMeasureEntryMessage.tensionBr2Br3,
|
||||
stripSpeed: data.appMeasureEntryMessage.stripSpeed
|
||||
});
|
||||
}
|
||||
|
||||
if (data.appMeasureFurnaceMessage) {
|
||||
this.addDataPoint('furnace', timeLabel, {
|
||||
phFurnaceTemperatureActual: data.appMeasureFurnaceMessage.phFurnaceTemperatureActual,
|
||||
nof1FurnaceTemperatureActual: data.appMeasureFurnaceMessage.nof1FurnaceTemperatureActual,
|
||||
nof1FurnaceTemperatureSet: data.appMeasureFurnaceMessage.nof1FurnaceTemperatureSet
|
||||
});
|
||||
}
|
||||
|
||||
if (data.appMeasureCoatMessage) {
|
||||
this.addDataPoint('coat', timeLabel, {
|
||||
avrCoatingWeightTop: data.appMeasureCoatMessage.avrCoatingWeightTop,
|
||||
avrCoatingWeightBottom: data.appMeasureCoatMessage.avrCoatingWeightBottom,
|
||||
airKnifePressure: data.appMeasureCoatMessage.airKnifePressure,
|
||||
stripSpeedTmExit: data.appMeasureCoatMessage.stripSpeedTmExit
|
||||
});
|
||||
}
|
||||
|
||||
if (data.appMeasureExitMessage) {
|
||||
this.addDataPoint('exit', timeLabel, {
|
||||
tensionBr8Br9: data.appMeasureExitMessage.tensionBr8Br9,
|
||||
tensionBr9Tr: data.appMeasureExitMessage.tensionBr9Tr,
|
||||
speedExitSection: data.appMeasureExitMessage.speedExitSection
|
||||
});
|
||||
}
|
||||
|
||||
this.updateCharts();
|
||||
},
|
||||
|
||||
addDataPoint(chartType, time, values) {
|
||||
this.chartData[chartType].time.push(time);
|
||||
|
||||
Object.keys(values).forEach(key => {
|
||||
if (this.chartData[chartType][key] !== undefined) {
|
||||
this.chartData[chartType][key].push(values[key]);
|
||||
}
|
||||
});
|
||||
|
||||
if (this.chartData[chartType].time.length > this.maxDataPoints) {
|
||||
this.chartData[chartType].time.shift();
|
||||
|
||||
Object.keys(values).forEach(key => {
|
||||
if (this.chartData[chartType][key] !== undefined) {
|
||||
this.chartData[chartType][key].shift();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
updateCharts() {
|
||||
if (this.entryChart) {
|
||||
this.entryChart.setOption({
|
||||
xAxis: { data: this.chartData.entry.time },
|
||||
series: [
|
||||
{ data: this.chartData.entry.tensionPorBr1 },
|
||||
{ data: this.chartData.entry.tensionBr1Br2 },
|
||||
{ data: this.chartData.entry.tensionBr2Br3 },
|
||||
{ data: this.chartData.entry.stripSpeed }
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
if (this.furnaceChart) {
|
||||
this.furnaceChart.setOption({
|
||||
xAxis: { data: this.chartData.furnace.time },
|
||||
series: [
|
||||
{ data: this.chartData.furnace.phFurnaceTemperatureActual },
|
||||
{ data: this.chartData.furnace.nof1FurnaceTemperatureActual },
|
||||
{ data: this.chartData.furnace.nof1FurnaceTemperatureSet }
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
if (this.coatChart) {
|
||||
this.coatChart.setOption({
|
||||
xAxis: { data: this.chartData.coat.time },
|
||||
series: [
|
||||
{ data: this.chartData.coat.avrCoatingWeightTop },
|
||||
{ data: this.chartData.coat.avrCoatingWeightBottom },
|
||||
{ data: this.chartData.coat.airKnifePressure },
|
||||
{ data: this.chartData.coat.stripSpeedTmExit }
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
if (this.exitChart) {
|
||||
this.exitChart.setOption({
|
||||
xAxis: { data: this.chartData.exit.time },
|
||||
series: [
|
||||
{ data: this.chartData.exit.tensionBr8Br9 },
|
||||
{ data: this.chartData.exit.tensionBr9Tr },
|
||||
{ data: this.chartData.exit.speedExitSection }
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 样式保持不变 */
|
||||
.socket-monitor {
|
||||
padding: 20px;
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #3f4449;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.type-selector {
|
||||
margin-bottom: 15px;
|
||||
padding: 10px;
|
||||
background-color: #4a4f55;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.type-selector select {
|
||||
margin-left: 10px;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid #5d6268;
|
||||
border-radius: 4px;
|
||||
background-color: #555a60;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.connection-status {
|
||||
margin-bottom: 20px;
|
||||
padding: 8px 10px;
|
||||
border-radius: 4px;
|
||||
background-color: #4a4f55;
|
||||
color: #ffd700;
|
||||
}
|
||||
|
||||
.connection-status.connected {
|
||||
background-color: #4a4f55;
|
||||
color: #32cd32;
|
||||
}
|
||||
|
||||
.charts-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(600px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.chart-group {
|
||||
background-color: #4a4f55;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.chart-group h3 {
|
||||
margin-top: 0;
|
||||
color: #f0f0f0;
|
||||
font-size: 16px;
|
||||
border-bottom: 1px solid #5d6268;
|
||||
padding-bottom: 8px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.other-type-info {
|
||||
text-align: center;
|
||||
padding: 50px;
|
||||
background-color: #4a4f55;
|
||||
border-radius: 6px;
|
||||
color: #b0b0b0;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.raw-data {
|
||||
background-color: #4a4f55;
|
||||
border-radius: 6px;
|
||||
padding: 15px;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.raw-data h3 {
|
||||
margin-top: 0;
|
||||
color: #f0f0f0;
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #5d6268;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.raw-data pre {
|
||||
margin: 0;
|
||||
font-family: monospace;
|
||||
color: #b0b0b0;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.raw-data::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.raw-data::-webkit-scrollbar-track {
|
||||
background: #555a60;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.raw-data::-webkit-scrollbar-thumb {
|
||||
background: #6d7278;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.raw-data::-webkit-scrollbar-thumb:hover {
|
||||
background: #858a90;
|
||||
}
|
||||
</style>
|
||||
@@ -39,7 +39,16 @@ module.exports = {
|
||||
pathRewrite: {
|
||||
['^' + process.env.VUE_APP_BASE_API]: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
// 新增WebSocket代理配置
|
||||
// '/ws-api': { // 匹配前端WebSocket连接的路径(如ws://localhost:80/ws-api)
|
||||
// target: '140.143.206.120:8089', // 目标WebSocket服务地址
|
||||
// ws: true, // 启用WebSocket代理
|
||||
// changeOrigin: true, // 改变请求源,解决跨域问题
|
||||
// pathRewrite: {
|
||||
// '^/ws-api': '' // 如果目标服务不需要路径前缀,可移除
|
||||
// }
|
||||
// }
|
||||
},
|
||||
disableHostCheck: true
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user