chore: 初始化株洲中车部装平台 Pad
This commit is contained in:
2
.env.development
Normal file
2
.env.development
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ENV = 'development'
|
||||||
|
VITE_BASE_URL = 'http://localhost:10081'
|
||||||
2
.env.production
Normal file
2
.env.production
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ENV = 'production'
|
||||||
|
VITE_BASE_URL = 'http://127.0.0.1:10081'
|
||||||
70
.eslintrc.cjs
Normal file
70
.eslintrc.cjs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
const { defineConfig } = require('eslint-define-config')
|
||||||
|
module.exports = defineConfig({
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
node: true,
|
||||||
|
es6: true
|
||||||
|
},
|
||||||
|
parser: 'vue-eslint-parser',
|
||||||
|
parserOptions: {
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
sourceType: 'module',
|
||||||
|
jsxPragma: 'React',
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
'plugin:vue/vue3-recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'prettier',
|
||||||
|
'plugin:prettier/recommended'
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
'vue/no-setup-props-destructure': 'off',
|
||||||
|
'vue/script-setup-uses-vars': 'error',
|
||||||
|
'vue/no-reserved-component-names': 'off',
|
||||||
|
'@typescript-eslint/ban-ts-ignore': 'off',
|
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'@typescript-eslint/no-var-requires': 'off',
|
||||||
|
'@typescript-eslint/no-empty-function': 'off',
|
||||||
|
'vue/custom-event-name-casing': 'off',
|
||||||
|
'no-use-before-define': 'off',
|
||||||
|
'@typescript-eslint/no-use-before-define': 'off',
|
||||||
|
'@typescript-eslint/ban-ts-comment': 'off',
|
||||||
|
'@typescript-eslint/ban-types': 'off',
|
||||||
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
'@typescript-eslint/no-unused-vars': 'off',
|
||||||
|
'no-unused-vars': 'off',
|
||||||
|
'space-before-function-paren': 'off',
|
||||||
|
|
||||||
|
'vue/attributes-order': 'off',
|
||||||
|
'vue/one-component-per-file': 'off',
|
||||||
|
'vue/html-closing-bracket-newline': 'off',
|
||||||
|
'vue/max-attributes-per-line': 'off',
|
||||||
|
'vue/multiline-html-element-content-newline': 'off',
|
||||||
|
'vue/singleline-html-element-content-newline': 'off',
|
||||||
|
'vue/attribute-hyphenation': 'off',
|
||||||
|
'vue/require-default-prop': 'off',
|
||||||
|
'vue/require-explicit-emits': 'off',
|
||||||
|
'vue/html-self-closing': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
html: {
|
||||||
|
void: 'always',
|
||||||
|
normal: 'never',
|
||||||
|
component: 'always'
|
||||||
|
},
|
||||||
|
svg: 'always',
|
||||||
|
math: 'always'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'vue/multi-word-component-names': 'off',
|
||||||
|
'vue/no-v-html': 'off',
|
||||||
|
'vue/require-toggle-inside-transition': 'off'
|
||||||
|
}
|
||||||
|
})
|
||||||
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
16
index.html
Normal file
16
index.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<link href="/vite.svg" rel="icon" type="image/svg+xml"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||||
|
<title>株洲中车部装平台Pad</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
document.write("<script src='./public/config.js?v=" + new Date().getTime() + "'><\/script>");
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script src="/src/main.js" type="module"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
4453
package-lock.json
generated
Normal file
4453
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
30
package.json
Normal file
30
package.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "zzbz-pad",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
|
"axios": "^1.7.7",
|
||||||
|
"element-plus": "^2.8.6",
|
||||||
|
"js-cookie": "^3.0.5",
|
||||||
|
"mqtt": "^5.10.4",
|
||||||
|
"pinia": "^2.2.5",
|
||||||
|
"rollup-plugin-copy": "^3.5.0",
|
||||||
|
"tdesign-vue-next": "^1.10.3",
|
||||||
|
"uuid": "^11.1.0",
|
||||||
|
"vue": "^3.5.12",
|
||||||
|
"vue-cookies": "^1.8.4",
|
||||||
|
"vue-router": "^4.4.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-vue": "^5.1.4",
|
||||||
|
"sass": "^1.80.5",
|
||||||
|
"vite": "^5.4.10"
|
||||||
|
}
|
||||||
|
}
|
||||||
19
prettier.config.js
Normal file
19
prettier.config.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export default {
|
||||||
|
printWidth: 100, // 一行最多多少字符
|
||||||
|
tabWidth: 2, // 缩进的宽度,2 个空格
|
||||||
|
useTabs: false, // 是否使用制表符,不使用制表符,使用空格
|
||||||
|
semi: false, // 语句结尾是否使用分号
|
||||||
|
bracketSpacing: true, // 大括号 {} 中开始和结束是否要空格,true — { foo: 1 },false — {foo: 1}
|
||||||
|
trailingComma: 'none', // 数组或对象或参数的最后一项是否尾随逗号,none — 没有尾随逗号,all — 尽可能使用尾随逗号,es5 — 在 ES5 中有效的尾随逗号(对象、数组等),TypeScript 和 Flow 类型参数中的尾随逗号。
|
||||||
|
arrowParens: 'always', // 只有一个参数的箭头函数是否带括号,always — 始终带括号,avoid — 不带括号
|
||||||
|
proseWrap: 'always', // 什么对代码进行折行,always — 如果超过 printWidth 指定的一行最多字符宽度,则进行折行;never — 将每块代码块展开成一行;preserve — 什么都不做,保持原样。
|
||||||
|
htmlWhitespaceSensitivity: 'strict', // 根据显示样式决定 html 要不要折行
|
||||||
|
endOfLine: 'auto', // 每行的结束符(回车符、换行符),取值请参考 https://www.prettier.cn/docs/options.html#end-of-line
|
||||||
|
// 每个文件格式化的范围是文件的全部内容
|
||||||
|
rangeStart: 0,
|
||||||
|
rangeEnd: Infinity,
|
||||||
|
// 不需要写文件开头的@prettier
|
||||||
|
requirePragma: false,
|
||||||
|
// 不需要自动在文件开头插入@prettier
|
||||||
|
insertPragma: false,
|
||||||
|
}
|
||||||
BIN
public/TopLogo.jpg
Normal file
BIN
public/TopLogo.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
61
public/config.js
Normal file
61
public/config.js
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
window.g = {
|
||||||
|
API_MES_URL: 'http://127.0.0.1:9981',
|
||||||
|
API_WEB_URL: 'http://127.0.0.1:10081',
|
||||||
|
Mqtt_Ip: "ws://124.220.15.242:8083/mqtt",
|
||||||
|
keyDataSearchCycle: 3,
|
||||||
|
};
|
||||||
|
window.plcPos = {
|
||||||
|
correspondenceList: {
|
||||||
|
600004: { name: '点动选择灯', value: 'carStatus1' },
|
||||||
|
600005: { name: '半自动选择灯', value: 'carStatus2' },
|
||||||
|
600006: { name: '上料自动选择灯', value: 'carStatus3' },
|
||||||
|
600007: { name: '下料自动选择灯', value: 'carStatus4' },
|
||||||
|
600010: { name: '正在充电灯', value: 'ZZCD' },
|
||||||
|
600011: { name: '电刷伸出到位灯', value: 'DSSCDW' },
|
||||||
|
600020: { name: '升降回原完成灯', value: 'SJHYWC' },
|
||||||
|
600025: { name: '上料位选择状态灯', value: 'SLXZ' },
|
||||||
|
600026: { name: '上料位到达状态灯', value: 'SLDD' },
|
||||||
|
600030: { name: '充电位选择状态灯', value: 'CDWXZ' },
|
||||||
|
600031: { name: '充电位到达状态灯', value: 'CDWDD' },
|
||||||
|
600033: { name: '位置1选择状态灯', value: 'WZ1XZ' },
|
||||||
|
600034: { name: '位置1到达状态灯', value: 'WZ1DD' },
|
||||||
|
600036: { name: '位置2选择状态灯', value: 'WZ2XZ' },
|
||||||
|
600037: { name: '位置2到达状态灯', value: 'WZ2DD' },
|
||||||
|
600041: { name: '位置3选择状态灯', value: 'WZ3XZ' },
|
||||||
|
600042: { name: '位置3到达状态灯', value: 'WZ3DD' },
|
||||||
|
600044: { name: '位置4选择状态灯', value: 'WZ4XZ' },
|
||||||
|
600045: { name: '位置4到达状态灯', value: 'WZ4DD' },
|
||||||
|
600047: { name: '位置5选择状态灯', value: 'WZ5XZ' },
|
||||||
|
600050: { name: '位置5到达状态灯', value: 'WZ5DD' },
|
||||||
|
600060: { name: '当前电量', value: 'batteryLevel' },
|
||||||
|
600100: { name: '小车位置', value: 'XCWZ' },
|
||||||
|
600140: { name: '升降位置', value: 'SJWZ' },
|
||||||
|
600180: { name: '充电电流', value: 'CDDL' },
|
||||||
|
600200: { name: '充电电压', value: 'CDDY' },
|
||||||
|
600220: { name: '心跳计数', value: 'XT' },
|
||||||
|
600240: { name: '充电模式', value: 'CDMS' },
|
||||||
|
},
|
||||||
|
buttonList: {
|
||||||
|
'启动': 600014,
|
||||||
|
'复位': 600015,
|
||||||
|
'点动': 600000,
|
||||||
|
'半自动': 600001,
|
||||||
|
'上料自动': 600002,
|
||||||
|
'下料自动': 600003,
|
||||||
|
'小车前进': 600016,
|
||||||
|
'小车后退': 600017,
|
||||||
|
'升降回原位': 600021,
|
||||||
|
'上升定位': 600022,
|
||||||
|
'下降定位': 600023,
|
||||||
|
'开始充电': 600012,
|
||||||
|
'停止充电': 600013,
|
||||||
|
'上料位选择': 600024,
|
||||||
|
'充电位选择': 600027,
|
||||||
|
'位置1选择': 600032,
|
||||||
|
'位置2选择': 600035,
|
||||||
|
'位置3选择': 600040,
|
||||||
|
'位置4选择': 600043,
|
||||||
|
'位置5选择': 600046,
|
||||||
|
'定位启动': 600051,
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/login.png
Normal file
BIN
public/login.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 MiB |
1
public/vite.svg
Normal file
1
public/vite.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
56
src/App.vue
Normal file
56
src/App.vue
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<template>
|
||||||
|
<t-loading :loading="isLoading" size="large" text="加载中(大)...">
|
||||||
|
<router-view/>
|
||||||
|
</t-loading>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {useAppStore} from "@/store/app.js";
|
||||||
|
import {storeToRefs} from "pinia";
|
||||||
|
|
||||||
|
const store = useAppStore();
|
||||||
|
// storeToRefs 响应式解构赋值 pinia
|
||||||
|
const {isLoading} = storeToRefs(store);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
// 定义的全局变量
|
||||||
|
body {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*修改提示框样式 更醒目*/
|
||||||
|
.el-message-box {
|
||||||
|
|
||||||
|
// 标题
|
||||||
|
.el-message-box__title {
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: rgb(255, 143, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提示文本
|
||||||
|
.el-message-box__message p {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// icon图标
|
||||||
|
.el-message-box__status {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-message-box__btns {
|
||||||
|
justify-content: space-evenly;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
width: 48%;
|
||||||
|
height: 6vh;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
BIN
src/assets/404_images/404.png
Normal file
BIN
src/assets/404_images/404.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
BIN
src/assets/404_images/404_cloud.png
Normal file
BIN
src/assets/404_images/404_cloud.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
50
src/components/HelloWorld.vue
Normal file
50
src/components/HelloWorld.vue
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<button type="button" @click="count++">count is {{ count }}</button>
|
||||||
|
<p>
|
||||||
|
Edit
|
||||||
|
<code>components/HelloWorld.vue</code> to test HMR
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Check out
|
||||||
|
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
||||||
|
>create-vue</a
|
||||||
|
>, the official Vue + Vite starter
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Learn more about IDE Support for Vue in the
|
||||||
|
<a
|
||||||
|
href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
|
||||||
|
target="_blank"
|
||||||
|
>Vue Docs Scaling up Guide</a
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
||||||
|
<el-button type="primary">21321312</el-button>
|
||||||
|
<t-button disabled loading>确定</t-button>
|
||||||
|
<t-button variant="dashed" ghost>幽灵按钮</t-button>
|
||||||
|
<icon name="cps-icon-home-sheep" url="https://tdesign.gtimg.com/icon/default-demo/index.js" size="2em" />
|
||||||
|
|
||||||
|
123
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Icon } from 'tdesign-icons-vue-next';
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
msg: String,
|
||||||
|
})
|
||||||
|
|
||||||
|
const count = ref(0)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.read-the-docs {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
48
src/main.js
Normal file
48
src/main.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import {createApp} from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
//ElementPlus
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
import 'element-plus/dist/index.css'
|
||||||
|
// TDesign
|
||||||
|
import TDesign from 'tdesign-vue-next'
|
||||||
|
// 引入组件库的少量全局样式变量
|
||||||
|
import 'tdesign-vue-next/es/style/index.css'
|
||||||
|
// pinia
|
||||||
|
import {createPinia} from 'pinia'
|
||||||
|
//router
|
||||||
|
import router from './router/index.js'
|
||||||
|
//crud
|
||||||
|
import curdVue3 from './utils/curdVue3'
|
||||||
|
// el-icon
|
||||||
|
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||||
|
import zhCn from 'element-plus/es/locale/lang/zh-cn'
|
||||||
|
|
||||||
|
const app = createApp(App)
|
||||||
|
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||||
|
app.component(key, component)
|
||||||
|
}
|
||||||
|
// 提供全局方法
|
||||||
|
|
||||||
|
|
||||||
|
app.use(ElementPlus, {
|
||||||
|
locale: zhCn,
|
||||||
|
})
|
||||||
|
|
||||||
|
app.use(TDesign)
|
||||||
|
const pinia = createPinia() // 创建 Pinia 实例
|
||||||
|
app.use(pinia)
|
||||||
|
app.use(curdVue3)
|
||||||
|
app.use(router)
|
||||||
|
|
||||||
|
app.provide('CreateData', app.config.globalProperties.CreateData)
|
||||||
|
app.provide('ExecDatabase', app.config.globalProperties.ExecDatabase)
|
||||||
|
app.provide('ExecDatabaseByParam', app.config.globalProperties.ExecDatabaseByParam)
|
||||||
|
app.provide('ExecWritePLC', app.config.globalProperties.ExecWritePLC)
|
||||||
|
app.provide('ExecReadPLC', app.config.globalProperties.ExecReadPLC)
|
||||||
|
app.provide('ExecMultReadPLC', app.config.globalProperties.ExecMultReadPLC)
|
||||||
|
app.provide('ExecIMESAPI', app.config.globalProperties.ExecIMESAPI)
|
||||||
|
|
||||||
|
app.mount('#app')
|
||||||
|
|
||||||
|
// useRouteGuard(); // 使用路由守卫
|
||||||
|
|
||||||
181
src/router/index.js
Normal file
181
src/router/index.js
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
import {createRouter, createWebHashHistory} from "vue-router";
|
||||||
|
import Cookies from 'js-cookie'
|
||||||
|
import {useAppStore} from "@/store/app.js";
|
||||||
|
|
||||||
|
// cookies
|
||||||
|
|
||||||
|
// 创建routes
|
||||||
|
const routes = [
|
||||||
|
{
|
||||||
|
// 重定向
|
||||||
|
path: "/home",
|
||||||
|
redirect: "/",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
//前台首页
|
||||||
|
path: "/",
|
||||||
|
name: "root",
|
||||||
|
component: () => import("@/views/Layout/index.vue"),
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
//前台首页
|
||||||
|
path: "/login",
|
||||||
|
component: () => import("@/views/Login/index.vue"),
|
||||||
|
},
|
||||||
|
// { // 404有毛病 目前 初始化动态路由有问题 404暂改为重定向到首页
|
||||||
|
// // 404
|
||||||
|
// path: "/:pathMatch(.*)*",
|
||||||
|
// component: () => import("@/views/404.vue"),
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
// 404
|
||||||
|
path: "/:pathMatch(.*)*",
|
||||||
|
redirect: "/login",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
//History路由模型
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHashHistory(import.meta.env.BASE_URL),
|
||||||
|
routes,
|
||||||
|
});
|
||||||
|
|
||||||
|
//这里设置路由拦截
|
||||||
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
// 设置游览器标题
|
||||||
|
if (to.meta.title) {
|
||||||
|
window.document.title = to.meta.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取store实例
|
||||||
|
const store = useAppStore();
|
||||||
|
|
||||||
|
// 检查Cookie中是否有用户信息
|
||||||
|
const userInfo = Cookies.get('userInfo');
|
||||||
|
const lastApiMesUrl = Cookies.get('API_MES_URL')
|
||||||
|
if (lastApiMesUrl) {
|
||||||
|
console.log('从cookie中获取的中控接口IP:', lastApiMesUrl)
|
||||||
|
window.g.API_MES_URL = lastApiMesUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastApiMeControlCode = Cookies.get('API_MES_ControlCode')
|
||||||
|
if (lastApiMeControlCode) {
|
||||||
|
console.log('从cookie中获取的中控代码:', lastApiMeControlCode)
|
||||||
|
window.g.API_MES_ControlCode = lastApiMeControlCode
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to.path === '/login') {
|
||||||
|
// 如果已经登录,则不允许访问登录页面
|
||||||
|
if (store.user.AID || userInfo) {
|
||||||
|
next('/');
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果未登录且Cookie中有用户信息,则恢复用户信息
|
||||||
|
if (!store.user.AID && userInfo) {
|
||||||
|
try {
|
||||||
|
const parsedUserInfo = JSON.parse(userInfo);
|
||||||
|
store.user = {
|
||||||
|
...store.user,
|
||||||
|
...parsedUserInfo
|
||||||
|
};
|
||||||
|
next();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析用户信息失败:', error);
|
||||||
|
next('/login');
|
||||||
|
}
|
||||||
|
} else if (!store.user.AID) {
|
||||||
|
// 如果未登录且Cookie中也没有用户信息,则跳转到登录页面
|
||||||
|
next('/login');
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 递归替换引入component
|
||||||
|
function dynamicRouter(routerList) {
|
||||||
|
const list = [];
|
||||||
|
routerList.forEach((route) => {
|
||||||
|
const routeItem = {
|
||||||
|
path: '/' + route.path,
|
||||||
|
name: route.path,
|
||||||
|
meta: {
|
||||||
|
title: route.权限模块,
|
||||||
|
},
|
||||||
|
component: async () => {
|
||||||
|
try {
|
||||||
|
const component = await import(`@/views/${route.path}/index.vue`);
|
||||||
|
console.log(component)
|
||||||
|
return component.default || component;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('引入路由组件失败,请确认地址是否配置正确:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
list.push(routeItem);
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动态添加路由的函数
|
||||||
|
export async function addDynamicRoutes(routerList) {
|
||||||
|
try {
|
||||||
|
// routerList.forEach(route => {
|
||||||
|
// console.log(123, route)
|
||||||
|
// // {权限模块:车体到位,path:CarBodyPlace}
|
||||||
|
// router.addRoute('root', {
|
||||||
|
// path: '/' + route.path,
|
||||||
|
// name:route.path,
|
||||||
|
// meta: {
|
||||||
|
// title: route.权限模块,
|
||||||
|
// },
|
||||||
|
// component: () => import(`@/views/${route.path}/index.vue`),
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// router.addRoute('root',{
|
||||||
|
// children: dynamicRouter(routerList)
|
||||||
|
// })
|
||||||
|
|
||||||
|
|
||||||
|
// let userId = Cookies.get('userId')
|
||||||
|
// if(userId !== ''){
|
||||||
|
// // 获取权限列表
|
||||||
|
// var param = []
|
||||||
|
// param[0] = ['userId', userId]
|
||||||
|
// var Data = CreateData('11', '基础表_权限模块_查询', param)
|
||||||
|
// ExecDatabase(Data).then(response => {
|
||||||
|
// if(response.data.length > 0){
|
||||||
|
// routerData.value.userRouterList = response.data
|
||||||
|
// // 创建动态路由列表
|
||||||
|
// const dynamicRoutes = dynamicRouter(response.data);
|
||||||
|
//
|
||||||
|
// dynamicRoutes.forEach((route) => {
|
||||||
|
// // 检查是否已存在该路由,避免重复添加
|
||||||
|
// if (!router.hasRoute(route.name)) {
|
||||||
|
// router.addRoute('root', route);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }else{
|
||||||
|
// ElMessage.warning('该角色未分配角色模块,请先进行分配!')
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
// 创建动态路由列表
|
||||||
|
const dynamicRoutes = dynamicRouter(routerList);
|
||||||
|
|
||||||
|
dynamicRoutes.forEach((route) => {
|
||||||
|
// 检查是否已存在该路由,避免重复添加
|
||||||
|
if (!router.hasRoute(route.name)) {
|
||||||
|
router.addRoute('root', route);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('动态添加路由失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default router;
|
||||||
76
src/router/useRouteGuard.js
Normal file
76
src/router/useRouteGuard.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import { inject } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import {ElMessage} from "element-plus";
|
||||||
|
import Cookies from "vue-cookies";
|
||||||
|
|
||||||
|
|
||||||
|
export function useRouteGuard() {
|
||||||
|
const router = useRouter();
|
||||||
|
const CreateData = inject('CreateData');
|
||||||
|
const ExecDatabase = inject('ExecDatabase');
|
||||||
|
let userId = Cookies.get('userId')
|
||||||
|
// 防止首次或者刷新界面路由失效
|
||||||
|
let registerRouteFresh = true
|
||||||
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
if (registerRouteFresh) {
|
||||||
|
if(userId !== ''){
|
||||||
|
// 获取权限列表
|
||||||
|
var param = []
|
||||||
|
param[0] = ['userId', userId]
|
||||||
|
var Data = CreateData('11', '基础表_权限模块_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if(response.data.length > 0){
|
||||||
|
routerData.value.userRouterList = response.data
|
||||||
|
// 创建动态路由列表
|
||||||
|
const dynamicRoutes = dynamicRouter(response.data);
|
||||||
|
|
||||||
|
dynamicRoutes.forEach((route) => {
|
||||||
|
// 检查是否已存在该路由,避免重复添加
|
||||||
|
if (!router.hasRoute(route.name)) {
|
||||||
|
router.addRoute('root', route);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
ElMessage.warning('该角色未分配角色模块,请先进行分配!')
|
||||||
|
}
|
||||||
|
next({ ...to, replace: true })
|
||||||
|
registerRouteFresh = false
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
next({ ...to, replace: true })
|
||||||
|
registerRouteFresh = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (to.meta.title) {
|
||||||
|
window.document.title = to.meta.title;
|
||||||
|
}
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 递归替换引入component
|
||||||
|
function dynamicRouter(routerList) {
|
||||||
|
const list = [];
|
||||||
|
routerList.forEach((route) => {
|
||||||
|
const routeItem = {
|
||||||
|
path: '/' + route.path,
|
||||||
|
name:route.path,
|
||||||
|
meta: {
|
||||||
|
title: route.权限模块,
|
||||||
|
},
|
||||||
|
component: async () => {
|
||||||
|
try {
|
||||||
|
const component = await import(`@/views/${route.path}/index.vue`);
|
||||||
|
console.log(component)
|
||||||
|
return component.default || component;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('引入路由组件失败,请确认地址是否配置正确:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
list.push(routeItem);
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
52
src/store/app.js
Normal file
52
src/store/app.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import {defineStore} from 'pinia'
|
||||||
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
|
|
||||||
|
// 第一个参数是应用程序中 store 的唯一 id
|
||||||
|
export const useAppStore = defineStore('app', {
|
||||||
|
// 其它配置项
|
||||||
|
state: () => {
|
||||||
|
let userData = {
|
||||||
|
isLoading: false,
|
||||||
|
isShow: true,
|
||||||
|
isShowFooter: false,
|
||||||
|
user: {
|
||||||
|
AID: '',
|
||||||
|
name: '',
|
||||||
|
classes: '',
|
||||||
|
teamGroup: '',
|
||||||
|
role: '',
|
||||||
|
userName: '',
|
||||||
|
password: '',
|
||||||
|
opName: '',
|
||||||
|
opDescription: '',
|
||||||
|
roleType: '',
|
||||||
|
},
|
||||||
|
routerData: {
|
||||||
|
userRouterList: [],
|
||||||
|
nowRouterPath: '',
|
||||||
|
nowRouterTitle: '',
|
||||||
|
selected: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 从Cookie中读取用户信息
|
||||||
|
const userInfoStr = Cookies.get('userInfo')
|
||||||
|
const loginKey = Cookies.get('loginKey')
|
||||||
|
|
||||||
|
if (userInfoStr && loginKey) {
|
||||||
|
try {
|
||||||
|
const userInfo = JSON.parse(userInfoStr)
|
||||||
|
userData.user = {
|
||||||
|
...userData.user,
|
||||||
|
...userInfo,
|
||||||
|
opDescription: userInfo.opDescription || Cookies.get('lastOpDescription') || userInfo.opName
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to parse user info from cookie', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return userData;
|
||||||
|
},
|
||||||
|
})
|
||||||
15
src/utils/auth.js
Normal file
15
src/utils/auth.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
|
const TokenKey = 'Admin-Token'
|
||||||
|
|
||||||
|
export function getToken() {
|
||||||
|
return Cookies.get(TokenKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setToken(token) {
|
||||||
|
return Cookies.set(TokenKey, token)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeToken() {
|
||||||
|
return Cookies.remove(TokenKey)
|
||||||
|
}
|
||||||
435
src/utils/curd.js
Normal file
435
src/utils/curd.js
Normal file
@@ -0,0 +1,435 @@
|
|||||||
|
import { ExcelDownLoad } from '@/utils/request'
|
||||||
|
import request from '@/utils/request'
|
||||||
|
import Cookie from 'js-cookie'
|
||||||
|
import { type } from './tool' // type判断传入值的类型,比typeof更详细
|
||||||
|
export default {
|
||||||
|
exportExcel_NPOI(param) {
|
||||||
|
console.log(param, 1)
|
||||||
|
download(`${ExcelDownLoad}?param=${param}`)
|
||||||
|
},
|
||||||
|
// 用于生成传通讯服务器参数。
|
||||||
|
// 传入参数
|
||||||
|
// 1)type:11查询;12增删改,必须
|
||||||
|
// 2)name:存储过程名,必须
|
||||||
|
// 3)data:存储过程参数名和对应值,例如:
|
||||||
|
// param[0] = ['工艺计划流水号', this.工艺计划流水号] 输入参数
|
||||||
|
// param[1] = ['PageCurrent', '1111', 'int', '1'] output参数
|
||||||
|
// 数组里四个分别对应:存储过程参数名(必须);存储过程参数值(必须);参数类型(若是output必须);参数是否为output(0否1是)
|
||||||
|
// 4)pageSize,pageList:分页使用,可选
|
||||||
|
CreateData(type, name, data, pageSize, pageList) {
|
||||||
|
var param_Str = ''
|
||||||
|
var param_array = []
|
||||||
|
if (type === '7') {
|
||||||
|
data.map(v => {
|
||||||
|
pageSize.map(h => {
|
||||||
|
const val = h.toString()
|
||||||
|
if (!v[val]) {
|
||||||
|
this.$set(v, val, '')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
param_Str = data
|
||||||
|
} else {
|
||||||
|
if (data !== undefined) {
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
param_array.push({
|
||||||
|
name: data[i][0],
|
||||||
|
value: data[i][1],
|
||||||
|
type: data[i][2],
|
||||||
|
output: data[i][3]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
param_Str = JSON.stringify(param_array)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var obj = []
|
||||||
|
obj[0] = {}
|
||||||
|
obj[0].type = type
|
||||||
|
obj[0].name = name
|
||||||
|
obj[0].param = param_Str
|
||||||
|
obj[0].pageSize = pageSize
|
||||||
|
obj[0].pageList = pageList
|
||||||
|
obj[0].UserID = Cookie.get('username')
|
||||||
|
obj[0].ModularID = ''//this.$router.currentRoute.path
|
||||||
|
console.log(obj[0], 'obj[0]')
|
||||||
|
var numn = JSON.stringify(obj[0])
|
||||||
|
return numn
|
||||||
|
},
|
||||||
|
// 新通讯11/12---<
|
||||||
|
ExecDatabase(data) {
|
||||||
|
return request({
|
||||||
|
url: '',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 高精原CreateData
|
||||||
|
// Vue.prototype.CreateData = function(type, name, data, pageSize, pageList) {
|
||||||
|
// var paramStr = ''
|
||||||
|
// var paramarray = []
|
||||||
|
// if (data !== undefined) {
|
||||||
|
// for (let i = 0; i < data.length; i++) {
|
||||||
|
// paramarray.push({
|
||||||
|
// name: data[i][0],
|
||||||
|
// value: data[i][1],
|
||||||
|
// type: data[i][2],
|
||||||
|
// output: data[i][3]
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// paramStr = JSON.stringify(paramarray)
|
||||||
|
// }
|
||||||
|
// var obj = []
|
||||||
|
// obj[0] = {}
|
||||||
|
// obj[0].type = type
|
||||||
|
// obj[0].name = name
|
||||||
|
// obj[0].param = paramStr
|
||||||
|
// obj[0].pageSize = pageSize
|
||||||
|
// obj[0].pageList = pageList
|
||||||
|
// var numn = JSON.stringify(obj[0])
|
||||||
|
// return numn
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 用于打开增加框,方法能重置表单,并使表单内容回到初始化状态。
|
||||||
|
// 传入参数
|
||||||
|
// 1)表单名称,字符串形式如'form',必须
|
||||||
|
// 2) 打开表单后需要做什么,可以传数组[this.dialogvisiale = false, fetchData],也可以传回调函数function() { this.dialogvisiale = false } 可选
|
||||||
|
addForm(form, callback) {
|
||||||
|
if (type(form) === 'string') {
|
||||||
|
if (this.$refs[form]) { // 判断是否需要重置表单,如果需要重置表单
|
||||||
|
this.$refs[form].resetFields()
|
||||||
|
}
|
||||||
|
if (type(callback) === 'array') { // 判断传入是否为数组,如果是遍历数组,遇到函数将函数体变成函数执行,其余正常执行
|
||||||
|
if (callback && callback.length !== 0) {
|
||||||
|
for (let i = 0, len = callback.length; i < len; i++) {
|
||||||
|
typeof callback[i] === 'function' ? callback[i]() : callback[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type(callback) === 'function') { // 判断传入是否为回调函数
|
||||||
|
callback.call(this) // 回调函数执行,需将this改为该组件
|
||||||
|
}
|
||||||
|
this[form] = Object.assign(this.$data[form], this.$options.data()[form]) // 将表单中的数据变为初始状态。其中,this.$options.data是所有初始化的数据,this.$data是目前的数据
|
||||||
|
} else {
|
||||||
|
console.error('传入参数错误')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 用于打开编辑框,方法能自动传入行的数据到对应的表单中,并将表单中所有纯数字转成int。前提是行的名称需跟表单名称一样。
|
||||||
|
// 传入参数
|
||||||
|
// 1) 编辑这一行的row
|
||||||
|
// 2)表单名称,字符串形式如'form'
|
||||||
|
// 3) 打开编辑需要做什么,同样是[] 和 function
|
||||||
|
editForm(row, form, callback) {
|
||||||
|
if (type(row) === 'object' && type(form) === 'string') {
|
||||||
|
if (this.$refs[form]) { // 判断是否需要重置表单
|
||||||
|
this.$refs[form].resetFields()
|
||||||
|
}
|
||||||
|
const isNum = /^[0-9]+$/ // 正则表达式,是否全都为纯数字
|
||||||
|
for (const prop in this[form]) { // 遍历表单,当表单和row中属性名一样时,表单row中的属性赋值给form
|
||||||
|
isNum.lastIndex = 0 // 正则每一次匹配后的索引归0,否则循环会造成问题
|
||||||
|
isNum.exec(row[prop]) ? this[form][prop] = parseInt(row[prop]) : this[form][prop] = row[prop] // 通过正则匹配数字,当匹配成功后,将字符串转为int。当然你也不用担心空转成NaN,因为''匹配通不过!
|
||||||
|
}
|
||||||
|
if (type(callback) === 'array') { // 这部分处理与打开表单相同
|
||||||
|
if (callback && callback.length !== 0) {
|
||||||
|
for (let i = 0, len = callback.length; i < len; i++) {
|
||||||
|
typeof callback[i] === 'function' ? callback[i]() : callback[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type(callback) === 'function') {
|
||||||
|
callback.call(this)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('传入参数错误')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 用于获取下拉框中的数据
|
||||||
|
// 传入参数
|
||||||
|
// 1)请求数据函数引用如getXXX,必须
|
||||||
|
// 2)数组的实行名称['XXXX名称', 'XXXX代码'],必须
|
||||||
|
// 3)需要用哪个数组接收这个结果,字符串形式。如在组件也需要用this.select,传入值就为'select',必须
|
||||||
|
// 4) 请求函数传入的参数,可选
|
||||||
|
getSelect(requestData, select, carrier, param) {
|
||||||
|
if (type(requestData) === 'function' && type(select) === 'array' && type(carrier) === 'string') {
|
||||||
|
if (type(param) === 'array') {
|
||||||
|
requestData(...param).then(response => { // 这个方法没什么难度,不注释了
|
||||||
|
this[carrier] = []
|
||||||
|
for (let i = 0, len = response.data.length; i < len; i++) {
|
||||||
|
if (select.length === 2) {
|
||||||
|
this[carrier].push({
|
||||||
|
label: response.data[i][select[0]],
|
||||||
|
value: response.data[i][select[1]]
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this[carrier].push({
|
||||||
|
value: response.data[i][select[0]]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
requestData(param).then(response => { // 这个方法没什么难度,不注释了
|
||||||
|
this[carrier] = []
|
||||||
|
for (let i = 0, len = response.data.length; i < len; i++) {
|
||||||
|
if (select.length === 2) {
|
||||||
|
this[carrier].push({
|
||||||
|
label: response.data[i][select[0]],
|
||||||
|
value: response.data[i][select[1]]
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this[carrier].push({
|
||||||
|
value: response.data[i][select[0]]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('参数传递错误')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 普通获取数据
|
||||||
|
// 传入参数
|
||||||
|
// 1) 请求数据函数引用如getXXX,必须
|
||||||
|
// 2) 需要用哪个数组接收这个结果,字符串形式。如在组件也需要用this.select,传入值就为'select',必须
|
||||||
|
// 3) 请求函数传入的参数,可选
|
||||||
|
getData(requestData, carrier, param) {
|
||||||
|
if (type(requestData) === 'function' && type(carrier) === 'string') {
|
||||||
|
if (type(param) === 'undefined') {
|
||||||
|
requestData(param).then(response => {
|
||||||
|
const data = response.data
|
||||||
|
this[carrier] = data
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
let Param = []
|
||||||
|
if (type(param) !== 'array') {
|
||||||
|
Param.push(param)
|
||||||
|
} else {
|
||||||
|
Param = param
|
||||||
|
}
|
||||||
|
requestData(...Param).then(response => {
|
||||||
|
const data = response.data
|
||||||
|
this[carrier] = data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('传入参数错误')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取表格数据,将表格中的年月日时分秒,转换成年月日
|
||||||
|
// 传入参数
|
||||||
|
// 1)请求数据函数引用如getXXX,必须
|
||||||
|
// 2)请求的参数,可选
|
||||||
|
// 3)接受值,数组,一般是['table','total','loading']顺序不能变
|
||||||
|
getTable(requestData, param, e) {
|
||||||
|
requestData(...param).then(response => {
|
||||||
|
const data = response.data.rows
|
||||||
|
this[e[0]] = []
|
||||||
|
this[e[1]] = 0
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
const isTime = /^\d{4}([-\/.])\d{1,2}\1\d{1,2}/ // 判断是否是时间的正则表达式
|
||||||
|
for (let i = 0, len = data.length; i < len; i++) { // 循环得到每一条数据
|
||||||
|
for (const prop in data[i]) { // 循环每一条的每一项
|
||||||
|
isTime.lastIndex = 0 // 正则每一次指针复位
|
||||||
|
if (isTime.test(data[i][prop])) { // 判断是否是时间,如果是切割
|
||||||
|
data[i][prop] = data[i][prop].split(' ')[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this[e[0]] = data
|
||||||
|
this[e[1]] = parseInt(response.data.total)
|
||||||
|
} else {
|
||||||
|
this[e[0]] = []
|
||||||
|
// console.log('暂无数据')
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
this[e[2]] = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 添加表格数据
|
||||||
|
// 传入参数
|
||||||
|
// 1) 请求数据函数引用如getXXX,必须
|
||||||
|
// 2) 请求的参数,可选
|
||||||
|
// 3) 验证的表单名称,必须
|
||||||
|
// 4) 回调函数,必须
|
||||||
|
addTable(requestData, param, form, callback) {
|
||||||
|
if (type(callback) === 'function' && type(requestData) === 'function' && type(form) === 'string') {
|
||||||
|
console.log(this.$refs[form])
|
||||||
|
this.$refs[form].validate((valid) => {
|
||||||
|
console.log(valid)
|
||||||
|
if (valid) {
|
||||||
|
requestData(...param).then(response => {
|
||||||
|
if (response.data[0].result === '1') {
|
||||||
|
this.$message.success('增加成功')
|
||||||
|
callback.call(this)
|
||||||
|
} else { this.$message.error('增加失败') }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error('error submit!!')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error('参数传递错误')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 编辑表格数据
|
||||||
|
// 传入参数
|
||||||
|
// 1) 请求数据函数引用如getXXX,必须
|
||||||
|
// 2) 请求的参数,可选
|
||||||
|
// 3) 验证的表单名称,必须
|
||||||
|
// 4) 回调函数,必须
|
||||||
|
editTable(requestData, param, form, callback) {
|
||||||
|
if (type(callback) === 'function' && type(requestData) === 'function' && type(form) === 'string') {
|
||||||
|
this.$refs[form].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
requestData(...param).then(response => {
|
||||||
|
if (response.data[0].result === '1') {
|
||||||
|
this.$message.success('修改成功')
|
||||||
|
callback.call(this) // 回调函数修正this指向组件本身
|
||||||
|
} else { this.$message.error('修改失败') }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error('error submit!!')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error('参数传递错误')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 删除表格数据
|
||||||
|
// 传入参数
|
||||||
|
// 1) 请求数据函数引用如getXXX,必须
|
||||||
|
// 2) id传入删除条件,必须
|
||||||
|
// 3) 回调函数,必须
|
||||||
|
deleteRow(requestData, id, callback) {
|
||||||
|
if (type(callback) === 'function' && type(requestData) === 'function') {
|
||||||
|
if (this.tableData && this.tableData.length === 1 && this.pageCurrent > 1) { // 判断删除的是否是最后一页最后一行,如果是且不是第一页,页数减一
|
||||||
|
this.pageCurrent--
|
||||||
|
}
|
||||||
|
this.$confirm('此操作将永久删除该行, 是否继续?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
requestData(id).then(response => {
|
||||||
|
if (response.data[0].result === '1') {
|
||||||
|
this.$message.success('删除成功')
|
||||||
|
callback.call(this) // 回调函数修正this指向组件本身
|
||||||
|
} else { this.$message.error('数据占用') }
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
this.$message({
|
||||||
|
type: 'info',
|
||||||
|
message: '已取消删除'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error('参数传递错误')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 设置字段宽度
|
||||||
|
setColumnWidth(str) {
|
||||||
|
let columnWidth = 0
|
||||||
|
if (str === '日期') {
|
||||||
|
columnWidth = 90
|
||||||
|
} else if (str === '订单编号' || str === '领料单号' || str === '调拨单号' || str === '订单号' || str === '机床名称') {
|
||||||
|
columnWidth = 140
|
||||||
|
} else if (str === '合同编号' || str === '补货单号') {
|
||||||
|
columnWidth = 140
|
||||||
|
} else if (str === '产品名称' || str === '部件名称') {
|
||||||
|
columnWidth = 110
|
||||||
|
} else if (str === '序号') {
|
||||||
|
columnWidth = 60
|
||||||
|
} else if (str === '单位') {
|
||||||
|
columnWidth = 60
|
||||||
|
} else if (str === '数量' || str === '库存') {
|
||||||
|
columnWidth = 80
|
||||||
|
} else if (str === '单价') {
|
||||||
|
columnWidth = 90
|
||||||
|
} else if (str === '金额') {
|
||||||
|
columnWidth = 120
|
||||||
|
} else if (str === '状态' || str === '类型' || str === '选入' || str === '选出') {
|
||||||
|
columnWidth = 80
|
||||||
|
} else if (str === '付款方式') {
|
||||||
|
columnWidth = 100
|
||||||
|
} else if (str === '买方' || str === '买方名称') {
|
||||||
|
columnWidth = 150
|
||||||
|
} else if (str === '外协厂家' || str === '调入仓库' || str === '调出仓库') {
|
||||||
|
columnWidth = 150
|
||||||
|
} else if (str === '姓名') {
|
||||||
|
columnWidth = 80
|
||||||
|
} else if (str === '日期时间') {
|
||||||
|
columnWidth = 140
|
||||||
|
} else if (str === '工序') {
|
||||||
|
columnWidth = 80
|
||||||
|
} else if (str === '物料名称' || str === '工件名称' || str === '零件名称') {
|
||||||
|
columnWidth = 140
|
||||||
|
} else if (str === '图号或型号' || str === '规格' || str === '零件图号' || str === '图号' || str === '图号/型号') {
|
||||||
|
columnWidth = 120
|
||||||
|
} else if (str === '物料编码' || str === '物料编号') {
|
||||||
|
columnWidth = 120
|
||||||
|
} else if (str === '材料') {
|
||||||
|
columnWidth = 80
|
||||||
|
} else if (str === '仓位' || str === '库位') {
|
||||||
|
columnWidth = 90
|
||||||
|
} else if (str === '品名/规格/型号') {
|
||||||
|
columnWidth = 140
|
||||||
|
} else if (str === '备注') {
|
||||||
|
columnWidth = 120
|
||||||
|
} else if (str === '工序名称') {
|
||||||
|
columnWidth = 150
|
||||||
|
} else if (str === '工序说明') {
|
||||||
|
columnWidth = 300
|
||||||
|
} else if (str === '加工工时M' || str === '加工时长H' || str === '加工时长M') {
|
||||||
|
columnWidth = 90
|
||||||
|
} else if (str === '加工设备') {
|
||||||
|
columnWidth = 130
|
||||||
|
} else if (str === '产品详情' || str === '详情') {
|
||||||
|
columnWidth = 340
|
||||||
|
} else if (str === '最低库存') {
|
||||||
|
columnWidth = 110
|
||||||
|
} else if (str === '本次到货数' || str === '本次入库' || str === '补货数') {
|
||||||
|
columnWidth = 100
|
||||||
|
} else {
|
||||||
|
columnWidth = 110
|
||||||
|
}
|
||||||
|
return columnWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function download(url) {
|
||||||
|
getBlob(url, function(blob, filename) {
|
||||||
|
console.log(blob, filename, 2)
|
||||||
|
saveAs(blob, filename)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBlob(url, cb) {
|
||||||
|
var xhr = new XMLHttpRequest()
|
||||||
|
xhr.open('GET', url, true)
|
||||||
|
xhr.responseType = 'blob'
|
||||||
|
xhr.onload = function() {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
const name = xhr.getResponseHeader('content-disposition').split('=')[1]
|
||||||
|
var filename = decodeURIComponent(name)
|
||||||
|
cb(xhr.response, filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr.send()
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveAs(blob, filename) {
|
||||||
|
if (window.navigator.msSaveOrOpenBlob) {
|
||||||
|
navigator.msSaveBlob(blob, filename)
|
||||||
|
} else {
|
||||||
|
var link = document.createElement('a')
|
||||||
|
var body = document.querySelector('body')
|
||||||
|
link.href = window.URL.createObjectURL(blob)
|
||||||
|
link.download = filename
|
||||||
|
// fix Firefox
|
||||||
|
link.style.display = 'none'
|
||||||
|
body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
body.removeChild(link)
|
||||||
|
window.URL.revokeObjectURL(link.href)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
160
src/utils/curdVue3.js
Normal file
160
src/utils/curdVue3.js
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
import Cookie from 'js-cookie'
|
||||||
|
import {ElMessage} from 'element-plus'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
install(app) {
|
||||||
|
// 添加一个获取API URL的函数
|
||||||
|
const getApiUrl = () => {
|
||||||
|
// 优先从Cookie中获取
|
||||||
|
const apiUrl = Cookie.get('API_MES_URL')
|
||||||
|
// 如果Cookie中有值就用Cookie中的,没有就用全局变量的
|
||||||
|
return "http://" + (apiUrl || window.g.API_MES_URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
app.config.globalProperties.CreateData = function (type, name, data, pageSize, pageList) {
|
||||||
|
var param_Str = ''
|
||||||
|
var param_array = []
|
||||||
|
if (type === '7') {
|
||||||
|
data.map(v => {
|
||||||
|
pageSize.map(h => {
|
||||||
|
const val = h.toString()
|
||||||
|
if (!v[val]) {
|
||||||
|
this.$set(v, val, '')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
param_Str = data
|
||||||
|
} else {
|
||||||
|
if (data !== undefined) {
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
param_array.push({
|
||||||
|
name: data[i][0],
|
||||||
|
value: data[i][1],
|
||||||
|
type: data[i][2],
|
||||||
|
output: data[i][3]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
param_Str = JSON.stringify(param_array)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var obj = []
|
||||||
|
obj[0] = {}
|
||||||
|
obj[0].type = type
|
||||||
|
obj[0].name = name
|
||||||
|
obj[0].param = param_Str
|
||||||
|
obj[0].pageSize = pageSize
|
||||||
|
obj[0].pageList = pageList
|
||||||
|
obj[0].UserID = Cookie.get('username')
|
||||||
|
obj[0].ModularID = ''//this.$router.currentRoute.path
|
||||||
|
var numn = JSON.stringify(obj[0])
|
||||||
|
return numn
|
||||||
|
}
|
||||||
|
app.config.globalProperties.ExecDatabase = function (data) {
|
||||||
|
return request({
|
||||||
|
url: '',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
app.config.globalProperties.ExecDatabaseByParam = function (type, name, data, pageSize, pageList) {
|
||||||
|
var param_Str = ''
|
||||||
|
var param_array = []
|
||||||
|
if (type === '7') {
|
||||||
|
data.map(v => {
|
||||||
|
pageSize.map(h => {
|
||||||
|
const val = h.toString()
|
||||||
|
if (!v[val]) {
|
||||||
|
this.$set(v, val, '')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
param_Str = data
|
||||||
|
} else {
|
||||||
|
if (data !== undefined) {
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
param_array.push({
|
||||||
|
name: data[i][0],
|
||||||
|
value: data[i][1],
|
||||||
|
type: data[i][2],
|
||||||
|
output: data[i][3]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
param_Str = JSON.stringify(param_array)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var obj = []
|
||||||
|
obj[0] = {}
|
||||||
|
obj[0].type = type
|
||||||
|
obj[0].name = name
|
||||||
|
obj[0].param = param_Str
|
||||||
|
obj[0].pageSize = pageSize
|
||||||
|
obj[0].pageList = pageList
|
||||||
|
obj[0].UserID = Cookie.get('username')
|
||||||
|
obj[0].ModularID = ''//this.$router.currentRoute.path
|
||||||
|
console.log(obj[0], 'obj[0]')
|
||||||
|
var numn = JSON.stringify(obj[0])
|
||||||
|
return request({
|
||||||
|
url: '',
|
||||||
|
method: 'post',
|
||||||
|
data: numn
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
app.config.globalProperties.ExecWritePLC = function (opName, tagTypeCodeID, value) {
|
||||||
|
return request({
|
||||||
|
url: getApiUrl() + '/api/imes/Web_WritePLC',
|
||||||
|
method: 'post',
|
||||||
|
timeout: 20000,
|
||||||
|
data: {
|
||||||
|
tagTypeCodeID: tagTypeCodeID,
|
||||||
|
OPName: opName,
|
||||||
|
tagValue: value,
|
||||||
|
}
|
||||||
|
}).catch(function (error) {
|
||||||
|
// 如果接口调用失败,弹出错误弹窗
|
||||||
|
ElMessage.error('写入PLC数据接口失败: ' + error.message)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
app.config.globalProperties.ExecReadPLC = function (opName, tagTypeCodeID) {
|
||||||
|
return request({
|
||||||
|
url: getApiUrl() + '/api/imes/Web_ReadPLC',
|
||||||
|
method: 'post',
|
||||||
|
timeout: 30000,
|
||||||
|
data: {
|
||||||
|
tagTypeCodeID: tagTypeCodeID,
|
||||||
|
OPName: opName,
|
||||||
|
}
|
||||||
|
}).catch(function (error) {
|
||||||
|
// 如果接口调用失败,弹出错误弹窗
|
||||||
|
ElMessage.error('读取PLC数据接口失败: ' + error.message)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
app.config.globalProperties.ExecMultReadPLC = function (opName, tagTypeCodeIDs) {
|
||||||
|
return request({
|
||||||
|
url: getApiUrl() + '/api/imes/Web_MultReadPLC',
|
||||||
|
method: 'post',
|
||||||
|
timeout: 30000,
|
||||||
|
data: {
|
||||||
|
tagTypeCodeIDs: tagTypeCodeIDs,
|
||||||
|
OPName: opName,
|
||||||
|
}
|
||||||
|
}).catch(function (error) {
|
||||||
|
// 如果接口调用失败,弹出错误弹窗
|
||||||
|
ElMessage.error('批量读取PLC数据接口失败: ' + error.message)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
app.config.globalProperties.ExecIMESAPI = function (apiName, param) {
|
||||||
|
return request({
|
||||||
|
url: getApiUrl() + '/api/imes/' + apiName,
|
||||||
|
method: 'post',
|
||||||
|
timeout: 30000,
|
||||||
|
data: param
|
||||||
|
}).catch(function (error) {
|
||||||
|
// 如果接口调用失败,弹出错误弹窗
|
||||||
|
ElMessage.error('调用MES' + apiName + '接口失败: ' + error.message)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
96
src/utils/index.js
Normal file
96
src/utils/index.js
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/**
|
||||||
|
* Created by jiachenpan on 16/11/18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function parseTime(time, cFormat) {
|
||||||
|
if (arguments.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
|
||||||
|
let date
|
||||||
|
if (typeof time === 'object') {
|
||||||
|
date = time
|
||||||
|
} else {
|
||||||
|
if (('' + time).length === 10) time = parseInt(time) * 1000
|
||||||
|
date = new Date(time)
|
||||||
|
}
|
||||||
|
const formatObj = {
|
||||||
|
y: date.getFullYear(),
|
||||||
|
m: date.getMonth() + 1,
|
||||||
|
d: date.getDate(),
|
||||||
|
h: date.getHours(),
|
||||||
|
i: date.getMinutes(),
|
||||||
|
s: date.getSeconds(),
|
||||||
|
a: date.getDay()
|
||||||
|
}
|
||||||
|
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
|
||||||
|
let value = formatObj[key]
|
||||||
|
// Note: getDay() returns 0 on Sunday
|
||||||
|
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
|
||||||
|
if (result.length > 0 && value < 10) {
|
||||||
|
value = '0' + value
|
||||||
|
}
|
||||||
|
return value || 0
|
||||||
|
})
|
||||||
|
return time_str
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatTime(time, option) {
|
||||||
|
time = +time * 1000
|
||||||
|
const d = new Date(time)
|
||||||
|
const now = Date.now()
|
||||||
|
|
||||||
|
const diff = (now - d) / 1000
|
||||||
|
|
||||||
|
if (diff < 30) {
|
||||||
|
return '刚刚'
|
||||||
|
} else if (diff < 3600) {
|
||||||
|
// less 1 hour
|
||||||
|
return Math.ceil(diff / 60) + '分钟前'
|
||||||
|
} else if (diff < 3600 * 24) {
|
||||||
|
return Math.ceil(diff / 3600) + '小时前'
|
||||||
|
} else if (diff < 3600 * 24 * 2) {
|
||||||
|
return '1天前'
|
||||||
|
}
|
||||||
|
if (option) {
|
||||||
|
return parseTime(time, option)
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
d.getMonth() +
|
||||||
|
1 +
|
||||||
|
'月' +
|
||||||
|
d.getDate() +
|
||||||
|
'日' +
|
||||||
|
d.getHours() +
|
||||||
|
'时' +
|
||||||
|
d.getMinutes() +
|
||||||
|
'分'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function zeroFill(i) {
|
||||||
|
if (i >= 0 && i <= 9) {
|
||||||
|
return '0' + i
|
||||||
|
} else {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNowDAY() { // 默认显示今天
|
||||||
|
// 获取当前时间
|
||||||
|
const date = new Date()
|
||||||
|
const month = zeroFill(date.getMonth() + 1)
|
||||||
|
const day = zeroFill(date.getDate())
|
||||||
|
const time = date.getFullYear() + '-' + month + '-' + day
|
||||||
|
return time
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get90DAY() { // 3个月显示今天
|
||||||
|
var Data = new Date()
|
||||||
|
Data.setTime(Data.getTime() - 3600 * 1000 * 24 * 90)
|
||||||
|
const month = zeroFill(Data.getMonth() + 1)
|
||||||
|
const day = zeroFill(Data.getDate())
|
||||||
|
const time = Data.getFullYear() + '-' + month + '-' + day
|
||||||
|
return time
|
||||||
|
}
|
||||||
104
src/utils/mqtt.js
Normal file
104
src/utils/mqtt.js
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import { v4 as uuid } from 'uuid'
|
||||||
|
import mqtt from 'mqtt'
|
||||||
|
export { Mqtt }
|
||||||
|
class Mqtt {
|
||||||
|
constructor(config) {
|
||||||
|
this.connection = {
|
||||||
|
host: config.host,
|
||||||
|
port: config.port,
|
||||||
|
endpoint: config.endpoint || '/mqtt',
|
||||||
|
clean: config.clean || true,
|
||||||
|
connectTimeout: config.connectTimeout || 4000,
|
||||||
|
reconnectPeriod: config.reconnectPeriod || 4000,
|
||||||
|
clientId: config.clientId || uuid(),
|
||||||
|
username: config.username || '',
|
||||||
|
password: config.password || ''
|
||||||
|
}
|
||||||
|
this.client = {
|
||||||
|
connected: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 创建连接
|
||||||
|
createConnection() {
|
||||||
|
// 连接字符串, 通过协议指定使用的连接方式
|
||||||
|
// ws 未加密 WebSocket 连接
|
||||||
|
// wss 加密 WebSocket 连接
|
||||||
|
// mqtt 未加密 TCP 连接
|
||||||
|
// mqtts 加密 TCP 连接
|
||||||
|
// wxs 微信小程序连接
|
||||||
|
// alis 支付宝小程序连接
|
||||||
|
const { host, port, endpoint, ...options } = this.connection
|
||||||
|
const connectUrl = `ws://${host}:${port}${endpoint}`
|
||||||
|
try {
|
||||||
|
this.client = mqtt.connect(connectUrl, options)
|
||||||
|
} catch (error) {
|
||||||
|
// 连接错位、
|
||||||
|
this.connectError(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connectError(error) {
|
||||||
|
console.log('mqtt.connect error', error)
|
||||||
|
}
|
||||||
|
// 订阅主题
|
||||||
|
doSubscribe(subscription) {
|
||||||
|
const { topic, qos } = subscription
|
||||||
|
let subscribeSuccess = false
|
||||||
|
this.client.subscribe(topic, { qos }, (error, res) => {
|
||||||
|
if (error) {
|
||||||
|
subscribeSuccess = false
|
||||||
|
console.log('Subscribe to topics error', error)
|
||||||
|
} else {
|
||||||
|
subscribeSuccess = true
|
||||||
|
console.log('Subscribe to topics res', res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return subscribeSuccess
|
||||||
|
}
|
||||||
|
// 取消订阅
|
||||||
|
doUnSubscribe(subscription) {
|
||||||
|
const { topic } = subscription
|
||||||
|
let unSubscribeSuccess = false
|
||||||
|
this.client.unsubscribe(topic, error => {
|
||||||
|
if (error) {
|
||||||
|
unSubscribeSuccess = false
|
||||||
|
console.log('Unsubscribe error', error)
|
||||||
|
} else {
|
||||||
|
unSubscribeSuccess = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return unSubscribeSuccess
|
||||||
|
}
|
||||||
|
// 发送消息
|
||||||
|
doPublish(publish) {
|
||||||
|
const { topic, qos, payload } = publish
|
||||||
|
let doPublishSuccess = false
|
||||||
|
this.client.publish(topic, payload, qos, error => {
|
||||||
|
if (error) {
|
||||||
|
doPublishSuccess = false
|
||||||
|
console.log('Publish error', error)
|
||||||
|
} else {
|
||||||
|
doPublishSuccess = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return doPublishSuccess
|
||||||
|
}
|
||||||
|
// 断开连接
|
||||||
|
destroyConnection() {
|
||||||
|
let destroyConnectionSuccess = false
|
||||||
|
if (this.client.connected) {
|
||||||
|
try {
|
||||||
|
this.client.end()
|
||||||
|
this.client = {
|
||||||
|
connected: false
|
||||||
|
}
|
||||||
|
destroyConnectionSuccess = true
|
||||||
|
console.log('Successfully disconnected!')
|
||||||
|
} catch (error) {
|
||||||
|
destroyConnectionSuccess = false
|
||||||
|
console.log('Disconnect failed', error.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return destroyConnectionSuccess
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
34
src/utils/request.js
Normal file
34
src/utils/request.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
// import store from '@/store'
|
||||||
|
import {ElMessage} from 'element-plus' // 引入Element Plus的消息提示组件
|
||||||
|
const name_config = `OP8888`
|
||||||
|
// import.meta.env.VITE_BASE_URL
|
||||||
|
const request_config = window.g.API_WEB_URL + `/submit/MESCommonBase.ashx`
|
||||||
|
export const name = name_config
|
||||||
|
const service = axios.create({
|
||||||
|
baseURL: request_config,
|
||||||
|
timeout: 1000 * 5 // 请求超时时间
|
||||||
|
})
|
||||||
|
|
||||||
|
// && config.data.name !== '菜单系统模块_通知信息_查询数据' && config.data.name !== '菜单系统模块_首页信息_查询数据1' && config.data.name !== '菜单系统模块_首页信息_查询数据2'
|
||||||
|
service.interceptors.request.use(config => {
|
||||||
|
|
||||||
|
return config
|
||||||
|
}, error => {
|
||||||
|
if (error.code === 'ECONNABORTED' && error.message.includes('timeout')) {
|
||||||
|
ElMessage({
|
||||||
|
message: '请求超时,请稍后再试。',
|
||||||
|
type: 'error',
|
||||||
|
duration: 20000
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
message: '请求失败,请稍后再试。',
|
||||||
|
type: 'error',
|
||||||
|
duration: 20000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return Promise.reject(error)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default service
|
||||||
90
src/utils/setMethods.js
Normal file
90
src/utils/setMethods.js
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the time to string
|
||||||
|
* @param {(Object|string|number)} time
|
||||||
|
* @param {string} cFormat
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export function parseTime(time, cFormat) {
|
||||||
|
if (arguments.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
|
||||||
|
let date
|
||||||
|
if (typeof time === 'object') {
|
||||||
|
date = time
|
||||||
|
} else {
|
||||||
|
if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
|
||||||
|
time = parseInt(time)
|
||||||
|
}
|
||||||
|
if (typeof time === 'number' && time.toString().length === 10) {
|
||||||
|
time = time * 1000
|
||||||
|
}
|
||||||
|
date = new Date(time)
|
||||||
|
}
|
||||||
|
const formatObj = {
|
||||||
|
y: date.getFullYear(),
|
||||||
|
m: date.getMonth() + 1,
|
||||||
|
d: date.getDate(),
|
||||||
|
h: date.getHours(),
|
||||||
|
i: date.getMinutes(),
|
||||||
|
s: date.getSeconds(),
|
||||||
|
a: date.getDay()
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line
|
||||||
|
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
|
||||||
|
let value = formatObj[key]
|
||||||
|
// Note: getDay() returns 0 on Sunday
|
||||||
|
if (key === 'a') {
|
||||||
|
return ['日', '一', '二', '三', '四', '五', '六'][value]
|
||||||
|
}
|
||||||
|
if (result.length > 0 && value < 10) {
|
||||||
|
value = '0' + value
|
||||||
|
}
|
||||||
|
return value || 0
|
||||||
|
})
|
||||||
|
// eslint-disable-next-line
|
||||||
|
return time_str
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the json to excel
|
||||||
|
* tableJson 导出数据 ; filenames导出表的名字; autowidth表格宽度自动 true or false; bookTypes xlsx & csv & txt
|
||||||
|
* @param {(Object)} tableJson
|
||||||
|
* @param {string} filenames
|
||||||
|
* @param {boolean} autowidth
|
||||||
|
* @param {string} bookTypes
|
||||||
|
*/
|
||||||
|
export function json2excel(tableJson, filenames, autowidth, bookTypes) {
|
||||||
|
import('@/vendor/Export2Excel').then(excel => {
|
||||||
|
var tHeader = []
|
||||||
|
var dataArr = []
|
||||||
|
var sheetnames = []
|
||||||
|
for (var i in tableJson) {
|
||||||
|
tHeader.push(tableJson[i].tHeader)
|
||||||
|
dataArr.push(formatJson(tableJson[i].filterVal, tableJson[i].tableDatas))
|
||||||
|
sheetnames.push(tableJson[i].sheetName)
|
||||||
|
}
|
||||||
|
console.log(dataArr, 9191)
|
||||||
|
excel.export_json_to_excel2({
|
||||||
|
header: tHeader,
|
||||||
|
data: dataArr,
|
||||||
|
sheetname: sheetnames,
|
||||||
|
filename: filenames,
|
||||||
|
autoWidth: autowidth,
|
||||||
|
bookType: bookTypes
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 数据过滤,时间过滤
|
||||||
|
function formatJson(filterVal, jsonData) {
|
||||||
|
return jsonData.map(v =>
|
||||||
|
filterVal.map(j => {
|
||||||
|
if (j === 'timestamp') {
|
||||||
|
return parseTime(v[j])
|
||||||
|
} else {
|
||||||
|
return v[j]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
361
src/utils/tool.js
Normal file
361
src/utils/tool.js
Normal file
@@ -0,0 +1,361 @@
|
|||||||
|
// 数组去重
|
||||||
|
export function arrayUnique(arr) {
|
||||||
|
arr.filter((element, index, arr) => {
|
||||||
|
return arr.indexOf(element) === index
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数组去重,数组中值是对象
|
||||||
|
export function arrayUnique2(arr, name) {
|
||||||
|
const hash = {}
|
||||||
|
return arr.reduce(function (item, next) {
|
||||||
|
hash[next[name]] ? '' : hash[next[name]] = true && item.push(next)
|
||||||
|
return item
|
||||||
|
}, [])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 时间转时间戳
|
||||||
|
export function timeToStamp(time) {
|
||||||
|
const date = new Date(time)
|
||||||
|
return date.getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数组的深度拷贝
|
||||||
|
export function arrDeepCopy(arr) {
|
||||||
|
const newArr = []
|
||||||
|
for (const prop in arr) newArr[prop] = typeof arr[prop] === 'object' ? arrDeepCopy(arr[prop]) : arr[prop]
|
||||||
|
return newArr
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对象的深度拷贝
|
||||||
|
export function objDeepCopy(obj) {
|
||||||
|
const newObj = {}
|
||||||
|
for (const prop in obj) newObj[prop] = typeof obj[prop] === 'object' ? objDeepCopy(obj[prop]) : obj[prop]
|
||||||
|
return newObj
|
||||||
|
}
|
||||||
|
|
||||||
|
function zeroFill(i) {
|
||||||
|
if (i >= 0 && i <= 9) {
|
||||||
|
return '0' + i
|
||||||
|
} else {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前时间(yyyy-mm-dd hh:mm:ss)
|
||||||
|
export function getNowTime() {
|
||||||
|
const date = new Date()
|
||||||
|
const month = zeroFill(date.getMonth() + 1)
|
||||||
|
const day = zeroFill(date.getDate())
|
||||||
|
const hour = zeroFill(date.getHours())
|
||||||
|
const minute = zeroFill(date.getMinutes())
|
||||||
|
const second = zeroFill(date.getSeconds())
|
||||||
|
const time = date.getFullYear() + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second
|
||||||
|
return time
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNowTime2() {
|
||||||
|
const date66 = new Date()
|
||||||
|
const month66 = zeroFill(date66.getMonth() + 1)
|
||||||
|
const day66 = zeroFill(date66.getDate())
|
||||||
|
const date = date66.getFullYear() + '-' + month66 + '-' + day66
|
||||||
|
// var date = '2019-3-31'
|
||||||
|
var arr = date.split('-')
|
||||||
|
var year = arr[0] // 获取当前日期的年份
|
||||||
|
var month = arr[1] // 获取当前日期的月份
|
||||||
|
var day = arr[2] // 获取当前日期的日
|
||||||
|
// var days = new Date(year, month, 0)
|
||||||
|
// days = days.getDate() // 获取当前日期中月的天数
|
||||||
|
var year2 = year
|
||||||
|
var month2 = parseInt(month) - 1
|
||||||
|
if (month2 === 0) {
|
||||||
|
year2 = parseInt(year2) - 1
|
||||||
|
month2 = 12
|
||||||
|
}
|
||||||
|
var day2 = day
|
||||||
|
var days2 = new Date(year2, month2, 0)
|
||||||
|
days2 = days2.getDate()
|
||||||
|
if (day2 > days2) {
|
||||||
|
day2 = days2
|
||||||
|
}
|
||||||
|
if (month2 < 10) {
|
||||||
|
month2 = '0' + month2
|
||||||
|
}
|
||||||
|
var t2 = year2 + '-' + month2 + '-' + day2
|
||||||
|
return t2
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前时间(yyyy-mm-dd)
|
||||||
|
export function getNowShotTime() {
|
||||||
|
const date = new Date()
|
||||||
|
const month = zeroFill(date.getMonth() + 1)
|
||||||
|
const day = zeroFill(date.getDate())
|
||||||
|
const time = date.getFullYear() + '-' + month + '-' + day
|
||||||
|
return time
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前时间(yyyy/mm/dd)
|
||||||
|
export function getNowShotTime1() {
|
||||||
|
const date = new Date()
|
||||||
|
const month = zeroFill(date.getMonth() + 1)
|
||||||
|
const day = zeroFill(date.getDate())
|
||||||
|
const time = date.getFullYear() + '/' + month + '/' + day
|
||||||
|
return time
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前0晨
|
||||||
|
export function getNowTime1() {
|
||||||
|
const date = new Date()
|
||||||
|
const month = zeroFill(date.getMonth() + 1)
|
||||||
|
const year = zeroFill(date.getFullYear())
|
||||||
|
const day = zeroFill(date.getDate())
|
||||||
|
let hour = zeroFill(date.getHours())
|
||||||
|
hour = hour < 10 ? ('0' + hour) : hour
|
||||||
|
let minute = zeroFill(date.getMinutes())
|
||||||
|
minute = minute < 10 ? ('0' + minute) : minute
|
||||||
|
let second = zeroFill(date.getSeconds())
|
||||||
|
second = second < 10 ? ('0' + second) : second
|
||||||
|
// const hour = '00'
|
||||||
|
// const minute = '00'
|
||||||
|
// const second = '00'
|
||||||
|
const time = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second
|
||||||
|
return time
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNowTime3(date) {
|
||||||
|
const month = zeroFill2(date.getMonth() + 1)
|
||||||
|
const day = zeroFill(date.getDate())
|
||||||
|
return date.getFullYear() + '-' + month + '-' + day
|
||||||
|
}
|
||||||
|
|
||||||
|
function zeroFill2(i) {
|
||||||
|
if (i >= 0 && i <= 9) {
|
||||||
|
if (i === 0) {
|
||||||
|
return '01'
|
||||||
|
} else {
|
||||||
|
return '0' + i
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 工时统计上个月26-本月25
|
||||||
|
export function getTime26() {
|
||||||
|
const date = new Date()
|
||||||
|
const day = date.getDate()
|
||||||
|
if (day >= 25) {
|
||||||
|
var month = zeroFill(date.getMonth() + 1)
|
||||||
|
if (month === 0) {
|
||||||
|
month = 12
|
||||||
|
const day = 26
|
||||||
|
const time = date.getFullYear() - 1 + '-' + month + '-' + day
|
||||||
|
return time
|
||||||
|
} else {
|
||||||
|
const day = 26
|
||||||
|
const time = date.getFullYear() + '-' + month + '-' + day
|
||||||
|
return time
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var month2 = zeroFill(date.getMonth() + 1) - 1
|
||||||
|
if (month2 === 0) {
|
||||||
|
month2 = 12
|
||||||
|
const day = 26
|
||||||
|
const time = date.getFullYear() - 1 + '-' + month2 + '-' + day
|
||||||
|
return time
|
||||||
|
} else {
|
||||||
|
const day = 26
|
||||||
|
const time = date.getFullYear() + '-' + month2 + '-' + day
|
||||||
|
return time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTime25() {
|
||||||
|
const date = new Date()
|
||||||
|
const day = date.getDate()
|
||||||
|
if (day >= 25) {
|
||||||
|
const month = zeroFill(date.getMonth() + 2)
|
||||||
|
const day2 = 25
|
||||||
|
const time = date.getFullYear() + '-' + month + '-' + day2
|
||||||
|
return time
|
||||||
|
} else {
|
||||||
|
const month = zeroFill(date.getMonth() + 1)
|
||||||
|
const day2 = 25
|
||||||
|
const time = date.getFullYear() + '-' + month + '-' + day2
|
||||||
|
return time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断类型
|
||||||
|
export function type(target) {
|
||||||
|
const ret = typeof (target)
|
||||||
|
const template = {
|
||||||
|
'[object Array]': 'array',
|
||||||
|
'[object Object]': 'object',
|
||||||
|
'[object String]': 'string - object',
|
||||||
|
'[object Number]': 'Number - object',
|
||||||
|
'[object Boolean]': 'Boolean - object'
|
||||||
|
}
|
||||||
|
if (target === null) {
|
||||||
|
return 'null'
|
||||||
|
}
|
||||||
|
if (ret === 'object') {
|
||||||
|
const str = Object.prototype.toString.call(target)
|
||||||
|
return template[str]
|
||||||
|
} else {
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SectionToChinese(section) {
|
||||||
|
const chnNumChar = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
|
||||||
|
const chnUnitChar = ['', '十', '百', '千']
|
||||||
|
let strIns = ''
|
||||||
|
let chnStr = ''
|
||||||
|
let unitPos = 0
|
||||||
|
let zero = true
|
||||||
|
while (section > 0) {
|
||||||
|
const v = section % 10
|
||||||
|
if (v === 0) {
|
||||||
|
if (!zero) {
|
||||||
|
zero = true
|
||||||
|
chnStr = chnNumChar[v] + chnStr
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zero = false
|
||||||
|
strIns = chnNumChar[v]
|
||||||
|
strIns += chnUnitChar[unitPos]
|
||||||
|
chnStr = strIns + chnStr
|
||||||
|
}
|
||||||
|
unitPos++
|
||||||
|
section = Math.floor(section / 10)
|
||||||
|
}
|
||||||
|
return chnStr
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sleep(time) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
setTimeout(resolve, time)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function groupBy(datas, keys) {
|
||||||
|
const list = datas || []
|
||||||
|
const groups = []
|
||||||
|
const result = []
|
||||||
|
list.forEach(v => {
|
||||||
|
const key = {}
|
||||||
|
keys.forEach(k => {
|
||||||
|
key[k] = v[k]
|
||||||
|
})
|
||||||
|
let group = groups.find(v => {
|
||||||
|
return v._key === JSON.stringify(key)
|
||||||
|
})
|
||||||
|
if (!group) {
|
||||||
|
group = {
|
||||||
|
_key: JSON.stringify(key),
|
||||||
|
key: key
|
||||||
|
}
|
||||||
|
groups.push(group)
|
||||||
|
}
|
||||||
|
group.data1 = group.data1 || 0
|
||||||
|
group.key.数量 = group.data1 += v.数量
|
||||||
|
group.data2 = group.data2 || ''
|
||||||
|
group.key.机床图号_组号 = group.data2 += (v.机床图号 || '') + '-' + (v.组号 ? v.组号.split('组')[0] : '') + '<br/>'
|
||||||
|
group.data3 = group.data3 || 0
|
||||||
|
group.key.合计 = group.data3 += v.合计
|
||||||
|
})
|
||||||
|
groups.map(v => {
|
||||||
|
result.push(v.key)
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除js浮点加法bug
|
||||||
|
export function numAdd(arg1, arg2) {
|
||||||
|
var r1, r2, m
|
||||||
|
try {
|
||||||
|
r1 = arg1.toString().split('.')[1].length
|
||||||
|
} catch (e) {
|
||||||
|
r1 = 0
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
r2 = arg2.toString().split('.')[1].length
|
||||||
|
} catch (e) {
|
||||||
|
r2 = 0
|
||||||
|
}
|
||||||
|
m = Math.pow(10, Math.max(r1, r2))
|
||||||
|
return (arg1 * m + arg2 * m) / m
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除js浮点减法bug
|
||||||
|
export function numSubtract(arg1, arg2) {
|
||||||
|
var r1, r2, m, n
|
||||||
|
try {
|
||||||
|
r1 = arg1.toString().split('.')[1].length
|
||||||
|
} catch (e) {
|
||||||
|
r1 = 0
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
r2 = arg2.toString().split('.')[1].length
|
||||||
|
} catch (e) {
|
||||||
|
r2 = 0
|
||||||
|
}
|
||||||
|
m = Math.pow(10, Math.max(r1, r2))
|
||||||
|
n = (r1 >= r2) ? r1 : r2
|
||||||
|
return ((arg1 * m - arg2 * m) / m).toFixed(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除js浮点乘法bug
|
||||||
|
export function numMultiply(arg1, arg2) {
|
||||||
|
var m = 0
|
||||||
|
var s1 = arg1.toString()
|
||||||
|
var s2 = arg2.toString()
|
||||||
|
try {
|
||||||
|
m += s1.split('.')[1].length
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
m += s2.split('.')[1].length
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除js浮点除法bug
|
||||||
|
export function numDivide(arg1, arg2) {
|
||||||
|
var t1 = 0
|
||||||
|
var t2 = 0
|
||||||
|
var r1, r2
|
||||||
|
try {
|
||||||
|
t1 = arg1.toString().split('.')[1].length
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
t2 = arg2.toString().split('.')[1].length
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
r1 = Math.Number(arg1.toString().replace('.', ''))
|
||||||
|
r2 = Math.Number(arg2.toString().replace('.', ''))
|
||||||
|
return (r1 / r2) * Math.pow(10, t2 - t1)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function base64ImgtoFile(dataurl, filename = 'file') {
|
||||||
|
const arr = dataurl.split(',')
|
||||||
|
const mime = arr[0].match(/:(.*?);/)[1]
|
||||||
|
const suffix = mime.split('/')[1]
|
||||||
|
const bstr = atob(arr[1])
|
||||||
|
let n = bstr.length
|
||||||
|
const u8arr = new Uint8Array(n)
|
||||||
|
while (n--) {
|
||||||
|
u8arr[n] = bstr.charCodeAt(n)
|
||||||
|
}
|
||||||
|
return new File([u8arr], `${filename}.${suffix}`, {
|
||||||
|
type: mime
|
||||||
|
})
|
||||||
|
}
|
||||||
32
src/utils/validate.js
Normal file
32
src/utils/validate.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Created by jiachenpan on 16/11/18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function isvalidUsername(str) {
|
||||||
|
const user = /^[0-9]{5,7}$/
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 合法uri*/
|
||||||
|
export function validateURL(textval) {
|
||||||
|
const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
|
||||||
|
return urlregex.test(textval)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 小写字母*/
|
||||||
|
export function validateLowerCase(str) {
|
||||||
|
const reg = /^[a-z]+$/
|
||||||
|
return reg.test(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 大写字母*/
|
||||||
|
export function validateUpperCase(str) {
|
||||||
|
const reg = /^[A-Z]+$/
|
||||||
|
return reg.test(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 大小写字母*/
|
||||||
|
export function validatAlphabets(str) {
|
||||||
|
const reg = /^[A-Za-z]+$/
|
||||||
|
return reg.test(str)
|
||||||
|
}
|
||||||
248
src/views/404.vue
Normal file
248
src/views/404.vue
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
<template>
|
||||||
|
<div class="wscn-http404-container">
|
||||||
|
<div class="wscn-http404">
|
||||||
|
<div class="pic-404">
|
||||||
|
<img
|
||||||
|
class="pic-404__parent"
|
||||||
|
src="@/assets/404_images/404.png"
|
||||||
|
alt="404"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
class="pic-404__child left"
|
||||||
|
src="@/assets/404_images/404_cloud.png"
|
||||||
|
alt="404"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
class="pic-404__child mid"
|
||||||
|
src="@/assets/404_images/404_cloud.png"
|
||||||
|
alt="404"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
class="pic-404__child right"
|
||||||
|
src="@/assets/404_images/404_cloud.png"
|
||||||
|
alt="404"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="bullshit">
|
||||||
|
<div class="bullshit__oops">OOPS!</div>
|
||||||
|
<div class="bullshit__info">
|
||||||
|
版权所有
|
||||||
|
<a class="link-type" href="https://wallstreetcn.com" target="_blank"
|
||||||
|
>华尔街见闻</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="bullshit__headline">{{ message }}</div>
|
||||||
|
<div class="bullshit__info">
|
||||||
|
请检查您输入的网址是否正确,请点击以下按钮返回主页或者发送错误报告
|
||||||
|
</div>
|
||||||
|
<a href="/" class="bullshit__return-home">返回首页</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Page404",
|
||||||
|
computed: {
|
||||||
|
message() {
|
||||||
|
return "网管说这个页面你不能进......";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
.wscn-http404-container {
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
position: absolute;
|
||||||
|
top: 40%;
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
.wscn-http404 {
|
||||||
|
position: relative;
|
||||||
|
width: 1200px;
|
||||||
|
padding: 0 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
.pic-404 {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
width: 600px;
|
||||||
|
overflow: hidden;
|
||||||
|
&__parent {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
&__child {
|
||||||
|
position: absolute;
|
||||||
|
&.left {
|
||||||
|
width: 80px;
|
||||||
|
top: 17px;
|
||||||
|
left: 220px;
|
||||||
|
opacity: 0;
|
||||||
|
animation-name: cloudLeft;
|
||||||
|
animation-duration: 2s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-delay: 1s;
|
||||||
|
}
|
||||||
|
&.mid {
|
||||||
|
width: 46px;
|
||||||
|
top: 10px;
|
||||||
|
left: 420px;
|
||||||
|
opacity: 0;
|
||||||
|
animation-name: cloudMid;
|
||||||
|
animation-duration: 2s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-delay: 1.2s;
|
||||||
|
}
|
||||||
|
&.right {
|
||||||
|
width: 62px;
|
||||||
|
top: 100px;
|
||||||
|
left: 500px;
|
||||||
|
opacity: 0;
|
||||||
|
animation-name: cloudRight;
|
||||||
|
animation-duration: 2s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-delay: 1s;
|
||||||
|
}
|
||||||
|
@keyframes cloudLeft {
|
||||||
|
0% {
|
||||||
|
top: 17px;
|
||||||
|
left: 220px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
top: 33px;
|
||||||
|
left: 188px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
top: 81px;
|
||||||
|
left: 92px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
top: 97px;
|
||||||
|
left: 60px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes cloudMid {
|
||||||
|
0% {
|
||||||
|
top: 10px;
|
||||||
|
left: 420px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
top: 40px;
|
||||||
|
left: 360px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
top: 130px;
|
||||||
|
left: 180px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
top: 160px;
|
||||||
|
left: 120px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes cloudRight {
|
||||||
|
0% {
|
||||||
|
top: 100px;
|
||||||
|
left: 500px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
top: 120px;
|
||||||
|
left: 460px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
top: 180px;
|
||||||
|
left: 340px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
top: 200px;
|
||||||
|
left: 300px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bullshit {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
width: 300px;
|
||||||
|
padding: 30px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
&__oops {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 40px;
|
||||||
|
color: #1482f0;
|
||||||
|
opacity: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
animation-name: slideUp;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
&__headline {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #222;
|
||||||
|
font-weight: bold;
|
||||||
|
opacity: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
animation-name: slideUp;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-delay: 0.1s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
&__info {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 21px;
|
||||||
|
color: grey;
|
||||||
|
opacity: 0;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
animation-name: slideUp;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-delay: 0.2s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
&__return-home {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
width: 110px;
|
||||||
|
height: 36px;
|
||||||
|
background: #1482f0;
|
||||||
|
border-radius: 100px;
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
opacity: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 36px;
|
||||||
|
cursor: pointer;
|
||||||
|
animation-name: slideUp;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-delay: 0.3s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
@keyframes slideUp {
|
||||||
|
0% {
|
||||||
|
transform: translateY(60px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
99
src/views/CameraManagement/index.vue
Normal file
99
src/views/CameraManagement/index.vue
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tableBox">
|
||||||
|
<el-table :data="CameraTableData" border height="80vh" stripe style="width: 100%">
|
||||||
|
<el-table-column align="center" label="序号" type="index" width="80"/>
|
||||||
|
<el-table-column align="center" label="工位号">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.工位号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="门禁名称">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.门禁名称 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="摄像头IP">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.摄像头IP }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="摄像头位置">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.摄像头位置 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column align="center" label="是否启用" width="80">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-checkbox v-model="scope.row.是否启用" :false-value="0" :true-value="1"
|
||||||
|
size="large" @click="setCameraPermission(scope.row)"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {inject, onMounted, reactive} from 'vue'
|
||||||
|
import {ElMessage} from "element-plus";
|
||||||
|
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
|
||||||
|
const CameraTableData = reactive([])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getCameraData()
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const getCameraData = () => {
|
||||||
|
var param = []
|
||||||
|
var Data = CreateData('11', '基础表_工位门禁摄像头关联表_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
CameraTableData.length = 0
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
CameraTableData.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const setCameraPermission = (row) => {
|
||||||
|
var param = []
|
||||||
|
param.push(['AID', row.AID])
|
||||||
|
var Data = CreateData('11', '基础表_工位门禁摄像头关联表_是否启用_修改', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
if (response.data[0].result === 1) {
|
||||||
|
ElMessage.success(response.data[0].msg)
|
||||||
|
getCameraData()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.data[0].msg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error('数据异常')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.tableBox {
|
||||||
|
width: 98vw;
|
||||||
|
margin: 2vh auto 0 auto;
|
||||||
|
border: 1px solid #9f9f9f;
|
||||||
|
background-color: #ecf0f3;
|
||||||
|
box-shadow: 10px 10px 10px #d1d9e6, -10px -10px 10px #f9f9f9;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.tableTop {
|
||||||
|
width: 100%;
|
||||||
|
margin: 1vh auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block {
|
||||||
|
margin-bottom: 1vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
738
src/views/CarBodyPlace/index.vue
Normal file
738
src/views/CarBodyPlace/index.vue
Normal file
@@ -0,0 +1,738 @@
|
|||||||
|
<template>
|
||||||
|
<div class="topOp">
|
||||||
|
<span>当前台位</span>
|
||||||
|
<span class="text">{{ store.user.opDescription || store.user.opName }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="main">
|
||||||
|
<!-- 状态显示框 -->
|
||||||
|
<div class="status-box">
|
||||||
|
<div class="title">状态监控</div>
|
||||||
|
<div class="status-content">
|
||||||
|
<div class="status-item">
|
||||||
|
<div class="status-title">MES连接:</div>
|
||||||
|
<span v-if="nowStatus.isProductionOnline" class="status-value success">在线</span>
|
||||||
|
<span v-else class="status-value danger">离线</span>
|
||||||
|
</div>
|
||||||
|
<div class="status-item">
|
||||||
|
<div class="status-title">数据库连接:</div>
|
||||||
|
<span v-if="nowStatus.isSqlOnline" class="status-value success">已连接</span>
|
||||||
|
<span v-else class="status-value danger">已断开</span>
|
||||||
|
</div>
|
||||||
|
<div class="status-item">
|
||||||
|
<div class="status-title">MQTT连接:</div>
|
||||||
|
<span v-if="nowStatus.isMqttOnline" class="status-value success">已连接</span>
|
||||||
|
<span v-else class="status-value danger">已断开</span>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="status-item">
|
||||||
|
<div class="status-title">MES连接:</div>
|
||||||
|
<span v-if="nowStatus.isMesOnline" class="status-value success">已连接</span>
|
||||||
|
<span v-else class="status-value danger">已断开</span>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 项目数据显示框 -->
|
||||||
|
<div class="project-box">
|
||||||
|
<div class="title">项目信息</div>
|
||||||
|
<div class="project-content">
|
||||||
|
<div class="project-item">
|
||||||
|
<div class="project-title">项目编号:</div>
|
||||||
|
<el-autocomplete v-model="carInputData.projectNo" :fetch-suggestions="(queryString, cb) => {
|
||||||
|
const results = queryString
|
||||||
|
? projectList.filter(item => item.项目编号.toLowerCase().includes(queryString.toLowerCase()))
|
||||||
|
: projectList
|
||||||
|
cb(results.map(item => ({
|
||||||
|
value: item.项目编号,
|
||||||
|
label: `${item.项目编号} - ${item.项目名称}`
|
||||||
|
})))
|
||||||
|
}" placeholder="请输入或选择项目编号" clearable @select="({ value }) => handleProjectChange(value)"
|
||||||
|
@input="handleProjectInput" @blur="handleProjectBlur" style="width: 86%" />
|
||||||
|
</div>
|
||||||
|
<div class="project-item">
|
||||||
|
</div>
|
||||||
|
<div class="project-item">
|
||||||
|
<div class="project-title">项目名称:</div>
|
||||||
|
<el-input v-model="carInputData.projectName" placeholder="项目名称" />
|
||||||
|
</div>
|
||||||
|
<div class="project-item">
|
||||||
|
<div class="project-title">车体:</div>
|
||||||
|
<el-select v-model="carInputData.carBody" filterable allow-create placeholder="请输入或选择车体" clearable
|
||||||
|
style="flex: 1">
|
||||||
|
<el-option v-for="item in carBodyList" :key="item.车体" :label="item.车体" :value="item.车体" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="project-item">
|
||||||
|
<div class="project-title">车号:</div>
|
||||||
|
<el-input v-model="carInputData.carNo" placeholder="车号" />
|
||||||
|
</div>
|
||||||
|
<div class="project-item">
|
||||||
|
<div class="project-title">伸缩缝:</div>
|
||||||
|
<el-select v-model="carInputData.expansionJoint" filterable allow-create placeholder="请输入或选择伸缩缝" clearable
|
||||||
|
style="flex: 1">
|
||||||
|
<el-option v-for="item in expansionJointList" :key="item.伸缩缝" :label="item.伸缩缝" :value="item.伸缩缝" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="project-item">
|
||||||
|
<div class="project-title">车节:</div>
|
||||||
|
<el-select v-model="carInputData.carSection" filterable allow-create placeholder="请输入或选择车节号" clearable
|
||||||
|
@change="editCarSection" style="flex: 1">
|
||||||
|
<el-option v-for="item in carSectionList" :key="item.车节" :label="item.车节" :value="item.车节" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="project-item">
|
||||||
|
<div class="project-title">调节参数:</div>
|
||||||
|
<el-select v-model="carInputData.adjustTheParameters" filterable allow-create placeholder="请输入或选择调节参数"
|
||||||
|
clearable style="flex: 1">
|
||||||
|
<el-option v-for="item in adjustParametersList" :key="item.调节参数" :label="item.调节参数" :value="item.调节参数" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<div class="button-group">
|
||||||
|
<el-button plain type="danger" @click="carPlace">车体到位</el-button>
|
||||||
|
<el-button :disabled="carInputData.fenceTime" plain type="primary" @click="guardrailsAreInstalledInPlace">
|
||||||
|
护栏安装到位
|
||||||
|
</el-button>
|
||||||
|
<el-button plain type="warning" @click="carLeave">车体离位</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { inject, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||||
|
import { useAppStore } from '@/store/app.js'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import mqtt from "mqtt";
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const store = useAppStore()
|
||||||
|
const { user, isLoading, routerData } = storeToRefs(store)
|
||||||
|
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
const ExecWritePLC = inject('ExecWritePLC')
|
||||||
|
const ExecReadPLC = inject('ExecReadPLC')
|
||||||
|
const ExecMultReadPLC = inject('ExecMultReadPLC')
|
||||||
|
const ExecIMESAPI = inject('ExecIMESAPI')
|
||||||
|
|
||||||
|
const isEnableUI = ref(false)
|
||||||
|
|
||||||
|
const carSectionList = reactive([])
|
||||||
|
const projectList = reactive([])
|
||||||
|
const carBodyList = reactive([]) // 车体列表
|
||||||
|
const expansionJointList = reactive([]) // 伸缩缝列表
|
||||||
|
const adjustParametersList = reactive([]) // 调节参数列表
|
||||||
|
const carInputData = reactive({
|
||||||
|
projectNo: '', // 项目编号
|
||||||
|
projectName: '', // 项目名称
|
||||||
|
carNo: '', // 车号
|
||||||
|
carSection: '', // 车节
|
||||||
|
carBody: '', // 车体
|
||||||
|
carBodyCode: '', // 车体流水号
|
||||||
|
expansionJoint: '', // 伸缩缝
|
||||||
|
adjustTheParameters: '', // 调节参数
|
||||||
|
fenceTime: '', // 护栏安装到位时间
|
||||||
|
pos1: true,
|
||||||
|
pos2: true,
|
||||||
|
pos3: true,
|
||||||
|
pos4: true,
|
||||||
|
pos5: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const nowStatus = reactive({
|
||||||
|
isPeople: false, // 护栏是否有人
|
||||||
|
isCarArrive: false, // 车体到位
|
||||||
|
isRgvShipping: false, // RGV开始送料
|
||||||
|
isRgvWorking: false, // RGV工作中
|
||||||
|
isRgvIdle: false, // RGV空闲
|
||||||
|
isRgvAlarm: false, // RGV报警
|
||||||
|
isDoorLocked: false, // 门禁状态
|
||||||
|
isProductionOnline: false, // 生产模式
|
||||||
|
isSqlOnline: false, // 数据库连接
|
||||||
|
isMqttOnline: false, // MQTT连接
|
||||||
|
isMesOnline: false, // MES连接
|
||||||
|
})
|
||||||
|
|
||||||
|
var client = null
|
||||||
|
var timer1 = null
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getCarData()
|
||||||
|
getCarSectionList()
|
||||||
|
getProjectList()
|
||||||
|
getCarBodyList()
|
||||||
|
getExpansionJointList()
|
||||||
|
getAdjustParametersList()
|
||||||
|
connectMqtt()
|
||||||
|
// 初始化时获取所有状态
|
||||||
|
getConnectionStatus()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 离开网页 删除定时器
|
||||||
|
onUnmounted(() => {
|
||||||
|
try {
|
||||||
|
if (client) {
|
||||||
|
client.end();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('关闭连接失败:', error);
|
||||||
|
}
|
||||||
|
client = null;
|
||||||
|
})
|
||||||
|
|
||||||
|
//连接MQTT
|
||||||
|
const connectMqtt = async () => {
|
||||||
|
const topics = ['PLCToWebUI']
|
||||||
|
// 连接选项
|
||||||
|
const options = {
|
||||||
|
keepalive: 60, // 心跳时间
|
||||||
|
reconnectPeriod: 3000, // 重新连接间隔时间
|
||||||
|
clean: true, // 是否清除会话
|
||||||
|
clientId: 'WEB_Op_' + getUUID(),//要确保唯一性,例如随机数或者UUID,
|
||||||
|
username: '',//mqtt服务器配置里面的账号,
|
||||||
|
password: ''//mqtt服务器配置里面的密码,
|
||||||
|
}
|
||||||
|
console.log(window.g.Mqtt_Ip)
|
||||||
|
client = mqtt.connect(window.g.Mqtt_Ip, options);
|
||||||
|
client.on('reconnect', (error) => {
|
||||||
|
console.log('正在重连:', error)
|
||||||
|
ElMessage.warning('正在重连' + error)
|
||||||
|
})
|
||||||
|
client.on('error', (error) => {
|
||||||
|
console.log('连接失败:', error)
|
||||||
|
ElMessage.warning('连接失败' + error)
|
||||||
|
})
|
||||||
|
client.on('connect', (e) => {
|
||||||
|
console.log('MQTT连接成功');
|
||||||
|
// 订阅多个主题
|
||||||
|
client.subscribe(topics, { qos: 0 }, function (err) {
|
||||||
|
if (!err) {
|
||||||
|
console.log('订阅成功');
|
||||||
|
} else {
|
||||||
|
console.error('订阅失败:', err);
|
||||||
|
ElMessage.warning('订阅失败' + err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
client.on('message', (topic, message, packet) => {
|
||||||
|
messageHandle(topic, message.toString())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取连接状态
|
||||||
|
const getConnectionStatus = async () => {
|
||||||
|
var param = []
|
||||||
|
param[0] = ['ControlCode', window.g.API_MES_ControlCode]
|
||||||
|
var Data = CreateData('11', 'CRRC_台位_Moby_连接状态初始化查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
let data = response.data[0]
|
||||||
|
nowStatus.isSqlOnline = data.DBConnState === 1
|
||||||
|
nowStatus.isMqttOnline = data.MQTTConnState === 1
|
||||||
|
nowStatus.isMesOnline = data.MESConnState === 1
|
||||||
|
nowStatus.isProductionOnline = data.MESConnState === 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理MQTT消息
|
||||||
|
const messageHandle = (topic, message) => {
|
||||||
|
switch (topic) {
|
||||||
|
case 'PLCToWebUI':
|
||||||
|
let reqData = JSON.parse(message)
|
||||||
|
console.log(reqData)
|
||||||
|
if (reqData.OPCode != store.user.opName) {
|
||||||
|
// 处理连接状态
|
||||||
|
switch (reqData.OPCode) {
|
||||||
|
case 'OnLine_MES':
|
||||||
|
nowStatus.isProductionOnline = reqData.tagValue === '1'
|
||||||
|
nowStatus.isMesOnline = reqData.tagValue === '1'
|
||||||
|
break
|
||||||
|
case 'OnLine_Sql':
|
||||||
|
nowStatus.isSqlOnline = reqData.tagValue === '1'
|
||||||
|
break
|
||||||
|
case 'OnLine_MQTT':
|
||||||
|
nowStatus.isMqttOnline = reqData.tagValue === '1'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUUID = () => {
|
||||||
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||||
|
var r = Math.random() * 16 | 0,
|
||||||
|
v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCarData = () => {
|
||||||
|
// 获取权限列表
|
||||||
|
var param = []
|
||||||
|
param[0] = ['opName', store.user.opName]
|
||||||
|
var Data = CreateData('11', 'CRRC_台位_Moby_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
let data = response.data[0]
|
||||||
|
carInputData.projectNo = data.项目编号
|
||||||
|
carInputData.projectName = data.项目名称
|
||||||
|
carInputData.carNo = data.车号
|
||||||
|
carInputData.carSection = data.车节
|
||||||
|
carInputData.carBody = data.车体参数1
|
||||||
|
carInputData.carBodyCode = data.车体流水号
|
||||||
|
carInputData.expansionJoint = data.伸缩缝参数1
|
||||||
|
carInputData.adjustTheParameters = data.调节参数1
|
||||||
|
carInputData.fenceTime = data.护栏安装到位确认时间
|
||||||
|
carInputData.pos1 = data.位置1 == 1
|
||||||
|
carInputData.pos2 = data.位置2 == 1
|
||||||
|
carInputData.pos3 = data.位置3 == 1
|
||||||
|
carInputData.pos4 = data.位置4 == 1
|
||||||
|
carInputData.pos5 = data.位置5 == 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCarSectionList = () => {
|
||||||
|
carSectionList.length = 0
|
||||||
|
// 获取车节列表
|
||||||
|
var param = []
|
||||||
|
param.push(['参数类型', '车节'])
|
||||||
|
var Data = CreateData('11', 'CRRC_基础数据_车体参数_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
carSectionList.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取车体列表
|
||||||
|
const getCarBodyList = () => {
|
||||||
|
carBodyList.length = 0
|
||||||
|
var param = []
|
||||||
|
param.push(['参数类型', '车体'])
|
||||||
|
var Data = CreateData('11', 'CRRC_基础数据_车体参数_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
carBodyList.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取伸缩缝列表
|
||||||
|
const getExpansionJointList = () => {
|
||||||
|
expansionJointList.length = 0
|
||||||
|
var param = []
|
||||||
|
param.push(['参数类型', '伸缩缝'])
|
||||||
|
var Data = CreateData('11', 'CRRC_基础数据_车体参数_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
expansionJointList.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取调节参数列表
|
||||||
|
const getAdjustParametersList = () => {
|
||||||
|
adjustParametersList.length = 0
|
||||||
|
var param = []
|
||||||
|
param.push(['参数类型', '调节参数'])
|
||||||
|
var Data = CreateData('11', 'CRRC_基础数据_车体参数_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
adjustParametersList.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getProjectList = () => {
|
||||||
|
projectList.length = 0
|
||||||
|
var param = []
|
||||||
|
var Data = CreateData('11', 'CRRC_车体_项目_下拉查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
projectList.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleProjectChange = (val) => {
|
||||||
|
// 查找选中的项目
|
||||||
|
const selectedProject = projectList.find(item => item.项目编号 === val)
|
||||||
|
if (selectedProject) {
|
||||||
|
// 同步更新项目名称
|
||||||
|
carInputData.projectName = selectedProject.项目名称
|
||||||
|
}
|
||||||
|
// 如果车节也有值,查询历史车体参数
|
||||||
|
if (carInputData.carSection) {
|
||||||
|
getHistoryCarBody()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理项目编号输入
|
||||||
|
const handleProjectInput = (val) => {
|
||||||
|
// 查找是否有匹配的项目
|
||||||
|
const matchedProject = projectList.find(item => item.项目编号 === val)
|
||||||
|
if (matchedProject) {
|
||||||
|
carInputData.projectName = matchedProject.项目名称
|
||||||
|
} else {
|
||||||
|
carInputData.projectName = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理项目编号失焦
|
||||||
|
const handleProjectBlur = () => {
|
||||||
|
// 如果车节也有值,查询历史车体参数
|
||||||
|
if (carInputData.projectNo && carInputData.carSection) {
|
||||||
|
getHistoryCarBody()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理车节选择
|
||||||
|
const handleCarSectionChange = (val) => {
|
||||||
|
editCarSection()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理车节输入
|
||||||
|
const handleCarSectionInput = (val) => {
|
||||||
|
// 输入时暂不做处理,等失焦时再查询
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理车节失焦
|
||||||
|
const handleCarSectionBlur = () => {
|
||||||
|
// 先尝试从车节列表中查找匹配的记录
|
||||||
|
for (let i = 0; i < carSectionList.length; i++) {
|
||||||
|
if (carSectionList[i].车节 == carInputData.carSection) {
|
||||||
|
let clickItem = carSectionList[i]
|
||||||
|
carInputData.carBody = clickItem.车体参数1
|
||||||
|
carInputData.expansionJoint = clickItem.伸缩缝参数1
|
||||||
|
carInputData.adjustTheParameters = clickItem.调节参数1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果项目编号也有值,查询历史车体参数
|
||||||
|
if (carInputData.projectNo && carInputData.carSection) {
|
||||||
|
getHistoryCarBody()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const editCarSection = () => {
|
||||||
|
// 获取 车节列表对应项
|
||||||
|
for (let i = 0; i < carSectionList.length; i++) {
|
||||||
|
if (carSectionList[i].车节 == carInputData.carSection) {
|
||||||
|
let clickItem = carSectionList[i]
|
||||||
|
carInputData.carBody = clickItem.车体参数1
|
||||||
|
carInputData.expansionJoint = clickItem.伸缩缝参数1
|
||||||
|
carInputData.adjustTheParameters = clickItem.调节参数1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果项目编号也有值,查询历史车体参数
|
||||||
|
if (carInputData.projectNo) {
|
||||||
|
getHistoryCarBody()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询历史车体参数
|
||||||
|
const getHistoryCarBody = () => {
|
||||||
|
if (!carInputData.projectNo || !carInputData.carSection) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var param = []
|
||||||
|
param.push(['项目编号', carInputData.projectNo])
|
||||||
|
param.push(['车节', carInputData.carSection])
|
||||||
|
var Data = CreateData('11', 'CRRC_基础数据_车体参数_根据项目号车节_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
// 直接将查询到的结果赋值到输入框
|
||||||
|
carInputData.carBody = response.data[0].车体 || ''
|
||||||
|
carInputData.expansionJoint = response.data[0].伸缩缝 || ''
|
||||||
|
carInputData.adjustTheParameters = response.data[0].调节参数 || ''
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('查询历史车体参数失败:', error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
const carInit = async () => {
|
||||||
|
var param = {
|
||||||
|
OPName: store.user.opName,
|
||||||
|
Operator: store.user.AID
|
||||||
|
}
|
||||||
|
let response = await ExecIMESAPI('WebInit', param)
|
||||||
|
if (response.data.code != 0) {
|
||||||
|
ElMessage.error(response.data.msg)
|
||||||
|
} else {
|
||||||
|
ElMessage.success('初始化成功!')
|
||||||
|
getCarData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 车体到位
|
||||||
|
const carPlace = async () => {
|
||||||
|
var param = {
|
||||||
|
OPName: store.user.opName,
|
||||||
|
ProBH: carInputData.projectNo,
|
||||||
|
ProName: carInputData.projectName,
|
||||||
|
CarBH: carInputData.carNo,
|
||||||
|
CarBody: carInputData.carSection,
|
||||||
|
CarBodyParam: carInputData.carBody, // 车体参数
|
||||||
|
ExpansionJoint: carInputData.expansionJoint, // 伸缩缝参数
|
||||||
|
AdjustParam: carInputData.adjustTheParameters, // 调节参数
|
||||||
|
// Position_1: carInputData.pos1 ? 1 : 0,
|
||||||
|
// Position_2: carInputData.pos2 ? 1 : 0,
|
||||||
|
// Position_3: carInputData.pos3 ? 1 : 0,
|
||||||
|
// Position_4: carInputData.pos4 ? 1 : 0,
|
||||||
|
// Position_5: carInputData.pos5 ? 1 : 0,
|
||||||
|
Operator: store.user.AID
|
||||||
|
}
|
||||||
|
let response = await ExecIMESAPI('CarArrived', param)
|
||||||
|
if (response.data.code != 0) {
|
||||||
|
ElMessage.error(response.data.msg)
|
||||||
|
} else {
|
||||||
|
ElMessage.success('车体到位成功!')
|
||||||
|
getCarData()
|
||||||
|
getCarBodyList()
|
||||||
|
getExpansionJointList()
|
||||||
|
getAdjustParametersList()
|
||||||
|
getCarSectionList()
|
||||||
|
getProjectList()
|
||||||
|
// routerTo({path: 'MaterialPlatform'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 车体离位
|
||||||
|
const carLeave = async () => {
|
||||||
|
// let responseReadPLC = await ExecWritePLC(store.user.opName, 100001, 0)
|
||||||
|
// if (responseReadPLC.data.code == 0) {
|
||||||
|
// var param = []
|
||||||
|
// param.push(['OPName', store.user.opName])
|
||||||
|
// var Data = CreateData('11', 'CRRC_生产_车体离位', param)
|
||||||
|
// ExecDatabase(Data).then(response => {
|
||||||
|
// if (response.data.length > 0) {
|
||||||
|
// if (response.data[0].result === 1) {
|
||||||
|
// ElMessage.success(response.data[0].msg)
|
||||||
|
// getCarData()
|
||||||
|
// } else {
|
||||||
|
// ElMessage.error(response.data[0].msg)
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// ElMessage.error('数据异常')
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// } else {
|
||||||
|
// ElMessage.error(responseReadPLC.data.msg)
|
||||||
|
// }
|
||||||
|
var param = {
|
||||||
|
OPName: store.user.opName,
|
||||||
|
Operator: store.user.AID
|
||||||
|
}
|
||||||
|
let response = await ExecIMESAPI('CarLeave', param)
|
||||||
|
if (response.data.code != 0) {
|
||||||
|
ElMessage.error(response.data.msg)
|
||||||
|
} else {
|
||||||
|
ElMessage.success('车体离位成功!')
|
||||||
|
getCarData()
|
||||||
|
getCarBodyList()
|
||||||
|
getExpansionJointList()
|
||||||
|
getAdjustParametersList()
|
||||||
|
getCarSectionList()
|
||||||
|
getProjectList()
|
||||||
|
// routerTo({path: 'MaterialPlatform'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 护栏安装到位 更新到 moby 不点无所谓 不跳转可不选
|
||||||
|
const guardrailsAreInstalledInPlace = async () => {
|
||||||
|
// // 判断当前是否有初始化的车体 有才允许点击CarBodyPlace
|
||||||
|
// if (carInputData.carBody == '') {
|
||||||
|
// ElMessage.error('请先选择车体')
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// if (carInputData.carBodyCode == '') {
|
||||||
|
// ElMessage.error('请先选择车体流水号')
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// 二次确认护栏是否安装到位
|
||||||
|
ElMessageBox.confirm('护栏是否安装到位?', '二次确认').then(() => {
|
||||||
|
var param = []
|
||||||
|
param.push(['opName', store.user.opName])
|
||||||
|
var Data = CreateData('11', 'CRRC_台位_Moby_护栏安装到位', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
if (response.data[0].result === 1) {
|
||||||
|
ElMessage.success(response.data[0].msg)
|
||||||
|
getCarData()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.data[0].msg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error('数据异常')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const routerTo = (item) => {
|
||||||
|
const targetRoute = routerData.value.userRouterList.find(r => r.path === item.path)
|
||||||
|
if (targetRoute) {
|
||||||
|
routerData.nowRouterPath = targetRoute.path
|
||||||
|
routerData.nowRouterTitle = targetRoute.权限模块
|
||||||
|
routerData.selected = true
|
||||||
|
router.push({ path: '/' + targetRoute.path })
|
||||||
|
|
||||||
|
console.log(targetRoute)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.main {
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
margin-top: 3vh;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-box,
|
||||||
|
.project-box {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-title {
|
||||||
|
width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-value {
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
&.success {
|
||||||
|
background-color: #00802d;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
background-color: #ff9900;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.danger {
|
||||||
|
background-color: #b32f43;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.info {
|
||||||
|
background-color: #7b7e87;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-title {
|
||||||
|
width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-value {
|
||||||
|
flex: 1;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input,
|
||||||
|
.el-select,
|
||||||
|
.el-autocomplete {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 30px;
|
||||||
|
margin-top: 30px;
|
||||||
|
padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
width: 180px;
|
||||||
|
height: 60px;
|
||||||
|
font-size: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.topOp {
|
||||||
|
position: absolute;
|
||||||
|
top: 7vh;
|
||||||
|
left: 5vw;
|
||||||
|
font-size: 2vw;
|
||||||
|
|
||||||
|
.text {
|
||||||
|
background-color: #008000;
|
||||||
|
margin-left: 20px;
|
||||||
|
padding: 0 1vw;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
262
src/views/CarBodyPlaceSearch/index.vue
Normal file
262
src/views/CarBodyPlaceSearch/index.vue
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tableBox">
|
||||||
|
<div class="tableTop">
|
||||||
|
<span style="margin-left: 1vw">查询日期:</span>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateTime"
|
||||||
|
:clearable="false"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
range-separator="~"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
style="width: 190px;"
|
||||||
|
type="daterange"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
/>
|
||||||
|
<span style="margin-left: 1vw">台位号:</span>
|
||||||
|
<el-select v-model="searchObj.opName" clearable placeholder="台位号" style="width: 8vw;">
|
||||||
|
<el-option
|
||||||
|
v-for="item in opNameList"
|
||||||
|
:key="item.工位名称"
|
||||||
|
:label="item.工位描述"
|
||||||
|
:value="item.工位名称">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
<span style="margin-left: 1vw">项目编号:</span>
|
||||||
|
<el-input
|
||||||
|
v-model="searchObj.projectCode"
|
||||||
|
clearable
|
||||||
|
placeholder="项目编号"
|
||||||
|
style="width: 180px"
|
||||||
|
/>
|
||||||
|
<span style="margin-left: 1vw">项目名称:</span>
|
||||||
|
<el-input
|
||||||
|
v-model="searchObj.projectName"
|
||||||
|
clearable
|
||||||
|
placeholder="项目名称"
|
||||||
|
style="width: 180px"
|
||||||
|
/>
|
||||||
|
<span style="margin-left: 1vw">车节:</span>
|
||||||
|
<el-input
|
||||||
|
v-model="searchObj.carJ"
|
||||||
|
clearable
|
||||||
|
placeholder="车节"
|
||||||
|
style="width: 180px"
|
||||||
|
/>
|
||||||
|
<span style="margin-left: 1vw">车号:</span>
|
||||||
|
<el-input
|
||||||
|
v-model="searchObj.carH"
|
||||||
|
clearable
|
||||||
|
placeholder="车号"
|
||||||
|
style="width: 180px"
|
||||||
|
/>
|
||||||
|
<el-button :icon="Search" style="margin-left: 1vw" type="success" @click="searchTable">查询</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="tableData" border height="80vh" stripe style="width: 100%">
|
||||||
|
<el-table-column align="center" label="序号" type="index" width="80"/>
|
||||||
|
<el-table-column align="center" label="台位号" width="90">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ getOpNameDescription(scope.row.工作台位) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="left" label="项目编号">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.项目编号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="left" label="项目名称">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.项目名称 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="left" label="车号" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="车节" width="90">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车节 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="工作状态" width="90">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.工作状态文本 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="开始时间" width="170">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.开始时间 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 删除列,只有角色编号为1的用户才显示 -->
|
||||||
|
<el-table-column v-if="user.role == '1'" align="center" label="操作" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
:icon="Delete"
|
||||||
|
size="small"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="block" style="margin-top: 5px;">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="page.pageList"
|
||||||
|
v-model:page-size="page.pageSize"
|
||||||
|
:page-sizes="[30, 50, 100, 200]"
|
||||||
|
:total="page.total"
|
||||||
|
background
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
style="padding-left: 1vw"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {inject, onMounted, reactive, ref} from 'vue'
|
||||||
|
import {Search, Delete} from "@element-plus/icons-vue";
|
||||||
|
import { useAppStore } from "@/store/app.js";
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
const store = useAppStore();
|
||||||
|
const { user } = storeToRefs(store);
|
||||||
|
|
||||||
|
const dateTime = ref([new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], new Date().toISOString().split('T')[0]]) // 开始结束时间段
|
||||||
|
|
||||||
|
const opNameList = reactive([])
|
||||||
|
const tableData = reactive([])
|
||||||
|
const searchObj = reactive({
|
||||||
|
opName: '',
|
||||||
|
projectCode: '',
|
||||||
|
projectName: '',
|
||||||
|
carH: '',
|
||||||
|
carJ: '',
|
||||||
|
})
|
||||||
|
const page = reactive({
|
||||||
|
total: 0, // 总条数
|
||||||
|
pageSize: 50, // 每页显示条数
|
||||||
|
pageList: 1, // 后台获取页
|
||||||
|
loading: false, // 是否显示加载
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getOpName()
|
||||||
|
searchTable()
|
||||||
|
console.log(user.value)
|
||||||
|
});
|
||||||
|
|
||||||
|
const getOpNameDescription = (opName) => {
|
||||||
|
return opNameList.find(item => item.工位名称 === opName)?.工位描述 || opName
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const searchTable = () => {
|
||||||
|
page.loading = true
|
||||||
|
tableData.length = 0
|
||||||
|
var param = []
|
||||||
|
param.push(['开始时间', dateTime.value[0]])
|
||||||
|
param.push(['结束时间', dateTime.value[1]])
|
||||||
|
param.push(['台位号', searchObj.opName])
|
||||||
|
param.push(['项目编号', searchObj.projectCode])
|
||||||
|
param.push(['项目名称', searchObj.projectName])
|
||||||
|
param.push(['车号', searchObj.carH])
|
||||||
|
param.push(['车节', searchObj.carJ])
|
||||||
|
param.push(['PageCurrent', page.pageList])
|
||||||
|
param.push(['PageSize', page.pageSize])
|
||||||
|
param.push(['PageCount', '1111', 'int', '1'])
|
||||||
|
param.push(['ItemCount', '1111', 'int', '1'])
|
||||||
|
var Data = CreateData('11', 'CRRC_车体_项目_车体信息_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length !== 0) {
|
||||||
|
tableData.push(...response.data.result)
|
||||||
|
}
|
||||||
|
page.total = parseInt(response.data.output[0].ItemCount)
|
||||||
|
page.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getOpName = () => {
|
||||||
|
opNameList.length = 0
|
||||||
|
// 获取当前操作员名称
|
||||||
|
var param = []
|
||||||
|
param.push(['OPType', 1])
|
||||||
|
var Data = CreateData('11', 'CRRC_台位_Moby_登录台位列表_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
opNameList.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
const handleSizeChange = (val) => {
|
||||||
|
page.pageList = 1
|
||||||
|
page.pageSize = val
|
||||||
|
searchTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange = (val) => {
|
||||||
|
page.pageList = val
|
||||||
|
searchTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除功能
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定要删除该记录吗?`,
|
||||||
|
'删除确认',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
dangerouslyUseHTMLString: true
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
// 调用删除存储过程
|
||||||
|
var param = []
|
||||||
|
param.push(['AID', row.AID])
|
||||||
|
var Data = CreateData('12', 'CRRC_台位_Moby_历史_删除', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
// 重新加载数据
|
||||||
|
searchTable()
|
||||||
|
}).catch(error => {
|
||||||
|
ElMessage.error('删除失败:' + error.message)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.tableBox {
|
||||||
|
width: 98vw;
|
||||||
|
margin: 2vh auto 0 auto;
|
||||||
|
border: 1px solid #9f9f9f;
|
||||||
|
background-color: #ecf0f3;
|
||||||
|
box-shadow: 10px 10px 10px #d1d9e6, -10px -10px 10px #f9f9f9;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.tableTop {
|
||||||
|
width: 100%;
|
||||||
|
margin: 1vh auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block {
|
||||||
|
margin-bottom: 1vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
326
src/views/FeedDataSearch/index.vue
Normal file
326
src/views/FeedDataSearch/index.vue
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tableBox">
|
||||||
|
<div class="tableTop">
|
||||||
|
<span style="margin-left: 1vw">查询日期:</span>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateTime"
|
||||||
|
:clearable="false"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
range-separator="~"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
style="width: 190px;"
|
||||||
|
type="daterange"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
/>
|
||||||
|
<span style="margin-left: 1vw">通道号:</span>
|
||||||
|
<el-select v-model="searchObj.opName" clearable placeholder="通道号" style="width: 8vw;">
|
||||||
|
<el-option
|
||||||
|
v-for="item in opNameList"
|
||||||
|
:key="item.工位名称"
|
||||||
|
:label="item.工位描述"
|
||||||
|
:value="item.工位名称">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
<span style="margin-left: 1vw">项目编号:</span>
|
||||||
|
<el-input
|
||||||
|
v-model="searchObj.projectCode"
|
||||||
|
clearable
|
||||||
|
placeholder="项目编号"
|
||||||
|
style="width: 180px"
|
||||||
|
/>
|
||||||
|
<span style="margin-left: 1vw">项目名称:</span>
|
||||||
|
<el-input
|
||||||
|
v-model="searchObj.projectName"
|
||||||
|
clearable
|
||||||
|
placeholder="项目名称"
|
||||||
|
style="width: 180px"
|
||||||
|
/>
|
||||||
|
<span style="margin-left: 1vw">车节:</span>
|
||||||
|
<el-input
|
||||||
|
v-model="searchObj.carJ"
|
||||||
|
clearable
|
||||||
|
placeholder="车节"
|
||||||
|
style="width: 180px"
|
||||||
|
/>
|
||||||
|
<span style="margin-left: 1vw">车号:</span>
|
||||||
|
<el-input
|
||||||
|
v-model="searchObj.carH"
|
||||||
|
clearable
|
||||||
|
placeholder="车号"
|
||||||
|
style="width: 180px"
|
||||||
|
/>
|
||||||
|
<el-button :icon="Search" style="margin-left: 1vw" type="success" @click="searchTable">查询</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="tableData" border height="80vh" stripe style="width: 100%">
|
||||||
|
<el-table-column align="center" label="序号" type="index" width="80"/>
|
||||||
|
<el-table-column align="center" label="通道号" width="90">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ getOpNameDescription(scope.row.台位名称) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="位置1" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.位置1文本 === '不使用'" type="info">{{ scope.row.位置1文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置1文本 === '缺料'" type="warning">{{ scope.row.位置1文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置1文本 === '需送料'" type="danger">{{ scope.row.位置1文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置1文本 === '已到位'" type="success">{{ scope.row.位置1文本 }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="位置2" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.位置2文本 === '不使用'" type="info">{{ scope.row.位置2文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置2文本 === '缺料'" type="warning">{{ scope.row.位置2文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置2文本 === '需送料'" type="danger">{{ scope.row.位置2文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置2文本 === '已到位'" type="success">{{ scope.row.位置2文本 }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="位置3" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.位置3文本 === '不使用'" type="info">{{ scope.row.位置3文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置3文本 === '缺料'" type="warning">{{ scope.row.位置3文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置3文本 === '需送料'" type="danger">{{ scope.row.位置3文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置3文本 === '已到位'" type="success">{{ scope.row.位置3文本 }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="位置4" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.位置4文本 === '不使用'" type="info">{{ scope.row.位置4文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置4文本 === '缺料'" type="warning">{{ scope.row.位置4文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置4文本 === '需送料'" type="danger">{{ scope.row.位置4文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置4文本 === '已到位'" type="success">{{ scope.row.位置4文本 }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="位置5" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.位置5文本 === '不使用'" type="info">{{ scope.row.位置5文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置5文本 === '缺料'" type="warning">{{ scope.row.位置5文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置5文本 === '需送料'" type="danger">{{ scope.row.位置5文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置5文本 === '已到位'" type="success">{{ scope.row.位置5文本 }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="位置6" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.位置6文本 === '不使用'" type="info">{{ scope.row.位置6文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置6文本 === '缺料'" type="warning">{{ scope.row.位置6文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置6文本 === '需送料'" type="danger">{{ scope.row.位置6文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置6文本 === '已到位'" type="success">{{ scope.row.位置6文本 }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="位置7" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.位置7文本 === '不使用'" type="info">{{ scope.row.位置7文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置7文本 === '缺料'" type="warning">{{ scope.row.位置7文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置7文本 === '需送料'" type="danger">{{ scope.row.位置7文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置7文本 === '已到位'" type="success">{{ scope.row.位置7文本 }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="位置8" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.位置8文本 === '不使用'" type="info">{{ scope.row.位置8文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置8文本 === '缺料'" type="warning">{{ scope.row.位置8文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置8文本 === '需送料'" type="danger">{{ scope.row.位置8文本 }}</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.位置8文本 === '已到位'" type="success">{{ scope.row.位置8文本 }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="left" label="项目编号">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.项目编号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="left" label="项目名称">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.项目名称 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="left" label="车号" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="车节" width="90">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车节 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="送料状态" width="90">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.送料状态文本 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="开始时间" width="170">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.开始时间 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 删除列,只有角色编号为1的用户才显示 -->
|
||||||
|
<el-table-column v-if="user.role == '1'" align="center" label="操作" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
:icon="Delete"
|
||||||
|
size="small"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="block" style="margin-top: 5px;">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="page.pageList"
|
||||||
|
v-model:page-size="page.pageSize"
|
||||||
|
:page-sizes="[30, 50, 100, 200]"
|
||||||
|
:total="page.total"
|
||||||
|
background
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
style="padding-left: 1vw"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {inject, onMounted, reactive, ref} from 'vue'
|
||||||
|
import {Search, Delete} from "@element-plus/icons-vue";
|
||||||
|
import { useAppStore } from "@/store/app.js";
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
const store = useAppStore();
|
||||||
|
const { user } = storeToRefs(store);
|
||||||
|
|
||||||
|
const dateTime = ref([new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], new Date().toISOString().split('T')[0]]) // 开始结束时间段
|
||||||
|
|
||||||
|
const opNameList = reactive([])
|
||||||
|
const tableData = reactive([])
|
||||||
|
const searchObj = reactive({
|
||||||
|
opName: '',
|
||||||
|
projectCode: '',
|
||||||
|
projectName: '',
|
||||||
|
carH: '',
|
||||||
|
carJ: '',
|
||||||
|
})
|
||||||
|
const page = reactive({
|
||||||
|
total: 0, // 总条数
|
||||||
|
pageSize: 50, // 每页显示条数
|
||||||
|
pageList: 1, // 后台获取页
|
||||||
|
loading: false, // 是否显示加载
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getOpName()
|
||||||
|
searchTable()
|
||||||
|
console.log(user.value)
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const searchTable = () => {
|
||||||
|
page.loading = true
|
||||||
|
tableData.length = 0
|
||||||
|
var param = []
|
||||||
|
param.push(['开始时间', dateTime.value[0]])
|
||||||
|
param.push(['结束时间', dateTime.value[1]])
|
||||||
|
param.push(['台位名称', searchObj.opName])
|
||||||
|
param.push(['项目编号', searchObj.projectCode])
|
||||||
|
param.push(['项目名称', searchObj.projectName])
|
||||||
|
param.push(['车号', searchObj.carH])
|
||||||
|
param.push(['车节', searchObj.carJ])
|
||||||
|
param.push(['PageCurrent', page.pageList])
|
||||||
|
param.push(['PageSize', page.pageSize])
|
||||||
|
param.push(['PageCount', '1111', 'int', '1'])
|
||||||
|
param.push(['ItemCount', '1111', 'int', '1'])
|
||||||
|
var Data = CreateData('11', 'CRRC_台位_RGV送料Moby_历史_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length !== 0) {
|
||||||
|
tableData.push(...response.data.result)
|
||||||
|
}
|
||||||
|
page.total = parseInt(response.data.output[0].ItemCount)
|
||||||
|
page.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getOpNameDescription = (opName) => {
|
||||||
|
return opNameList.find(item => item.工位名称 === opName)?.工位描述 || opName
|
||||||
|
}
|
||||||
|
|
||||||
|
const getOpName = () => {
|
||||||
|
opNameList.length = 0
|
||||||
|
// 获取当前操作员名称
|
||||||
|
var param = [['OPType',2]]
|
||||||
|
|
||||||
|
var Data = CreateData('11', 'CRRC_台位_Moby_登录台位列表_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
opNameList.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
const handleSizeChange = (val) => {
|
||||||
|
page.pageList = 1
|
||||||
|
page.pageSize = val
|
||||||
|
searchTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange = (val) => {
|
||||||
|
page.pageList = val
|
||||||
|
searchTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除功能
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定要删除该记录吗?`,
|
||||||
|
'删除确认',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
dangerouslyUseHTMLString: true
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
// 调用删除存储过程
|
||||||
|
var param = []
|
||||||
|
param.push(['ID', row.ID])
|
||||||
|
var Data = CreateData('12', 'CRRC_台位_RGV送料Moby_历史_删除', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
// 重新加载数据
|
||||||
|
searchTable()
|
||||||
|
}).catch(error => {
|
||||||
|
ElMessage.error('删除失败:' + error.message)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.tableBox {
|
||||||
|
width: 98vw;
|
||||||
|
margin: 2vh auto 0 auto;
|
||||||
|
border: 1px solid #9f9f9f;
|
||||||
|
background-color: #ecf0f3;
|
||||||
|
box-shadow: 10px 10px 10px #d1d9e6, -10px -10px 10px #f9f9f9;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.tableTop {
|
||||||
|
width: 100%;
|
||||||
|
margin: 1vh auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block {
|
||||||
|
margin-bottom: 1vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
663
src/views/HMIView/index.vue
Normal file
663
src/views/HMIView/index.vue
Normal file
@@ -0,0 +1,663 @@
|
|||||||
|
<template>
|
||||||
|
<div class="main">
|
||||||
|
<div class="top">
|
||||||
|
<div class="left">
|
||||||
|
<span>当前RGV通道</span>
|
||||||
|
<span class="text">{{ store.user.opDescription || store.user.opName }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<el-button type="success" @mousedown="WritePlc('启动',1)" @mouseup="WritePlc('启动',0)">启动</el-button>
|
||||||
|
<el-button type="warning" @mousedown="WritePlc('复位',1)" @mouseup="WritePlc('复位',0)">复位</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="center">
|
||||||
|
<fieldset class="left">
|
||||||
|
<legend class="title">主界面</legend>
|
||||||
|
<div class="main">
|
||||||
|
<div class="carBattery">
|
||||||
|
当前电量
|
||||||
|
<div class="battery">
|
||||||
|
<div :style="{ height: data.batteryLevel + '%' }" class="battery-bar"></div>
|
||||||
|
<div style="position: relative;top: 40%">{{ data.batteryLevel }} %</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="carPosList">
|
||||||
|
<div class="item">
|
||||||
|
<div class="unit">{{ data.XCWZ }} mm</div>
|
||||||
|
<div class="text">小车位置</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="unit">{{ data.SJWZ }} mm</div>
|
||||||
|
<div class="text">升降位置</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="carStatus">
|
||||||
|
<div class="item">
|
||||||
|
<div :style="{ backgroundColor: data.carStatus1 ? '#1afa29' : '#8a8a8a' }" class="status"></div>
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('点动',1)" @mouseup="WritePlc('点动',0)">点动</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div :style="{ backgroundColor: data.carStatus2 ? '#1afa29' : '#8a8a8a' }" class="status"></div>
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('半自动',1)" @mouseup="WritePlc('半自动',0)">半自动</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div :style="{ backgroundColor: data.carStatus3 ? '#1afa29' : '#8a8a8a' }" class="status"></div>
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('上料自动',1)" @mouseup="WritePlc('上料自动',0)">上料自动</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div :style="{ backgroundColor: data.carStatus4 ? '#1afa29' : '#8a8a8a' }" class="status"></div>
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('下料自动',1)" @mouseup="WritePlc('下料自动',0)">下料自动</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="right">
|
||||||
|
<legend class="title">手动操作</legend>
|
||||||
|
<div class="itemList">
|
||||||
|
<div class="item"></div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="ellipseTest"
|
||||||
|
:style="{ backgroundColor: data.SJHYWC ? 'rgba(26, 250, 41,1)' : 'rgba(26, 250, 41,0)' }">升降回原完成</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('小车前进',1)" @mouseup="WritePlc('小车前进',0)">小车前进</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('升降回原位',1)" @mouseup="WritePlc('升降回原位',0)">升降回原位</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('小车后退',1)" @mouseup="WritePlc('小车后退',0)">小车后退</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('上升定位',1)" @mouseup="WritePlc('上升定位',0)">上升定位</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item"></div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('下降定位',1)" @mouseup="WritePlc('下降定位',0)">下降定位</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
<div class="bottom">
|
||||||
|
<fieldset class="left">
|
||||||
|
<legend class="title">充电桩</legend>
|
||||||
|
<div class="itemList">
|
||||||
|
<div class="item">
|
||||||
|
<div class="ellipseTest"
|
||||||
|
:style="{ backgroundColor: data.ZZCD ? 'rgba(26, 250, 41,1)' : 'rgba(26, 250, 41,0)' }">正在充电</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="unit">{{ data.CDDL }}</div>
|
||||||
|
<div class="text">充电电流</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="unit">{{ data.CDDY }}</div>
|
||||||
|
<div class="text">充电电压</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="ellipseTest"
|
||||||
|
:style="{ backgroundColor: data.DSSCDW ? 'rgba(26, 250, 41,1)' : 'rgba(26, 250, 41,0)' }">电刷伸出到位</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="unit">{{ data.CDMS }}</div>
|
||||||
|
<div class="text">充电模式</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="unit">{{ data.XT }}</div>
|
||||||
|
<div class="text">心跳</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex">
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('开始充电',1)" @mouseup="WritePlc('开始充电',0)">开始充电</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('停止充电',1)" @mouseup="WritePlc('停止充电',0)">停止充电</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="right">
|
||||||
|
<legend class="title">工位操作</legend>
|
||||||
|
<div class="itemList">
|
||||||
|
<div class="item">上料位</div>
|
||||||
|
<div class="item">充电位</div>
|
||||||
|
<div class="item">位置1</div>
|
||||||
|
<div class="item">位置2</div>
|
||||||
|
<div class="item">位置3</div>
|
||||||
|
<div class="item">位置4</div>
|
||||||
|
<div class="item">位置5</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.SLDD) }">{{ data.SLDD ? '已到' : '未到' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.CDWDD) }">{{ data.CDWDD ? '已到' : '未到' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.WZ1DD) }">{{ data.WZ1DD ? '已到' : '未到' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.WZ2DD) }">{{ data.WZ2DD ? '已到' : '未到' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.WZ3DD) }">{{ data.WZ3DD ? '已到' : '未到' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.WZ4DD) }">{{ data.WZ4DD ? '已到' : '未到' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.WZ5DD) }">{{ data.WZ5DD ? '已到' : '未到' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.SLXZ) }">{{ data.SLXZ ? '已选' : '未选' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.CDXZ) }">{{ data.CDXZ ? '已选' : '未选' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.WZ1XZ) }">{{ data.WZ1XZ ? '已选' : '未选' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.WZ2XZ) }">{{ data.WZ2XZ ? '已选' : '未选' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.WZ3XZ) }">{{ data.WZ3XZ ? '已选' : '未选' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.WZ4XZ) }">{{ data.WZ4XZ ? '已选' : '未选' }}</div>
|
||||||
|
<div class="item" :style="{ color: getYdColor(data.WZ5XZ) }">{{ data.WZ5XZ ? '已选' : '未选' }}</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('上料位选择',1)" @mouseup="WritePlc('上料位选择',0)">选择</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('充电位选择',1)" @mouseup="WritePlc('充电位选择',0)">选择</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('位置1选择',1)" @mouseup="WritePlc('位置1选择',0)">选择</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('位置2选择',1)" @mouseup="WritePlc('位置2选择',0)">选择</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('位置3选择',1)" @mouseup="WritePlc('位置3选择',0)">选择</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('位置4选择',1)" @mouseup="WritePlc('位置4选择',0)">选择</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('位置5选择',1)" @mouseup="WritePlc('位置5选择',0)">选择</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" @mousedown="WritePlc('定位启动',1)" @mouseup="WritePlc('定位启动',0)">定位启动</el-button>
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { useAppStore } from "@/store/app.js";
|
||||||
|
import { inject, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||||
|
import mqtt from "mqtt";
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
|
||||||
|
const store = useAppStore();
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
const ExecReadPLC = inject('ExecReadPLC')
|
||||||
|
const ExecIMESAPI = inject('ExecIMESAPI')
|
||||||
|
const ExecWritePLC = inject('ExecWritePLC')
|
||||||
|
const ExecMultReadPLC = inject('ExecMultReadPLC')
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
batteryLevel: 0, // 当前电量
|
||||||
|
XCWZ: '0', // 小车位置
|
||||||
|
SJWZ: '0.00', // 升降位置
|
||||||
|
carStatus1: false, // 点动
|
||||||
|
carStatus2: false, // 半自动
|
||||||
|
carStatus3: false, // 上料自动
|
||||||
|
carStatus4: false, // 下料自动
|
||||||
|
SJHYWC: false, // 升降回原完成
|
||||||
|
ZZCD: false, // 正在充电
|
||||||
|
DSSCDW: false, // 电刷伸出到位
|
||||||
|
CDDL: '0.00', // 充电电流
|
||||||
|
CDDY: '0.00', // 充电电压
|
||||||
|
CDMS: '0.00', // 充电模式
|
||||||
|
XT: '0.00', // 心跳
|
||||||
|
SLDD: false, // 上料到达
|
||||||
|
CDWDD: false, // 充电位到达
|
||||||
|
WZ1DD: false, // 位置1到达
|
||||||
|
WZ2DD: false, // 位置2到达
|
||||||
|
WZ3DD: false, // 位置3到达
|
||||||
|
WZ4DD: false, // 位置4到达
|
||||||
|
WZ5DD: false, // 位置5到达
|
||||||
|
SLXZ: false, // 上料选择
|
||||||
|
CDWXZ: false, // 充电位选择
|
||||||
|
WZ1XZ: false, // 位置1选择
|
||||||
|
WZ2XZ: false, // 位置2选择
|
||||||
|
WZ3XZ: false, // 位置3选择
|
||||||
|
WZ4XZ: false, // 位置4选择
|
||||||
|
WZ5XZ: false, // 位置5选择
|
||||||
|
})
|
||||||
|
|
||||||
|
var client = null
|
||||||
|
var timer1 = null
|
||||||
|
onMounted(() => {
|
||||||
|
connectMqtt()
|
||||||
|
initData()
|
||||||
|
timer1 = setInterval(() => {
|
||||||
|
readMultiPLCByTagIds()
|
||||||
|
}, 1000 * 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
try {
|
||||||
|
if (client) {
|
||||||
|
client.end();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('关闭连接失败:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可选:重置 client 为 null
|
||||||
|
client = null;
|
||||||
|
// 关闭定时器
|
||||||
|
clearInterval(timer1);
|
||||||
|
});
|
||||||
|
|
||||||
|
//连接MQTT
|
||||||
|
const connectMqtt = async () => {
|
||||||
|
const topics = ['PLCToWebUI']
|
||||||
|
// 连接选项
|
||||||
|
const options = {
|
||||||
|
keepalive: 60, // 心跳时间
|
||||||
|
reconnectPeriod: 3000, // 重新连接间隔时间
|
||||||
|
clean: true, // 是否清除会话
|
||||||
|
clientId: 'WEB_Op_' + getUUID(),//要确保唯一性,例如随机数或者UUID,
|
||||||
|
username: '',//mqtt服务器配置里面的账号,
|
||||||
|
password: ''//mqtt服务器配置里面的密码,
|
||||||
|
}
|
||||||
|
console.log(window.g.Mqtt_Ip)
|
||||||
|
client = mqtt.connect(window.g.Mqtt_Ip, options);
|
||||||
|
client.on('reconnect', (error) => {
|
||||||
|
console.log('正在重连:', error)
|
||||||
|
ElMessage.warning('正在重连' + error)
|
||||||
|
})
|
||||||
|
client.on('error', (error) => {
|
||||||
|
console.log('连接失败:', error)
|
||||||
|
ElMessage.warning('连接失败' + error)
|
||||||
|
})
|
||||||
|
client.on('connect', (e) => {
|
||||||
|
console.log('MQTT连接成功');
|
||||||
|
// 订阅多个主题
|
||||||
|
client.subscribe(topics, { qos: 0 }, function (err) {
|
||||||
|
if (!err) {
|
||||||
|
console.log('订阅成功');
|
||||||
|
} else {
|
||||||
|
console.error('订阅失败:', err);
|
||||||
|
ElMessage.warning('订阅失败' + err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
client.on('message', (topic, message, packet) => {
|
||||||
|
messageHandle(topic, message.toString())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//状态灯信号监控
|
||||||
|
// case 600004://点动选择灯
|
||||||
|
// case 600005://半自动选择灯
|
||||||
|
// case 600006://上料自动选择灯
|
||||||
|
// case 600007://下料自动选择灯
|
||||||
|
// case 600010://正在充电灯
|
||||||
|
// case 600011://电刷伸出到位灯
|
||||||
|
// case 600020://升降回原完成灯
|
||||||
|
// case 600025://上料位选择状态灯
|
||||||
|
// case 600026://上料位到达状态灯
|
||||||
|
// case 600030://充电位选择状态灯
|
||||||
|
// case 600031://充电位到达状态灯
|
||||||
|
// case 600033://位置1选择状态灯
|
||||||
|
// case 600034://位置1到达状态灯
|
||||||
|
// case 600036://位置2选择状态灯
|
||||||
|
// case 600037://位置2到达状态灯
|
||||||
|
// case 600041://位置3选择状态灯
|
||||||
|
// case 600042://位置3到达状态灯
|
||||||
|
// case 600044://位置4选择状态灯
|
||||||
|
// case 600045://位置4到达状态灯
|
||||||
|
// case 600047://位置5选择状态灯
|
||||||
|
// case 600050://位置5到达状态灯
|
||||||
|
// case 600060://当前电量
|
||||||
|
// case 600100://小车位置
|
||||||
|
// case 600100://小车位置
|
||||||
|
// case 600140://升降位置
|
||||||
|
// case 600180://充电电流
|
||||||
|
// case 600200://充电电压
|
||||||
|
// case 600220://心跳计数
|
||||||
|
// case 600240://充电模式
|
||||||
|
|
||||||
|
const correspondenceList = window.plcPos.correspondenceList
|
||||||
|
|
||||||
|
const buttonList = window.plcPos.buttonList
|
||||||
|
|
||||||
|
|
||||||
|
const messageHandle = (topic, message) => {
|
||||||
|
switch (topic) {
|
||||||
|
case 'PLCToWebUI':
|
||||||
|
let reqData = JSON.parse(message)
|
||||||
|
console.log(reqData)
|
||||||
|
if (reqData.OPCode == store.user.opName) {
|
||||||
|
// 先判断data对象是否存在该tagId 如果存在 则该对应的数据
|
||||||
|
if (reqData.tagTypeCodeID in correspondenceList) {
|
||||||
|
data[correspondenceList[reqData.tagTypeCodeID].value] = reqData.tagValue
|
||||||
|
console.log('接收到信号【' + correspondenceList[reqData.tagTypeCodeID].name + '】信号值:' + reqData.tagValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUUID = () => {
|
||||||
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||||
|
var r = Math.random() * 16 | 0,
|
||||||
|
v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量读取PLC标签
|
||||||
|
const readMultiPLCByTagIds = () => {
|
||||||
|
// 需要读取的所有标签ID
|
||||||
|
const tagIds = ["600060", "600100", "600140", "600180", "600200", "600220", "600240"]
|
||||||
|
|
||||||
|
ExecMultReadPLC(store.user.opName, tagIds).then(response => {
|
||||||
|
if (response.data.code == 0) {
|
||||||
|
const results = response.data.ReadRes_SignalValues
|
||||||
|
|
||||||
|
// 处理所有返回的数据
|
||||||
|
results.forEach(result => {
|
||||||
|
const tagId = result.tagTypeCodeID
|
||||||
|
let value = result.tagValue
|
||||||
|
|
||||||
|
// 转换布尔值
|
||||||
|
if (value === 'True') {
|
||||||
|
value = true
|
||||||
|
} else if (value === 'False') {
|
||||||
|
value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果对应表中有该标签,则更新数据
|
||||||
|
if (tagId in correspondenceList) {
|
||||||
|
data[correspondenceList[tagId].value] = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保留原始方法,但不再使用
|
||||||
|
const readPLCByTagId = (tagId) => {
|
||||||
|
ExecReadPLC(store.user.opName, tagId).then(responseReadPLC => {
|
||||||
|
if (responseReadPLC.data.code == 0) {
|
||||||
|
if (responseReadPLC.data.tagValue == 'True') {
|
||||||
|
responseReadPLC.data.tagValue = true
|
||||||
|
} else if (responseReadPLC.data.tagValue == 'False') {
|
||||||
|
responseReadPLC.data.tagValue = false
|
||||||
|
}
|
||||||
|
|
||||||
|
data[correspondenceList[tagId].value] = responseReadPLC.data.tagValue
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const initData = async () => {
|
||||||
|
var param = {
|
||||||
|
OPName: store.user.opName,
|
||||||
|
Operator: store.user.AID
|
||||||
|
}
|
||||||
|
let response = await ExecIMESAPI('WebHMIInit', param)
|
||||||
|
if (response.data.code != 0) {
|
||||||
|
ElMessage.error(response.data.msg)
|
||||||
|
} else {
|
||||||
|
for (let item of response.data.dataValues) {
|
||||||
|
if (item.tagValue == 'True') {
|
||||||
|
item.tagValue = true
|
||||||
|
} else if (item.tagValue == 'False') {
|
||||||
|
item.tagValue = false
|
||||||
|
}
|
||||||
|
|
||||||
|
data[correspondenceList[item.tagTypeCodeID].value] = item.tagValue
|
||||||
|
}
|
||||||
|
ElMessage.success('初始化成功!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getYdColor = (isOk) => {
|
||||||
|
if (isOk) {
|
||||||
|
return '#1afa29'
|
||||||
|
} else {
|
||||||
|
return '#000000'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const WritePlc = async (tagName, value) => {
|
||||||
|
let tagId = buttonList[tagName]
|
||||||
|
console.log('WritePlc',tagName,tagId, value)
|
||||||
|
let responseReadPLC = await ExecWritePLC(store.user.opName, tagId, value)
|
||||||
|
if (responseReadPLC.data.code == 0) {
|
||||||
|
if (value == 1) {
|
||||||
|
ElMessage.warning(tagName+'按钮按下')
|
||||||
|
} else if(value == 0) {
|
||||||
|
ElMessage.success(tagName+'按钮抬起')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error(responseReadPLC.data.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
// 左侧盒子
|
||||||
|
.left {
|
||||||
|
width: 49vw;
|
||||||
|
padding-left: 1vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 右侧盒子
|
||||||
|
.right {
|
||||||
|
width: 49vw;
|
||||||
|
padding-left: 1vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标题
|
||||||
|
.title {
|
||||||
|
font-size: 1.5vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 椭圆状态球
|
||||||
|
.ellipseTest {
|
||||||
|
width: 15vw;
|
||||||
|
height: 6vh;
|
||||||
|
line-height: 6vh;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
//color: #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
//background-color: #1296db;
|
||||||
|
border: 10px solid #1296db;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
font-size: 1vw;
|
||||||
|
|
||||||
|
.top {
|
||||||
|
display: flex;
|
||||||
|
padding: 2vh 0;
|
||||||
|
font-size: 2vw;
|
||||||
|
height: 7vh;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
.text {
|
||||||
|
background-color: #008000;
|
||||||
|
margin-left: 20px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
.el-button {
|
||||||
|
width: 9vw;
|
||||||
|
height: 6vh;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
margin: 0 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//中间部分
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
// 主界面
|
||||||
|
.left {
|
||||||
|
.main {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
|
||||||
|
.carBattery {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.battery {
|
||||||
|
width: 8vw;
|
||||||
|
height: 30vh;
|
||||||
|
background-color: #ddd;
|
||||||
|
position: relative;
|
||||||
|
border-radius: 3px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.battery-bar {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #32cd32;
|
||||||
|
transition: height 0.3s ease;
|
||||||
|
/* 平滑过渡效果 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.carPosList {
|
||||||
|
width: 15vw;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 8.2vh;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
font-size: 1.5vw;
|
||||||
|
|
||||||
|
.unit {
|
||||||
|
height: 8.2vh;
|
||||||
|
background-color: #ffffc0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
height: 8.2vh;
|
||||||
|
background-color: #48d1cc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.carStatus {
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
margin: 1.5vh 0;
|
||||||
|
|
||||||
|
.status {
|
||||||
|
width: 3vw;
|
||||||
|
height: 3vw;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #1afa29;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
width: 9vw;
|
||||||
|
height: 6vh;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
margin: 0 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手动操作
|
||||||
|
.right {
|
||||||
|
.itemList {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
width: 50%;
|
||||||
|
height: 25%;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
height: 80%;
|
||||||
|
width: 60%;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
.itemList {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
width: 30%;
|
||||||
|
height: 25%;
|
||||||
|
margin: 1vh 1.6%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
|
||||||
|
.unit {
|
||||||
|
height: 5.2vh;
|
||||||
|
background-color: #ffffc0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
height: 5.2vh;
|
||||||
|
background-color: #48d1cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ellipseTest {
|
||||||
|
position: relative;
|
||||||
|
left: -1vw;
|
||||||
|
top: 2vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
margin: 2vh 2vw;
|
||||||
|
width: 9vw;
|
||||||
|
height: 6vh;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
.itemList {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-content: flex-start;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
width: 14.28%;
|
||||||
|
height: 7vh;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
width: 6vw;
|
||||||
|
height: 5vh;
|
||||||
|
font-size: 1.3vw;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
width: 9vw;
|
||||||
|
height: 6vh;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
332
src/views/Layout/index.vue
Normal file
332
src/views/Layout/index.vue
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
<template>
|
||||||
|
<div class="topBar">
|
||||||
|
<t-head-menu v-model="menuValue" height="120px" theme="dark">
|
||||||
|
<!-- <template #logo>
|
||||||
|
<img alt="logo" height="120px" src="/public/TopLogo.jpg"/>
|
||||||
|
</template> -->
|
||||||
|
<div style="height: 100%;line-height: 100%;width: 80vw;overflow: auto;display: flex">
|
||||||
|
<t-menu-item v-for="router in routerData.userRouterList"
|
||||||
|
:key="router.path"
|
||||||
|
:selected="router.selected"
|
||||||
|
:value="router.path"
|
||||||
|
style="height: 100%"
|
||||||
|
@click="routerTo(router)">
|
||||||
|
{{ router.权限模块 }}
|
||||||
|
</t-menu-item>
|
||||||
|
</div>
|
||||||
|
<template #operations>
|
||||||
|
<div class="dateTime">
|
||||||
|
<div class="date">{{ date }}</div>
|
||||||
|
<div class="time">{{ time }} {{ nowWeek }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="t-demo-menu--dark">
|
||||||
|
<!-- <t-button shape="square" variant="text">-->
|
||||||
|
<!-- <template #icon>-->
|
||||||
|
<!-- <t-icon name="search"/>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
<!-- </t-button>-->
|
||||||
|
<!-- <t-button shape="square" variant="text">-->
|
||||||
|
<!-- <template #icon>-->
|
||||||
|
<!-- <t-icon name="mail"/>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
<!-- </t-button>-->
|
||||||
|
<!-- <t-button shape="square" variant="text">-->
|
||||||
|
<!-- <template #icon>-->
|
||||||
|
<!-- <t-icon name="user"/>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
<!-- </t-button>-->
|
||||||
|
<el-button :icon="SwitchButton" circle @click="logout" style="background: transparent; border: none; color: #fff; font-size: 20px;" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</t-head-menu>
|
||||||
|
</div>
|
||||||
|
<div class="main">
|
||||||
|
<router-view/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {inject, onMounted, onUnmounted, ref} from 'vue'
|
||||||
|
import {useAppStore} from '@/store/app.js'
|
||||||
|
import {storeToRefs} from 'pinia'
|
||||||
|
import {addDynamicRoutes} from '@/router/index.js'
|
||||||
|
import {ElMessage} from 'element-plus'
|
||||||
|
import {useRouter} from 'vue-router'
|
||||||
|
import Cookies from 'js-cookie'
|
||||||
|
import { SwitchButton } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const store = useAppStore()
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
// storeToRefs 响应式解构赋值 pinia
|
||||||
|
const {user, isLoading, routerData} = storeToRefs(store)
|
||||||
|
|
||||||
|
const menuValue = ref('')
|
||||||
|
const date = ref('')
|
||||||
|
const time = ref('')
|
||||||
|
const nowWeek = ref('')
|
||||||
|
const week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
|
||||||
|
|
||||||
|
let checkTimer = null
|
||||||
|
|
||||||
|
const checkLoginStatus = () => {
|
||||||
|
const loginKey = Cookies.get('loginKey')
|
||||||
|
const opName = Cookies.get('lastOpName')
|
||||||
|
|
||||||
|
if (!loginKey || !opName) {
|
||||||
|
if (checkTimer) {
|
||||||
|
clearInterval(checkTimer)
|
||||||
|
checkTimer = null
|
||||||
|
}
|
||||||
|
store.isLoading = false
|
||||||
|
router.push('/login')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var param = []
|
||||||
|
param[0] = ['工位号', opName]
|
||||||
|
param[1] = ['Key', loginKey]
|
||||||
|
var Data = CreateData('11', 'CRRC_登陆_Key_校验', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data[0].result !== 1) {
|
||||||
|
if (checkTimer) {
|
||||||
|
clearInterval(checkTimer)
|
||||||
|
checkTimer = null
|
||||||
|
}
|
||||||
|
ElMessage.warning(response.data[0].msg || '登录已失效,请重新登录')
|
||||||
|
store.isLoading = false
|
||||||
|
// 直接清除数据并跳转,避免递归调用logout
|
||||||
|
store.$reset()
|
||||||
|
Cookies.remove('loginKey')
|
||||||
|
Cookies.remove('userInfo')
|
||||||
|
Cookies.remove('lastOpName')
|
||||||
|
Cookies.remove('roleType')
|
||||||
|
router.push('/login')
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('登录状态检查失败:', error)
|
||||||
|
// 网络错误时不强制退出,避免影响用户体验
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateDateTime = () => {
|
||||||
|
const now = new Date()
|
||||||
|
date.value = now.toLocaleDateString()
|
||||||
|
time.value = now.toLocaleTimeString()
|
||||||
|
nowWeek.value = week[now.getDay()]
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
console.log('store.user.AID', store.user.AID)
|
||||||
|
// 立即更新一次时间
|
||||||
|
updateDateTime()
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
// 检查Cookie中是否有用户信息
|
||||||
|
const userInfo = Cookies.get('userInfo')
|
||||||
|
if (userInfo) {
|
||||||
|
try {
|
||||||
|
const parsedUserInfo = JSON.parse(userInfo)
|
||||||
|
// 将Cookie中的用户信息恢复到store
|
||||||
|
store.user = {
|
||||||
|
...store.user,
|
||||||
|
...parsedUserInfo
|
||||||
|
}
|
||||||
|
getRouter()
|
||||||
|
// 获取当前实时日期时间 与星期几
|
||||||
|
setInterval(updateDateTime, 1000)
|
||||||
|
|
||||||
|
// 启动登录状态检查定时器
|
||||||
|
checkTimer = setInterval(checkLoginStatus, 30000) // 每30秒检查一次
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析用户信息失败:', error)
|
||||||
|
router.push({path: '/login'})
|
||||||
|
}
|
||||||
|
} else if (!store.user.AID) {
|
||||||
|
console.log('store.user.AID为空且Cookie中无用户信息,返回主页!')
|
||||||
|
router.push({path: '/login'})
|
||||||
|
} else {
|
||||||
|
getRouter()
|
||||||
|
// 获取当前实时日期时间 与星期几
|
||||||
|
setInterval(updateDateTime, 1000)
|
||||||
|
|
||||||
|
// 启动登录状态检查定时器
|
||||||
|
checkTimer = setInterval(checkLoginStatus, 30000) // 每30秒检查一次
|
||||||
|
}
|
||||||
|
}, 200)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (checkTimer) {
|
||||||
|
clearInterval(checkTimer)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取权限列表
|
||||||
|
const getRouter = async () => {
|
||||||
|
// 获取权限列表
|
||||||
|
var param = []
|
||||||
|
param[0] = ['userId', store.user.AID]
|
||||||
|
var Data = CreateData('11', '基础表_权限模块_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
for (let item of response.data) {
|
||||||
|
item.selected = false
|
||||||
|
}
|
||||||
|
response.data[0].selected = true
|
||||||
|
|
||||||
|
// 从cookie中获取角色类型
|
||||||
|
const roleType = Cookies.get('roleType')
|
||||||
|
|
||||||
|
// 如果角色类型为1,过滤掉"车体到位"模块
|
||||||
|
if (roleType == '1') {
|
||||||
|
response.data = response.data.filter(item => item.权限模块 !== '物料平台')
|
||||||
|
response.data = response.data.filter(item => item.权限模块 !== 'HMI界面')
|
||||||
|
}else{
|
||||||
|
response.data = response.data.filter(item => item.权限模块 !== '车体到位')
|
||||||
|
}
|
||||||
|
|
||||||
|
routerData.value.userRouterList = response.data
|
||||||
|
initRouter()
|
||||||
|
} else {
|
||||||
|
ElMessage.warning('该角色未分配角色模块,请先进行分配!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const initRouter = async () => {
|
||||||
|
// 动态添加路由
|
||||||
|
await addDynamicRoutes(routerData.value.userRouterList).then(() => {
|
||||||
|
menuValue.value = routerData.value.userRouterList[0].path
|
||||||
|
routerData.nowRouterPath = routerData.value.userRouterList[0].path
|
||||||
|
routerData.nowRouterTitle = routerData.value.userRouterList[0].权限模块
|
||||||
|
router.push({path: '/' + routerData.value.userRouterList[0].path})
|
||||||
|
store.isLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const routerTo = (item) => {
|
||||||
|
const targetRoute = routerData.value.userRouterList.find(r => r.path === item.path)
|
||||||
|
if (targetRoute) {
|
||||||
|
routerData.nowRouterPath = targetRoute.path
|
||||||
|
routerData.nowRouterTitle = targetRoute.权限模块
|
||||||
|
routerData.selected = true
|
||||||
|
router.push({path: '/' + targetRoute.path})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
// 清理定时器,防止干扰
|
||||||
|
if (checkTimer) {
|
||||||
|
clearInterval(checkTimer)
|
||||||
|
checkTimer = null
|
||||||
|
}
|
||||||
|
|
||||||
|
var param = []
|
||||||
|
param[0] = ['userId', user.value.AID]
|
||||||
|
param[1] = ['opName', user.value.opName]
|
||||||
|
var Data = CreateData('11', '基础表_用户角色_退出登录', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
// 先清除所有相关Cookie,再重置pinia数据
|
||||||
|
Cookies.remove('loginKey')
|
||||||
|
Cookies.remove('userInfo')
|
||||||
|
Cookies.remove('lastOpName')
|
||||||
|
Cookies.remove('roleType')
|
||||||
|
// 重置pinia数据
|
||||||
|
store.$reset()
|
||||||
|
// 只跳转一次到登录页面
|
||||||
|
router.push('/login')
|
||||||
|
ElMessage.success('退出登录成功!')
|
||||||
|
} else {
|
||||||
|
ElMessage.warning('退出登录失败,数据未清空!')
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('退出登录请求失败:', error)
|
||||||
|
// 即使请求失败,也要清理本地数据并跳转
|
||||||
|
if (checkTimer) {
|
||||||
|
clearInterval(checkTimer)
|
||||||
|
checkTimer = null
|
||||||
|
}
|
||||||
|
// 先清除Cookie,再重置store
|
||||||
|
Cookies.remove('loginKey')
|
||||||
|
Cookies.remove('userInfo')
|
||||||
|
Cookies.remove('lastOpName')
|
||||||
|
Cookies.remove('roleType')
|
||||||
|
store.$reset()
|
||||||
|
router.push('/login')
|
||||||
|
ElMessage.warning('网络异常,已强制退出登录!')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.topBar {
|
||||||
|
width: 100vw;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.dateTime {
|
||||||
|
font-size: .8vw;
|
||||||
|
float: right;
|
||||||
|
width: 10vw;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
div {
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.t-menu__operations {
|
||||||
|
.t-button {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.t-demo-menu--dark {
|
||||||
|
.t-button {
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #4b4b4b;
|
||||||
|
border-color: transparent;
|
||||||
|
--ripple-color: #383838;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 滚动条样式 */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 4px; /* 设置纵轴(y轴)轴滚动条 */
|
||||||
|
height: 4px; /* 设置横轴(x轴)轴滚动条 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滚动条滑块(里面小方块) */
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
|
background: #7ba2cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滚动条轨道 */
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.main{
|
||||||
|
width: 100vw;
|
||||||
|
// height去掉topBar
|
||||||
|
height: calc(100vh - 60px);
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
background: #f9f9f9;
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
257
src/views/Login/index.vue
Normal file
257
src/views/Login/index.vue
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
<template>
|
||||||
|
<div class="main">
|
||||||
|
<div class="login">
|
||||||
|
<div class="title">Login</div>
|
||||||
|
<div class="logeType">
|
||||||
|
<div class="item">用户名登录</div>
|
||||||
|
</div>
|
||||||
|
<div class="logFrom">
|
||||||
|
<div class="item">
|
||||||
|
<el-input v-model="userform.userName" :prefix-icon="User" clearable placeholder="请输入用户名" style="height: 40px"
|
||||||
|
type="text" @input="userform.password = ''" />
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-input v-model="userform.password" :prefix-icon="Lock" clearable placeholder="请输入密码" show-password
|
||||||
|
style="height: 40px" type="password" @keyup.enter="login" />
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-select v-model="userform.role" placeholder="请选择角色" style="width: 100%" @change="getOpName()">
|
||||||
|
<el-option v-for="item in roleList" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<el-select v-model="userform.opName" placeholder="请选择台位号" style="width: 100%">
|
||||||
|
<el-option v-for="item in opNameList" :key="item.工位名称" :label="item.工位描述" :value="item.工位名称" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="item" style="margin-top: 40px">
|
||||||
|
<el-button :prefix-icon="Promotion" style="width: 100%" type="danger" @click="login">
|
||||||
|
登录
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { inject, onMounted, reactive } from 'vue'
|
||||||
|
import { Lock, Promotion, User } from '@element-plus/icons-vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useAppStore } from "@/store/app.js";
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
const store = useAppStore();
|
||||||
|
// storeToRefs 响应式解构赋值 pinia
|
||||||
|
const { user, isLoading } = storeToRefs(store);
|
||||||
|
|
||||||
|
const opNameList = reactive([])
|
||||||
|
const userform = reactive({
|
||||||
|
userName: '',
|
||||||
|
password: '',
|
||||||
|
opName: '',
|
||||||
|
role: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const roleList = [{ label: '进车员', value: '1' }, { label: '其他', value: '2' }]
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 从cookie中获取上次登录的角色和工位信息
|
||||||
|
const lastRoleType = Cookies.get('roleType')
|
||||||
|
const lastOpName = Cookies.get('lastOpName')
|
||||||
|
const lastApiMesUrl = Cookies.get('API_MES_URL')
|
||||||
|
|
||||||
|
console.log('从cookie中获取的角色类型:', lastRoleType)
|
||||||
|
console.log('从cookie中获取的工位:', lastOpName)
|
||||||
|
console.log('从cookie中获取的中控接口IP:', lastApiMesUrl)
|
||||||
|
|
||||||
|
// 如果cookie中有中控接口IP,则设置到全局变量
|
||||||
|
if (lastApiMesUrl) {
|
||||||
|
window.g.API_MES_URL = lastApiMesUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果cookie中有角色信息,则自动选择
|
||||||
|
if (lastRoleType) {
|
||||||
|
userform.role = lastRoleType
|
||||||
|
// 获取对应角色的工位列表
|
||||||
|
getOpName()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const login = () => {
|
||||||
|
if (userform.userName === '' || userform.password === '') {
|
||||||
|
ElMessage.warning('用户名或密码不能为空')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (userform.role === '') {
|
||||||
|
ElMessage.warning('请选择角色')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (userform.opName === '') {
|
||||||
|
ElMessage.warning('请选择台位号')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(user)
|
||||||
|
var param = []
|
||||||
|
param[0] = ['userName', userform.userName]
|
||||||
|
param[1] = ['password', userform.password]
|
||||||
|
param[2] = ['opName', userform.opName]
|
||||||
|
var Data = CreateData('11', '基础表_用户角色_用户登录', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
user.value.AID = response.data[0].AID
|
||||||
|
user.value.name = response.data[0].姓名
|
||||||
|
user.value.classes = response.data[0].班次
|
||||||
|
user.value.teamGroup = response.data[0].班组
|
||||||
|
user.value.role = response.data[0].用户角色
|
||||||
|
user.value.userName = response.data[0].登录密码
|
||||||
|
user.value.password = response.data[0].登录账号
|
||||||
|
user.value.opName = userform.opName
|
||||||
|
user.value.roleType = userform.role
|
||||||
|
|
||||||
|
// 获取工位描述并保存
|
||||||
|
const selectedOpInfo = opNameList.find(item => item.工位名称 === userform.opName);
|
||||||
|
user.value.opDescription = selectedOpInfo?.工位描述 || userform.opName;
|
||||||
|
|
||||||
|
const userInfo = {
|
||||||
|
AID: response.data[0].AID,
|
||||||
|
name: response.data[0].姓名,
|
||||||
|
classes: response.data[0].班次,
|
||||||
|
teamGroup: response.data[0].班组,
|
||||||
|
role: response.data[0].用户角色,
|
||||||
|
userName: response.data[0].登录密码,
|
||||||
|
password: response.data[0].登录账号,
|
||||||
|
opName: userform.opName,
|
||||||
|
opDescription: selectedOpInfo?.工位描述 || userform.opName,
|
||||||
|
roleType: userform.role
|
||||||
|
}
|
||||||
|
|
||||||
|
var param2 = []
|
||||||
|
param2[0] = ['工位号', userform.opName]
|
||||||
|
var Data2 = CreateData('11', 'CRRC_SCADA_CHControl_Moby_工位查询', param2)
|
||||||
|
ExecDatabase(Data2).then(response => {
|
||||||
|
if (response.data.length > 0 && response.data[0].中控接口IP) {
|
||||||
|
window.g.API_MES_URL = response.data[0].中控接口IP
|
||||||
|
window.g.API_MES_ControlCode = response.data[0].中控程序代码
|
||||||
|
// 将中控接口IP存入cookie,有效期3天
|
||||||
|
Cookies.set('API_MES_URL', response.data[0].中控接口IP, { expires: 3 })
|
||||||
|
Cookies.set('API_MES_ControlCode', response.data[0].中控程序代码, { expires: 3 })
|
||||||
|
|
||||||
|
// 生成随机LoginKey
|
||||||
|
const loginKey = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
|
||||||
|
|
||||||
|
// 存入Cookie
|
||||||
|
Cookies.set('loginKey', loginKey, { expires: 3 })
|
||||||
|
|
||||||
|
// 调用存储过程保存LoginKey
|
||||||
|
var paramKey = []
|
||||||
|
paramKey[0] = ['工位号', userform.opName]
|
||||||
|
paramKey[1] = ['Key', loginKey]
|
||||||
|
var DataKey = CreateData('12', 'CRRC_登陆_Key_登陆', paramKey)
|
||||||
|
ExecDatabase(DataKey).then(() => {
|
||||||
|
Cookies.set('userInfo', JSON.stringify(userInfo), { expires: 3 })
|
||||||
|
// 保存工位号到cookie,有效期3天
|
||||||
|
Cookies.set('lastOpName', userform.opName, { expires: 3 })
|
||||||
|
// 保存工位描述到cookie,有效期3天
|
||||||
|
Cookies.set('lastOpDescription', userInfo.opDescription, { expires: 3 })
|
||||||
|
// 保存角色类型到cookie,有效期3天
|
||||||
|
Cookies.set('roleType', userform.role, { expires: 3 })
|
||||||
|
|
||||||
|
ElMessage.success('登录成功,跳转主页')
|
||||||
|
store.isLoading = true
|
||||||
|
router.push('/')
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
ElMessage.warning('未读取到对应中控IP!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
ElMessage.warning('用户名或密码错误,请重试!')
|
||||||
|
}
|
||||||
|
console.log(response)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getOpName = () => {
|
||||||
|
userform.opName = ''
|
||||||
|
opNameList.length = 0
|
||||||
|
// 获取当前操作员名称
|
||||||
|
var param = []
|
||||||
|
param.push(['OPType', userform.role])
|
||||||
|
var Data = CreateData('11', 'CRRC_台位_Moby_登录台位列表_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
opNameList.push(...response.data)
|
||||||
|
|
||||||
|
// 从cookie中获取上次登录的工位号
|
||||||
|
const lastOpName = Cookies.get('lastOpName')
|
||||||
|
// 如果cookie中有工位号且在列表中,则自动选择
|
||||||
|
if (lastOpName && opNameList.some(item => item.工位名称 === lastOpName)) {
|
||||||
|
userform.opName = lastOpName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(response)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.main {
|
||||||
|
position: relative;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
background-image: url("/public/login.png");
|
||||||
|
background-size: 100% 100%;
|
||||||
|
|
||||||
|
.login {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 25vw;
|
||||||
|
//height: 40vh;
|
||||||
|
background-color: rgba(255, 255, 255, 0.8);
|
||||||
|
border: 2px solid #730215;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #f50107;
|
||||||
|
font-size: 40px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 3vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logeType {
|
||||||
|
width: 80%;
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 3px solid #bcbcbc;
|
||||||
|
margin: 30px auto;
|
||||||
|
height: 30px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
color: #e43852;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
border-bottom: 2px solid #ff123a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logFrom {
|
||||||
|
width: 80%;
|
||||||
|
margin: 0px auto;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
1173
src/views/MaterialPlatform/index.vue
Normal file
1173
src/views/MaterialPlatform/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
406
src/views/PermissionManagement/index.vue
Normal file
406
src/views/PermissionManagement/index.vue
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
<template>
|
||||||
|
<div class="top">
|
||||||
|
<div class="left">
|
||||||
|
<el-button round style="float: right" type="primary" @click="addRole">添加</el-button>
|
||||||
|
<el-table :data="roleTableData" height="300px" highlight-current-row stripe style="width: 100%"
|
||||||
|
@row-click="roleRowClick">
|
||||||
|
<el-table-column align="center" label="角色编号">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.角色编号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="角色名称">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.角色名称 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" fixed="right" label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-link type="error" @click="deleteRole(scope.row)">删除</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<el-table :data="permissionTableData" height="300px" stripe style="width: 100%">
|
||||||
|
<el-table-column align="center" label="是否分配" width="60">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-checkbox v-model="scope.row.是否分配" :false-value="0" :true-value="1"
|
||||||
|
size="large" @click="setRolePermission(scope.row)"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="序号" type="index" width="80"/>
|
||||||
|
<el-table-column align="center" label="权限模块">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.权限模块 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="路径">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.path }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main">
|
||||||
|
<el-button round type="primary" @click="resetPeopleUpdate();showPeopleUpdate = true">添加</el-button>
|
||||||
|
<el-table :data="peopleTableData" height="400px" stripe style="width: 100%;margin: 0 auto">
|
||||||
|
<el-table-column label="序号" type="index" width="80"/>
|
||||||
|
<el-table-column align="center" label="姓名">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.姓名 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="角色名称">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.角色名称 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="工号" width="200">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.登录账号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="登陆密码">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.登录密码 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="门禁1权限">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.门禁1权限" type="success">有权限</el-tag>
|
||||||
|
<el-tag v-if="!scope.row.门禁1权限" type="danger">无权限</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="门禁2权限">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.门禁2权限" type="success">有权限</el-tag>
|
||||||
|
<el-tag v-if="!scope.row.门禁2权限" type="danger">无权限</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="门禁3权限">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.门禁3权限" type="success">有权限</el-tag>
|
||||||
|
<el-tag v-if="!scope.row.门禁3权限" type="danger">无权限</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="班次">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.班次 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="班组">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.班组 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" fixed="right" label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-link type="warning" @click="updatePeople(scope.row)">修改</el-link>
|
||||||
|
|
||||||
|
<el-link type="error" @click="deletePeople(scope.row)">删除</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<t-dialog
|
||||||
|
v-model:visible="showPeopleUpdate"
|
||||||
|
:confirm-on-enter="true"
|
||||||
|
:header="peopleUpdate.AID ? '修改人员' : '新增人员'"
|
||||||
|
:on-close="close"
|
||||||
|
:on-confirm="updatePeopleSubmit"
|
||||||
|
draggable
|
||||||
|
width="30%"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
:model="peopleUpdate"
|
||||||
|
label-position="right"
|
||||||
|
label-width="auto"
|
||||||
|
style="max-width: 600px"
|
||||||
|
>
|
||||||
|
<el-form-item label="姓名">
|
||||||
|
<el-input v-model="peopleUpdate.name"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="角色">
|
||||||
|
<t-select v-model="peopleUpdate.role" placeholder="请选择">
|
||||||
|
<t-option v-for="item in roleTableData" :key="item.角色编号" :label="item.角色名称" :value="item.角色编号"/>
|
||||||
|
</t-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="工号">
|
||||||
|
<el-input v-model="peopleUpdate.userName"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="登录密码">
|
||||||
|
<el-input v-model="peopleUpdate.password"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="门禁1权限">
|
||||||
|
<t-select v-model="peopleUpdate.RKE1" placeholder="请选择">
|
||||||
|
<t-option :value="1" label="有权限"/>
|
||||||
|
<t-option :value="0" label="无权限"/>
|
||||||
|
</t-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="门禁2权限">
|
||||||
|
<t-select v-model="peopleUpdate.RKE2" placeholder="请选择">
|
||||||
|
<t-option :value="1" label="有权限"/>
|
||||||
|
<t-option :value="0" label="无权限"/>
|
||||||
|
</t-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="门禁3权限">
|
||||||
|
<t-select v-model="peopleUpdate.RKE3" placeholder="请选择">
|
||||||
|
<t-option :value="1" label="有权限"/>
|
||||||
|
<t-option :value="0" label="无权限"/>
|
||||||
|
</t-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="班次">
|
||||||
|
<el-input v-model="peopleUpdate.classes"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="班组">
|
||||||
|
<el-input v-model="peopleUpdate.teamGroup"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</t-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {inject, onMounted, reactive, ref} from 'vue'
|
||||||
|
import {useAppStore} from "@/store/app.js";
|
||||||
|
import {ElMessage, ElMessageBox} from "element-plus";
|
||||||
|
|
||||||
|
const store = useAppStore();
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
|
||||||
|
const showPeopleUpdate = ref(false)
|
||||||
|
|
||||||
|
const roleTableData = reactive([])
|
||||||
|
const permissionTableData = reactive([])
|
||||||
|
const peopleTableData = reactive([])
|
||||||
|
const peopleUpdate = reactive({
|
||||||
|
AID: 0,
|
||||||
|
name: '', // 名称
|
||||||
|
classes: '', // 班次
|
||||||
|
teamGroup: '', // 班组
|
||||||
|
role: '', // 角色
|
||||||
|
userName: '', // 用户名
|
||||||
|
password: '', // 密码
|
||||||
|
RKE1: 0, // 门禁
|
||||||
|
RKE2: 0,
|
||||||
|
RKE3: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getRoleData()
|
||||||
|
getPeopleTableData()
|
||||||
|
});
|
||||||
|
|
||||||
|
const getRoleData = () => {
|
||||||
|
var param = []
|
||||||
|
var Data = CreateData('11', '基础表_人员角色_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
roleTableData.length = 0
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
roleTableData.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const roleRowClick = (row, column, event) => {
|
||||||
|
getRolePermissionData(row.角色编号)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRolePermissionData = (roleId) => {
|
||||||
|
var param = []
|
||||||
|
param.push(['角色编号', roleId])
|
||||||
|
var Data = CreateData('11', '基础表_模块分配_页面分配_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
permissionTableData.length = 0
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
permissionTableData.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const setRolePermission = (row) => {
|
||||||
|
var param = []
|
||||||
|
param.push(['角色编号', row.查询角色])
|
||||||
|
param.push(['模块编号', row.AID])
|
||||||
|
var Data = CreateData('11', '基础表_模块分配_角色分配模块', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
if (response.data[0].result === 1) {
|
||||||
|
ElMessage.success(response.data[0].msg)
|
||||||
|
getRolePermissionData(row.查询角色)
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.data[0].msg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error('数据异常')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPeopleTableData = () => {
|
||||||
|
var param = []
|
||||||
|
var Data = CreateData('11', '基础表_用户与角色_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
peopleTableData.length = 0
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
peopleTableData.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatePeople = (row) => {
|
||||||
|
resetPeopleUpdate()
|
||||||
|
console.log(row)
|
||||||
|
peopleUpdate.AID = row.AID
|
||||||
|
peopleUpdate.name = row.姓名
|
||||||
|
peopleUpdate.classes = row.班次
|
||||||
|
peopleUpdate.teamGroup = row.班组
|
||||||
|
peopleUpdate.role = row.用户角色
|
||||||
|
peopleUpdate.userName = row.登录账号
|
||||||
|
peopleUpdate.password = row.登录密码
|
||||||
|
peopleUpdate.RKE1 = row.门禁1权限
|
||||||
|
peopleUpdate.RKE2 = row.门禁2权限
|
||||||
|
peopleUpdate.RKE3 = row.门禁3权限
|
||||||
|
|
||||||
|
showPeopleUpdate.value = true
|
||||||
|
console.log(peopleUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetPeopleUpdate = () => {
|
||||||
|
peopleUpdate.AID = 0
|
||||||
|
peopleUpdate.name = ''
|
||||||
|
peopleUpdate.classes = ''
|
||||||
|
peopleUpdate.teamGroup = ''
|
||||||
|
peopleUpdate.role = ''
|
||||||
|
peopleUpdate.userName = ''
|
||||||
|
peopleUpdate.password = ''
|
||||||
|
peopleUpdate.RKE1 = 0
|
||||||
|
peopleUpdate.RKE2 = 0
|
||||||
|
peopleUpdate.RKE3 = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatePeopleSubmit = () => {
|
||||||
|
var param = []
|
||||||
|
param.push(['AID', peopleUpdate.AID])
|
||||||
|
param.push(['姓名', peopleUpdate.name])
|
||||||
|
param.push(['用户角色', peopleUpdate.role])
|
||||||
|
param.push(['登录账号', peopleUpdate.userName])
|
||||||
|
param.push(['登录密码', peopleUpdate.password])
|
||||||
|
param.push(['门禁1权限', peopleUpdate.RKE1])
|
||||||
|
param.push(['门禁2权限', peopleUpdate.RKE2])
|
||||||
|
param.push(['门禁3权限', peopleUpdate.RKE3])
|
||||||
|
param.push(['班次', peopleUpdate.classes])
|
||||||
|
param.push(['班组', peopleUpdate.teamGroup])
|
||||||
|
var Data = CreateData('11', '基础表_用户角色_新增修改', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
if (response.data[0].result === 1) {
|
||||||
|
ElMessage.success(response.data[0].msg)
|
||||||
|
getPeopleTableData()
|
||||||
|
showPeopleUpdate.value = false;
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.data[0].msg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error('数据异常')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const addRole = () => {
|
||||||
|
ElMessageBox.prompt('请输入添加的角色名称?', '提示').then(({value}) => {
|
||||||
|
var param = []
|
||||||
|
param.push(['角色名称', value])
|
||||||
|
var Data = CreateData('11', '基础表_人员角色_增加', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
if (response.data[0].result === 1) {
|
||||||
|
ElMessage.success(response.data[0].msg)
|
||||||
|
getRoleData()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.data[0].msg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error('数据异常')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteRole = (row) => {
|
||||||
|
// 弹窗确认是否删除
|
||||||
|
ElMessageBox.confirm('是否删除此角色?', '警告').then(() => {
|
||||||
|
var param = []
|
||||||
|
param.push(['AID', row.AID])
|
||||||
|
var Data = CreateData('11', '基础表_人员角色_删除', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
if (response.data[0].result === 1) {
|
||||||
|
ElMessage.success(response.data[0].msg)
|
||||||
|
getRoleData()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.data[0].msg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error('数据异常')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const deletePeople = (row) => {
|
||||||
|
// 弹窗确认是否删除
|
||||||
|
ElMessageBox.confirm('是否删除该用户?', '警告').then(() => {
|
||||||
|
var param = []
|
||||||
|
param.push(['AID', row.AID])
|
||||||
|
var Data = CreateData('11', '基础表_用户角色_删除', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
if (response.data[0].result === 1) {
|
||||||
|
ElMessage.success(response.data[0].msg)
|
||||||
|
getPeopleTableData()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.data[0].msg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error('数据异常')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
.top {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
margin-top: 30px;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
border: 1px solid #a8a8a8;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
width: 30vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
width: 65vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
width: 97vw;
|
||||||
|
margin: 20px auto;
|
||||||
|
border: 1px solid #a8a8a8;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
461
src/views/PowerGasDataSearch/index.vue
Normal file
461
src/views/PowerGasDataSearch/index.vue
Normal file
@@ -0,0 +1,461 @@
|
|||||||
|
<template>
|
||||||
|
<div class="main">
|
||||||
|
<div class="power">
|
||||||
|
<div class="DataList">
|
||||||
|
<div v-for="(item) in powerOldData" class="items">
|
||||||
|
<div class="title">{{ item.电表编号 }}</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">今日消耗:</div>
|
||||||
|
<div class="right">{{ item.今日电能 }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">电压A:</div>
|
||||||
|
<div class="right">{{ item.电压A }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">电压B:</div>
|
||||||
|
<div class="right">{{ item.电压B }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">电压C:</div>
|
||||||
|
<div class="right">{{ item.电压C }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">电压AB:</div>
|
||||||
|
<div class="right">{{ item.电压AB }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">电压BC:</div>
|
||||||
|
<div class="right">{{ item.电压BC }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">电压CA:</div>
|
||||||
|
<div class="right">{{ item.电压CA }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">电流A:</div>
|
||||||
|
<div class="right">{{ item.电流A }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">电流B:</div>
|
||||||
|
<div class="right">{{ item.电流B }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">电流C:</div>
|
||||||
|
<div class="right">{{ item.电流C }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">有功功率:</div>
|
||||||
|
<div class="right">{{ item.有功功率总 }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">无功功率:</div>
|
||||||
|
<div class="right">{{ item.无功功率总 }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item" style="width: 100%;">
|
||||||
|
<div class="left" style="width: 60%;">有功电能累计:</div>
|
||||||
|
<div class="right">{{ item.有功电能 }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="powerTable">
|
||||||
|
<span style="margin-left: 1vw">查询日期:</span>
|
||||||
|
<el-date-picker v-model="dateTime" :clearable="false" end-placeholder="结束日期" format="YYYY-MM-DD"
|
||||||
|
range-separator="~" start-placeholder="开始日期" style="width: 14vw;" type="daterange"
|
||||||
|
value-format="YYYY-MM-DD" />
|
||||||
|
<span style="margin-left: 1vw">电表编号:</span>
|
||||||
|
<el-select v-model="clickPowerCode" placeholder="请选择" clearable style="width: 8vw;">
|
||||||
|
<el-option v-for="item in powerCodeData" :key="item" :label="item" :value="item">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-button :icon="Search" type="success" @click="getPowerDayData">查询</el-button>
|
||||||
|
|
||||||
|
<el-table v-loading="page.loading" :data="powerDayData" height="300px" stripe style="width: 100%">
|
||||||
|
<el-table-column align="center" label="序号" type="index" width="80" />
|
||||||
|
<el-table-column align="center" label="日期" width="110">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.今日日期.slice(0, 10) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="电表编号">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.电表编号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="消耗" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.电能 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="开始电能" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.开始电能 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="结束电能" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.结束电能 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="开始时间" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.开始时间 ? scope.row.开始时间.split(' ')[1] : '' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="结束时间" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.结束时间 ? scope.row.结束时间.split(' ')[1] : '' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="block" style="margin-top: 5px;">
|
||||||
|
<el-pagination v-model:current-page="page.pageList" v-model:page-size="page.pageSize"
|
||||||
|
:page-sizes="[30, 50, 100, 200]" :total="page.total" background
|
||||||
|
layout="total, sizes, prev, pager, next, jumper" style="padding-left: 1vw" @size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gas">
|
||||||
|
<div class="DataList">
|
||||||
|
<div v-for="(item) in airOldData" class="items">
|
||||||
|
<div class="title">{{ item.气表编号 }}</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">今日日期:</div>
|
||||||
|
<div class="right">{{ item.今日日期 ? item.今日日期.split(' ')[0] : '' }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">今日用量:</div>
|
||||||
|
<div class="right">{{ item.今日用量.toFixed(1) }}</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="item">
|
||||||
|
<div class="left">前日日期:</div>
|
||||||
|
<div class="right">{{ item.前一日的时间 ? item.前一日的时间.split(' ')[0] : '' }}</div>
|
||||||
|
</div> -->
|
||||||
|
<!-- <div class="item">
|
||||||
|
<div class="left">前日用量:</div>
|
||||||
|
<div class="right">{{ item.前一日的用量.toFixed(1) }}</div>
|
||||||
|
</div> -->
|
||||||
|
<div class="item">
|
||||||
|
<div class="left">累计:</div>
|
||||||
|
<div class="right">{{ item.累计.toFixed(1) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="powerTable">
|
||||||
|
<span style="margin-left: 1vw">查询日期:</span>
|
||||||
|
<el-date-picker v-model="dateTime2" :clearable="false" end-placeholder="结束日期" format="YYYY-MM-DD"
|
||||||
|
range-separator="~" start-placeholder="开始日期" style="width: 14vw;" type="daterange"
|
||||||
|
value-format="YYYY-MM-DD" />
|
||||||
|
<span style="margin-left: 1vw">气表编号:</span>
|
||||||
|
<el-select v-model="clickAirCode" placeholder="请选择" clearable style="width: 8vw;">
|
||||||
|
<el-option v-for="item in airCodeData" :key="item" :label="item" :value="item">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-button :icon="Search" type="success" @click="getAirDayData">查询</el-button>
|
||||||
|
<el-table v-loading="page2.loading" :data="airDayData" height="300px" stripe style="width: 100%">
|
||||||
|
<el-table-column align="center" label="序号" type="index" width="80" />
|
||||||
|
<el-table-column align="center" label="日期" width="110">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.今日日期.slice(0, 10) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="气表编号">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.气表编号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="流量" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.流量 ? scope.row.流量.toFixed(1) : '' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="开始值" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.开始值 ? scope.row.开始值.toFixed(1) : '' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="结束值" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.结束值 ? scope.row.结束值.toFixed(1) : '' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="开始时间" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.开始时间 ? scope.row.开始时间.split(' ')[1] : '' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="结束时间" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.结束时间 ? scope.row.结束时间.split(' ')[1] : '' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="block" style="margin-top: 5px;">
|
||||||
|
<el-pagination v-model:current-page="page2.pageList" v-model:page-size="page2.pageSize"
|
||||||
|
:page-sizes="[30, 50, 100, 200]" :total="page2.total" background
|
||||||
|
layout="total, sizes, prev, pager, next, jumper" style="padding-left: 1vw" @size-change="handleSizeChange2"
|
||||||
|
@current-change="handleCurrentChange2" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { Search } from '@element-plus/icons-vue'
|
||||||
|
import { inject, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||||
|
import { useAppStore } from '@/store/app.js'
|
||||||
|
|
||||||
|
const store = useAppStore()
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
|
||||||
|
const clickPowerCode = ref('') // 电能昨日数据
|
||||||
|
const clickAirCode = ref('') // 电能昨日数据
|
||||||
|
const powerOldData = reactive([]) // 电能昨日数据
|
||||||
|
const powerDayData = reactive([]) // 电能每日数据
|
||||||
|
const airOldData = reactive([]) // 电能昨日数据
|
||||||
|
const airDayData = reactive([]) // 电能每日数据
|
||||||
|
const dateTime = ref([new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], new Date().toISOString().split('T')[0]]) // 开始结束时间段
|
||||||
|
const dateTime2 = ref([new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], new Date().toISOString().split('T')[0]]) // 开始结束时间段
|
||||||
|
const powerCodeData = reactive(['EleMeter1', 'EleMeter2', 'EleMeter3', 'EleMeter4']) // 电能每日数据
|
||||||
|
const airCodeData = reactive(['AirMeter1', 'AirMeter2', 'AirMeter3', 'AirMeter4', 'AirMeter5', 'AirMeter6']) // 电能每日数据
|
||||||
|
const page = reactive({
|
||||||
|
total: 0, // 总条数
|
||||||
|
pageSize: 50, // 每页显示条数
|
||||||
|
pageList: 1, // 后台获取页
|
||||||
|
loading: false, // 是否显示加载
|
||||||
|
})
|
||||||
|
const page2 = reactive({
|
||||||
|
total: 0, // 总条数
|
||||||
|
pageSize: 50, // 每页显示条数
|
||||||
|
pageList: 1, // 后台获取页
|
||||||
|
loading: false, // 是否显示加载
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
var timer1 = null;
|
||||||
|
onMounted(() => {
|
||||||
|
getPowerOldData()
|
||||||
|
getPowerDayData()
|
||||||
|
getAirOldData()
|
||||||
|
getAirDayData()
|
||||||
|
|
||||||
|
timer1 = setInterval(() => {
|
||||||
|
getPowerOldData()
|
||||||
|
getAirOldData()
|
||||||
|
}, 1000 * 5)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 离开网页 删除定时器
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(timer1)
|
||||||
|
})
|
||||||
|
|
||||||
|
const getPowerOldData = () => {
|
||||||
|
// 获取权限列表
|
||||||
|
var param = []
|
||||||
|
var Data = CreateData('11', 'CRRC_能源管理_电表_今日昨日_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
powerOldData.length = 0
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
powerOldData.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const getPowerDayData = () => {
|
||||||
|
console.log(dateTime)
|
||||||
|
page.loading = true
|
||||||
|
powerDayData.length = 0
|
||||||
|
// 获取权限列表
|
||||||
|
var param = []
|
||||||
|
param[0] = ['开始时间', dateTime.value[0]]
|
||||||
|
param[1] = ['结束时间', dateTime.value[1]]
|
||||||
|
param[2] = ['电表编号', clickPowerCode.value]
|
||||||
|
param[3] = ['PageCurrent', page.pageList]
|
||||||
|
param[4] = ['PageSize', page.pageSize]
|
||||||
|
param[5] = ['PageCount', '1111', 'int', '1']
|
||||||
|
param[6] = ['ItemCount', '1111', 'int', '1']
|
||||||
|
console.log('param', param)
|
||||||
|
var Data = CreateData('11', 'CRRC_能源管理_电表_日结算_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
console.log(response)
|
||||||
|
if (response.data.length !== 0) {
|
||||||
|
powerDayData.push(...response.data.result)
|
||||||
|
}
|
||||||
|
page.total = parseInt(response.data.output[0].ItemCount)
|
||||||
|
page.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getAirOldData = () => {
|
||||||
|
// 获取权限列表
|
||||||
|
var param = []
|
||||||
|
var Data = CreateData('11', 'CRRC_能源管理_气表_今日昨日_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
airOldData.length = 0
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
airOldData.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const getAirDayData = () => {
|
||||||
|
console.log(dateTime)
|
||||||
|
page2.loading = true
|
||||||
|
airDayData.length = 0
|
||||||
|
var param = []
|
||||||
|
param[0] = ['开始时间', dateTime2.value[0]]
|
||||||
|
param[1] = ['结束时间', dateTime2.value[1]]
|
||||||
|
param[2] = ['气表编号', clickAirCode.value]
|
||||||
|
param[3] = ['PageCurrent', page2.pageList]
|
||||||
|
param[4] = ['PageSize', page2.pageSize]
|
||||||
|
param[5] = ['PageCount', '1111', 'int', '1']
|
||||||
|
param[6] = ['ItemCount', '1111', 'int', '1']
|
||||||
|
console.log('param', param)
|
||||||
|
var Data = CreateData('11', 'CRRC_能源管理_气表_日结算_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
console.log(response)
|
||||||
|
if (response.data.length !== 0) {
|
||||||
|
airDayData.push(...response.data.result)
|
||||||
|
}
|
||||||
|
page2.total = parseInt(response.data.output[0].ItemCount)
|
||||||
|
page2.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
const handleSizeChange = (val) => {
|
||||||
|
page.pageList = 1
|
||||||
|
page.pageSize = val
|
||||||
|
getPowerDayData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange = (val) => {
|
||||||
|
page.pageList = val
|
||||||
|
getPowerDayData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
const handleSizeChange2 = (val) => {
|
||||||
|
page2.pageList = 1
|
||||||
|
page2.pageSize = val
|
||||||
|
getAirDayData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange2 = (val) => {
|
||||||
|
page2.pageList = val
|
||||||
|
getAirDayData()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.main {
|
||||||
|
display: flex;
|
||||||
|
font-size: 1rem;
|
||||||
|
|
||||||
|
//电表
|
||||||
|
.power {
|
||||||
|
width: 49.9%;
|
||||||
|
height: 90vh;
|
||||||
|
border: 1px solid #9f9f9f;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.DataList {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 100%;
|
||||||
|
height: 60%;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.items {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 49%;
|
||||||
|
margin: 0 auto;
|
||||||
|
border: 1px solid #9f9f9f;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.6vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 50%;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
width: 70%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
color: #ff9a02;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.powerTable {
|
||||||
|
height: 40%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 气表
|
||||||
|
.gas {
|
||||||
|
|
||||||
|
width: 50%;
|
||||||
|
height: 90vh;
|
||||||
|
border: 1px solid #9f9f9f;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.DataList {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 100%;
|
||||||
|
height: 60%;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.items {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 49%;
|
||||||
|
margin: 0 auto;
|
||||||
|
border: 1px solid #9f9f9f;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.6vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
width: 45%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
color: #ff9a02;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.powerTable {
|
||||||
|
height: 40%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
357
src/views/ProductionMonitoring/index.vue
Normal file
357
src/views/ProductionMonitoring/index.vue
Normal file
@@ -0,0 +1,357 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="carMainData two-columns">
|
||||||
|
<div class="column">
|
||||||
|
<div class="column-title">台位1项目信息</div>
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">项目编号:</div>
|
||||||
|
{{ projectData.projectNo }}
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">项目名称:</div>
|
||||||
|
{{ projectData.projectName }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">车体:</div>
|
||||||
|
{{ projectData.carBody }}
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">车号:</div>
|
||||||
|
{{ projectData.carNo }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">伸缩缝:</div>
|
||||||
|
{{ projectData.expansionJoint }}
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">车节:</div>
|
||||||
|
{{ projectData.carSection }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">调节参数:</div>
|
||||||
|
{{ projectData.adjustTheParameters }}
|
||||||
|
</div>
|
||||||
|
<div class="item"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="column-title">台位2项目信息</div>
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">项目编号:</div>
|
||||||
|
{{ projectData2.projectNo }}
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">项目名称:</div>
|
||||||
|
{{ projectData2.projectName }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">车体:</div>
|
||||||
|
{{ projectData2.carBody }}
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">车号:</div>
|
||||||
|
{{ projectData2.carNo }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">伸缩缝:</div>
|
||||||
|
{{ projectData2.expansionJoint }}
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">车节:</div>
|
||||||
|
{{ projectData2.carSection }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">调节参数:</div>
|
||||||
|
{{ projectData2.adjustTheParameters }}
|
||||||
|
</div>
|
||||||
|
<div class="item"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="dataList">
|
||||||
|
<div class="OpList" v-for="item in tvData">
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">RGV通道:</div>
|
||||||
|
<div class="value">{{ item.RGV通道 }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">中控程序代码:</div>
|
||||||
|
<div class="value">{{ item.中控程序代码 }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">MES连接:</div>
|
||||||
|
<div class="value" :style="{ color: item.生产模式 == '在线' ? '#00802d' : '#7b7e87' }">{{ item.生产模式 }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">网络状态:</div>
|
||||||
|
<div class="value" :style="{ color: item.网络状态 == '通' ? '#00802d' : '#b32f43' }">{{ item.网络状态 }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">门禁状态:</div>
|
||||||
|
<div class="value" :style="{ color: item.门禁状态 == '解锁' ? '#ff9900' : '#00802d' }">{{ item.门禁状态 }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">RGV状态:</div>
|
||||||
|
<div class="value" :style="{ color: item.RGV状态 == '空闲' ? '#ff9900' : '#00802d' }">{{ item.RGV状态 }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">是否有车:</div>
|
||||||
|
<div class="value" :style="{ color: item.是否有车 == '有车' ? '#00802d' : '#b32f43' }">{{ item.是否有车 }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="dataList" style="margin-top: 5vh;">
|
||||||
|
<div class="OpList" >
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">气表编号:</div>
|
||||||
|
<div class="value">累计消耗</div>
|
||||||
|
</div>
|
||||||
|
<div class="item" v-for="item in airData">
|
||||||
|
<div class="label">{{ item.气表编号 }}:</div>
|
||||||
|
<div class="value">{{ item.累计 }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="OpList" >
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">电表编号:</div>
|
||||||
|
<div class="value">有功电能</div>
|
||||||
|
</div>
|
||||||
|
<div class="item" v-for="item in eleData">
|
||||||
|
<div class="label">{{ item.电表编号 }}:</div>
|
||||||
|
<div class="value">{{ item.有功电能 }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { inject, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||||
|
import { useAppStore } from "@/store/app.js";
|
||||||
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
import mqtt from "mqtt";
|
||||||
|
|
||||||
|
const store = useAppStore();
|
||||||
|
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
const ExecWritePLC = inject('ExecWritePLC')
|
||||||
|
const ExecReadPLC = inject('ExecReadPLC')
|
||||||
|
const ExecMultReadPLC = inject('ExecMultReadPLC')
|
||||||
|
const ExecIMESAPI = inject('ExecIMESAPI')
|
||||||
|
|
||||||
|
const projectData = reactive({
|
||||||
|
projectNo: '', // 项目编号
|
||||||
|
projectName: '', // 项目名称
|
||||||
|
carNo: '', // 车号
|
||||||
|
carSection: '', // 车节
|
||||||
|
carBodyNo: '', // 车体流水号
|
||||||
|
carBody: '', // 车体
|
||||||
|
carBodyCode: '', // 车体流水号
|
||||||
|
expansionJoint: '', // 伸缩缝
|
||||||
|
adjustTheParameters: '', // 调节参数
|
||||||
|
})
|
||||||
|
|
||||||
|
const projectData2 = reactive({
|
||||||
|
projectNo: '', // 项目编号
|
||||||
|
projectName: '', // 项目名称
|
||||||
|
carNo: '', // 车号
|
||||||
|
carSection: '', // 车节
|
||||||
|
carBodyNo: '', // 车体流水号
|
||||||
|
carBody: '', // 车体
|
||||||
|
carBodyCode: '', // 车体流水号
|
||||||
|
expansionJoint: '', // 伸缩缝
|
||||||
|
adjustTheParameters: '', // 调节参数
|
||||||
|
})
|
||||||
|
|
||||||
|
const tvData = reactive([])
|
||||||
|
const airData = reactive([])
|
||||||
|
const eleData = reactive([])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getRGVData()
|
||||||
|
getTVData()
|
||||||
|
getAirData()
|
||||||
|
getEleData()
|
||||||
|
// getPLCStatus()
|
||||||
|
// // 初始化时获取所有状态
|
||||||
|
// getConnectionStatus()
|
||||||
|
// timer1 = setInterval(() => {
|
||||||
|
// getRGVData()
|
||||||
|
// // getPLCStatus()
|
||||||
|
// }, 1000 * 5)
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const getRGVData = () => {
|
||||||
|
var param = []
|
||||||
|
param[0] = ['opName', 'RGVCH2']
|
||||||
|
var Data = CreateData('11', 'CRRC_台位_RGV送料Moby_送料平台_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
let data = response.data[0]
|
||||||
|
projectData.projectNo = data.项目编号
|
||||||
|
projectData.projectName = data.项目名称
|
||||||
|
projectData.carNo = data.车号
|
||||||
|
projectData.carSection = data.车节
|
||||||
|
projectData.carBodyNo = data.车体流水号
|
||||||
|
projectData.carBody = data.车体
|
||||||
|
projectData.carBodyCode = data.车体流水号
|
||||||
|
projectData.expansionJoint = data.伸缩缝
|
||||||
|
projectData.adjustTheParameters = data.调节参数
|
||||||
|
|
||||||
|
if (response.data.length > 1) {
|
||||||
|
projectData2.projectNo = response.data[1].项目编号
|
||||||
|
projectData2.projectName = response.data[1].项目名称
|
||||||
|
projectData2.carNo = response.data[1].车号
|
||||||
|
projectData2.carSection = response.data[1].车节
|
||||||
|
projectData2.carBodyNo = response.data[1].车体流水号
|
||||||
|
projectData2.carBody = response.data[1].车体
|
||||||
|
projectData2.carBodyCode = response.data[1].车体流水号
|
||||||
|
projectData2.expansionJoint = response.data[1].伸缩缝
|
||||||
|
projectData2.adjustTheParameters = response.data[1].调节参数
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTVData = () => {
|
||||||
|
var param = []
|
||||||
|
var Data = CreateData('11', 'CRRC_生产看板_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
tvData.length = 0
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
tvData.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getAirData = () => {
|
||||||
|
var param = []
|
||||||
|
var Data = CreateData('11', 'CRRC_能源管理_气表_当前值_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
airData.length = 0
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
airData.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getEleData = () => {
|
||||||
|
var param = []
|
||||||
|
var Data = CreateData('11', 'CRRC_能源管理_电表_当前值_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
eleData.length = 0
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
eleData.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.carMainData {
|
||||||
|
width: 90vw;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 3vh auto 30px auto;
|
||||||
|
border: 1px solid #a8a8a8;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px 0;
|
||||||
|
|
||||||
|
&.two-columns {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
.column {
|
||||||
|
flex: 1;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 15px;
|
||||||
|
background: #f9f9f9;
|
||||||
|
|
||||||
|
.column-title {
|
||||||
|
width: 100% !important;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-row {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
margin: 5px 0;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
line-height: 32px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 40%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
width: 100%;
|
||||||
|
margin: 5px 0;
|
||||||
|
display: flex;
|
||||||
|
line-height: 32px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 40%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.two-columns .item {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataList {
|
||||||
|
display: flex;
|
||||||
|
font-size: 18px;
|
||||||
|
|
||||||
|
.OpList {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
width: 40%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
width: 60%;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
181
src/views/RCBanditDataSearch/index.vue
Normal file
181
src/views/RCBanditDataSearch/index.vue
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tableBox">
|
||||||
|
<div class="tableTop">
|
||||||
|
<span style="margin-left: 1vw">查询日期:</span>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateTime"
|
||||||
|
:clearable="false"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
range-separator="~"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
style="width: 190px;"
|
||||||
|
type="daterange"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span style="margin-left: 1vw">车辆编号:</span>
|
||||||
|
<el-input
|
||||||
|
v-model="searchObj.carCode"
|
||||||
|
clearable
|
||||||
|
placeholder="车辆编号"
|
||||||
|
style="width: 240px"
|
||||||
|
/>
|
||||||
|
<el-button :icon="Search" style="margin-left: 1vw" type="success" @click="searchTable">查询</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="tableData" border height="80vh" stripe style="width: 100%">
|
||||||
|
<el-table-column align="center" label="序号" type="index" width="80"/>
|
||||||
|
<el-table-column align="center" label="车辆编号" width="90">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车辆编号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="车辆类型">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车辆类型 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="电池电压">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.电池电压 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="电池电量">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.电池电量 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="车辆前后倾角">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车辆前后倾角 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="车辆左右倾角">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车辆左右倾角 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="车辆故障码">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车辆故障码 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="车辆状态">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车辆状态 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="车辆模式">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车辆模式 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="车辆厂商">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车辆厂商 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="接收时间" width="170">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.接收时间 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="block" style="margin-top: 5px;">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="page.pageList"
|
||||||
|
v-model:page-size="page.pageSize"
|
||||||
|
:page-sizes="[30, 50, 100, 200]"
|
||||||
|
:total="page.total"
|
||||||
|
background
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
style="padding-left: 1vw"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {inject, onMounted, reactive, ref} from 'vue'
|
||||||
|
import {Search} from "@element-plus/icons-vue";
|
||||||
|
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
|
||||||
|
const dateTime = ref([new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], new Date().toISOString().split('T')[0]]) // 开始结束时间段
|
||||||
|
|
||||||
|
const tableData = reactive([])
|
||||||
|
const searchObj = reactive({
|
||||||
|
carCode: ''
|
||||||
|
})
|
||||||
|
const page = reactive({
|
||||||
|
total: 0, // 总条数
|
||||||
|
pageSize: 50, // 每页显示条数
|
||||||
|
pageList: 1, // 后台获取页
|
||||||
|
loading: false, // 是否显示加载
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
searchTable()
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const searchTable = () => {
|
||||||
|
page.loading = true
|
||||||
|
tableData.length = 0
|
||||||
|
var param = []
|
||||||
|
param.push(['开始时间', dateTime.value[0]])
|
||||||
|
param.push(['结束时间', dateTime.value[1]])
|
||||||
|
param.push(['车辆编号', searchObj.carCode])
|
||||||
|
param.push(['PageCurrent', page.pageList])
|
||||||
|
param.push(['PageSize', page.pageSize])
|
||||||
|
param.push(['PageCount', '1111', 'int', '1'])
|
||||||
|
param.push(['ItemCount', '1111', 'int', '1'])
|
||||||
|
var Data = CreateData('11', 'CRRC_能源管理_遥控车_历史记录_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length !== 0) {
|
||||||
|
tableData.push(...response.data.result)
|
||||||
|
}
|
||||||
|
page.total = parseInt(response.data.output[0].ItemCount)
|
||||||
|
page.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
const handleSizeChange = (val) => {
|
||||||
|
page.pageList = 1
|
||||||
|
page.pageSize = val
|
||||||
|
searchTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange = (val) => {
|
||||||
|
page.pageList = val
|
||||||
|
searchTable()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.tableBox {
|
||||||
|
width: 98vw;
|
||||||
|
margin: 2vh auto 0 auto;
|
||||||
|
border: 1px solid #9f9f9f;
|
||||||
|
background-color: #ecf0f3;
|
||||||
|
box-shadow: 10px 10px 10px #d1d9e6, -10px -10px 10px #f9f9f9;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.tableTop {
|
||||||
|
width: 100%;
|
||||||
|
margin: 1vh auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block {
|
||||||
|
margin-bottom: 1vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
103
src/views/RealTimeKeySearch/index.vue
Normal file
103
src/views/RealTimeKeySearch/index.vue
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tableBox">
|
||||||
|
<el-tabs v-model="activeTab" type="card" class="tabs-container">
|
||||||
|
<el-tab-pane v-for="(channel, index) in channels" :key="index" :label="'OPCH' + (index + 1)">
|
||||||
|
<el-table :data="channelData[channel]" border height="80vh" stripe style="width: 100%">
|
||||||
|
<el-table-column align="center" label="序号" type="index" width="60"/>
|
||||||
|
<el-table-column align="center" label="信号通道" prop="信号通道" width="130"/>
|
||||||
|
<el-table-column align="center" label="信号名称" prop="信号名称"/>
|
||||||
|
<el-table-column align="center" label="信号地址" prop="信号地址" width="120"/>
|
||||||
|
<el-table-column align="center" label="信号状态" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag :type="scope.row.当前值 == '1' ? 'success' : 'warning'" effect="dark">
|
||||||
|
{{ scope.row.当前值 == '1' ? 'true' : 'false' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="变化时间" prop="变化时间" width="200"/>
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {inject, onMounted, onUnmounted, reactive, ref} from 'vue'
|
||||||
|
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
|
||||||
|
const channels = ['AssemblyCH1', 'AssemblyCH2', 'AssemblyCH3', 'AssemblyCH4']
|
||||||
|
const activeTab = ref('0') // 默认显示第一个tab
|
||||||
|
const channelData = reactive({
|
||||||
|
OPCH1: [],
|
||||||
|
OPCH2: [],
|
||||||
|
OPCH3: [],
|
||||||
|
OPCH4: []
|
||||||
|
})
|
||||||
|
let autoQueryTimer = null
|
||||||
|
|
||||||
|
const searchTable = () => {
|
||||||
|
var param = []
|
||||||
|
var Data = CreateData('11', 'CRRC_平台信号监控_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
// 清空现有数据
|
||||||
|
channels.forEach(channel => {
|
||||||
|
channelData[channel] = []
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response?.data) {
|
||||||
|
// 按通道分类数据
|
||||||
|
response.data.forEach(item => {
|
||||||
|
const channel = item.信号通道
|
||||||
|
if (channels.includes(channel)) {
|
||||||
|
channelData[channel].push(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const startAutoQuery = () => {
|
||||||
|
if (autoQueryTimer) return
|
||||||
|
searchTable()
|
||||||
|
autoQueryTimer = setInterval(() => {
|
||||||
|
searchTable()
|
||||||
|
}, window.g.keyDataSearchCycle * 1000) // 将秒转换为毫秒
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
startAutoQuery()
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (autoQueryTimer) {
|
||||||
|
clearInterval(autoQueryTimer)
|
||||||
|
autoQueryTimer = null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.tableBox {
|
||||||
|
width: 97vw;
|
||||||
|
margin: 2vh auto 0 auto;
|
||||||
|
border: 1px solid #9f9f9f;
|
||||||
|
background-color: #ecf0f3;
|
||||||
|
box-shadow: 10px 10px 10px #d1d9e6, -10px -10px 10px #f9f9f9;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.tabs-container {
|
||||||
|
:deep(.el-tabs__item) {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__item.is-active) {
|
||||||
|
color: #409EFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
214
src/views/ScanSearch/index.vue
Normal file
214
src/views/ScanSearch/index.vue
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tableBox">
|
||||||
|
<div class="tableTop">
|
||||||
|
<span style="margin-left: 1vw">查询日期:</span>
|
||||||
|
<el-date-picker v-model="dateTime" :clearable="false" end-placeholder="结束日期" format="YYYY-MM-DD"
|
||||||
|
range-separator="~" start-placeholder="开始日期" style="width: 190px;" type="daterange" value-format="YYYY-MM-DD" />
|
||||||
|
<span style="margin-left: 1vw">台位号:</span>
|
||||||
|
<el-select v-model="searchObj.opName" clearable placeholder="台位号" style="width: 8vw;">
|
||||||
|
<el-option v-for="item in opNameList" :key="item.工位名称" :label="item.工位描述" :value="item.工位名称">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
<span style="margin-left: 1vw">码值:</span>
|
||||||
|
<el-input v-model="searchObj.scanCode" clearable placeholder="码值" style="width: 240px" />
|
||||||
|
<el-button :icon="Search" style="margin-left: 1vw" type="success" @click="searchTable">查询</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="tableData" border height="80vh" stripe style="width: 100%">
|
||||||
|
<el-table-column align="center" label="序号" type="index" width="80" />
|
||||||
|
<el-table-column align="center" label="台位号" width="80">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ getOpNameDescription(scope.row.扫码枪工位) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="项目名称" width="170">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.项目名称 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="项目编号" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.项目编号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="车号" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车号 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="车节" width="70">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.车节 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="left" label="物料码">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.物料码 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="扫码时间" width="170">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.扫码时间 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="操作人" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.姓名 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 删除列,只有角色编号为1的用户才显示 -->
|
||||||
|
<el-table-column v-if="user.role == '1'" align="center" label="操作" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
:icon="Delete"
|
||||||
|
size="small"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="block" style="margin-top: 5px;">
|
||||||
|
<el-pagination v-model:current-page="page.pageList" v-model:page-size="page.pageSize"
|
||||||
|
:page-sizes="[30, 50, 100, 200]" :total="page.total" background layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
style="padding-left: 1vw" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { inject, onMounted, reactive, ref } from 'vue'
|
||||||
|
import { Search, Delete } from "@element-plus/icons-vue";
|
||||||
|
import { useAppStore } from "@/store/app.js";
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const CreateData = inject('CreateData')
|
||||||
|
const ExecDatabase = inject('ExecDatabase')
|
||||||
|
const store = useAppStore();
|
||||||
|
const { user } = storeToRefs(store);
|
||||||
|
|
||||||
|
const dateTime = ref([new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], new Date().toISOString().split('T')[0]]) // 开始结束时间段
|
||||||
|
|
||||||
|
const opNameList = reactive([])
|
||||||
|
const tableData = reactive([])
|
||||||
|
const searchObj = reactive({
|
||||||
|
opName: '',
|
||||||
|
scanCode: ''
|
||||||
|
})
|
||||||
|
const page = reactive({
|
||||||
|
total: 0, // 总条数
|
||||||
|
pageSize: 50, // 每页显示条数
|
||||||
|
pageList: 1, // 后台获取页
|
||||||
|
loading: false, // 是否显示加载
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getOpName()
|
||||||
|
searchTable()
|
||||||
|
console.log(user.value)
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const searchTable = () => {
|
||||||
|
page.loading = true
|
||||||
|
tableData.length = 0
|
||||||
|
var param = []
|
||||||
|
param.push(['开始时间', dateTime.value[0]])
|
||||||
|
param.push(['结束时间', dateTime.value[1]])
|
||||||
|
param.push(['台位号', searchObj.opName])
|
||||||
|
param.push(['码值', searchObj.scanCode])
|
||||||
|
param.push(['PageCurrent', page.pageList])
|
||||||
|
param.push(['PageSize', page.pageSize])
|
||||||
|
param.push(['PageCount', '1111', 'int', '1'])
|
||||||
|
param.push(['ItemCount', '1111', 'int', '1'])
|
||||||
|
var Data = CreateData('11', 'CRRC_扫码枪_扫码记录_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length !== 0) {
|
||||||
|
tableData.push(...response.data.result)
|
||||||
|
}
|
||||||
|
page.total = parseInt(response.data.output[0].ItemCount)
|
||||||
|
page.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getOpName = () => {
|
||||||
|
opNameList.length = 0
|
||||||
|
// 获取当前操作员名称
|
||||||
|
var param = []
|
||||||
|
param.push(['OPType', 0])
|
||||||
|
var Data = CreateData('11', 'CRRC_台位_Moby_登录台位列表_查询', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
opNameList.push(...response.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getOpNameDescription = (opName) => {
|
||||||
|
return opNameList.find(item => item.工位名称 === opName)?.工位描述 || opName
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
const handleSizeChange = (val) => {
|
||||||
|
page.pageList = 1
|
||||||
|
page.pageSize = val
|
||||||
|
searchTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange = (val) => {
|
||||||
|
page.pageList = val
|
||||||
|
searchTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除功能
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定要删除该记录吗?`,
|
||||||
|
'删除确认',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
dangerouslyUseHTMLString: true
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
// 调用删除存储过程
|
||||||
|
var param = []
|
||||||
|
param.push(['AID', row.AID])
|
||||||
|
var Data = CreateData('12', 'CRRC_扫码枪_扫码记录_删除', param)
|
||||||
|
ExecDatabase(Data).then(response => {
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
// 重新加载数据
|
||||||
|
searchTable()
|
||||||
|
}).catch(error => {
|
||||||
|
ElMessage.error('删除失败:' + error.message)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.tableBox {
|
||||||
|
width: 98vw;
|
||||||
|
margin: 2vh auto 0 auto;
|
||||||
|
border: 1px solid #9f9f9f;
|
||||||
|
background-color: #ecf0f3;
|
||||||
|
box-shadow: 10px 10px 10px #d1d9e6, -10px -10px 10px #f9f9f9;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.tableTop {
|
||||||
|
width: 100%;
|
||||||
|
margin: 1vh auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block {
|
||||||
|
margin-bottom: 1vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
10
src/views/VideoMonitoring/index.vue
Normal file
10
src/views/VideoMonitoring/index.vue
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<template>
|
||||||
|
<div>视频监控</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
48
vite.config.js
Normal file
48
vite.config.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import { fileURLToPath, URL } from "node:url";
|
||||||
|
import copy from 'rollup-plugin-copy'
|
||||||
|
import { resolve } from 'path'
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
base: './',
|
||||||
|
plugins: [
|
||||||
|
vue()
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@": fileURLToPath(new URL("./src", import.meta.url)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pluginOptions: {
|
||||||
|
'style-resources-loader': {
|
||||||
|
preProcessor: 'scss',
|
||||||
|
patterns: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
define: {
|
||||||
|
'process.env': {}
|
||||||
|
},
|
||||||
|
// 完全禁用默认的 public 目录处理
|
||||||
|
publicDir: false,
|
||||||
|
build: {
|
||||||
|
// 清空输出目录时保留自定义拷贝的文件
|
||||||
|
emptyOutDir: true,
|
||||||
|
|
||||||
|
rollupOptions: {
|
||||||
|
plugins: [
|
||||||
|
copy({
|
||||||
|
targets: [
|
||||||
|
{
|
||||||
|
src: 'public/**/*', // 复制整个 public 目录
|
||||||
|
dest: 'dist/public' // 输出到 dist/public
|
||||||
|
}
|
||||||
|
],
|
||||||
|
hook: 'writeBundle', // 在构建完成后执行
|
||||||
|
copyOnce: true // 仅拷贝一次
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user