Compare commits
197 Commits
gtz
...
a08af6774e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a08af6774e | ||
|
|
3c38763cf4 | ||
|
|
23b7b85b39 | ||
| 2f2eaf4e20 | |||
|
|
a5a4f93328 | ||
|
|
f7938f30e2 | ||
|
|
d23cb260a4 | ||
|
|
e5eb49a7b6 | ||
|
|
35d5d91c23 | ||
| f3a7e38d13 | |||
| 5d36eb676c | |||
| 14b933fb0c | |||
| 92f52ab553 | |||
| 15210c2f12 | |||
| 8447b8f7ab | |||
| ca7fda73e3 | |||
| 1617bc347a | |||
| 762861a922 | |||
| 68c271618a | |||
| 127347fab0 | |||
| b9ac64ab13 | |||
| 089a6517d3 | |||
| 1047dd78ec | |||
| 5a08d8c1dd | |||
| d0f113513c | |||
| ff11e1d3fb | |||
| b54298fe09 | |||
| 5b2de3fb27 | |||
| 9c13434c48 | |||
| 86d3f63178 | |||
| 3f43f0c979 | |||
| ae8a3668c8 | |||
| d5af6a01f5 | |||
| 0b54133132 | |||
| 246baa1768 | |||
| 37c0c445a3 | |||
| 72f9793edf | |||
| b7002fe17a | |||
| 1b670dc0ac | |||
| 3907f5161e | |||
| d493b34a5f | |||
| 747247aed6 | |||
| 1caf68592a | |||
| 5d32750d87 | |||
| a0253cc235 | |||
| 13df2016b9 | |||
| 749e503f75 | |||
| 1554562933 | |||
| ea1c7de4ca | |||
| 9b0f724da2 | |||
| f33d0c9048 | |||
| 4c9ce641fa | |||
| 31834662c9 | |||
| 4f39481693 | |||
| 5a45aead7c | |||
| 31f496cc13 | |||
| 399589bb3b | |||
| 1ad64efe59 | |||
| b21d91c8da | |||
| a95a7a20d3 | |||
| 7ed4a512bc | |||
| 9187d56f6c | |||
| 41cd01ecb0 | |||
| f590d09671 | |||
| 5158d9a315 | |||
| cc5aa4d72f | |||
| a03d1db029 | |||
| 3999e4e589 | |||
| a0fef0454d | |||
| e532989ddf | |||
| 10e454eb2a | |||
| ce9c0f9d76 | |||
| a2423905fd | |||
| 04dc0bcc49 | |||
| 1006ef0d6a | |||
| d9ff6226b3 | |||
| 08aa78fdb1 | |||
| 2d557c8196 | |||
| e020c1e174 | |||
| e46c392e0f | |||
| 076eaa5f2a | |||
| 12556886b9 | |||
| 744f288b70 | |||
| 64ee3cb64e | |||
| 268207b383 | |||
| b71a61191b | |||
| a438bcad2f | |||
| 5b37798a20 | |||
| 70303f3f06 | |||
| 666059af6e | |||
| 90a93e4f8b | |||
| 803248ca22 | |||
| cfa1cca44a | |||
| 2df5897f3d | |||
| 3668f92731 | |||
| 1b17b760ae | |||
| 6e06159250 | |||
| 3fe0d26d8f | |||
| c0900dba9c | |||
| 974079296b | |||
| 1e78bbf6ee | |||
| e690c90d74 | |||
| 349870ce5d | |||
| 96cea7cc0d | |||
| 38afe6cbb9 | |||
| 9df5f3b336 | |||
| 626e543fa5 | |||
| 2e40570969 | |||
| 70485d293c | |||
| 6bbc0d3d08 | |||
| 8f124e06b1 | |||
| 4297798d44 | |||
| 9a22601f5b | |||
| 69dda72fab | |||
| 0b4433dd80 | |||
| a30e2e1ae2 | |||
| 37df2abcc5 | |||
| fef9bca0ae | |||
| 197b4734d5 | |||
| dedcedec06 | |||
| 93b401071a | |||
| a15e78dcaf | |||
| 3c4af47e2d | |||
| 686002a48e | |||
| 4cae583333 | |||
| 8aaaf2c7ad | |||
| 56ab0220e2 | |||
| 8943eb56b3 | |||
| 6063b664a6 | |||
| 3e42b99996 | |||
| f17fab4749 | |||
| 566c900a24 | |||
| 8ad162aab6 | |||
| 3d851e4362 | |||
| 23e508916e | |||
| 535004719c | |||
| 51022a6e6d | |||
| b4e00bbca0 | |||
| a9265d6708 | |||
| 302d1832df | |||
| 00343fa5b9 | |||
| d1dd52fe90 | |||
| 04f19e82e3 | |||
| 19730bb635 | |||
| ba44951b71 | |||
| b3aba50b09 | |||
| 3f2e8e8b9e | |||
| db5b5091e1 | |||
| 0ef30e1985 | |||
| cd9beb120a | |||
| a1056abe80 | |||
| 0ddba21e1c | |||
| 535cb490b1 | |||
| c1e152405d | |||
| c435901f3b | |||
| 174e5efae5 | |||
| bc08dffda2 | |||
| e91520e99d | |||
| 83fb096f6d | |||
| 90e34584ec | |||
| 9653474e2f | |||
| df3b11b6dd | |||
| ffd095b6b8 | |||
| 559cffc5f0 | |||
| cfec6ff3f5 | |||
| 5d8f537d05 | |||
| 669c8f90c6 | |||
| 2557026002 | |||
| 0733660c2f | |||
| 32dd90969a | |||
| a150905840 | |||
| 2911cf2a90 | |||
| e3849933d9 | |||
| c15671c496 | |||
| 1e118a6d5d | |||
| f415f30f9e | |||
| 56bbc2497a | |||
| 06193447c8 | |||
| 1b760cb844 | |||
| afc4577335 | |||
| 333da8433e | |||
| 65c4ce9d45 | |||
| 93912aa193 | |||
| 374da7b1e9 | |||
| 43f33be189 | |||
| ee27a93181 | |||
| 8f802c5580 | |||
| cf28335d9e | |||
| 4bd6ad1f47 | |||
| b79efe0a19 | |||
| ffad1a2643 | |||
| affea8af59 | |||
| 8b060b8bf1 | |||
| d4e7bda03b | |||
| 3df2939fb4 | |||
| d3752c4f40 | |||
| 0566808861 |
7
.dockerignore
Normal file
@@ -0,0 +1,7 @@
|
||||
.vscode/
|
||||
.idea/
|
||||
node_modules/
|
||||
dist/
|
||||
**/*.log
|
||||
LICENSE
|
||||
README.md
|
||||
52
.drone.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: docker:dind
|
||||
volumes:
|
||||
- name: dockersock
|
||||
path: /var/run/docker.sock
|
||||
- name: dockerconfig
|
||||
path: /root/.docker
|
||||
commands:
|
||||
- docker build -t harbor.picaiba.com/kszny/mes-ui:1.0.0-india ./ && docker push harbor.picaiba.com/kszny/mes-ui:1.0.0-india
|
||||
|
||||
- name: deploy
|
||||
image: harbor.picaiba.com/tools/kubectl:1.19.8
|
||||
commands:
|
||||
- echo "172.27.0.20 lb.kubesphere.local" >> /etc/hosts
|
||||
#- echo "52.74.223.119 github.com" >> /etc/hosts
|
||||
- sleep 1
|
||||
- kubectl scale --replicas=0 deployment/mes-ui -n mes-india
|
||||
- sleep 3
|
||||
- kubectl scale --replicas=1 deployment/mes-ui -n mes-india
|
||||
depends_on:
|
||||
- build
|
||||
|
||||
- name: notification
|
||||
image: lddsb/drone-dingtalk-message
|
||||
settings:
|
||||
token: 37a6483274f6de648a26d6710e4d8160eb7d471752abb2d70f8b7958af58fe11
|
||||
type: markdown
|
||||
secret: SEC83b10f5fefd6127e4073360d4447bb7276a90386aeee1275b2797dd377a903e7
|
||||
tpl: http://res.picaiba.com/msg/msg.md
|
||||
tips_title: 你有新消息
|
||||
success_color: 008800
|
||||
failure_color: FF0000
|
||||
|
||||
volumes:
|
||||
- name: dockersock
|
||||
host:
|
||||
path: /var/run/docker.sock
|
||||
- name: dockerconfig
|
||||
host:
|
||||
path: /root/.docker
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- develop
|
||||
event:
|
||||
- push
|
||||
12
.prettierrc
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"tabWidth": 2,
|
||||
"bracketSameLine": true,
|
||||
"jsxBracketSameLine": true,
|
||||
"embeddedLanguageFormatting": "auto",
|
||||
"printWidth": 180,
|
||||
"quoteProps": "consistent",
|
||||
"trailingComma": "none",
|
||||
"semi": false,
|
||||
"useTabs": true
|
||||
}
|
||||
244
AddOrUpdateConfig.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# Add Or Update Dialog Configs
|
||||
|
||||
> 通过传入合理的配置项来使用 addOrUpdate Dialog
|
||||
|
||||
## 用途
|
||||
|
||||
通过给对话框传递配置项,并自动根据这些配置项来初始化对话框的功能
|
||||
|
||||
## props
|
||||
|
||||
- configs 对象
|
||||
|
||||
```
|
||||
<my-dialog :configs="SomeConfigs" ... />
|
||||
|
||||
|
||||
type Operation = {
|
||||
name: 'add' | 'edit' | 'detail' | 'delete' | ...,
|
||||
url: string, /** 该操作需要的接口地址,如删除接口 */
|
||||
showAlways: boolean,
|
||||
showOnEdit: boolean,
|
||||
permission: string,
|
||||
}
|
||||
|
||||
type SubTableConfig = {
|
||||
[_:string]: any,
|
||||
title: string, /** 表格的名称 */
|
||||
url: string, /** 涉及的接口 */
|
||||
tableConfigs: {
|
||||
[_:string]: any,
|
||||
type?: 'index' | ...,
|
||||
prop: string,
|
||||
name: string,
|
||||
rules?: any[],
|
||||
fixed?: string,
|
||||
width?: string,
|
||||
subcomponent: VueComponent,
|
||||
options: any[],
|
||||
formField: boolean, /** 是否在新增编辑子表单里出现该字段 */
|
||||
}[], /** 表格prop配置数组,参考 components/base-table 组件和 element-ui 文档 */
|
||||
}
|
||||
|
||||
type ExtraComponent = {
|
||||
name: string,
|
||||
label: string,
|
||||
hasModel: boolean, /** 是否需要为该组件设置 v-model */
|
||||
component: VueComponent, /** 动态加载的 vue 组件 */
|
||||
props: {
|
||||
[_:string]: string | object
|
||||
extraParams?: { /** 上传组件使用 */
|
||||
typeCode: string
|
||||
}
|
||||
}[]
|
||||
}
|
||||
|
||||
type Field = {
|
||||
[_:string]: string | boolean | object | object[],
|
||||
name: string,
|
||||
type?: 'input' | 'select' | ...,
|
||||
options?: any[], /** 设置 type 为 select 时的选项数据 */
|
||||
label?: string, /** 没有时会用 name 替代 */
|
||||
placeholder?: string, /** 没有时会生成默认占位符 */
|
||||
api?: string, /** 如果有该字段,就自动从api地址获取数据并填充到对应的输入框里,一般为 getCode 的接口 */
|
||||
relatedField?: string, /** 关联字段,当设置此字段时,意味着需要在对话框组件上监听 select-change 事件,并当该字段数据被改变时刷新 relatedField 的列表,一般是像选择产线时更新工段列表这样的场景使用 */,
|
||||
required?: boolean, /** 验证规则的简写,只需要限制必填项时,不需要其他验证规则时使用 */
|
||||
rules?: object[], /** 规则设置参考 element-ui 的表单验证配置 */
|
||||
}
|
||||
|
||||
type Configs = {
|
||||
type: 'dialog',
|
||||
infoUrl: string, /** 编辑时获取信息的接口地址 */
|
||||
fields: Field[],
|
||||
extraComponents?: ExtraComponent[],
|
||||
subtable?: SubTableConfig[],
|
||||
operations?: Operation[]
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
## 示例
|
||||
|
||||
```js
|
||||
const addOrUpdateConfigs = {
|
||||
type: 'dialog', // dialog | drawer | page
|
||||
infoUrl: '/monitoring/product',
|
||||
fields: [
|
||||
'name',
|
||||
{
|
||||
name: 'code',
|
||||
api: '/monitoring/product/getCode'
|
||||
},
|
||||
{
|
||||
name: 'processTime',
|
||||
label: '加工时间',
|
||||
placeholder: '请输入加工时间',
|
||||
type: 'number', // type: number(input+number) | default(input) | textarea | select(options在父组件里获取) | datetime
|
||||
required: true,
|
||||
rules: [
|
||||
// 除了required之外的验证规则
|
||||
{
|
||||
type: 'number',
|
||||
trigger: 'blur',
|
||||
transform: val => Number(val),
|
||||
message: '必须输入数字'
|
||||
}
|
||||
]
|
||||
},
|
||||
'remark',
|
||||
'specifications',
|
||||
{
|
||||
name: 'typeDictValue',
|
||||
rules: [{ required: true, trigger: 'blur' }],
|
||||
label: '产品类型', // 对于非常见属性,最好自己指定label
|
||||
type: 'select',
|
||||
options: [
|
||||
// 动态获取
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'unitDictValue',
|
||||
label: '单位',
|
||||
type: 'select',
|
||||
placeholder: '请选择单位',
|
||||
options: [
|
||||
// 动态获取
|
||||
]
|
||||
}
|
||||
],
|
||||
operations: [
|
||||
// { name: 'reset', url: true },
|
||||
{ name: 'cancel', url: true, showAlways: true },
|
||||
{ name: 'save', url: '/monitoring/product', permission: '', showOnEdit: false },
|
||||
{ name: 'update', url: '/monitoring/product', permission: '', showOnEdit: true }
|
||||
],
|
||||
subtable: {
|
||||
// for i18n
|
||||
title: '动态属性',
|
||||
url: '/monitoring/productArrt',
|
||||
tableConfigs: [
|
||||
{ type: 'index', name: '序号' },
|
||||
{ prop: 'createTime', name: '添加时间', filter: val => (val ? moment(val).format('YYYY-MM-DD hh:mm:ss') : '-') },
|
||||
{ prop: 'name', name: '属性名', formField: true, rules: [{ required: true, message: '必填', trigger: 'blur' }] },
|
||||
{ prop: 'code', name: '属性值', formField: true },
|
||||
{ prop: 'operations', name: '操作', fixed: 'right', width: 180, subcomponent: TableOperateComponent, options: ['edit', 'delete'] }
|
||||
]
|
||||
},
|
||||
extraComponents: [
|
||||
{
|
||||
name: 'CompName',
|
||||
label: 'markdown编辑器',
|
||||
component: () => import('xx.vue')
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 配置项解释
|
||||
|
||||
<br>
|
||||
|
||||
### type
|
||||
|
||||
类型: string
|
||||
值:dialog | drawer | page
|
||||
含义:对话框、抽屉、新页面
|
||||
|
||||
### infoUrl
|
||||
|
||||
类型:string
|
||||
含义:详情的接口,如 `/monitoring/product`
|
||||
|
||||
### fields
|
||||
|
||||
含义:设置新增、编辑时的字段
|
||||
类型:`Array<string | object>`
|
||||
|
||||
- 当类型为 string 时,默认渲染 `<input>`
|
||||
- 当类型为 object 时,有如下选项:
|
||||
- name: 字段名
|
||||
- label: 字段的 label
|
||||
- api: 如果设置了该属性,则该字段会自动从服务器获取值,一般为 code 字段需要
|
||||
- placeholder
|
||||
- type: 渲染何种类型的组件,默认值: 'input'
|
||||
- options: 当上一条 type 值为 'select' 时,需要自行动态获取并加载 options 列表
|
||||
- required: 是否是必须填写的字段(或可用过 rules 做更加具体的设定,设定方式参考 async-validator )
|
||||
- rules: 验证规则数组,如果只有"必填"的需求,可直接用上一条
|
||||
|
||||
### operations
|
||||
|
||||
含义:设置对话框等组件里,需要哪些按钮
|
||||
类型:`Array<object>`
|
||||
属性:
|
||||
|
||||
- name,按钮的类型,决定按钮的文字和颜色
|
||||
- url,按钮操作的接口地址,不需要的可以给 null 或 true
|
||||
- permission,该操作需要的权限,如 "sys:xxx:add" 形式
|
||||
- showOnEdit: boolean,是否编辑页面展示,不设置则始终展示
|
||||
示例:
|
||||
|
||||
```js
|
||||
operations: [
|
||||
{ name: 'reset', url: true },
|
||||
{ name: 'cancel', url: true, showAlways: true },
|
||||
{ name: 'save', url: '/monitoring/product', permission: '', showOnEdit: false },
|
||||
{ name: 'update', url: '/monitoring/product', permission: '', showOnEdit: true }
|
||||
],
|
||||
```
|
||||
|
||||
### subtable
|
||||
|
||||
含义:有些对话框里需要额外的表格来展示更深层次的数据,如“产品属性”
|
||||
类型:object
|
||||
选项:
|
||||
|
||||
- title, 内嵌表格的标题
|
||||
- url, 内嵌表格的数据地址
|
||||
- tableConfigs,内嵌表格的配置选项
|
||||
- 类型:`Array<object>`
|
||||
- 配置:
|
||||
- type: 同 element-ui 的 table 属性的 type
|
||||
- fixed: 同 element-ui 的 table 属性的 fixed
|
||||
- width: 同 element-ui 的 table 属性的 width
|
||||
- name: 表头显示的内容
|
||||
- filter: 一般用于转换时间
|
||||
- prop: 字段
|
||||
- formField: boolean, 是否用于表单的填写
|
||||
- rules: 表单验证规则,详见:async-validator
|
||||
- subcomponent: 同 base-table 的 subcomponent
|
||||
- options: 表格操作列需要哪些操作
|
||||
- 值:`edit` | `delete` | `detail`,需要其他可自行添加(修改 base-table 组件)
|
||||
|
||||
### extraComponents
|
||||
|
||||
含义: 需要在对话框里使用的自定义组件列表
|
||||
类型: Array<object>
|
||||
对象选项:
|
||||
|
||||
- name: 该组件对应的 dataForm 字段(需要参照后端文档来指定)
|
||||
- hasModel: boolean, 上传组件一般设置为 false,设置是否和 dataForm 关联
|
||||
- label
|
||||
- fieldType: 设置该组件的数据将以什么数据类型形式来保存
|
||||
- component: 组件
|
||||
- props 传给组件的配置
|
||||
10
Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM node:12 AS builder
|
||||
WORKDIR /app
|
||||
ADD package.json /app/
|
||||
RUN npm config set registry https://registry.npmmirror.com && npm install
|
||||
ADD . /app
|
||||
RUN npm run build:prod
|
||||
|
||||
FROM busybox
|
||||
LABEL maintainer thomas.hairong@gmail.com
|
||||
COPY --from=builder /app/dist /html
|
||||
7
TODO.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# TODO List
|
||||
|
||||
1. 按钮加权限
|
||||
2. 国际化
|
||||
3. 表格高度 √
|
||||
4. 表格时间格式修改 √
|
||||
5. icon列表 √
|
||||
55
package-lock.json
generated
@@ -2603,6 +2603,12 @@
|
||||
"resolved": "https://registry.npm.taobao.org/@types/json-schema/download/@types/json-schema-7.0.5.tgz",
|
||||
"integrity": "sha1-3M5EMOZLRDuolF8CkPtWStW6xt0="
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.182",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz",
|
||||
"integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/minimatch": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npm.taobao.org/@types/minimatch/download/@types/minimatch-3.0.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fminimatch%2Fdownload%2F%40types%2Fminimatch-3.0.3.tgz",
|
||||
@@ -5277,6 +5283,19 @@
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"ckeditor4-integrations-common": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ckeditor4-integrations-common/-/ckeditor4-integrations-common-1.0.0.tgz",
|
||||
"integrity": "sha512-OAoQT/gYrHkg0qgzf6MS/rndYhq3SScLVQ3rtXQeuCE8ju7nFHg3qZ7WGA2XpFxcZzsMP6hhugXqdel5vbcC3g=="
|
||||
},
|
||||
"ckeditor4-vue": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ckeditor4-vue/-/ckeditor4-vue-2.1.1.tgz",
|
||||
"integrity": "sha512-BBmpT1BYxOmaA+qy9+hvhG0tDYCGqFve1eDSol0ZNwWCm1hZvmPAke809AhkHFUjb834dbNRlTwH3c2qedjtkQ==",
|
||||
"requires": {
|
||||
"ckeditor4-integrations-common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"class-utils": {
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npm.taobao.org/class-utils/download/class-utils-0.3.6.tgz",
|
||||
@@ -7101,6 +7120,22 @@
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"echarts": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.3.3.tgz",
|
||||
"integrity": "sha512-BRw2serInRwO5SIwRviZ6Xgm5Lb7irgz+sLiFMmy/HOaf4SQ+7oYqxKzRHAKp4xHQ05AuHw1xvoQWJjDQq/FGw==",
|
||||
"requires": {
|
||||
"tslib": "2.3.0",
|
||||
"zrender": "5.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
|
||||
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz",
|
||||
@@ -10942,6 +10977,11 @@
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.4",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
||||
},
|
||||
"move-concurrently": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz",
|
||||
@@ -17245,6 +17285,21 @@
|
||||
"integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA="
|
||||
}
|
||||
}
|
||||
},
|
||||
"zrender": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.2.tgz",
|
||||
"integrity": "sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==",
|
||||
"requires": {
|
||||
"tslib": "2.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
|
||||
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
"version": "5.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"serve": "vue-cli-service serve --mode production",
|
||||
"serve:dev": "vue-cli-service serve --mode development",
|
||||
"build": "vue-cli-service build",
|
||||
"build:prod": "vue-cli-service build --mode production",
|
||||
"build:sit": "vue-cli-service build --mode production.sit",
|
||||
@@ -13,14 +14,17 @@
|
||||
"axios": "^0.19.2",
|
||||
"babel-eslint": "^8.0.1",
|
||||
"babel-plugin-component": "^1.1.1",
|
||||
"ckeditor4-vue": "^2.1.1",
|
||||
"core-js": "^3.6.5",
|
||||
"echarts": "^5.3.3",
|
||||
"element-theme": "^2.0.1",
|
||||
"element-ui": "^2.15.7",
|
||||
"js-cookie": "^2.2.1",
|
||||
"lodash": "^4.17.19",
|
||||
"sass": "^1.26.5",
|
||||
"moment": "^2.29.4",
|
||||
"qs": "^6.9.4",
|
||||
"quill": "^1.3.7",
|
||||
"sass": "^1.26.5",
|
||||
"sass-loader": "^9.0.2",
|
||||
"screenfull": "^4.2.1",
|
||||
"svg-sprite-loader": "^5.0.0",
|
||||
@@ -31,6 +35,7 @@
|
||||
"vuex": "^3.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.182",
|
||||
"@vue/cli-plugin-babel": "^4.4.6",
|
||||
"@vue/cli-service": "^4.4.6",
|
||||
"element-theme-chalk": "^2.15.7",
|
||||
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 1.6 KiB |
25
public/i18n.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Created by Jacky.Gao on 2017-10-01.
|
||||
*/
|
||||
import defaultI18nJsonData from './designer.json';
|
||||
import en18nJsonData from './designer_en.json';
|
||||
export default function buildLocal () {
|
||||
let language = getCookie('language') || 'zh-CN';
|
||||
window.i18n = defaultI18nJsonData;
|
||||
if (language !== 'zh-CN') {
|
||||
window.i18n = en18nJsonData;
|
||||
}
|
||||
}
|
||||
|
||||
function getCookie (name) {
|
||||
var strcookie = document.cookie;//获取cookie字符串
|
||||
var arrcookie = strcookie.split("; ");//分割
|
||||
//遍历匹配
|
||||
for (var i = 0; i < arrcookie.length; i++) {
|
||||
var arr = arrcookie[i].split("=");
|
||||
if (arr[0] == name){
|
||||
return arr[1];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
window.SITE_CONFIG['version'] = 'v5.0.0';
|
||||
window.SITE_CONFIG['nodeEnv'] = '<%= process.env.VUE_APP_NODE_ENV %>';
|
||||
window.SITE_CONFIG['apiURL'] = ''; // api请求地址
|
||||
window.SITE_CONFIG['projURL'] = ''; // api请求地址
|
||||
window.SITE_CONFIG['storeState'] = {}; // vuex本地储存初始化状态(用于不刷新页面的情况下,也能重置初始化项目中所有状态)
|
||||
window.SITE_CONFIG['contentTabDefault'] = { // 内容标签页默认属性对象
|
||||
'name': '', // 名称, 由 this.$route.name 自动赋值(默认,名称 === 路由名称 === 路由路径)
|
||||
@@ -30,25 +31,25 @@
|
||||
<!-- 开发环境 -->
|
||||
<% if (process.env.VUE_APP_NODE_ENV === 'dev') { %>
|
||||
<script>
|
||||
window.SITE_CONFIG['apiURL'] = 'http://localhost:8080/renren-admin';
|
||||
window.SITE_CONFIG['apiURL'] = 'http://india.mes.picaiba.com/';
|
||||
</script>
|
||||
<% } %>
|
||||
<!-- 集成测试环境 -->
|
||||
<% if (process.env.VUE_APP_NODE_ENV === 'prod:sit') { %>
|
||||
<script>
|
||||
window.SITE_CONFIG['apiURL'] = 'http://localhost:8080/renren-admin';
|
||||
window.SITE_CONFIG['apiURL'] = 'http://india.mes.picaiba.com/';
|
||||
</script>
|
||||
<% } %>
|
||||
<!-- 验收测试环境 -->
|
||||
<% if (process.env.VUE_APP_NODE_ENV === 'prod:uat') { %>
|
||||
<script>
|
||||
window.SITE_CONFIG['apiURL'] = 'http://localhost:8080/renren-admin';
|
||||
window.SITE_CONFIG['apiURL'] = 'http://india.mes.picaiba.com/';
|
||||
</script>
|
||||
<% } %>
|
||||
<!-- 生产环境 -->
|
||||
<% if (process.env.VUE_APP_NODE_ENV === 'prod') { %>
|
||||
<script>
|
||||
window.SITE_CONFIG['apiURL'] = 'http://localhost:8080/renren-admin';
|
||||
window.SITE_CONFIG['apiURL'] = 'http://india.mes.picaiba.com/';
|
||||
</script>
|
||||
<% } %>
|
||||
</head>
|
||||
|
||||
57
src/App.vue
@@ -1,34 +1,43 @@
|
||||
<!--
|
||||
* @Descripttion:
|
||||
* @version:
|
||||
* @Author: fzq
|
||||
* @Date: 2022-11-25 09:51:46
|
||||
* @LastEditors: fzq
|
||||
* @LastEditTime: 2022-12-13 19:44:21
|
||||
-->
|
||||
<template>
|
||||
<transition name="el-fade-in-linear">
|
||||
<router-view />
|
||||
</transition>
|
||||
<transition name="el-fade-in-linear">
|
||||
<router-view />
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.el-table th.gutter{
|
||||
display: table-cell!important;
|
||||
}
|
||||
.el-table th.gutter {
|
||||
display: table-cell !important;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import Cookies from 'js-cookie'
|
||||
import { messages } from '@/i18n'
|
||||
// import { messages } from '@/i18n'
|
||||
export default {
|
||||
watch: {
|
||||
'$i18n.locale': 'i18nHandle'
|
||||
},
|
||||
created () {
|
||||
this.i18nHandle(this.$i18n.locale)
|
||||
},
|
||||
methods: {
|
||||
i18nHandle (val, oldVal) {
|
||||
Cookies.set('language', val)
|
||||
document.querySelector('html').setAttribute('lang', val)
|
||||
document.title = messages[val].brand.lg
|
||||
// 非登录页面,切换语言刷新页面
|
||||
if (this.$route.name !== 'login' && oldVal) {
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
watch: {
|
||||
'$i18n.locale': 'i18nHandle'
|
||||
},
|
||||
created() {
|
||||
this.i18nHandle(this.$i18n.locale)
|
||||
},
|
||||
methods: {
|
||||
i18nHandle(val, oldVal) {
|
||||
Cookies.set('language', val)
|
||||
document.querySelector('html').setAttribute('lang', val)
|
||||
// 不注释掉会报错
|
||||
// document.title = messages[val].brand.lg
|
||||
// 非登录页面,切换语言刷新页面
|
||||
if (this.$route.name !== 'login' && oldVal) {
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
BIN
src/assets/img/choicepart/Basic Data.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
src/assets/img/choicepart/Data Analysis.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
src/assets/img/choicepart/Equipment PLC.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
src/assets/img/choicepart/Factory Management.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
src/assets/img/choicepart/Log Management.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
src/assets/img/choicepart/Log Management2.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
src/assets/img/choicepart/MaterialsManage.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
src/assets/img/choicepart/OperationalOverview.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
src/assets/img/choicepart/Permission Management.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
src/assets/img/choicepart/Quality Management.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
src/assets/img/choicepart/Report Management.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
src/assets/img/choicepart/System Settings.png
Normal file
|
After Width: | Height: | Size: 8.8 KiB |
BIN
src/assets/img/choicepart/choice-item-back.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
src/assets/img/choicepart/choicepart-back.png
Normal file
|
After Width: | Height: | Size: 3.5 MiB |
BIN
src/assets/img/choicepart/packingManage.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
src/assets/img/choicepart/厂务管理.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
src/assets/img/choicepart/基本资料.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
src/assets/img/choicepart/报表管理.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
src/assets/img/choicepart/数据分析.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
src/assets/img/choicepart/日志管理.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
src/assets/img/choicepart/日志管理2.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
src/assets/img/choicepart/权限管理.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
src/assets/img/choicepart/系统设置.png
Normal file
|
After Width: | Height: | Size: 8.8 KiB |
BIN
src/assets/img/choicepart/设备数采.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
src/assets/img/choicepart/质量管理.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
src/assets/img/cnbm.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/img/login-back.jpg
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
src/assets/img/login-back.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
src/assets/img/login.gif
Normal file
|
After Width: | Height: | Size: 4.6 MiB |
BIN
src/assets/img/logo.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/img/logo@2x.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
src/assets/img/logo@4x.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
@@ -5,6 +5,8 @@
|
||||
}
|
||||
body {
|
||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||
// font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
|
||||
// font-family: Avenir,Helvetica Neue,Arial,Helvetica,sans-serif;
|
||||
font-size: $--font-size-base;
|
||||
line-height: $base--line-height;
|
||||
color: $--color-text-primary;
|
||||
@@ -15,8 +17,8 @@ a {
|
||||
text-decoration: none;
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: $--color-primary;
|
||||
text-decoration: underline;
|
||||
color: #fff;
|
||||
// text-decoration: underline;
|
||||
}
|
||||
}
|
||||
img {
|
||||
@@ -217,6 +219,17 @@ img {
|
||||
&__brand {
|
||||
&-lg {
|
||||
display: none;
|
||||
// margin: 0;
|
||||
// color: #fff;
|
||||
// width: 189px;
|
||||
// overflow: hidden;
|
||||
// text-overflow: ellipsis;
|
||||
// white-space: nowrap;
|
||||
// font-weight: 500;
|
||||
// line-height: 50px;
|
||||
// font-size: 14px;
|
||||
// font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
|
||||
// vertical-align: middle;
|
||||
}
|
||||
&-mini {
|
||||
display: inline-block;
|
||||
@@ -241,6 +254,9 @@ img {
|
||||
margin-right: 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
&__close {
|
||||
width: 0px;
|
||||
}
|
||||
}
|
||||
.aui-content {
|
||||
&__wrapper {
|
||||
@@ -265,10 +281,24 @@ img {
|
||||
align-items: stretch;
|
||||
height: $navbar--height;
|
||||
background-color: $--color-primary;
|
||||
box-shadow: 0 1px 0 0 rgba(0, 0, 0, .05);
|
||||
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.05);
|
||||
.home {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 1030;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
height: $navbar--height;
|
||||
background-color: #409EFF;
|
||||
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
&--colorful {
|
||||
.aui-navbar__body {
|
||||
// navbar body颜色
|
||||
background-color: transparent;
|
||||
// background-color: #304156;
|
||||
}
|
||||
.aui-navbar__menu {
|
||||
> .el-menu-item,
|
||||
@@ -278,6 +308,7 @@ img {
|
||||
&:hover {
|
||||
color: #fff;
|
||||
background-color: mix(#000, $--color-primary, 15%);
|
||||
// background-color: #001528;
|
||||
}
|
||||
}
|
||||
> .el-menu-item.is-active,
|
||||
@@ -285,7 +316,7 @@ img {
|
||||
color: #fff;
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: #fff;
|
||||
color: #263445;
|
||||
}
|
||||
}
|
||||
.el-menu-item i,
|
||||
@@ -332,7 +363,16 @@ img {
|
||||
color: #fff;
|
||||
overflow: hidden;
|
||||
transition: width .3s;
|
||||
&-lg,
|
||||
&-lg {
|
||||
width: 238px;
|
||||
height: 100%;
|
||||
font-size: 18px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
line-height: 20px;
|
||||
margin-top: 7px;
|
||||
}
|
||||
&-mini {
|
||||
max-width: 100%;
|
||||
color: #fff;
|
||||
@@ -371,9 +411,13 @@ img {
|
||||
.el-menu-item.is-active,
|
||||
.el-submenu.is-active > .el-submenu__title {
|
||||
color: $--color-text-secondary;
|
||||
// background-color: rgb(13,43,104);
|
||||
&:focus,
|
||||
&:hover {
|
||||
// 点击之后图标颜色亮度
|
||||
color: $--color-text-primary;
|
||||
// color: #fff;
|
||||
// background-color: rgb(13,43,104);
|
||||
}
|
||||
}
|
||||
.el-menu-item {
|
||||
@@ -392,9 +436,10 @@ img {
|
||||
* {
|
||||
vertical-align: initial;
|
||||
}
|
||||
//
|
||||
.aui-navbar__icon-menu {
|
||||
vertical-align: middle;
|
||||
font-size: 16px;
|
||||
font-size: 22px;
|
||||
}
|
||||
.el-dropdown {
|
||||
color: $--color-text-secondary;
|
||||
@@ -463,7 +508,8 @@ img {
|
||||
bottom: 0;
|
||||
z-index: 1020;
|
||||
width: $sidebar--width;
|
||||
background-color: #fff;
|
||||
// background-color: #fff;
|
||||
background-color:#304156;
|
||||
box-shadow: 1px 0 2px 0 rgba(0, 0, 0, .05);
|
||||
overflow: hidden;
|
||||
transition: width .3s;
|
||||
@@ -471,23 +517,28 @@ img {
|
||||
background-color: $sidebar--background-color-dark;
|
||||
.aui-sidebar__menu,
|
||||
> .el-menu--popup {
|
||||
background-color: $sidebar--background-color-dark;
|
||||
// background-color: $sidebar--background-color-dark;
|
||||
background-color: #304156;;
|
||||
.el-menu-item,
|
||||
.el-submenu > .el-submenu__title {
|
||||
color: $sidebar--text-color-dark;
|
||||
// color: $sidebar--text-color-dark;
|
||||
color: #f4f4f5;
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: mix(#fff, $sidebar--text-color-dark, 50%);
|
||||
background-color: mix(#fff, $sidebar--background-color-dark, 2.5%);
|
||||
// background-color: mix(#fff, $sidebar--background-color-dark, 2.5%);
|
||||
background-color:#0B253F;
|
||||
}
|
||||
}
|
||||
.el-menu,
|
||||
.el-submenu.is-opened {
|
||||
background-color: mix(#000, $sidebar--background-color-dark, 15%);
|
||||
// background-color: mix(#000, $sidebar--background-color-dark, 15%);
|
||||
background-color:#0B253F;
|
||||
}
|
||||
.el-menu-item.is-active,
|
||||
.el-submenu.is-active > .el-submenu__title {
|
||||
color: mix(#fff, $sidebar--text-color-dark, 80%);
|
||||
// color: mix(#fff, $sidebar--text-color-dark, 80%);
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -501,6 +552,10 @@ img {
|
||||
overflow-y: scroll;
|
||||
transition: width .3s;
|
||||
}
|
||||
.close {
|
||||
width: 0px;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
&__menu {
|
||||
width: $sidebar--width;
|
||||
border-right: 0;
|
||||
@@ -532,6 +587,7 @@ img {
|
||||
min-height: calc(100vh - #{$navbar--height});
|
||||
&__wrapper {
|
||||
position: relative;
|
||||
// 注释掉可隐藏侧边栏,但需要在main.vue中加入main-content的限制条件
|
||||
margin-left: $sidebar--width;
|
||||
min-height: calc(100vh - #{$navbar--height});
|
||||
background-color: $content--background-color;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
.mod-home {
|
||||
table {
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
border: 1px solid $--border-color-lighter;
|
||||
border-collapse: collapse;
|
||||
th,
|
||||
|
||||
@@ -5,15 +5,19 @@ $base--line-height: 1.15;
|
||||
$navbar--height: 50px;
|
||||
|
||||
// Sidebar
|
||||
$sidebar--width: 230px;
|
||||
// $sidebar--width: 300px;
|
||||
$sidebar--width: 248px;
|
||||
$sidebar--width-fold: 64px;
|
||||
$sidebar--background-color-dark: #263238;
|
||||
// $sidebar--background-color-dark: #263238;
|
||||
// $sidebar--background-color-dark: #001529;
|
||||
$sidebar--background-color-dark: #304156;
|
||||
$sidebar--text-color-dark: #8a979e;
|
||||
$sidebar--menu-item-height: 48px;
|
||||
|
||||
// Content
|
||||
$content--padding: 15px;
|
||||
$content--background-color: #f1f4f5;
|
||||
// $content--background-color: #f1f4f5;
|
||||
$content--background-color: #fff;
|
||||
$content--card-header-height: 60px;
|
||||
$content--tabs-header-height: 38px;
|
||||
// Content, 填充整屏高度(非tabs状态) = 整屏高度 - 导航条高度 - aui-content上下内边距高度
|
||||
|
||||
93
src/components/Breadcrumb/index.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<!--
|
||||
* @Author: your name
|
||||
* @Date: 2021-01-27 10:07:42
|
||||
* @LastEditTime: 2021-01-28 16:26:15
|
||||
* @LastEditors: gtz
|
||||
* @Description: In User Settings Edit
|
||||
* @FilePath: \mt-bus-fe\src\components\Breadcrumb\index.vue
|
||||
-->
|
||||
<template>
|
||||
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||
<transition-group name="breadcrumb">
|
||||
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
|
||||
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="isredirect">{{ item.meta.title }}</span>
|
||||
<span v-else class="no-redirect">{{ item.meta.title }}</span>
|
||||
<!-- @click.prevent="handleLink(item)" -->
|
||||
</el-breadcrumb-item>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import pathToRegexp from 'path-to-regexp'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
levelList: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route(route) {
|
||||
// if you go to the redirect page, do not update the breadcrumbs
|
||||
if (route.path.startsWith('/redirect/')) {
|
||||
return
|
||||
}
|
||||
this.getBreadcrumb()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getBreadcrumb()
|
||||
},
|
||||
methods: {
|
||||
getBreadcrumb() {
|
||||
// only show routes with meta.title
|
||||
const matched = this.$route.matched.filter(item => item.meta && item.meta.title)
|
||||
// const first = matched[0]
|
||||
|
||||
// if (!this.isDashboard(first)) {
|
||||
// matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
|
||||
// }
|
||||
|
||||
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
|
||||
},
|
||||
isDashboard(route) {
|
||||
const name = route && route.name
|
||||
if (!name) {
|
||||
return false
|
||||
}
|
||||
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
|
||||
},
|
||||
pathCompile(path) {
|
||||
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
|
||||
const { params } = this.$route
|
||||
var toPath = pathToRegexp.compile(path)
|
||||
return toPath(params)
|
||||
},
|
||||
handleLink(item) {
|
||||
const { redirect, path } = item
|
||||
if (redirect) {
|
||||
this.$router.push(redirect)
|
||||
return
|
||||
}
|
||||
this.$router.push(this.pathCompile(path))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-breadcrumb.el-breadcrumb {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 48px;
|
||||
margin-left: 8px;
|
||||
.isredirect {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
.no-redirect {
|
||||
color: #8C8C8C;
|
||||
cursor: text;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
35
src/components/Hamburger/index.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div style="padding: 5px 15px 5px 32px;" @click="toggleClick">
|
||||
<svg-icon style="width: 24px; height: 24px" class="item-icon hamburger" :class="{'is-active':isActive}" icon-class="hamburgerBtn" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Hamburger',
|
||||
props: {
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleClick() {
|
||||
this.$emit('toggleClick')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hamburger {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.hamburger.is-active {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
</style>
|
||||
62
src/components/SvgIcon/index.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
|
||||
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
|
||||
<use :xlink:href="iconName" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
|
||||
import { isExternal } from '@/utils/validate'
|
||||
|
||||
export default {
|
||||
name: 'SvgIcon',
|
||||
props: {
|
||||
iconClass: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isExternal() {
|
||||
return isExternal(this.iconClass)
|
||||
},
|
||||
iconName() {
|
||||
return `#icon-${this.iconClass}`
|
||||
},
|
||||
svgClass() {
|
||||
if (this.className) {
|
||||
return 'svg-icon ' + this.className
|
||||
} else {
|
||||
return 'svg-icon'
|
||||
}
|
||||
},
|
||||
styleExternalIcon() {
|
||||
return {
|
||||
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
|
||||
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.svg-external-icon {
|
||||
background-color: currentColor;
|
||||
mask-size: cover!important;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
548
src/components/base-detail-page/index.vue
Normal file
@@ -0,0 +1,548 @@
|
||||
<template>
|
||||
<div class="super-flexible-dialog" :title="isDetail ? title.detail : !dataForm.id ? title.add : title.edit" @close="handleClose">
|
||||
<div style="max-height: 60vh; overflow-y: scroll; overflow-x: hidden;">
|
||||
<el-form ref="dataForm" :model="dataForm" :rules="dataFormRules">
|
||||
<!-- 如果需要更精细一点的布局,可以根据配置项实现地再复杂一点,但此处暂时全部采用一行两列布局 -->
|
||||
<el-row v-for="n in rows" :key="n" :gutter="20">
|
||||
<el-col v-for="c in COLUMN_PER_ROW" :key="`${n}+'col'+${c}`" :span="getSpan(n, c)">
|
||||
<!-- <el-col v-for="c in COLUMN_PER_ROW" :key="`${n}+'col'+${c}`" :span="24 / COLUMN_PER_ROW"> -->
|
||||
<!-- :class="{ 'hidden-input': configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].hidden }" -->
|
||||
<el-form-item
|
||||
v-if="configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)]"
|
||||
:prop="configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name"
|
||||
:key="`${n}-col-${c}-item`"
|
||||
:label="getLabel(n, c)"
|
||||
>
|
||||
<!-- 暂时先不实现部分输入方式 -->
|
||||
<el-input
|
||||
v-if="getType(n, c) === 'input'"
|
||||
:placeholder="getPlaceholder(n, c)"
|
||||
v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"
|
||||
clearable
|
||||
/>
|
||||
<el-radio v-if="getType(n, c) === 'radio'" v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"></el-radio>
|
||||
<el-checkbox v-if="getType(n, c) === 'check'" v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"></el-checkbox>
|
||||
<el-select
|
||||
v-if="getType(n, c) === 'select'"
|
||||
:placeholder="getPlaceholder(n, c)"
|
||||
v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"
|
||||
clearable
|
||||
@change="emitSelectChange(configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name, $event)"
|
||||
>
|
||||
<el-option v-for="opt in configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].options" :key="opt.label" :label="opt.label" :value="opt.value" />
|
||||
</el-select>
|
||||
<el-switch v-if="getType(n, c) === 'switch'" v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"></el-switch>
|
||||
<el-cascader
|
||||
v-if="getType(n, c) === 'cascader'"
|
||||
v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"
|
||||
:options="configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].options"
|
||||
:props="configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].props"
|
||||
></el-cascader>
|
||||
<el-time-select v-if="getType(n, c) === 'time'" v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"></el-time-select>
|
||||
<el-date-picker
|
||||
v-if="getType(n, c) === 'date'"
|
||||
v-bind="configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].props"
|
||||
:placeholder="getPlaceholder(n, c)"
|
||||
v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- extra components , like Markdown or RichEdit -->
|
||||
<template v-if="configs.extraComponents && configs.extraComponents.length > 0">
|
||||
<el-form-item v-for="(ec, index) in configs.extraComponents" :key="ec.name + index" :label="ec.label" class="extra-components">
|
||||
<component style="margin-top: 40px;" v-if="ec.hasModel" :is="ec.component" v-bind="ec.props" v-model="dataForm[ec.name]" @ready="handleEditorReady" />
|
||||
<!-- <component v-if="ec.hasModel" :is="ec.component" v-bind="ec.props" v-model="dataForm[ec.name]" /> -->
|
||||
<component
|
||||
v-else
|
||||
:is="ec.component"
|
||||
v-bind="ec.props"
|
||||
@uploader-update-filelist="handleUploadListUpdate($event, ec.props.extraParams.typeCode)"
|
||||
:uploader-inject-file-list="/*用于设备分流的*/ fileList[ec.props.extraParams.typeCode]"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
|
||||
<template v-if="dataForm.id && configs.subtable">
|
||||
<attr-form :pId="dataForm.id" v-bind="configs.subtable" />
|
||||
</template>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<template v-for="(operate, index) in configs.operations">
|
||||
<!-- {{ operate.name | btnNameFilter }} -->
|
||||
<el-button
|
||||
v-if="
|
||||
operate.showAlways ||
|
||||
(((dataForm.id && operate.showOnEdit) || (!dataForm.id && !operate.showOnEdit)) && (operate.permission ? $hasPermission(operate.permission) : true))
|
||||
"
|
||||
:key="`operate-${index}`"
|
||||
:type="btnType[operate.name]"
|
||||
@click="handleClick(operate)"
|
||||
>{{ btnName[operate.name] }}</el-button
|
||||
>
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AttrForm from '../AttrForm'
|
||||
import { pick } from 'lodash/object'
|
||||
|
||||
// 标题 for i18n
|
||||
const title = {
|
||||
detail: i18n.t('detail'),
|
||||
add: i18n.t('add'),
|
||||
edit: '编辑'
|
||||
}
|
||||
|
||||
// 或者也可以改造成自定义颜色:
|
||||
const btnType = {
|
||||
save: 'success',
|
||||
update: 'primary',
|
||||
reset: 'text'
|
||||
// cancel: 'text'
|
||||
// add more...
|
||||
}
|
||||
|
||||
const btnName = {
|
||||
// for i18n
|
||||
save: '保存',
|
||||
update: '更新',
|
||||
reset: '重置',
|
||||
cancel: i18n.t('cancel')
|
||||
// add more...
|
||||
}
|
||||
|
||||
// 每行的列数
|
||||
const COLUMN_PER_ROW = 2
|
||||
|
||||
export default {
|
||||
name: 'AddOrUpdateDialog',
|
||||
components: { AttrForm },
|
||||
props: {
|
||||
configs: {
|
||||
/**
|
||||
* TODO: 定义及使用方式,应改用README.md文件记录
|
||||
* type: 'dialog' | 'drawer' | 'page'
|
||||
* fields: Array<string|object>
|
||||
* - fields.object: { name, type: 'number'|'textarea'|'select'|'date'|.., required: boolean, validator: boolean(是否需要验证), [options]: any[], api: string(自动获取数据的接口,一般为getcode接口)}
|
||||
* operations: Array[object], 操作名和对应的接口地址,还有permission(如,sys:dict:update)
|
||||
*/
|
||||
type: Object,
|
||||
default: () => ({}) // 此处省去类型检查,使用者自行注意就好
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
nameFilter: function(name) {
|
||||
if (!name) return null
|
||||
// for i18n
|
||||
const defaultNames = {
|
||||
name: i18n.t('name'),
|
||||
code: i18n.t('code'),
|
||||
remark: i18n.t('remark'),
|
||||
description: i18n.t('desc'),
|
||||
specifications: i18n.t('prod.spec')
|
||||
// add more...
|
||||
}
|
||||
|
||||
return defaultNames[name]
|
||||
}
|
||||
},
|
||||
// provide() {
|
||||
// return {
|
||||
// _df: this.dataForm
|
||||
// }
|
||||
// },
|
||||
data() {
|
||||
return {
|
||||
COLUMN_PER_ROW,
|
||||
title,
|
||||
/** 按钮相关属性 */
|
||||
btnName,
|
||||
btnType,
|
||||
defaultNames: {
|
||||
name: i18n.t('name'),
|
||||
code: i18n.t('code'),
|
||||
remark: i18n.t('remark'),
|
||||
description: i18n.t('desc'),
|
||||
specifications: i18n.t('prod.spec')
|
||||
// add more...
|
||||
},
|
||||
defaultPlaceholders: {}, // 自动根据 defaultNames 计算得来
|
||||
/** 表单相关属性 */
|
||||
visible: false,
|
||||
isEdit: false,
|
||||
isDetail: false,
|
||||
dataForm: {},
|
||||
dataFormRules: {},
|
||||
tempForm: [], // 临时保存自动生成的code,或其他数据
|
||||
shouldWait: null,
|
||||
fileForm: {}, // 文件上传分流用、合并用的表单,根据 typeCode 进行分流,在请求时合并
|
||||
fileList: {} // 文件加载时分流,依据 typeCode
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
rows() {
|
||||
// 本组件只实现了'一行两列'的表单布局
|
||||
return Math.ceil(this.configs.fields.length / COLUMN_PER_ROW)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
/** 计算 defaultPlaceholders */
|
||||
const prefix = '请输入'
|
||||
Object.entries(this.defaultNames).map(([key, value]) => {
|
||||
this.defaultPlaceholders[key] = prefix + value
|
||||
})
|
||||
|
||||
/** 转换 configs.fields 的结构,把纯字符串转为对象 */
|
||||
this.$nextTick(() => {
|
||||
this.configs.fields = this.configs.fields.map(item => {
|
||||
if (typeof item === 'string') {
|
||||
return { name: item }
|
||||
}
|
||||
return item
|
||||
})
|
||||
|
||||
/** 动态设置dataForm字段 */
|
||||
this.configs.fields.forEach(item => {
|
||||
this.$set(this.dataForm, [item.name], '')
|
||||
|
||||
/** select 的默认值设置 */
|
||||
if (item.type === 'select') {
|
||||
const opts = item.options || []
|
||||
const dft = opts.find(item => item.default || false)
|
||||
if (dft) {
|
||||
this.$set(this.dataForm, [item.name], dft.value)
|
||||
}
|
||||
}
|
||||
|
||||
if (item.api) {
|
||||
/** 自动请求并填充 */
|
||||
// or this.shouldWaitPool = []
|
||||
this.shouldWait = this.$http({
|
||||
url: this.$http.adornUrl(item.api),
|
||||
method: 'POST' // 也可以改成动态决定
|
||||
}).then(({ data: res }) => {
|
||||
if (res && res.code === 0) {
|
||||
// this.dataForm[item.name] = res.data // <=== 此处需要对接口
|
||||
this.tempForm.push({ name: item.name, data: res.data })
|
||||
}
|
||||
})
|
||||
} // end if (item.api)
|
||||
|
||||
if (item.required) {
|
||||
const requiredRule = {
|
||||
required: true,
|
||||
message: '请输入必填项',
|
||||
trigger: 'change'
|
||||
}
|
||||
/** 检查是否已经存在该字段的规则 */
|
||||
const exists = this.dataFormRules[item.name] || null
|
||||
/** 设置验证规则 */
|
||||
if (exists) {
|
||||
const unset = true
|
||||
for (const rule of exists) {
|
||||
if (rule.required) unset = false
|
||||
}
|
||||
if (unset) {
|
||||
exists.push(requiredRule)
|
||||
}
|
||||
} else {
|
||||
/** 不存在已有规则 */
|
||||
this.$set(this.dataFormRules, [item.name], [requiredRule])
|
||||
}
|
||||
} // end if (item.required)
|
||||
|
||||
if (item.rules) {
|
||||
const exists = this.dataFormRules[item.name] || null
|
||||
if (exists) {
|
||||
// 浅拷贝过去
|
||||
exists.push(...item.rules)
|
||||
} else {
|
||||
this.$set(this.dataFormRules, [item.name], [...item.rules])
|
||||
}
|
||||
} // end if (item.rules)
|
||||
})
|
||||
|
||||
/** 计算默认值 */
|
||||
function calDefault(type) {
|
||||
switch (type) {
|
||||
case 'array':
|
||||
return []
|
||||
// more case...
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
/** 检查是否需要额外的组件 */
|
||||
this.configs.extraComponents &&
|
||||
this.configs.extraComponents.forEach(item => {
|
||||
if (Object.hasOwn(this.dataForm, [item.name])) {
|
||||
console.log('有了!')
|
||||
return
|
||||
} else {
|
||||
console.log('新建!')
|
||||
this.$set(this.dataForm, [item.name], calDefault(item.fieldType))
|
||||
}
|
||||
|
||||
console.log('component: ', item.component)
|
||||
})
|
||||
|
||||
/** 单独设置 id */
|
||||
this.$set(this.dataForm, 'id', null)
|
||||
console.log('mounted: this.dataForm', JSON.stringify(this.dataForm))
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getSpan(n, c) {
|
||||
const opt = this.configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)]
|
||||
return opt && opt.span ? opt.span : 24 / COLUMN_PER_ROW
|
||||
},
|
||||
|
||||
getLabel(n, c) {
|
||||
const opt = this.configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)]
|
||||
if (opt) {
|
||||
// if opt is valid
|
||||
return opt.label ? opt.label : this.defaultNames[opt.name]
|
||||
}
|
||||
},
|
||||
|
||||
getPlaceholder(n, c) {
|
||||
const opt = this.configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)]
|
||||
if (opt) {
|
||||
// if opt is valid
|
||||
return opt.placeholder
|
||||
? opt.placeholder
|
||||
: this.defaultPlaceholders[opt.name]
|
||||
? this.defaultPlaceholders[opt.name]
|
||||
: opt.label
|
||||
? (opt.type === 'select' ? i18n.t('choose') : '请输入') + opt.label
|
||||
: null
|
||||
|
||||
// : opt.type === 'select'
|
||||
// ? i18n.t('choose')
|
||||
// : '请输入'
|
||||
}
|
||||
},
|
||||
|
||||
getType(n, c) {
|
||||
const opt = this.configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)]
|
||||
if (opt) {
|
||||
if (!opt.type || ['input', 'number' /** add more.. */].includes(opt.type)) {
|
||||
return 'input'
|
||||
} else if (['select' /** add more.. */].includes(opt.type)) {
|
||||
return 'select'
|
||||
} else if (['cascader'].includes(opt.type)) {
|
||||
return 'cascader'
|
||||
} else if (['date'].includes(opt.type)) {
|
||||
return 'date'
|
||||
}
|
||||
// add more...
|
||||
} else {
|
||||
return 'input'
|
||||
}
|
||||
},
|
||||
|
||||
init(id) {
|
||||
this.visible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].resetFields()
|
||||
this.dataForm.id = id || null
|
||||
if (this.dataForm.id) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`${this.configs.infoUrl}/${this.dataForm.id}`),
|
||||
method: 'get'
|
||||
}).then(({ data: res }) => {
|
||||
if (res && res.code === 0) {
|
||||
const dataFormKeys = Object.keys(this.dataForm)
|
||||
console.log('data form keys: ', dataFormKeys, pick(res.data, dataFormKeys))
|
||||
this.dataForm = pick(res.data, dataFormKeys)
|
||||
|
||||
// LABEL: FILE_RELATED
|
||||
/** 对文件下载进行分流 */
|
||||
this.fileList = {}
|
||||
if (this.dataForm.files) {
|
||||
console.log('files: ', this.dataForm.files)
|
||||
this.dataForm.files.forEach(file => {
|
||||
// const fileName = file.fileUrl.split('/').pop()
|
||||
/** [1] 处理 fileList */
|
||||
if (Object.hasOwn(this.fileList, file.typeCode)) {
|
||||
/** 已存在 */
|
||||
// this.fileList[file.typeCode].push({ id: file.id, name: fileName, typeCode: file.typeCode })
|
||||
this.fileList[file.typeCode].push(file)
|
||||
} else {
|
||||
// this.fileList[file.typeCode] = [{ id: file.id, name: fileName, typeCode: file.typeCode }]
|
||||
this.fileList[file.typeCode] = [file]
|
||||
}
|
||||
|
||||
/** [2] 处理 fileForm */
|
||||
if (Object.hasOwn(this.fileForm, file.typeCode)) {
|
||||
this.fileForm[file.typeCode].push(file.id)
|
||||
} else {
|
||||
this.fileForm[file.typeCode] = [file.id]
|
||||
}
|
||||
})
|
||||
console.log('after分流:', this.fileList)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
/** 如果不是编辑,就填充自动生成的数据 */
|
||||
if (this.shouldWait)
|
||||
this.shouldWait.then(() => {
|
||||
if (this.tempForm.length) {
|
||||
console.log('create new, tempform', JSON.stringify(this.tempForm.length))
|
||||
this.tempForm.forEach(item => {
|
||||
console.log('item data', item.data)
|
||||
this.dataForm[item.name] = item.data
|
||||
})
|
||||
console.log('create new, dataform', JSON.stringify(this.dataForm))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
emitSelectChange(name, id) {
|
||||
this.$emit('select-change', { name, id })
|
||||
},
|
||||
|
||||
handleEditorReady(val) {
|
||||
console.log('editor rready..', val)
|
||||
},
|
||||
|
||||
handleClick(btn) {
|
||||
/** 提取url */
|
||||
const urls = {}
|
||||
this.configs.operations.map(item => {
|
||||
urls[item.name] = {}
|
||||
urls[item.name].url = item.url
|
||||
urls[item.name].extraFields = item.extraFields || {}
|
||||
})
|
||||
/** 操作 */
|
||||
switch (btn.name) {
|
||||
case 'save':
|
||||
case 'update':
|
||||
/** 需要验证表单的操作 */
|
||||
this.$refs['dataForm'].validate(valid => {
|
||||
if (valid) {
|
||||
/** 对于文件上传的单独处理(合并处理) */
|
||||
if (Object.keys(this.fileForm).length) {
|
||||
console.log('fileform 有值')
|
||||
// LABEL: FILE_RELATED
|
||||
let fileIds = []
|
||||
for (const [key, item] of Object.entries(this.fileForm)) {
|
||||
if (Array.isArray(item)) {
|
||||
fileIds = fileIds.concat(item)
|
||||
} else {
|
||||
console.error('handleClick(): 上传文件数组类型不正确')
|
||||
}
|
||||
}
|
||||
this.$set(this.dataForm, 'fileIds', fileIds)
|
||||
}
|
||||
|
||||
console.log('before send: ', this.dataForm)
|
||||
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(urls[btn.name].url),
|
||||
method: btn.name === 'save' ? 'POST' : 'PUT',
|
||||
data: { ...this.dataForm, ...urls[btn.name].extraFields }
|
||||
})
|
||||
.then(({ data: res }) => {
|
||||
if (res && res.code === 0) {
|
||||
this.$message({
|
||||
message: btn.name === 'save' ? i18n.t('prompt.success') : '更新成功!',
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.$emit('refreshDataList')
|
||||
this.visible = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message({
|
||||
message: err,
|
||||
type: 'error',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
return
|
||||
case 'reset':
|
||||
for (const key of Object.keys(this.dataForm)) {
|
||||
if (typeof this.dataForm[key] === 'string') {
|
||||
this.dataForm[key] = ''
|
||||
} else if (this.dataForm[key] instanceof Array) {
|
||||
this.dataForm[key].splice(0)
|
||||
} else {
|
||||
this.dataForm[key] = null
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'cancel':
|
||||
this.visible = false
|
||||
// add more..
|
||||
}
|
||||
},
|
||||
|
||||
// LABEL: FILE_RELATED
|
||||
handleUploadListUpdate(filelist, typeCode = 'DefaultTypeCode') {
|
||||
console.log('before handleUploadListUpdate(): ', JSON.parse(JSON.stringify(this.fileForm)))
|
||||
// 设备类型 typeCode: EquipmentTypeFile
|
||||
// 设备信息 typeCode: EquipmentInfoFile | EquipmentInfoImage
|
||||
|
||||
// 原先写法:直接更新 dataForm 对象,不适用于有多个上传组件的需求
|
||||
// this.$set(
|
||||
// this.dataForm,
|
||||
// 'fileIds',
|
||||
// filelist.map(item => item.id)
|
||||
// )
|
||||
// console.log('handleUploadListUpdate(): ', this.dataForm)
|
||||
// 现更改为分流写法
|
||||
this.$set(
|
||||
this.fileForm,
|
||||
typeCode,
|
||||
filelist.map(item => item.id)
|
||||
)
|
||||
console.log('after handleUploadListUpdate(): ', this.fileForm)
|
||||
},
|
||||
|
||||
handleClose() {
|
||||
this.$emit('destory-dialog')
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.super-flexible-dialog >>> .el-select,
|
||||
.super-flexible-dialog >>> .el-cascader {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.super-flexible-dialog >>> ::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.super-flexible-dialog >>> ::-webkit-scrollbar-thumb {
|
||||
width: 4px;
|
||||
border-radius: 4px;
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
.super-flexible-dialog >>> .hidden-input {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
283
src/components/base-dialog/AttrForm/index.vue
Normal file
@@ -0,0 +1,283 @@
|
||||
<template>
|
||||
<div class="attr-form">
|
||||
<h3>
|
||||
{{ title }} <el-button style="margin-left: 8px;" type="text" v-if="!isDetail && !showAddAttr" @click="showAddAttr = true">{{ $t('add') }}</el-button>
|
||||
</h3>
|
||||
<div v-if="!showAddAttr">
|
||||
<component
|
||||
key="sub-table"
|
||||
:is="require('../../base-table/index.vue').default"
|
||||
:table-head-configs="filterTableConfigs()"
|
||||
:data="dataList"
|
||||
:page="pageIndex"
|
||||
:size="pageSize"
|
||||
:max-height="calcMaxHeight(8)"
|
||||
@operate-event="handleOperations"
|
||||
/>
|
||||
<el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[5, 10, 20, 50]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
<div v-else style="background: #eee; border-radius: 8px; padding: 12px;">
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form ref="AttrForm" :model="AttrForm" :rules="AttrFormRules" :inline="true" label-position="top">
|
||||
<el-row :gutter="20" style="padding: 0 24px;">
|
||||
<el-col :span="attrFormFields.length > 6 ? 6 : 12" v-for="field in attrFormFields" :key="field.prop + 'col'">
|
||||
<el-form-item :key="field.prop" :prop="field.prop" :label="field.name" style="width: 100%">
|
||||
<el-input v-if="field.formType === 'input' || !field.formType" v-model="AttrForm[field.prop]" :placeholder="$t('hints.input')" clearable />
|
||||
<el-select v-if="field.formType === 'select'" v-model="AttrForm[field.prop]" clearable>
|
||||
<el-option v-for="opt in field.formOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||||
</el-select>
|
||||
<!-- add more... -->
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="text-align: right;">
|
||||
<el-button size="small" @click="handleCloseAttrForm">{{ $t('cancel') }}</el-button>
|
||||
<el-button type="success" size="small" @click="handleSaveAttrForm">{{ $t('save') }}</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import i18n from '@/i18n'
|
||||
import BaseTable from '@/components/base-table'
|
||||
import { pick } from 'lodash/object'
|
||||
import { calcMaxHeight } from '@/utils'
|
||||
export default {
|
||||
name: 'AttrForm',
|
||||
components: { BaseTable },
|
||||
props: {
|
||||
isDetail: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/** subtable 需要设置的属性 */
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
tableConfigs: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
/** 表单提交需要的属性 */
|
||||
relatedId: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: null
|
||||
},
|
||||
relatedField: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
calcMaxHeight,
|
||||
showAddAttr: false,
|
||||
dataList: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
AttrForm: {}, // 需动态设置
|
||||
AttrFormRules: {} // 需动态设置
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
attrFormFields() {
|
||||
const _ = this.tableConfigs.filter(item => item.formField)
|
||||
/** 顺带配置 AttrForm */
|
||||
_.forEach(item => {
|
||||
this.$set(this.AttrForm, [item.prop], '')
|
||||
})
|
||||
|
||||
this.$set(this.AttrForm, 'id', null)
|
||||
return _
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getDataList()
|
||||
/** 设置 AttrForm 的 rules */
|
||||
for (const config of this.tableConfigs) {
|
||||
if (config.rules) {
|
||||
this.$set(this.AttrFormRules, [config.prop], config.rules)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
filterTableConfigs() {
|
||||
if (this.isDetail) {
|
||||
/** 如果是查看详情,就屏蔽操作列 */
|
||||
return this.tableConfigs.filter(opt => opt.prop !== 'operations')
|
||||
}
|
||||
return this.tableConfigs
|
||||
},
|
||||
/** init dataform */
|
||||
initAttrForm() {
|
||||
Object.entries(this.AttrForm).forEach(([key, value]) => {
|
||||
if (typeof value === 'object' || typeof value === 'number') {
|
||||
this.AttrForm[key] = null
|
||||
} else if (Array.isArray(value)) {
|
||||
this.AttrForm[key] = []
|
||||
} else {
|
||||
this.AttrForm[key] = ''
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/** requests */
|
||||
getDataList() {
|
||||
this.dataListLoading = true
|
||||
// 获取动态属性列表
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`${this.url}/page`),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams({
|
||||
page: this.pageIndex,
|
||||
limit: this.pageSize,
|
||||
[this.relatedField]: this.relatedId
|
||||
// order: 'asc/desc',
|
||||
// orderField: 'name'
|
||||
})
|
||||
}).then(({ data: res }) => {
|
||||
if (res && res.code === 0) {
|
||||
this.dataList = res.data.list
|
||||
this.totalPage = res.data.total
|
||||
} else {
|
||||
this.dataList = []
|
||||
this.totalPage = 0
|
||||
}
|
||||
this.dataListLoading = false
|
||||
})
|
||||
},
|
||||
|
||||
/** handlers */
|
||||
handleOperations({ type, data: id }) {
|
||||
switch (type) {
|
||||
case 'edit':
|
||||
{
|
||||
this.showAddAttr = true
|
||||
this.$nextTick(() => {
|
||||
this.$http.get(this.$http.adornUrl(`${this.url}/${id}`)).then(({ data: res }) => {
|
||||
if (res && res.code === 0 && res.data) {
|
||||
const neededFields = [...this.attrFormFields.map(item => item.prop), 'id']
|
||||
const filtered = pick(res.data, neededFields)
|
||||
for (let field of neededFields) {
|
||||
this.AttrForm[field] = filtered[field]
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'delete':
|
||||
return this.deleteHandle(id)
|
||||
}
|
||||
},
|
||||
deleteHandle(id) {
|
||||
var ids = id ? [id] : []
|
||||
|
||||
this.$confirm(`${i18n.t('prompt.info', { handle: id ? i18n.t('delete').toLowerCase() : i18n.t('deleteBatch').toLowerCase() })}`, i18n.t('prompt.title'), {
|
||||
confirmButtonText: i18n.t('confirm'),
|
||||
cancelButtonText: i18n.t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(this.url),
|
||||
method: 'delete',
|
||||
data: this.$http.adornData(ids, false, 'raw')
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: i18n.t('prompt.success'),
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.getDataList()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.error(data.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
handleCloseAttrForm() {
|
||||
this.showAddAttr = false
|
||||
this.initAttrForm()
|
||||
},
|
||||
|
||||
handleSaveAttrForm() {
|
||||
this.$refs['AttrForm'].validate(valid => {
|
||||
if (valid) {
|
||||
this.$http({
|
||||
// url: this.$http.adornUrl(`${this.url}/${!this.AttrForm.id ? '' : this.AttrForm.id}`),
|
||||
url: this.$http.adornUrl(this.url),
|
||||
method: this.AttrForm.id ? 'put' : 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data: JSON.stringify({ ...this.AttrForm, [this.relatedField]: this.relatedId })
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: i18n.t('prompt.success'),
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.showAddAttr = false
|
||||
this.getDataList()
|
||||
this.initAttrForm()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.error(data.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val
|
||||
this.pageIndex = 1
|
||||
this.getDataList()
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val
|
||||
this.getDataList()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.attr-form >>> .el-form .el-form-item__label {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
594
src/components/base-dialog/addOrUpdate/index.vue
Normal file
@@ -0,0 +1,594 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="super-flexible-dialog"
|
||||
:title="isDetail ? title.detail : !dataForm.id ? title.add : title.edit"
|
||||
:visible.sync="visible"
|
||||
@close="handleClose"
|
||||
:distory-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div style="max-height: 60vh; overflow-y: scroll; overflow-x: hidden;">
|
||||
<el-form ref="dataForm" :model="dataForm" :rules="dataFormRules">
|
||||
<!-- 如果需要更精细一点的布局,可以根据配置项实现地再复杂一点,但此处暂时全部采用一行两列布局 -->
|
||||
<el-row v-for="n in rows" :key="n" :gutter="20">
|
||||
<el-col v-for="c in COLUMN_PER_ROW" :key="`${n}+'col'+${c}`" :span="getSpan(n, c)">
|
||||
<!-- <el-col v-for="c in COLUMN_PER_ROW" :key="`${n}+'col'+${c}`" :span="24 / COLUMN_PER_ROW"> -->
|
||||
<!-- :class="{ 'hidden-input': configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].hidden }" -->
|
||||
<el-form-item
|
||||
v-if="configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)]"
|
||||
:prop="configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name"
|
||||
:key="`${n}-col-${c}-item`"
|
||||
:label="getLabel(n, c)"
|
||||
>
|
||||
<!-- 暂时先不实现部分输入方式 -->
|
||||
<el-input
|
||||
v-if="getType(n, c) === 'input'"
|
||||
:placeholder="getPlaceholder(n, c)"
|
||||
v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"
|
||||
clearable
|
||||
:disabled="isDetail"
|
||||
/>
|
||||
<el-radio v-if="getType(n, c) === 'radio'" v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]" :disabled="isDetail" />
|
||||
<el-checkbox v-if="getType(n, c) === 'check'" v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]" :disabled="isDetail" />
|
||||
<el-select
|
||||
v-if="getType(n, c) === 'select'"
|
||||
:placeholder="getPlaceholder(n, c)"
|
||||
v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"
|
||||
clearable
|
||||
:disabled="isDetail"
|
||||
@change="emitSelectChange(configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name, $event)"
|
||||
>
|
||||
<el-option v-for="opt in configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].options" :key="opt.label + Math.random()" :label="opt.label" :value="opt.value" />
|
||||
</el-select>
|
||||
<el-switch v-if="getType(n, c) === 'switch'" v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]" :disabled="isDetail" />
|
||||
<el-cascader
|
||||
v-if="getType(n, c) === 'cascader'"
|
||||
v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"
|
||||
:options="configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].options"
|
||||
:props="configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].props"
|
||||
:disabled="isDetail"
|
||||
clearable
|
||||
/>
|
||||
<el-time-select v-if="getType(n, c) === 'time'" v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]" :disabled="isDetail" />
|
||||
<el-date-picker
|
||||
v-if="getType(n, c) === 'date'"
|
||||
v-bind="configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].props"
|
||||
:placeholder="getPlaceholder(n, c)"
|
||||
v-model="dataForm[configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)].name]"
|
||||
:disabled="isDetail"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- extra components , like Markdown or RichEdit -->
|
||||
<template v-if="configs.extraComponents && configs.extraComponents.length > 0">
|
||||
<el-form-item v-for="(ec, index) in configs.extraComponents" :key="ec.name + index" :label="ec.label" class="extra-components">
|
||||
<component
|
||||
style="margin-top: 40px;"
|
||||
v-if="ec.hasModel"
|
||||
:is="ec.component"
|
||||
v-bind="ec.props"
|
||||
v-model="dataForm[ec.name]"
|
||||
@ready="handleEditorReady"
|
||||
:read-only="isDetail"
|
||||
/>
|
||||
<!-- <component v-if="ec.hasModel" :is="ec.component" v-bind="ec.props" v-model="dataForm[ec.name]" /> -->
|
||||
<component
|
||||
v-else
|
||||
:is="ec.component"
|
||||
v-bind="ec.props"
|
||||
@uploader-update-filelist="handleUploadListUpdate($event, ec.props.extraParams.typeCode)"
|
||||
:uploader-inject-file-list="/*用于设备分流的*/ fileList[ec.props.extraParams.typeCode]"
|
||||
:read-only="isDetail"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
|
||||
<template v-if="dataForm.id && configs.subtable">
|
||||
<attr-form :related-id="dataForm.id" v-bind="configs.subtable" :is-detail="isDetail" />
|
||||
</template>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<template v-for="(operate, index) in configs.operations">
|
||||
<!-- {{ operate.name | btnNameFilter }} -->
|
||||
<el-button
|
||||
v-if="
|
||||
!isDetail &&
|
||||
(operate.showAlways ||
|
||||
(((dataForm.id && operate.showOnEdit) || (!dataForm.id && !operate.showOnEdit)) && (operate.permission ? $hasPermission(operate.permission) : true)))
|
||||
"
|
||||
:key="`operate-${index}`"
|
||||
:type="btnType[operate.name]"
|
||||
@click="handleClick(operate)"
|
||||
>{{ btnName[operate.name] }}</el-button
|
||||
>
|
||||
</template>
|
||||
<el-button v-if="isDetail" @click="handleClick({ name: 'cancel' })">{{ $t('cancel') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CKEditor from 'ckeditor4-vue'
|
||||
import AttrForm from '../AttrForm'
|
||||
import { pick } from 'lodash/object'
|
||||
import { pick as __pick } from '@/utils/filters'
|
||||
import i18n from '@/i18n'
|
||||
// 标题 for i18n
|
||||
const title = {
|
||||
detail: i18n.t('detail'),
|
||||
add: i18n.t('add'),
|
||||
edit: i18n.t('edit')
|
||||
}
|
||||
|
||||
// 或者也可以改造成自定义颜色:
|
||||
const btnType = {
|
||||
save: 'success',
|
||||
update: 'primary',
|
||||
reset: 'text'
|
||||
// cancel: 'text'
|
||||
// add more...
|
||||
}
|
||||
|
||||
const btnName = {
|
||||
// for i18n
|
||||
save: i18n.t('save'),
|
||||
update: i18n.t('update'),
|
||||
reset: i18n.t('reset'),
|
||||
cancel: i18n.t('cancel')
|
||||
// add more...
|
||||
}
|
||||
|
||||
// 每行的列数
|
||||
const COLUMN_PER_ROW = 2
|
||||
|
||||
export default {
|
||||
name: 'AddOrUpdateDialog',
|
||||
components: { AttrForm },
|
||||
props: {
|
||||
configs: {
|
||||
type: Object,
|
||||
default: () => ({}) // 此处省去类型检查,使用者自行注意就好
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
nameFilter: function(name) {
|
||||
if (!name) return null
|
||||
// for i18n
|
||||
const defaultNames = {
|
||||
name: i18n.t('name'),
|
||||
code: i18n.t('code'),
|
||||
remark: i18n.t('remark'),
|
||||
description: i18n.t('desc'),
|
||||
specifications: i18n.t('prod.spec')
|
||||
// add more...
|
||||
}
|
||||
|
||||
return defaultNames[name]
|
||||
}
|
||||
},
|
||||
// provide() {
|
||||
// return {
|
||||
// _df: this.dataForm
|
||||
// }
|
||||
// },
|
||||
data() {
|
||||
return {
|
||||
COLUMN_PER_ROW,
|
||||
title,
|
||||
/** 按钮相关属性 */
|
||||
btnName,
|
||||
btnType,
|
||||
defaultNames: {
|
||||
name: i18n.t('name'),
|
||||
code: i18n.t('code'),
|
||||
remark: i18n.t('remark'),
|
||||
description: i18n.t('desc'),
|
||||
specifications: i18n.t('prod.spec')
|
||||
// add more...
|
||||
},
|
||||
defaultPlaceholders: {}, // 自动根据 defaultNames 计算得来
|
||||
/** 表单相关属性 */
|
||||
visible: false,
|
||||
isEdit: false,
|
||||
isDetail: false,
|
||||
dataForm: {},
|
||||
dataFormRules: {},
|
||||
tempForm: [], // 临时保存自动生成的code,或其他数据
|
||||
shouldWait: null,
|
||||
fileForm: {}, // 文件上传分流用、合并用的表单,根据 typeCode 进行分流,在请求时合并
|
||||
fileList: {} // 文件加载时分流,依据 typeCode
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
rows() {
|
||||
// 本组件只实现了'一行两列'的表单布局
|
||||
return Math.ceil(this.configs.fields.length / COLUMN_PER_ROW)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
/** load lang */
|
||||
// CKEditor.load()
|
||||
// console.log('lang', CKEditor.component.props.config.defaultLanguage = 'en' )
|
||||
},
|
||||
mounted() {
|
||||
/** 计算 defaultPlaceholders */
|
||||
const prefix = i18n.t('hints.input')
|
||||
Object.entries(this.defaultNames).map(([key, value]) => {
|
||||
this.defaultPlaceholders[key] = prefix + value
|
||||
})
|
||||
|
||||
/** 转换 configs.fields 的结构,把纯字符串转为对象 */
|
||||
this.$nextTick(() => {
|
||||
this.configs.fields = this.configs.fields.map(item => {
|
||||
if (typeof item === 'string') {
|
||||
return { name: item }
|
||||
}
|
||||
return item
|
||||
})
|
||||
|
||||
/** 动态设置dataForm字段 */
|
||||
this.configs.fields.forEach(item => {
|
||||
this.$set(this.dataForm, [item.name], '')
|
||||
|
||||
/** select 的默认值设置 */
|
||||
if (item.type === 'select') {
|
||||
const opts = item.options || []
|
||||
const dft = opts.find(item => item.default || false)
|
||||
if (dft) {
|
||||
this.$set(this.dataForm, [item.name], dft.value)
|
||||
}
|
||||
}
|
||||
|
||||
if (item.api) {
|
||||
/** 自动请求并填充 */
|
||||
// or this.shouldWaitPool = []
|
||||
this.shouldWait = this.$http({
|
||||
url: this.$http.adornUrl(item.api),
|
||||
method: 'POST' // 也可以改成动态决定
|
||||
}).then(({ data: res }) => {
|
||||
if (res && res.code === 0) {
|
||||
// this.dataForm[item.name] = res.data // <=== 此处需要对接口
|
||||
this.tempForm.push({ name: item.name, data: res.data })
|
||||
}
|
||||
})
|
||||
} // end if (item.api)
|
||||
|
||||
// 如果有 relatedField,就需要在当前item的数据加载后,刷新 relatedField 的列表
|
||||
if (item.relatedField) {
|
||||
this.$watch(
|
||||
function() {
|
||||
return this.dataForm[item.name]
|
||||
},
|
||||
function(val, old) {
|
||||
if (val && val !== old) {
|
||||
this.$emit('select-change', { name: item.name, id: val })
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
}
|
||||
|
||||
if (item.required) {
|
||||
const requiredRule = {
|
||||
required: true,
|
||||
message: i18n.t('validate.required'),
|
||||
// trigger: 'change'
|
||||
trigger: 'blur'
|
||||
}
|
||||
/** 检查是否已经存在该字段的规则 */
|
||||
const exists = this.dataFormRules[item.name] || null
|
||||
/** 设置验证规则 */
|
||||
if (exists) {
|
||||
const unset = true
|
||||
for (const rule of exists) {
|
||||
if (rule.required) unset = false
|
||||
}
|
||||
if (unset) {
|
||||
exists.push(requiredRule)
|
||||
}
|
||||
} else {
|
||||
/** 不存在已有规则 */
|
||||
this.$set(this.dataFormRules, [item.name], [requiredRule])
|
||||
}
|
||||
} // end if (item.required)
|
||||
|
||||
if (item.rules) {
|
||||
const exists = this.dataFormRules[item.name] || null
|
||||
if (exists) {
|
||||
// 浅拷贝过去
|
||||
exists.push(...item.rules)
|
||||
} else {
|
||||
this.$set(this.dataFormRules, [item.name], [...item.rules])
|
||||
}
|
||||
} // end if (item.rules)
|
||||
})
|
||||
|
||||
/** 计算默认值 */
|
||||
function calDefault(type) {
|
||||
switch (type) {
|
||||
case 'array':
|
||||
return []
|
||||
// more case...
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
/** 检查是否需要额外的组件 */
|
||||
this.configs.extraComponents &&
|
||||
this.configs.extraComponents.forEach(item => {
|
||||
// if (Object.hasOwn(this.dataForm, [item.name])) {
|
||||
if (this.dataForm.hasOwnProperty(item.name)) {
|
||||
return
|
||||
} else {
|
||||
this.$set(this.dataForm, [item.name], calDefault(item.fieldType))
|
||||
}
|
||||
})
|
||||
|
||||
/** 单独设置 id */
|
||||
this.$set(this.dataForm, 'id', null)
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getSpan(n, c) {
|
||||
const opt = this.configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)]
|
||||
return opt && opt.span ? opt.span : 24 / COLUMN_PER_ROW
|
||||
},
|
||||
|
||||
getLabel(n, c) {
|
||||
const opt = this.configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)]
|
||||
if (opt) {
|
||||
// if opt is valid
|
||||
return opt.label ? opt.label : this.defaultNames[opt.name]
|
||||
}
|
||||
},
|
||||
|
||||
getPlaceholder(n, c) {
|
||||
if (this.isDetail) {
|
||||
/** 如果是详情,就不展示 提示文本 */
|
||||
return ''
|
||||
}
|
||||
|
||||
const opt = this.configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)]
|
||||
if (opt) {
|
||||
// if opt is valid
|
||||
return opt.placeholder
|
||||
? opt.placeholder
|
||||
: this.defaultPlaceholders[opt.name]
|
||||
? this.defaultPlaceholders[opt.name]
|
||||
: opt.label
|
||||
? (opt.type === 'select' ? i18n.t('choose') : i18n.t('hints.input')) + opt.label
|
||||
: null
|
||||
|
||||
// : opt.type === 'select'
|
||||
// ? i18n.t('choose')
|
||||
// : '请输入'
|
||||
}
|
||||
},
|
||||
|
||||
getType(n, c) {
|
||||
const opt = this.configs.fields[(n - 1) * COLUMN_PER_ROW + (c - 1)]
|
||||
if (opt) {
|
||||
if (!opt.type || ['input', 'number' /** add more.. */].includes(opt.type)) {
|
||||
return 'input'
|
||||
} else if (['select' /** add more.. */].includes(opt.type)) {
|
||||
return 'select'
|
||||
} else if (['cascader'].includes(opt.type)) {
|
||||
return 'cascader'
|
||||
} else if (['date'].includes(opt.type)) {
|
||||
return 'date'
|
||||
}
|
||||
// add more...
|
||||
} else {
|
||||
return 'input'
|
||||
}
|
||||
},
|
||||
|
||||
init(id, isdetail = false) {
|
||||
this.isDetail = isdetail
|
||||
this.visible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].resetFields()
|
||||
this.dataForm.id = id || null
|
||||
if (this.dataForm.id) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`${this.configs.infoUrl}/${this.dataForm.id}`),
|
||||
method: 'get'
|
||||
}).then(({ data: res }) => {
|
||||
if (res && res.code === 0) {
|
||||
const dataFormKeys = Object.keys(this.dataForm)
|
||||
console.log('keys ===> ', dataFormKeys)
|
||||
// console.log('data form keys: ', dataFormKeys, pick(res.data, dataFormKeys))
|
||||
this.dataForm = __pick(res.data, dataFormKeys)
|
||||
console.log('pick(res.data, dataFormKeys) ===> ', __pick(res.data, dataFormKeys))
|
||||
// LABEL: FILE_RELATED
|
||||
/** 对文件下载进行分流 */
|
||||
this.fileList = {}
|
||||
if (this.dataForm.files) {
|
||||
// console.log('files: ', this.dataForm.files)
|
||||
this.dataForm.files.forEach(file => {
|
||||
// const fileName = file.fileUrl.split('/').pop()
|
||||
/** [1] 处理 fileList */
|
||||
// if (Object.hasOwn(this.fileList, file.typeCode)) {
|
||||
if (this.fileList.hasOwnProperty(file.typeCode)) {
|
||||
/** 已存在 */
|
||||
// this.fileList[file.typeCode].push({ id: file.id, name: fileName, typeCode: file.typeCode })
|
||||
this.fileList[file.typeCode].push(file)
|
||||
} else {
|
||||
// this.fileList[file.typeCode] = [{ id: file.id, name: fileName, typeCode: file.typeCode }]
|
||||
this.fileList[file.typeCode] = [file]
|
||||
}
|
||||
|
||||
/** [2] 处理 fileForm */
|
||||
// if (Object.hasOwn(this.fileForm, file.typeCode)) {
|
||||
if (this.fileForm.hasOwnProperty(file.typeCode)) {
|
||||
this.fileForm[file.typeCode].push(file.id)
|
||||
} else {
|
||||
this.fileForm[file.typeCode] = [file.id]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
/** 如果不是编辑,就填充自动生成的数据 */
|
||||
if (this.shouldWait)
|
||||
this.shouldWait.then(() => {
|
||||
if (this.tempForm.length) {
|
||||
// console.log('create new, tempform', JSON.stringify(this.tempForm.length))
|
||||
this.tempForm.forEach(item => {
|
||||
// console.log('item data', item.data)
|
||||
this.dataForm[item.name] = item.data
|
||||
})
|
||||
// console.log('create new, dataform', JSON.stringify(this.dataForm))
|
||||
}
|
||||
this.shouldWait = null
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
emitSelectChange(name, id) {
|
||||
const currentField = this.configs.fields.find(item => item.name === name)
|
||||
if (currentField.relatedField) {
|
||||
this.dataForm[currentField.relatedField] = null
|
||||
}
|
||||
this.$emit('select-change', { name, id })
|
||||
},
|
||||
|
||||
handleEditorReady(val) {},
|
||||
|
||||
handleClick(btn) {
|
||||
/** 提取url */
|
||||
const urls = {}
|
||||
this.configs.operations.map(item => {
|
||||
urls[item.name] = {}
|
||||
urls[item.name].url = item.url
|
||||
urls[item.name].extraFields = item.extraFields || {}
|
||||
})
|
||||
/** 操作 */
|
||||
switch (btn.name) {
|
||||
case 'save':
|
||||
case 'update':
|
||||
/** 需要验证表单的操作 */
|
||||
this.$refs['dataForm'].validate(valid => {
|
||||
if (valid) {
|
||||
/** 对于文件上传的单独处理(合并处理) */
|
||||
if (Object.keys(this.fileForm).length) {
|
||||
// LABEL: FILE_RELATED
|
||||
let fileIds = []
|
||||
for (const [key, item] of Object.entries(this.fileForm)) {
|
||||
if (Array.isArray(item)) {
|
||||
fileIds = fileIds.concat(item)
|
||||
} else {
|
||||
console.error('handleClick(): 上传文件数组类型不正确')
|
||||
}
|
||||
}
|
||||
this.$set(this.dataForm, 'fileIds', fileIds)
|
||||
}
|
||||
|
||||
// console.log('before send: ', this.dataForm)
|
||||
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(urls[btn.name].url),
|
||||
method: btn.name === 'save' ? 'POST' : 'PUT',
|
||||
data: { ...this.dataForm, ...urls[btn.name].extraFields }
|
||||
})
|
||||
.then(({ data: res }) => {
|
||||
if (res && res.code === 0) {
|
||||
this.$message({
|
||||
message: i18n.t('prompt.success'),
|
||||
// message: btn.name === 'save' ? i18n.t('prompt.success') : '更新成功!',
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.$emit('refreshDataList')
|
||||
this.visible = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message({
|
||||
message: err,
|
||||
type: 'error',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
return
|
||||
case 'reset':
|
||||
for (const key of Object.keys(this.dataForm)) {
|
||||
if (typeof this.dataForm[key] === 'string') {
|
||||
this.dataForm[key] = ''
|
||||
} else if (this.dataForm[key] instanceof Array) {
|
||||
this.dataForm[key].splice(0)
|
||||
} else {
|
||||
this.dataForm[key] = null
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'cancel':
|
||||
this.handleClose()
|
||||
// add more..
|
||||
}
|
||||
},
|
||||
|
||||
// LABEL: FILE_RELATED
|
||||
handleUploadListUpdate(filelist, typeCode = 'DefaultTypeCode') {
|
||||
// console.log('before handleUploadListUpdate(): ', JSON.parse(JSON.stringify(this.fileForm)))
|
||||
// 设备类型 typeCode: EquipmentTypeFile
|
||||
// 设备信息 typeCode: EquipmentInfoFile | EquipmentInfoImage
|
||||
|
||||
// 原先写法:直接更新 dataForm 对象,不适用于有多个上传组件的需求
|
||||
// this.$set(
|
||||
// this.dataForm,
|
||||
// 'fileIds',
|
||||
// filelist.map(item => item.id)
|
||||
// )
|
||||
// console.log('handleUploadListUpdate(): ', this.dataForm)
|
||||
// 现更改为分流写法
|
||||
this.$set(
|
||||
this.fileForm,
|
||||
typeCode,
|
||||
filelist.map(item => item.id)
|
||||
)
|
||||
// console.log('after handleUploadListUpdate(): ', this.fileForm)
|
||||
},
|
||||
|
||||
handleClose() {
|
||||
this.$emit('destory-dialog')
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.super-flexible-dialog >>> .el-select,
|
||||
.super-flexible-dialog >>> .el-cascader {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.super-flexible-dialog >>> ::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.super-flexible-dialog >>> ::-webkit-scrollbar-thumb {
|
||||
width: 4px;
|
||||
border-radius: 4px;
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
.super-flexible-dialog >>> .hidden-input {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
11
src/components/base-table/components/cell-container.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div class="cell-container">
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
30
src/components/base-table/components/detailComponent.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import i18n from '@/i18n'
|
||||
|
||||
export default {
|
||||
name: 'TableTextComponent',
|
||||
props: {
|
||||
injectData: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// for i18n inject:
|
||||
defaultText: i18n.t('viewdetail')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
emitClick() {
|
||||
// console.log('inject data:' ,this.injectData)
|
||||
this.$emit('emit-data', {
|
||||
type: this.injectData.head?.actionName || 'view-detail-action',
|
||||
data: this.injectData.head?.emitFullData ? this.injectData : this.injectData.id
|
||||
})
|
||||
}
|
||||
},
|
||||
render: function (h) {
|
||||
// console.log('button content:', this.injectData)
|
||||
return h('span', null, [h('el-button', { props: { type: 'text' }, style: { paddingLeft: 0 }, on: { click: this.emitClick } }, this.injectData.head?.buttonContent || this.defaultText)])
|
||||
}
|
||||
}
|
||||
64
src/components/base-table/components/operationComponent.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import i18n from '@/i18n'
|
||||
|
||||
export default {
|
||||
name: 'TableOperations',
|
||||
props: {
|
||||
injectData: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
btnTypes: {
|
||||
add: 'primary',
|
||||
delete: 'danger',
|
||||
detail: 'info'
|
||||
// add more...
|
||||
},
|
||||
colors: {
|
||||
delete: '#FF5454',
|
||||
preview: '#f09843',
|
||||
design: '#99089f',
|
||||
// 'view-trend': 'red'
|
||||
// add more...
|
||||
},
|
||||
text: {
|
||||
// TODO: i18n
|
||||
edit: i18n.t('edit'),
|
||||
detail: i18n.t('detail'),
|
||||
delete: i18n.t('delete'),
|
||||
viewAttr: i18n.t('viewattr'),
|
||||
preview: i18n.t('preview'),
|
||||
design: i18n.t('design'),
|
||||
'view-trend': '查看趋势'
|
||||
// add more...
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 发射事件
|
||||
emit(opt) {
|
||||
let emitFull = false
|
||||
let eventType = 'default'
|
||||
let customField
|
||||
if (typeof opt === 'object') {
|
||||
eventType = opt.name
|
||||
customField = opt.emitField || 'id'
|
||||
emitFull = opt.emitFull || false
|
||||
} else {
|
||||
eventType = opt
|
||||
}
|
||||
this.$emit('emit-data', { type: eventType, data: emitFull ? this.injectData : customField ? this.injectData[customField] : this.injectData.id })
|
||||
}
|
||||
},
|
||||
render: function (h) {
|
||||
let btns = []
|
||||
for (const optionStr of this.injectData.head?.options) {
|
||||
const optObj = typeof optionStr === 'object'
|
||||
// btns.push(h('el-button', { props: { type: this.btnTypes[optionStr] } }, optionStr))
|
||||
btns.push(h('el-button', { props: { type: 'text' }, style: { color: optObj ? this.colors[optionStr.name] : this.colors[optionStr] || '#409EFF' }, on: { click: this.emit.bind(null, optionStr) } }, typeof optionStr === 'object' ? this.text[optionStr.name] : this.text[optionStr]))
|
||||
}
|
||||
return h('span', null, btns)
|
||||
}
|
||||
}
|
||||
40
src/components/base-table/components/table-head.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<el-table-column
|
||||
:label="opt.label ? opt.label : opt.name"
|
||||
:prop="opt.prop || null"
|
||||
:width="opt.width || null"
|
||||
:min-width="opt.minWidth || null"
|
||||
:fixed="opt.fixed || null"
|
||||
:show-overflow-tooltip="opt.showOverflowTooltip || false"
|
||||
filter-placement="top"
|
||||
:align="opt.align || null"
|
||||
v-bind="opt.more"
|
||||
>
|
||||
<template v-if="opt.prop" slot-scope="scope">
|
||||
<component v-if="opt.subcomponent" :is="opt.subcomponent" :key="idx + 'sub'" :inject-data="{ ...scope.row, head: opt }" @emit-data="handleSubEmitData" />
|
||||
<!-- 直接展示数据或应用过滤器 -->
|
||||
<span v-else>{{ scope.row[opt.prop] | commonFilter(opt.filter) }}</span>
|
||||
</template>
|
||||
<!-- 递归 -->
|
||||
<template v-if="!opt.prop && opt.children">
|
||||
<TableHead v-for="(subhead, index) in opt.children" :key="'subhead' + index" :opt="subhead" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TableHead',
|
||||
filters: {
|
||||
commonFilter: (source, filterType = a => a) => {
|
||||
return filterType(source)
|
||||
}
|
||||
},
|
||||
props: {
|
||||
opt: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
215
src/components/base-table/index.vue
Normal file
@@ -0,0 +1,215 @@
|
||||
<template>
|
||||
<div class="base-table">
|
||||
<!-- 花式新增按钮 -->
|
||||
<div class="setting">
|
||||
<template v-if="topBtnConfig.length > 0">
|
||||
<!-- table顶部操作按钮区 -->
|
||||
<div class="action_btn">
|
||||
<template v-for="(btn, index) in topBtnConfig">
|
||||
<span v-if="btn.type === 'add'" :key="index" style="display: inline-block" @click="clickTopButton(btn.type)">
|
||||
<svg-icon style="width: 14px; height: 14px" class="iconPlus" icon-class="addPage" />
|
||||
<span class="add">{{ $t('add') }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 设置小齿轮table列的图标 -->
|
||||
<el-popover placement="bottom-start" width="200" trigger="click">
|
||||
<div class="setting-box">
|
||||
<el-checkbox v-for="(item, index) in tableHeadConfigs" :key="'cb' + index" v-model="selectedBox[index]" :label="item.name" />
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-s-tools" style="color: #0b58ff" />
|
||||
</el-popover>
|
||||
</div>
|
||||
<!-- border 属性增加边框:header-cell-style="{background:'#FAFAFA',color:'#606266',height: '40px'}" -->
|
||||
<!-- <el-table :data="data" -->
|
||||
<el-table
|
||||
:data="renderData"
|
||||
style="width: 100%"
|
||||
fit
|
||||
highlight-current-row
|
||||
:header-cell-style="{ background: '#FAFAFA', color: '#000', height: '40px' }"
|
||||
:max-height="maxHeight"
|
||||
:span-method="spanMethod || null"
|
||||
:row-style="{ height: '20px' }"
|
||||
:cell-style="{ padding: '0px' }">
|
||||
<!-- 表格头定义 -->
|
||||
<!-- in tableHeadConfigs -->
|
||||
<template v-for="(head, idx) in renderTableHeadList">
|
||||
<!-- 带type的表头 -->
|
||||
<el-table-column
|
||||
:key="idx"
|
||||
v-if="head.type"
|
||||
:type="head.type"
|
||||
:label="head.label || head.name || ''"
|
||||
:header-align="head.align || 'center'"
|
||||
:align="head.align || 'center'"
|
||||
:width="head.width || 50"
|
||||
:index="
|
||||
head.type === 'index'
|
||||
? (val) => {
|
||||
return val + 1 + (page - 1) * size
|
||||
}
|
||||
: null
|
||||
"
|
||||
v-bind="head.more"></el-table-column>
|
||||
<!-- 普通的表头 -->
|
||||
<el-table-column
|
||||
v-else
|
||||
:key="idx + 'else'"
|
||||
:label="head.label ? head.label : head.name"
|
||||
:prop="head.prop || null"
|
||||
:width="head.width || null"
|
||||
:min-width="head.minWidth || null"
|
||||
:fixed="head.fixed || null"
|
||||
:show-overflow-tooltip="head.showOverflowTooltip || true"
|
||||
:tooltip-effect="head.tooltipEffect || 'light'"
|
||||
filter-placement="top"
|
||||
:align="head.align || null"
|
||||
v-bind="head.more">
|
||||
<!-- 子组件 编辑/删除 -->
|
||||
<template v-if="head.prop" slot-scope="scope">
|
||||
<component v-if="head.subcomponent" :is="head.subcomponent" :key="idx + 'sub'" :inject-data="{ ...scope.row, head }" @emit-data="handleSubEmitData" />
|
||||
<!-- 直接展示数据或应用过滤器 -->
|
||||
<span v-else>{{ scope.row[head.prop] | commonFilter(head.filter) }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 多级表头 -->
|
||||
<template v-if="!head.prop && head.children">
|
||||
<TableHead v-for="(subhead, subindex) in head.children" :key="'subhead-' + idx + '-subindex-' + subindex" :opt="subhead" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isObject, isString } from 'lodash'
|
||||
import TableHead from './components/table-head.vue'
|
||||
export default {
|
||||
name: 'BaseTable',
|
||||
filters: {
|
||||
commonFilter: (source, filterType = (a) => a) => {
|
||||
return filterType(source)
|
||||
}
|
||||
},
|
||||
props: {
|
||||
tableHeadConfigs: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
// required: true,
|
||||
// validator: val => val.filter(item => !isString(item.prop) || !isString(item.name)).length === 0
|
||||
},
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
maxHeight: {
|
||||
type: Number,
|
||||
// default: window.innerHeight - 325
|
||||
default: 500
|
||||
},
|
||||
spanMethod: {
|
||||
type: Function,
|
||||
default: () => {
|
||||
;() => [0, 0]
|
||||
},
|
||||
required: false
|
||||
},
|
||||
page: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
// 新增的props
|
||||
// tableConfig: {
|
||||
// type: Array,
|
||||
// required: true,
|
||||
// validator: (val) => val.filter((item) => !isString(item.prop) || !isString(item.label)).length === 0
|
||||
// },
|
||||
topBtnConfig: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
commonFilter: (source, filterType = (a) => a) => {
|
||||
return filterType(source)
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedBox: new Array(100).fill(true)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
renderData() {
|
||||
return this.data.map((item, index) => {
|
||||
return {
|
||||
...item,
|
||||
_pageIndex: (this.page - 1) * this.limit + index + 1
|
||||
}
|
||||
})
|
||||
},
|
||||
renderTableHeadList() {
|
||||
return this.tableHeadConfigs.filter((item, index) => {
|
||||
return this.selectedBox[index]
|
||||
})
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
this.selectedBox = new Array(100).fill(true)
|
||||
if (this.highIndex) {
|
||||
this.tableRowIndex = 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// console.log(this.selectedBox)
|
||||
console.log(this.tableHeadConfigs)
|
||||
},
|
||||
methods: {
|
||||
handleSubEmitData(payload) {
|
||||
this.$emit('operate-event', payload)
|
||||
},
|
||||
clickTopButton(val) {
|
||||
this.$emit('clickTopBtn', val)
|
||||
}
|
||||
},
|
||||
components: { TableHead }
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.setting {
|
||||
text-align: right;
|
||||
padding: 0px 15px 7px;
|
||||
.action_btn {
|
||||
display: inline-block;
|
||||
margin-right: 15px;
|
||||
font-size: 14px;
|
||||
.add {
|
||||
color: #0b58ff;
|
||||
}
|
||||
}
|
||||
.setting-box {
|
||||
width: 100px;
|
||||
}
|
||||
i {
|
||||
color: #aaa;
|
||||
}
|
||||
}
|
||||
.el-table .success-row {
|
||||
background: #eaf1fc;
|
||||
}
|
||||
.iconPlus {
|
||||
color: #0b58ff;
|
||||
margin-right: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
213
src/components/base-upload/index.vue
Normal file
@@ -0,0 +1,213 @@
|
||||
<template>
|
||||
<div class="base-upload" style="border-radius: 8px; margin-top: 48px; padding: 0; max-height: 500px;">
|
||||
<el-upload
|
||||
class="yd-upload"
|
||||
action="#"
|
||||
:http-request="handleUpload"
|
||||
multiple
|
||||
:file-list="fileList"
|
||||
:on-preview="handleDownload"
|
||||
:on-remove="handleRemove"
|
||||
:before-upload="/.*?image.*?/i.test(extraParams.typeCode) ? validateImage : validateFile"
|
||||
>
|
||||
<!-- :before-remove="beforeRemove" -->
|
||||
<!-- accept="image/*" -->
|
||||
<!-- <el-upload class="yd-upload" :action="$http.adornUrl(url)" multiple name="files" :data="extraParams" :file-list="fileList" :on-remove="handleRemove" :before-remove="beforeRemove"> -->
|
||||
<el-button :disabled="readOnly" type="primary">{{ buttonContent }}</el-button>
|
||||
<div v-if="tip" slot="tip" class="el-upload__tip">{{ tip }}</div>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pick } from 'lodash/object'
|
||||
|
||||
export default {
|
||||
name: 'BaseUpload',
|
||||
props: {
|
||||
url: String,
|
||||
buttonContent: String,
|
||||
tip: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
extraParams: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
uploaderInjectFileList: {
|
||||
// 从外部传进来 fileList,用于展示文件列表用
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
readOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
// inject: {
|
||||
// parentDataForm: "_df"
|
||||
// },
|
||||
data() {
|
||||
return {
|
||||
fileList: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.fileList.splice(0)
|
||||
|
||||
this.$watch('uploaderInjectFileList', function(val) {
|
||||
if (val && val.length) {
|
||||
// console.log('this.uploaderInjectFileList', this.uploaderInjectFileList)
|
||||
/** uploaderInjectFileList 里关于文件的信息比较全,需要手动过滤一下 */
|
||||
this.fileList = val.map(item => {
|
||||
const name = item.fileUrl.split('/').pop()
|
||||
return { ...pick(item, ['id', 'fileName', 'typeCode']), name }
|
||||
})
|
||||
}
|
||||
// console.log('fillist: ', this.fileList)
|
||||
})
|
||||
|
||||
// if (this.parentDataForm) {
|
||||
// console.log('parent dataform: ', this.parentDataForm)
|
||||
// }
|
||||
},
|
||||
methods: {
|
||||
/** 自定义上传行为 */
|
||||
handleUpload(file) {
|
||||
const formData = new FormData()
|
||||
let files = file.file
|
||||
formData.append('files', files)
|
||||
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(this.url),
|
||||
method: 'POST',
|
||||
data: formData,
|
||||
params: {
|
||||
typeCode: this.extraParams.typeCode
|
||||
}
|
||||
}).then(({ data: res }) => {
|
||||
if (res && res.code === 0) {
|
||||
res.data.forEach(item => {
|
||||
const ext = item.fileUrl.split('.').reverse()[0]
|
||||
const name = `${item.fileName}.${ext}`
|
||||
this.fileList.push({ ...pick(item, ['id', 'fileName', 'typeCode']), name })
|
||||
})
|
||||
// TODO: 在新增和更新阶段,带入 fileIds[] 数组给后端,就可完成文件和设备类型的绑定、删除操作
|
||||
this.$emit('uploader-update-filelist', this.fileList)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/** 大小验证,由配置文件开启 */
|
||||
validateFile(file) {
|
||||
const isRightSize = file.size / 1024 / 1024 < 2
|
||||
if (!isRightSize) {
|
||||
// this.$message.error(this.$t('upload.picSizeAlarm'))
|
||||
this.$message.error('文件不应超过 2MB')
|
||||
}
|
||||
return isRightSize
|
||||
},
|
||||
|
||||
/** 图片验证,由配置文件开启 */
|
||||
validateImage(file) {
|
||||
// console.log('[*] 验证图片')
|
||||
|
||||
const isRightSize = file.size / 1024 / 1024 < 2
|
||||
if (!isRightSize) {
|
||||
this.$message.error('文件不应超过 2MB')
|
||||
// this.$message.error(this.$t('upload.picSizeAlarm'))
|
||||
}
|
||||
|
||||
const isAccept = new RegExp('image/*').test(file.type)
|
||||
if (!isAccept) {
|
||||
// this.$message.error(this.$t('upload.picAlarm'))
|
||||
this.$message.error('只允许上传图片')
|
||||
}
|
||||
return isRightSize && isAccept
|
||||
},
|
||||
|
||||
/** 点击下载 */
|
||||
handleDownload({ id: fileId, name: fileName }) {
|
||||
const type = {
|
||||
download: 1,
|
||||
preview: 0
|
||||
}
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/attachment/downloadFile'),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams({
|
||||
attachmentId: fileId,
|
||||
type: type.download
|
||||
// fileName,
|
||||
// outputQuality,
|
||||
// scale
|
||||
}),
|
||||
responseType: 'blob'
|
||||
}).then(({ data: res }) => {
|
||||
const blob = new Blob([res])
|
||||
// console.log('blob', blob)
|
||||
if ('download' in document.createElement('a')) {
|
||||
const alink = document.createElement('a')
|
||||
// console.log('filename: ', fileName)
|
||||
alink.download = fileName
|
||||
alink.style.display = 'none'
|
||||
alink.target = '_blank'
|
||||
alink.href = URL.createObjectURL(blob)
|
||||
document.body.appendChild(alink)
|
||||
alink.click()
|
||||
URL.revokeObjectURL(alink.href)
|
||||
document.body.removeChild(alink)
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// beforeRemove(file, filelist) {
|
||||
// return this.$confirm(`确定移除 ${file.name}?`)
|
||||
// },
|
||||
|
||||
handleRemove(file, filelist) {
|
||||
// 把更新后的 fileList 传递出去
|
||||
this.$emit('uploader-update-filelist', filelist)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.base-upload >>> .yd-upload {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* .base-upload >>> .el-button {
|
||||
display: block;
|
||||
width: 200px;
|
||||
position: relative;
|
||||
left: -50px;
|
||||
} */
|
||||
|
||||
/* .base-upload >>> .el-upload--text {
|
||||
width: 100px;
|
||||
position: relative;
|
||||
left: -100px;
|
||||
} */
|
||||
|
||||
.base-upload >>> .el-upload__tip {
|
||||
margin-top: 0;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.base-upload {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.yd-upload {
|
||||
/* background-color: #efefef; */
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
</style>
|
||||
@@ -76,7 +76,7 @@ export default {
|
||||
return data.name.indexOf(value) !== -1
|
||||
},
|
||||
getDeptList (id) {
|
||||
return this.$http.get('/sys/dept/list').then(({ data: res }) => {
|
||||
return this.$http.get(this.$http.adornUrl('/sys/dept/list')).then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ export default {
|
||||
return data.name.indexOf(value) !== -1
|
||||
},
|
||||
getDataList (id) {
|
||||
return this.$http.get('/sys/region/tree').then(({ data: res }) => {
|
||||
return this.$http.get(this.$http.adornUrl('/sys/region/tree')).then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
|
||||
68
src/components/small-title/index.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<!--
|
||||
* @Author: lb
|
||||
* @Date: 2022-05-18 16:00:00
|
||||
* @LastEditors: lb
|
||||
* @LastEditTime: 2022-05-18 16:00:00
|
||||
* @Description:
|
||||
-->
|
||||
<template>
|
||||
<div :class="[className, { 'p-0': noPadding }]">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
size: {
|
||||
// 取值范围: xl lg md sm
|
||||
type: String,
|
||||
default: 'de',
|
||||
validator: function(val) {
|
||||
return ['xl', 'lg', 'de', 'md', 'sm'].indexOf(val) !== -1
|
||||
}
|
||||
},
|
||||
noPadding: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
className: function() {
|
||||
return `${this.size}-title`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$pxls: (xl, 28px) (lg, 24px) (de, 22px) (md, 18px) (sm, 16px);
|
||||
$mgr: 6px;
|
||||
@each $size, $height in $pxls {
|
||||
.#{$size}-title {
|
||||
padding: 8px 0;
|
||||
font-size: $height;
|
||||
line-height: $height;
|
||||
color: #000;
|
||||
font-weight: 500;
|
||||
// font-family: '微软雅黑', 'Microsoft YaHei', Arial, Helvetica, sans-serif;
|
||||
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 4px;
|
||||
height: $height + 2px;
|
||||
border-radius: 1px;
|
||||
margin-right: $mgr;
|
||||
// background-color: #0b58ff;
|
||||
background-color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.p-0 {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -16,7 +16,9 @@ $--color-transition-base: color .2s cubic-bezier(.645,.045,.355,1) !default;
|
||||
/* Color
|
||||
-------------------------- */
|
||||
/// color|1|Brand Color|0
|
||||
$--color-primary: #409EFF !default;
|
||||
// $--color-primary: #409EFF !default;
|
||||
// 左上标题背景颜色
|
||||
$--color-primary: #001529 !default;
|
||||
/// color|1|Background Color|4
|
||||
$--color-white: #FFFFFF !default;
|
||||
/// color|1|Background Color|4
|
||||
@@ -50,6 +52,7 @@ $--color-danger-lighter: mix($--color-white, $--color-danger, 90%) !default;
|
||||
$--color-info-lighter: mix($--color-white, $--color-info, 90%) !default;
|
||||
/// color|1|Font Color|2
|
||||
$--color-text-primary: #303133 !default;
|
||||
$--color-text-home: #fff !default;
|
||||
/// color|1|Font Color|2
|
||||
$--color-text-regular: #606266 !default;
|
||||
/// color|1|Font Color|2
|
||||
|
||||
624
src/i18n/en.js
Normal file
@@ -0,0 +1,624 @@
|
||||
const t = {}
|
||||
|
||||
t.loading = 'Loading...'
|
||||
t.createTime = 'Create Time'
|
||||
|
||||
t.brand = {}
|
||||
t.brand.lg = 'SCADA Platform'
|
||||
t.brand.mini = 'SCADA'
|
||||
|
||||
t.routes = {}
|
||||
t.routes['产品池'] = 'Products Pool'
|
||||
t.routes['基本资料'] = 'Basic Data'
|
||||
t.routes['设备数采'] = 'Equipment PLC'
|
||||
t.routes['厂务管理'] = 'Factory Management'
|
||||
t.routes['报表管理'] = 'Report Management'
|
||||
t.routes['质量管理'] = 'Quality Management'
|
||||
t.routes['权限管理'] = 'Permission Management'
|
||||
t.routes['系统设置'] = 'System Settings'
|
||||
t.routes['日志管理'] = 'Log Management'
|
||||
t.routes['数据分析'] = 'Data Analysis'
|
||||
|
||||
// 二级
|
||||
t.routes['厂务'] = 'Factory Affair'
|
||||
t.routes['设备'] = 'Equipment'
|
||||
t.routes['字典管理'] = 'Dict Management'
|
||||
t.routes['PLC信息'] = 'PLC'
|
||||
t.routes['设备与PLC关联配置'] = 'Relations between plc & equipments'
|
||||
t.routes['设备生产实时数据'] = 'Realtime Equipment Data'
|
||||
t.routes['产线生产实时数据'] = 'Realtime Productline Data'
|
||||
t.routes['质量检查实时数据'] = 'Realtime Quality Inspection Data'
|
||||
t.routes['报表总览'] = 'Report Overview'
|
||||
t.routes['报表分类'] = 'Report Types'
|
||||
t.routes['报表详情'] = 'Report Detail'
|
||||
t.routes['报表设计'] = 'Report Design'
|
||||
t.routes['报表预览'] = 'Report Preview'
|
||||
t.routes['质量检测基础数据'] = 'Quality Inspection Basic Data'
|
||||
t.routes['当前检测数据'] = 'Current Inspection Data'
|
||||
t.routes['检测统计数据'] = 'Statistics Data'
|
||||
t.routes['质量检查信息记录'] = 'Quality Inspection Records'
|
||||
t.routes['用户管理'] = 'User Management'
|
||||
t.routes['部门管理'] = 'Department Management'
|
||||
t.routes['角色管理'] = 'Role Management'
|
||||
t.routes['菜单管理'] = 'Menu Management'
|
||||
t.routes['参数管理'] = 'Params Management'
|
||||
t.routes['定时任务'] = 'Timed Tasks'
|
||||
t.routes['文件上传'] = 'File Upload'
|
||||
t.routes['登录日志'] = 'Login Records'
|
||||
t.routes['操作日志'] = 'Oprations Records'
|
||||
t.routes['设备效率分析'] = 'Equipment Efficiency Analysis'
|
||||
t.routes['设备异常分析'] = 'Equipment Exceptions Analysis'
|
||||
t.routes['设备状态时序图'] = 'Equipment Status Timesequence'
|
||||
|
||||
// 三级
|
||||
t.routes['工厂'] = 'Factory'
|
||||
t.routes['产线'] = 'Product Lines'
|
||||
t.routes['工段'] = 'Work Sections'
|
||||
t.routes['设备类型'] = 'Equipment Types'
|
||||
t.routes['设备分组'] = 'Equipment Groups'
|
||||
t.routes['设备信息'] = 'Equipment Details'
|
||||
t.routes['设备参数状态监控'] = 'Current Equipment State'
|
||||
t.routes['设备分组报警信息'] = 'Equipment Group Alarm'
|
||||
t.routes['设备历史参数'] = 'Equipment Historical Parameters'
|
||||
t.routes['质量检测类型'] = 'Quality Inpection Types'
|
||||
t.routes['质量检测信息'] = 'Quality Inpection Details'
|
||||
t.routes['安灯检测盒'] = 'Andeng inspection box'
|
||||
|
||||
|
||||
t.andeng = {}
|
||||
t.andeng.inspectContent = 'Inspection Content'
|
||||
t.andeng.btnVal = 'Button Value'
|
||||
t.andeng.btnBoxModel = 'Button Box Model'
|
||||
|
||||
|
||||
t.dictValueList = 'View Details'
|
||||
t.save = 'Save'
|
||||
t.add = 'Add'
|
||||
t.delete = 'Delete'
|
||||
t.deleteBatch = 'Delete Batch'
|
||||
t.update = 'Update'
|
||||
t.query = 'Search'
|
||||
t.export = 'Export'
|
||||
t.handle = 'Operations'
|
||||
t.confirm = 'Confirm'
|
||||
t.cancel = 'Cancel'
|
||||
t.clear = 'Clear'
|
||||
t.logout = 'Logout'
|
||||
t.manage = 'Handle'
|
||||
t.createDate = 'Create Date'
|
||||
t.keyword = 'Keyword(s): '
|
||||
t.choose = 'Please Choose '
|
||||
t.remark = 'Remark'
|
||||
t.delMark = 'Delete Mark '
|
||||
t.isvalid = 'is valid'
|
||||
t.available = 'available'
|
||||
t.unavailable = 'unavailable'
|
||||
t.alert = 'alert'
|
||||
t.creator = 'Creator'
|
||||
t.creatorName = 'Creator\'s name'
|
||||
t.updator = 'Updator'
|
||||
t.updatorName = 'Updator\'s name'
|
||||
t.updateTime = 'Update Time'
|
||||
t.version = 'Version'
|
||||
t.search = 'Search'
|
||||
t.countPerPage = '每页数' // ?
|
||||
t.currentPage = '当前页' // ?
|
||||
t.fetchList = '获取数据列表' // ?
|
||||
t.multi = '多选' // ?
|
||||
t.do = '进行' // ?
|
||||
t.submit = '表单提交' // ?
|
||||
t.desc = 'Description'
|
||||
t.disable = 'Disable'
|
||||
t.equipment = 'Equipment'
|
||||
t.enabled = 'Enabled'
|
||||
t.cannotempty = 'can\'t be empty'
|
||||
t.parameter = 'Parameters'
|
||||
t.enable = 'Enable'
|
||||
t.index = 'Index'
|
||||
t.relation = '关联'
|
||||
t.fetchInfo = 'Fetch Info'
|
||||
t.name = 'Name'
|
||||
t.code = 'Code'
|
||||
t.attrName = 'Attribute name'
|
||||
t.attrValue = 'Attribute value'
|
||||
t.unit = 'Unit'
|
||||
t.table = 'Table'
|
||||
t.table2 = 'Table'
|
||||
t.downloadurl = 'Download Url'
|
||||
t.recordTime = 'Record Time'
|
||||
t.notCollect = 'No'
|
||||
t.collect = 'Yes'
|
||||
t.required = 'Required'
|
||||
t.paramUrl = 'Parameter url'
|
||||
t.enname = 'English Name'
|
||||
t.collectOrNot = 'Collect or not'
|
||||
t.min = 'Min Value'
|
||||
t.max = 'Max Value'
|
||||
t.status = 'Status'
|
||||
t.normal = 'Normal'
|
||||
t.addr = 'Address'
|
||||
t.planStop = 'Plan to stop'
|
||||
t.startTime = 'Start Time'
|
||||
t.endTime = 'End Time'
|
||||
t.today = 'Today'
|
||||
|
||||
t.graph = 'Graph'
|
||||
t.category = 'Category'
|
||||
t.categoryName = 'Category Name'
|
||||
t.categoryCode = 'Category Code'
|
||||
t.rate = 'Rate'
|
||||
t.link = 'Link Url'
|
||||
t.refresh = 'Refresh'
|
||||
t.abbr = 'Abbreviation'
|
||||
t.detail = 'Details'
|
||||
t.viewdetail = 'Details'
|
||||
t.viewattr = 'View Attributions'
|
||||
t.edit = 'Edit'
|
||||
t.source = 'Source'
|
||||
t.auto = 'Auto'
|
||||
t.manual = 'Manually'
|
||||
t.loaddone = 'Loaded'
|
||||
t.produceTime = 'Date of manufacture'
|
||||
t.enterTime = 'Enter Time'
|
||||
t.manufacturer = 'Manufacturer'
|
||||
t.success = 'success!'
|
||||
t.all = 'All'
|
||||
t.reset = 'Reset'
|
||||
t.preview = 'Preview'
|
||||
t.design = 'Design'
|
||||
t.timetype = 'Time Type'
|
||||
t.reftimerange = 'By time range'
|
||||
t.refdate = 'By date'
|
||||
t.hour = 'Hour(s)'
|
||||
|
||||
t.errors = {}
|
||||
t.errors.nosection = 'There is no sections on this product line.'
|
||||
t.errors.numsection = 'There are {num} sections on this product line.'
|
||||
t.errors.nodata = 'Error, no data available!'
|
||||
|
||||
t.hints = {}
|
||||
t.hints.input = 'Please input '
|
||||
t.hints.select = 'Please select '
|
||||
t.hints.date = 'Please select date'
|
||||
t.hints.checktime = 'Please select inspection time'
|
||||
t.hints.number = 'Please input correct number'
|
||||
t.hints.integer = 'Please input correct integer'
|
||||
t.hints.addr = 'Please input address'
|
||||
t.hints.upload2m = 'File size cannot be larger than 2MB (2048KB)'
|
||||
t.hints.upload2mPic = 'Image files only. File size cannot be larger than 2MB (2048KB)'
|
||||
|
||||
t.factory = {}
|
||||
t.factory.title = 'Factory'
|
||||
t.factory.name = 'Factory Name'
|
||||
t.factory.code = 'Factory Code'
|
||||
|
||||
t.prod = {}
|
||||
t.prod.id = 'Product ID'
|
||||
t.prod.name = 'Product Name'
|
||||
t.prod.code = 'Product Code'
|
||||
t.prod.type = 'Product Type'
|
||||
t.prod.area = 'Area'
|
||||
t.prod.spec = 'Product Specification'
|
||||
t.prod.attr = 'Attributes'
|
||||
t.prod.attrcode = 'Attribute Code'
|
||||
t.prod.attrcodeHints = 'Please input attribute code'
|
||||
t.prod.attrname = 'Attribute Node'
|
||||
t.prod.attrnameHints = 'Please input attribute name'
|
||||
t.prod.attrvalueHints = 'Please input attribute value'
|
||||
t.prod.descHints = 'Please input description'
|
||||
// t.prod.processTime = 'Processing Time (Hours)'
|
||||
t.prod.processTime = 'Processing Time (s)'
|
||||
t.prod.processTimeHints = 'Please input processing time'
|
||||
t.prod.relatedPid = 'Related Product'
|
||||
|
||||
t.alarm = {}
|
||||
t.alarm.name = 'Alarm'
|
||||
t.alarm.info = 'Alarm Informations'
|
||||
t.alarm.view = 'View Alarm'
|
||||
t.alarm.eq = 'Alarm Equipment'
|
||||
t.alarm.type = 'Alarm Type'
|
||||
t.alarm.code = 'Alarm Code'
|
||||
t.alarm.level = 'Alarm Level'
|
||||
t.alarm.content = 'Alarm Content'
|
||||
t.alarm.source = 'Alarm Source'
|
||||
t.alarm.det = 'Alarm Details'
|
||||
t.alarm.externalCode = 'External Code'
|
||||
t.alarm.description = 'Description'
|
||||
t.alarm.remark = 'Remark'
|
||||
|
||||
|
||||
t.report = {}
|
||||
t.report.name = 'Report Name'
|
||||
t.report.det = 'Report Content'
|
||||
t.report.type = 'Report Type'
|
||||
t.report.code = 'Report Code'
|
||||
t.report.lnk = 'Report Url'
|
||||
|
||||
t.inspect = {}
|
||||
t.inspect.type = 'Inspection Type'
|
||||
t.inspect.code = 'Inspection Code'
|
||||
t.inspect.det = 'Inspection Details'
|
||||
t.inspect.detcode = 'Inspection Content Code'
|
||||
t.inspect.people = 'Inspector'
|
||||
t.inspect.time = 'Inspection Time'
|
||||
t.inspect.typetotal = 'Total Inspection Types'
|
||||
t.inspect.typename = 'Inspection Type'
|
||||
t.inspect.typecode = 'Inspection Code'
|
||||
t.inspect.ioTotal = 'Data of input/output and total inspections'
|
||||
t.inspect.plTotal = 'Inspection contents in each line'
|
||||
t.inspect.inTotal = 'Up Sum'
|
||||
t.inspect.outTotal = 'Down Sum'
|
||||
t.inspect.checkTotal = 'Total Inspections'
|
||||
t.inspect.rate = 'Rate'
|
||||
t.inspect.typeCount = 'Data of inspection types'
|
||||
|
||||
|
||||
t.realtime = {}
|
||||
t.realtime.eq = 'Realtime data of equipments'
|
||||
t.realtime.pl = 'Realtime data of product lines'
|
||||
t.realtime.inspect = 'Realtime data of quality inspections'
|
||||
t.realtime.in = 'in'
|
||||
t.realtime.out = 'out'
|
||||
t.realtime.data = 'scrap'
|
||||
t.realtime.num = 'scrap quantity'
|
||||
t.realtime.rate = 'scrap rate'
|
||||
t.realtime.total = 'total production'
|
||||
t.realtime.goodrate = 'Passed Rate'
|
||||
t.realtime.runState = 'running state'
|
||||
t.realtime.state = 'status'
|
||||
t.realtime.hasFault = 'malfunction'
|
||||
t.realtime.recentParamValue = 'recent parameters'
|
||||
t.realtime.view = 'view'
|
||||
t.realtime.input = 'input' //'投入数'
|
||||
t.realtime.output = 'output' //'产出数'
|
||||
t.realtime.eqName = 'Equipment name'
|
||||
t.realtime.eqCode = 'Equipment cdoe'
|
||||
t.realtime.productionSnapshotTime = 'production recording time' // '生产量记录时间'
|
||||
t.realtime.statusSnapshotTime = 'status recording time' // '状态记录时间'
|
||||
t.realtime.refresh = 'Refresh data...'
|
||||
|
||||
|
||||
t.ws = {}
|
||||
t.ws.title = 'Work Section'
|
||||
t.ws.id = 'Work Section ID'
|
||||
t.ws.name = 'Work Section Name'
|
||||
t.ws.code = 'Work Section Code'
|
||||
t.ws.binded = 'Binded Equipments'
|
||||
t.ws.unbind = 'Equipment Name'
|
||||
t.ws.eqbindplaceholder = 'Select an equipment'
|
||||
t.ws.sort = 'sort'
|
||||
t.ws.setorder = 'Please input order of equipments in the work section.'
|
||||
t.ws.bind = 'bind'
|
||||
t.ws.eqbind = 'Binded Equipment(s)'
|
||||
t.ws.belong = 'Product Line'
|
||||
|
||||
t.file = {}
|
||||
t.file.title = 'File'
|
||||
t.file.name = 'File Name'
|
||||
t.file.code = 'File Code'
|
||||
t.file.typeName = 'File Type'
|
||||
t.file.typeCode = 'File Type Code'
|
||||
|
||||
t.eq = {}
|
||||
t.eq.title = 'Equipment'
|
||||
t.eq.id = 'Equipment ID'
|
||||
t.eq.name = 'Equipment Name'
|
||||
t.eq.code = 'Equipment Code'
|
||||
t.eq.type = 'Equipment Type'
|
||||
t.eq.grade = 'Specification of equipment'
|
||||
t.eq.group = 'Equipment Group'
|
||||
t.eq.groupname = 'Group Name'
|
||||
t.eq.groupcode = 'Group Code'
|
||||
t.eq.excode = 'External Code'
|
||||
t.eq.input = 'Input Device'
|
||||
t.eq.output = 'Output Device'
|
||||
t.eq.tvalue = 'Device\'s TT Value'
|
||||
t.eq.processingTime = 'Processing Time (s)'
|
||||
t.eq.dtype = 'Data source'
|
||||
t.eq.dtypenone = 'none'
|
||||
t.eq.dtypeinput = 'Input Data Device'
|
||||
t.eq.dtypeoutput = 'Output Data Device'
|
||||
t.eq.upload = 'Upload'
|
||||
t.eq.image = 'Equipment Pictures'
|
||||
t.eq.viewattr = 'Equipment Attributions'
|
||||
t.eq.plcbarcode = 'PLC Bar Code'
|
||||
t.eq.plccode = 'PLC Code'
|
||||
t.eq.plcname = 'PLC Name'
|
||||
t.eq.port = 'Port'
|
||||
t.eq.type = 'Type'
|
||||
t.eq.typecode = 'Type Code'
|
||||
t.eq.parent = 'Parent'
|
||||
t.eq.mtbf = 'Mean time between failures[MTBF] (h)'
|
||||
t.eq.mttr = 'Mean time to repair[MTTR] (h)'
|
||||
t.eq.efficienttimeh = 'Working time(h)'
|
||||
t.eq.shutdowntimeh = 'Off time(h)'
|
||||
t.eq.worktimeh = 'Working time(h)'
|
||||
t.eq.downtimeh = 'Malfunction duration(h)'
|
||||
t.eq.stoptimeh = 'Halt duration(h)'
|
||||
t.eq.worktime = 'Functioning duration'
|
||||
t.eq.stoptime = 'Halt duration'
|
||||
t.eq.downtime = 'Malfunction duration'
|
||||
t.eq.downcount = 'Malfunction counts'
|
||||
t.eq.downrate = 'Malfunction rates'
|
||||
t.eq.stoplost = 'Lost'
|
||||
t.eq.ratio = 'percentage'
|
||||
t.eq.time = 'time'
|
||||
t.eq.timetrend = 'trend'
|
||||
t.eq.nogap = 'no interval'
|
||||
t.eq.monthgap = 'by month'
|
||||
t.eq.daygap = 'by day'
|
||||
t.eq.weekgap = 'by week'
|
||||
t.eq.hourgap = 'by hour'
|
||||
t.eq.workdurationratio = 'Functioning duration ratio' // '工作时长比率'
|
||||
t.eq.stopdurationratio = 'Halt duration ratio' // '停机时长比率'
|
||||
t.eq.stopratio = 'Halt ratio' // '停机比率'
|
||||
t.eq.downdurationratio = 'Malfunction duration ratio' // '故障时长比率'
|
||||
t.eq.speedefficiency = 'Speed launch rate' //'速度开动率'
|
||||
t.eq.speedlost = 'Speed lost'
|
||||
t.eq.timeefficiency = 'Time launch rate' //'时间开动率'
|
||||
t.eq.year = 'year'
|
||||
t.eq.month = 'month'
|
||||
t.eq.realyield = 'Actual processing speed'
|
||||
t.eq.designyield = 'Theoretical processing speed'
|
||||
t.eq.viewtrend = 'View Trends'
|
||||
|
||||
|
||||
|
||||
t.pl = {}
|
||||
t.pl.title = 'Product Line'
|
||||
t.pl.id = 'Product Line ID'
|
||||
t.pl.name = 'Product Line Name'
|
||||
t.pl.code = 'Product Line Code'
|
||||
t.pl.status = 'Product Line Status'
|
||||
t.pl.belong = 'Product Line'
|
||||
t.pl.tvalue = 'TT Value'
|
||||
t.pl.factoryHints = 'Please select a factory'
|
||||
|
||||
|
||||
t.prompt = {}
|
||||
t.prompt.title = 'Prompt'
|
||||
t.prompt.info = 'Are you sure to {handle}?'
|
||||
t.prompt.sure = 'Are you sure to delete this record?'
|
||||
t.prompt.success = 'success'
|
||||
t.prompt.failed = 'failed'
|
||||
t.prompt.deleteBatch = 'Please choose items to delete.'
|
||||
t.prompt.month = 'Please choose month'
|
||||
|
||||
t.validate = {}
|
||||
t.validate.required = 'This is required.'
|
||||
t.validate.format = '{attr} has a wrong format.'
|
||||
|
||||
t.upload = {}
|
||||
t.upload.title = 'Upload Assets'
|
||||
t.upload.text = '将文件拖到此处,或<em>点击上传</em>'
|
||||
t.upload.tip = 'Only support files with format: {format}'
|
||||
t.upload.button = 'upload'
|
||||
|
||||
t.datePicker = {}
|
||||
t.datePicker.range = 'to'
|
||||
t.datePicker.start = 'Start Time'
|
||||
t.datePicker.end = 'End Time'
|
||||
t.datePicker.starttime = 'Start Time'
|
||||
t.datePicker.endtime = 'End Time'
|
||||
|
||||
t.fullscreen = {}
|
||||
t.fullscreen.prompt = 'This operation is not supported by your browser.'
|
||||
|
||||
t.updatePassword = {}
|
||||
t.updatePassword.title = 'Update Password'
|
||||
t.updatePassword.username = 'Username'
|
||||
t.updatePassword.password = 'Current Password'
|
||||
t.updatePassword.newPassword = 'New Password'
|
||||
t.updatePassword.confirmPassword = 'Confirm Password'
|
||||
t.updatePassword.validate = {}
|
||||
t.updatePassword.validate.confirmPassword = 'The two passwords are different. Please check again.'
|
||||
|
||||
t.contentTabs = {}
|
||||
t.contentTabs.closeCurrent = 'Close current tab'
|
||||
t.contentTabs.closeOther = 'Close other tabs'
|
||||
t.contentTabs.closeAll = 'Close all tabs'
|
||||
|
||||
/* 页面 */
|
||||
t.notFound = {}
|
||||
t.notFound.desc = 'Sorry! The page you\'re looking is missing.'
|
||||
t.notFound.back = 'Back'
|
||||
t.notFound.home = 'Home Page'
|
||||
|
||||
t.login = {}
|
||||
t.login.title = 'Login'
|
||||
t.login.username = 'Username'
|
||||
t.login.password = 'Password'
|
||||
t.login.captcha = 'Captcha'
|
||||
t.login.demo = 'Demo'
|
||||
t.login.copyright = 'Copyright @Intelligent Automation Research Institute Co., Ltd Version: 1.0'
|
||||
t.login.warning = 'Already Login!'
|
||||
|
||||
t.schedule = {}
|
||||
t.schedule.beanName = 'Bean Name'
|
||||
t.schedule.beanNameTips = 'spring bean name, eg: testTask'
|
||||
t.schedule.pauseBatch = 'Pause'
|
||||
t.schedule.resumeBatch = 'Resume'
|
||||
t.schedule.runBatch = 'Run'
|
||||
t.schedule.log = 'Log List'
|
||||
t.schedule.params = 'Parameters'
|
||||
t.schedule.cronExpression = 'cron expression'
|
||||
t.schedule.cronExpressionTips = 'ex: 0 0 12 * * ?'
|
||||
t.schedule.remark = 'Remark'
|
||||
t.schedule.status = 'Status'
|
||||
t.schedule.status0 = 'Pause'
|
||||
t.schedule.status1 = 'Normal'
|
||||
t.schedule.statusLog0 = 'Failed'
|
||||
t.schedule.statusLog1 = 'Success'
|
||||
t.schedule.pause = 'Pause'
|
||||
t.schedule.resume = 'Resume'
|
||||
t.schedule.run = 'Excute'
|
||||
t.schedule.jobId = 'Job ID'
|
||||
t.schedule.times = 'Time Cost (ms)'
|
||||
t.schedule.createDate = 'Executed Tune' // ?
|
||||
|
||||
t.oss = {}
|
||||
t.oss.config = '云存储配置'
|
||||
t.oss.upload = '上传文件'
|
||||
t.oss.url = 'URL地址'
|
||||
t.oss.createDate = 'Create Time'
|
||||
t.oss.type = '类型'
|
||||
t.oss.type1 = '七牛'
|
||||
t.oss.type2 = '阿里云'
|
||||
t.oss.type3 = '腾讯云'
|
||||
t.oss.qiniuDomain = '域名'
|
||||
t.oss.qiniuDomainTips = '七牛绑定的域名'
|
||||
t.oss.qiniuPrefix = '路径前缀'
|
||||
t.oss.qiniuPrefixTips = '不设置默认为空'
|
||||
t.oss.qiniuAccessKey = 'AccessKey'
|
||||
t.oss.qiniuAccessKeyTips = '七牛AccessKey'
|
||||
t.oss.qiniuSecretKey = 'SecretKey'
|
||||
t.oss.qiniuSecretKeyTips = '七牛SecretKey'
|
||||
t.oss.qiniuBucketName = '空间名'
|
||||
t.oss.qiniuBucketNameTips = '七牛存储空间名'
|
||||
t.oss.aliyunDomain = '域名'
|
||||
t.oss.aliyunDomainTips = '阿里云绑定的域名,如:http://cdn.renren.io'
|
||||
t.oss.aliyunPrefix = '路径前缀'
|
||||
t.oss.aliyunPrefixTips = '不设置默认为空'
|
||||
t.oss.aliyunEndPoint = 'EndPoint'
|
||||
t.oss.aliyunEndPointTips = '阿里云EndPoint'
|
||||
t.oss.aliyunAccessKeyId = 'AccessKeyId'
|
||||
t.oss.aliyunAccessKeyIdTips = '阿里云AccessKeyId'
|
||||
t.oss.aliyunAccessKeySecret = 'AccessKeySecret'
|
||||
t.oss.aliyunAccessKeySecretTips = '阿里云AccessKeySecret'
|
||||
t.oss.aliyunBucketName = 'BucketName'
|
||||
t.oss.aliyunBucketNameTips = '阿里云BucketName'
|
||||
t.oss.qcloudDomain = '域名'
|
||||
t.oss.qcloudDomainTips = '腾讯云绑定的域名'
|
||||
t.oss.qcloudPrefix = '路径前缀'
|
||||
t.oss.qcloudPrefixTips = '不设置默认为空'
|
||||
t.oss.qcloudAppId = 'AppId'
|
||||
t.oss.qcloudAppIdTips = '腾讯云AppId'
|
||||
t.oss.qcloudSecretId = 'SecretId'
|
||||
t.oss.qcloudSecretIdTips = '腾讯云SecretId'
|
||||
t.oss.qcloudSecretKey = 'SecretKey'
|
||||
t.oss.qcloudSecretKeyTips = '腾讯云SecretKey'
|
||||
t.oss.qcloudBucketName = 'BucketName'
|
||||
t.oss.qcloudBucketNameTips = '腾讯云BucketName'
|
||||
t.oss.qcloudRegion = '所属地区'
|
||||
t.oss.qcloudRegionTips = '请选择'
|
||||
t.oss.qcloudRegionBeijing1 = '北京一区(华北)'
|
||||
t.oss.qcloudRegionBeijing = '北京'
|
||||
t.oss.qcloudRegionShanghai = '上海(华东)'
|
||||
t.oss.qcloudRegionGuangzhou = '广州(华南)'
|
||||
t.oss.qcloudRegionChengdu = '成都(西南)'
|
||||
t.oss.qcloudRegionChongqing = '重庆'
|
||||
t.oss.qcloudRegionSingapore = '新加坡'
|
||||
t.oss.qcloudRegionHongkong = '香港'
|
||||
t.oss.qcloudRegionToronto = '多伦多'
|
||||
t.oss.qcloudRegionFrankfurt = '法兰克福'
|
||||
|
||||
t.dept = {}
|
||||
t.dept.name = 'Department Name'
|
||||
t.dept.parentName = 'Superior Department'
|
||||
t.dept.sort = 'Sort'
|
||||
t.dept.parentNameDefault = 'First tier department'
|
||||
t.dept.chooseerror = 'Please select a department'
|
||||
t.dept.title = 'Department Selection'
|
||||
|
||||
t.dict = {}
|
||||
t.dict.dictName = 'Dictionary Name'
|
||||
t.dict.dictType = 'Dictionary Type'
|
||||
t.dict.dictLabel = 'Dictionary Label'
|
||||
t.dict.dictValue = 'Dictionary Value'
|
||||
t.dict.sort = 'Sort'
|
||||
t.dict.remark = 'Remark'
|
||||
t.dict.createDate = 'Create Time'
|
||||
|
||||
t.logError = {}
|
||||
t.logError.requestUri = 'Request URI'
|
||||
t.logError.requestMethod = 'Request Method'
|
||||
t.logError.requestParams = 'Request Parameters'
|
||||
t.logError.ip = 'IP'
|
||||
t.logError.userAgent = 'User Agent'
|
||||
t.logError.createDate = 'Create Time'
|
||||
t.logError.errorInfo = 'Exceptions'
|
||||
|
||||
t.logLogin = {}
|
||||
t.logLogin.creatorName = 'User Name'
|
||||
t.logLogin.status = 'Status'
|
||||
t.logLogin.status0 = 'Failed'
|
||||
t.logLogin.status1 = 'Success'
|
||||
t.logLogin.status2 = 'Account has been locked'
|
||||
t.logLogin.operation = 'Operation Type'
|
||||
t.logLogin.operation0 = 'Login'
|
||||
t.logLogin.operation1 = 'Logout'
|
||||
t.logLogin.ip = 'IP'
|
||||
t.logLogin.userAgent = 'User-Agent'
|
||||
t.logLogin.createDate = 'Create Time'
|
||||
|
||||
t.logOperation = {}
|
||||
t.logOperation.status = 'Status'
|
||||
t.logOperation.status0 = 'Failed'
|
||||
t.logOperation.status1 = 'Success'
|
||||
t.logOperation.creatorName = 'User Name'
|
||||
t.logOperation.operation = 'User Operations'
|
||||
t.logOperation.requestUri = 'Request URI'
|
||||
t.logOperation.requestMethod = 'Request Method'
|
||||
t.logOperation.requestParams = 'Request Parameters'
|
||||
t.logOperation.requestTime = 'Request Duration'
|
||||
t.logOperation.ip = 'IP'
|
||||
t.logOperation.userAgent = 'User-Agent'
|
||||
t.logOperation.createDate = 'Create Time'
|
||||
|
||||
t.menu = {}
|
||||
t.menu.name = 'Name'
|
||||
t.menu.icon = 'Icons'
|
||||
t.menu.type = 'Type'
|
||||
t.menu.type0 = 'Menu'
|
||||
t.menu.type1 = 'Button'
|
||||
t.menu.sort = 'Sort'
|
||||
t.menu.url = 'Route'
|
||||
t.menu.permissions = '授权标识'
|
||||
t.menu.permissionsTips = '多个用逗号分隔,如:sys:menu:save,sys:menu:update'
|
||||
t.menu.parentName = '上级菜单'
|
||||
t.menu.parentNameDefault = 'First tier menu'
|
||||
t.menu.resource = '授权资源'
|
||||
t.menu.resourceUrl = '资源URL'
|
||||
t.menu.resourceMethod = 'Request methods'
|
||||
t.menu.resourceAddItem = '添加一项'
|
||||
|
||||
t.params = {}
|
||||
t.params.name = 'Parameter Name'
|
||||
t.params.code = 'Parameter Code'
|
||||
t.params.paramCode = 'Parameter Code'
|
||||
t.params.paramValue = 'Parameter Value'
|
||||
t.params.paramStdValue = 'Standard Parameter Code'
|
||||
t.params.plctitle = 'PLC Collection Parameters'
|
||||
t.params.plcid = 'PLC连接表ID'
|
||||
t.params.remark = 'Remark'
|
||||
|
||||
t.role = {}
|
||||
t.role.name = 'Role Name'
|
||||
t.role.remark = 'Remark'
|
||||
t.role.createDate = 'Create Time'
|
||||
t.role.menuList = 'Menu authorization' // ?
|
||||
t.role.deptList = 'Data authorization' // ?
|
||||
|
||||
t.user = {}
|
||||
t.user.username = 'User Name'
|
||||
t.user.deptName = 'Department'
|
||||
t.user.email = 'Email'
|
||||
t.user.mobile = 'Phone'
|
||||
t.user.status = 'Status'
|
||||
t.user.status0 = 'Pause' // ?
|
||||
t.user.status1 = 'Normal'
|
||||
t.user.createDate = 'Create Time'
|
||||
t.user.password = 'Password'
|
||||
t.user.confirmPassword = 'Confirm Password'
|
||||
t.user.realName = 'Actual Name'
|
||||
t.user.gender = 'Gender'
|
||||
t.user.gender0 = 'male'
|
||||
t.user.gender1 = 'female'
|
||||
t.user.gender2 = 'secret'
|
||||
t.user.roleIdList = 'Role Configurations'
|
||||
t.user.validate = {}
|
||||
t.user.validate.confirmPassword = 'The two passwords are different. Please check again.'
|
||||
t.user.select = 'Select an user'
|
||||
t.user.selecterror = 'Pick up a record'
|
||||
|
||||
export default t
|
||||
@@ -1,9 +1,18 @@
|
||||
/*
|
||||
* @Descripttion:
|
||||
* @version:
|
||||
* @Author: fzq
|
||||
* @Date: 2022-11-25 09:51:46
|
||||
* @LastEditors: fzq
|
||||
* @LastEditTime: 2022-12-13 19:27:24
|
||||
*/
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import Cookies from 'js-cookie'
|
||||
import zhCNLocale from 'element-ui/lib/locale/lang/zh-CN'
|
||||
import enLocale from 'element-ui/lib/locale/lang/en'
|
||||
import zhCN from './zh-CN'
|
||||
|
||||
import en from './en'
|
||||
Vue.use(VueI18n)
|
||||
|
||||
export const messages = {
|
||||
@@ -11,10 +20,38 @@ export const messages = {
|
||||
'_lang': '简体中文',
|
||||
...zhCN,
|
||||
...zhCNLocale
|
||||
},
|
||||
'en': {
|
||||
'_lang': 'English',
|
||||
...en,
|
||||
...enLocale
|
||||
}
|
||||
}
|
||||
|
||||
export function getLanguage() {
|
||||
if (Cookies.get('language')) {
|
||||
return Cookies.get('language')
|
||||
}
|
||||
|
||||
// if has not choose language
|
||||
const language = (navigator.language || navigator.browserLanguage)
|
||||
|
||||
const locales = Object.keys(messages)
|
||||
for (const locale of locales) {
|
||||
if (language.indexOf(locale) > -1) {
|
||||
Cookies.set('language', locale)
|
||||
return locale
|
||||
}
|
||||
}
|
||||
Cookies.set('language', 'en')
|
||||
return 'en'
|
||||
|
||||
}
|
||||
|
||||
export default new VueI18n({
|
||||
locale: Cookies.get('language') || 'zh-CN',
|
||||
messages
|
||||
// locale: Cookies.get('language') || 'zh-CN',
|
||||
locale: getLanguage(), // 先默认中文
|
||||
messages,
|
||||
//抑制警告
|
||||
silentFallbackWarn: true,
|
||||
})
|
||||
|
||||
@@ -1,39 +1,394 @@
|
||||
const t = {}
|
||||
|
||||
t.loading = '加载中...'
|
||||
t.createTime = '添加时间'
|
||||
|
||||
t.brand = {}
|
||||
t.brand.lg = '人人权限系统'
|
||||
t.brand.mini = '人人'
|
||||
t.brand.lg = '深加工SCADA平台'
|
||||
t.brand.mini = 'SCADA'
|
||||
|
||||
t.add = '新增'
|
||||
t.delete = '删除'
|
||||
t.deleteBatch = '删除'
|
||||
t.update = '修改'
|
||||
t.query = '查询'
|
||||
t.export = '导出'
|
||||
t.handle = '操作'
|
||||
t.confirm = '确定'
|
||||
t.cancel = '取消'
|
||||
t.clear = '清除'
|
||||
t.logout = '退出'
|
||||
t.manage = '处理'
|
||||
t.createDate = '创建时间'
|
||||
t.keyword = '关键字:'
|
||||
t.choose = '请选择'
|
||||
t.routes = {}
|
||||
// 一级
|
||||
t.routes['产品池'] = '产品池'
|
||||
t.routes['基本资料'] = '基本资料'
|
||||
t.routes['设备数采'] = '设备数采'
|
||||
t.routes['厂务管理'] = '厂务管理'
|
||||
t.routes['报表管理'] = '报表管理'
|
||||
t.routes['质量管理'] = '质量管理'
|
||||
t.routes['权限管理'] = '权限管理'
|
||||
t.routes['系统设置'] = '系统设置'
|
||||
t.routes['日志管理'] = '日志管理'
|
||||
t.routes['数据分析'] = '数据分析'
|
||||
|
||||
// 二级
|
||||
t.routes['厂务'] = '厂务'
|
||||
t.routes['设备'] = '设备'
|
||||
t.routes['字典管理'] = '字典管理'
|
||||
t.routes['PLC信息'] = 'PLC信息'
|
||||
t.routes['设备与PLC关联配置'] = '设备与PLC关联配置' // ?
|
||||
t.routes['设备生产实时数据'] = '设备生产实时数据'
|
||||
t.routes['产线生产实时数据'] = '产线生产实时数据'
|
||||
t.routes['质量检查实时数据'] = '质量检查实时数据'
|
||||
t.routes['报表总览'] = '报表总览'
|
||||
t.routes['报表分类'] = '报表分类'
|
||||
t.routes['报表详情'] = '报表详情'
|
||||
t.routes['报表设计'] = '报表设计'
|
||||
t.routes['报表预览'] = '报表预览'
|
||||
t.routes['质量检测基础数据'] = '质量检测基础数据'
|
||||
t.routes['当前检测数据'] = '当前检测数据'
|
||||
t.routes['检测统计数据'] = '检测统计数据'
|
||||
t.routes['质量检查信息记录'] = '质量检查信息记录'
|
||||
t.routes['用户管理'] = '用户管理'
|
||||
t.routes['部门管理'] = '部门管理'
|
||||
t.routes['角色管理'] = '角色管理'
|
||||
t.routes['菜单管理'] = '菜单管理'
|
||||
t.routes['参数管理'] = '参数管理'
|
||||
t.routes['定时任务'] = '定时任务'
|
||||
t.routes['文件上传'] = '文件上传'
|
||||
t.routes['登录日志'] = '登录日志'
|
||||
t.routes['操作日志'] = '操作日志'
|
||||
t.routes['设备效率分析'] = '设备效率分析'
|
||||
t.routes['设备异常分析'] = '设备异常分析'
|
||||
t.routes['设备状态时序图'] = '设备状态时序图'
|
||||
|
||||
// 三级
|
||||
t.routes['工厂'] = '工厂'
|
||||
t.routes['产线'] = '产线'
|
||||
t.routes['工段'] = '工段'
|
||||
t.routes['设备类型'] = '设备类型'
|
||||
t.routes['设备分组'] = '设备分组'
|
||||
t.routes['设备信息'] = '设备信息'
|
||||
t.routes['设备参数状态监控'] = '设备参数状态监控'
|
||||
t.routes['设备分组报警信息'] = '设备分组报警信息'
|
||||
t.routes['设备历史参数'] = '设备历史参数'
|
||||
t.routes['质量检测类型'] = '质量检测类型'
|
||||
t.routes['质量检测信息'] = '质量检测信息'
|
||||
t.routes['安灯检测盒'] = '安灯检测盒'
|
||||
|
||||
t.andeng = {}
|
||||
t.andeng.inspectContent = '检测内容'
|
||||
t.andeng.btnVal = '按钮值'
|
||||
t.andeng.btnBoxModel = '按钮盒模式'
|
||||
|
||||
|
||||
t.dictValueList = '查看值列表'
|
||||
t.save = '保存'
|
||||
t.add = '新增' // 1
|
||||
t.delete = '删除' // 1
|
||||
t.deleteBatch = '批量删除' // 1
|
||||
t.update = '修改' // 1
|
||||
t.query = '查询' // 1
|
||||
t.export = '导出' // 1
|
||||
t.handle = '操作' // 1
|
||||
t.confirm = '确定' // 1
|
||||
t.cancel = '取消' // 1
|
||||
t.clear = '清除' // 1
|
||||
t.logout = '退出' // 1
|
||||
t.manage = '处理' // 1
|
||||
t.createDate = '创建时间' // 1
|
||||
t.keyword = '关键字:' // 1
|
||||
t.choose = '请选择' // 1
|
||||
t.remark = '备注' // 1
|
||||
t.delMark = '删除标志' // 0
|
||||
t.isvalid = '是否有效' // 0
|
||||
t.available = '可用' // 0
|
||||
t.unavailable = '不可用' // 0
|
||||
t.alert = '弹窗' // 0
|
||||
t.creator = '创建人' // 1
|
||||
t.creatorName = '创建人姓名' // 1
|
||||
t.updator = '更新人' // 1
|
||||
t.updatorName = '更新人姓名' // 1
|
||||
t.updateTime = '更新时间'
|
||||
t.version = '版本号' // 1
|
||||
t.search = '查询' // 1
|
||||
t.countPerPage = '每页数' // ?
|
||||
t.currentPage = '当前页' // ?
|
||||
t.fetchList = '获取数据列表' // ?
|
||||
t.multi = '多选' // ?
|
||||
t.do = '进行' // ?
|
||||
t.submit = '表单提交' // ?
|
||||
t.desc = '描述' // 1
|
||||
t.disable = '停用' // 1
|
||||
t.equipment = '设备' // 1
|
||||
t.enabled = '启用状态' // ?
|
||||
t.cannotempty = '不能为空' // ?
|
||||
t.parameter = '参数名' // 1
|
||||
t.enable = '启用' // 1
|
||||
t.index = '序号' // 1
|
||||
t.relation = '关联' // ?
|
||||
t.fetchInfo = '获取信息' // ?
|
||||
t.name = '名称' // 1
|
||||
t.code = '编码' // 1
|
||||
t.attrName = '属性名称' // 1
|
||||
t.attrValue = '属性值' // 1
|
||||
t.unit = '单位' // 1
|
||||
t.table = '表' // 1
|
||||
t.table2 = '表格' // 1
|
||||
t.downloadurl = '下载地址' // 1
|
||||
t.recordTime = '记录时间' // 1
|
||||
t.notCollect = '不采集' // 1
|
||||
t.collect = '采集' // 1
|
||||
t.required = '必填' // 1
|
||||
t.paramUrl = '参数地址' // 1
|
||||
t.enname = '英文名称' // 1
|
||||
t.collectOrNot = '是否采集' // 1
|
||||
t.min = '最小值' // 1
|
||||
t.max = '最大值' // 1
|
||||
t.status = '状态' // 1
|
||||
t.normal = '正常' // ?
|
||||
t.addr = '地址' // 1
|
||||
t.planStop = '计划停机' // ?
|
||||
t.startTime = '开始时间' // 1
|
||||
t.endTime = '结束时间' // 1
|
||||
t.to = '至' // 1
|
||||
t.today = '今天' // 1
|
||||
|
||||
t.graph = '图形'
|
||||
t.category = '分类'
|
||||
t.categoryName = '分类名称'
|
||||
t.categoryCode = '分类编码'
|
||||
t.rate = '比例'
|
||||
t.link = '链接地址'
|
||||
t.refresh = '刷新'
|
||||
t.abbr = '缩写'
|
||||
t.detail = '详情'
|
||||
t.viewdetail = '查看详情'
|
||||
t.viewattr = '查看属性'
|
||||
t.edit = '编辑'
|
||||
t.source = '来源'
|
||||
t.auto = '自动'
|
||||
t.manual = '手动'
|
||||
t.loaddone = '加载完成'
|
||||
t.produceTime = '生产日期'
|
||||
t.enterTime = '进厂日期'
|
||||
t.manufacturer = '制造商'
|
||||
t.success = '修改成功!'
|
||||
t.all = '全部'
|
||||
t.reset = '重置'
|
||||
t.preview = '预览'
|
||||
t.design = '设计'
|
||||
t.timetype = '时间类型'
|
||||
t.reftimerange = '按时间段'
|
||||
t.refdate = '按日期'
|
||||
t.hour = '小时'
|
||||
|
||||
t.errors = {}
|
||||
t.errors.nosection = '该产线没有工段'
|
||||
t.errors.numsection = '该产线有{num}条工段'
|
||||
t.errors.nodata = '没有查询到相关数据!'
|
||||
|
||||
t.hints = {}
|
||||
t.hints.input = '请输入'
|
||||
t.hints.select = '请选择'
|
||||
t.hints.date = '请选择日期'
|
||||
t.hints.checktime = '请选择检测时间'
|
||||
t.hints.number = '请输入正确的数值'
|
||||
t.hints.integer = '请输入正确的整数'
|
||||
t.hints.addr = '请输入地址'
|
||||
t.hints.upload2m = '上传文件大小不要超过 2MB (2048KB)'
|
||||
t.hints.upload2mPic = '上传图片文件,且大小不要超过 2MB (2048KB)'
|
||||
|
||||
t.factory = {}
|
||||
t.factory.title = '工厂'
|
||||
t.factory.name = '工厂名称'
|
||||
t.factory.code = '工厂编码'
|
||||
|
||||
t.prod = {}
|
||||
t.prod.id = '产品ID'
|
||||
t.prod.name = '产品名称'
|
||||
t.prod.code = '产品编码'
|
||||
t.prod.type = '产品类型'
|
||||
t.prod.area = '单位平方数'
|
||||
t.prod.spec = '规格'
|
||||
t.prod.attr = '属性'
|
||||
t.prod.attrcode = '属性编码'
|
||||
t.prod.attrcodeHints = '请输入属性编码'
|
||||
t.prod.attrname = '属性名称'
|
||||
t.prod.attrnameHints = '请输入属性名称'
|
||||
t.prod.attrvalueHints = '请输入属性值'
|
||||
t.prod.descHints = '请输入描述'
|
||||
// t.prod.processTime = '加工时间 (h)'
|
||||
t.prod.processTime = '产线完成单位产品用时 (s)'
|
||||
t.prod.processTimeHints = '请输入完成单位产品用时'
|
||||
// t.prod.processTimeHints = '请输入加工时间'
|
||||
t.prod.relatedPid = '关联产品'
|
||||
|
||||
t.alarm = {}
|
||||
t.alarm.name = '报警'
|
||||
t.alarm.info = '报警信息'
|
||||
t.alarm.view = '查看报警'
|
||||
t.alarm.eq = '报警设备'
|
||||
t.alarm.type = '报警类型'
|
||||
t.alarm.code = '报警编码'
|
||||
t.alarm.level = '报警级别'
|
||||
t.alarm.content = '报警内容'
|
||||
t.alarm.source = '报警来源'
|
||||
t.alarm.det = '报警详细内容'
|
||||
t.alarm.externalCode = '外部编码'
|
||||
t.alarm.description = '描述'
|
||||
t.alarm.remark = '备注'
|
||||
|
||||
t.report = {}
|
||||
t.report.name = '报表名称'
|
||||
t.report.det = '报表内容'
|
||||
t.report.type = '报表分类'
|
||||
t.report.code = '报表编码'
|
||||
t.report.lnk = '链接地址'
|
||||
|
||||
t.inspect = {}
|
||||
t.inspect.type = '检测类型'
|
||||
t.inspect.code = '检测编码'
|
||||
t.inspect.det = '检测内容'
|
||||
t.inspect.detcode = '内容编码'
|
||||
t.inspect.people = '检测人员'
|
||||
t.inspect.time = '检测时间'
|
||||
t.inspect.typetotal = '检测类型总数'
|
||||
t.inspect.typename = '检测类型名称'
|
||||
t.inspect.typecode = '检测类型编码'
|
||||
t.inspect.ioTotal = '上下片及检测总数统计'
|
||||
t.inspect.plTotal = '各产线检测内容统计'
|
||||
t.inspect.inTotal = '上片总数'
|
||||
t.inspect.outTotal = '下片总数'
|
||||
t.inspect.checkTotal = '检测总数'
|
||||
t.inspect.rate = '比例'
|
||||
t.inspect.typeCount = '检测类型统计数据'
|
||||
|
||||
|
||||
t.realtime = {}
|
||||
t.realtime.eq = '设备生产实时数据'
|
||||
t.realtime.pl = '产线生产实时数据'
|
||||
t.realtime.inspect = '质量检查实时数据'
|
||||
t.realtime.in = '进数据'
|
||||
t.realtime.out = '出数据'
|
||||
t.realtime.data = '报废数据'
|
||||
t.realtime.num = '报废数量'
|
||||
t.realtime.rate = '报废比例'
|
||||
t.realtime.total = '总产量'
|
||||
t.realtime.goodrate = '良品率'
|
||||
t.realtime.runState = '是否运行'
|
||||
t.realtime.state = '状态'
|
||||
t.realtime.hasFault = '是否故障'
|
||||
t.realtime.recentParamValue = '参数近期值'
|
||||
t.realtime.view = '查看'
|
||||
t.realtime.input = '投入数'
|
||||
t.realtime.output = '产出数'
|
||||
t.realtime.eqName = '设备名称'
|
||||
t.realtime.eqCode = '设备编码'
|
||||
t.realtime.productionSnapshotTime = '生产量记录时间'
|
||||
t.realtime.statusSnapshotTime = '状态记录时间'
|
||||
t.realtime.refresh = '刷新数据'
|
||||
|
||||
|
||||
t.ws = {}
|
||||
t.ws.title = '工段'
|
||||
t.ws.id = '工段ID'
|
||||
t.ws.name = '工段名称'
|
||||
t.ws.code = '工段编码'
|
||||
t.ws.binded = '已绑定的设备'
|
||||
t.ws.unbind = '设备名称'
|
||||
t.ws.eqbindplaceholder = '选择一个设备进行绑定'
|
||||
t.ws.sort = '工段排序'
|
||||
t.ws.setorder = '请输入工段中设备的顺序'
|
||||
t.ws.bind = '绑定'
|
||||
t.ws.eqbind = '设备绑定'
|
||||
t.ws.belong = '所属产线'
|
||||
|
||||
t.file = {}
|
||||
t.file.title = '文件'
|
||||
t.file.name = '文件名称'
|
||||
t.file.code = '文件编号'
|
||||
t.file.typeName = '文件类型名称'
|
||||
t.file.typeCode = '文件类型编号'
|
||||
|
||||
t.eq = {}
|
||||
t.eq.title = '设备'
|
||||
t.eq.id = '设备ID'
|
||||
t.eq.name = '设备名称'
|
||||
t.eq.code = '设备编码'
|
||||
t.eq.type = '设备类型'
|
||||
t.eq.grade = '设备规格'
|
||||
t.eq.group = '设备分组'
|
||||
t.eq.groupname = '分组名称'
|
||||
t.eq.groupcode = '分组编码'
|
||||
t.eq.excode = '设备外部代码'
|
||||
t.eq.input = '上片数据设备'
|
||||
t.eq.output = '下片数据设备'
|
||||
t.eq.tvalue = '设备TT值'
|
||||
t.eq.processingTime = '单件产品加工时间(秒)'
|
||||
t.eq.dtype = '数据类别'
|
||||
t.eq.dtypenone = '无类别'
|
||||
t.eq.dtypeinput = '上片数据设备'
|
||||
t.eq.dtypeoutput = '下片数据设备'
|
||||
t.eq.upload = '上传资料'
|
||||
t.eq.image = '设备图片'
|
||||
t.eq.viewattr = '查看设备属性'
|
||||
t.eq.plcbarcode = 'plc条码'
|
||||
t.eq.plccode = 'PLC编码'
|
||||
t.eq.plcname = 'PLC名称'
|
||||
t.eq.port = '端口'
|
||||
t.eq.type = '类型名称'
|
||||
t.eq.typecode = '类型编码'
|
||||
t.eq.parent = '父类'
|
||||
t.eq.mtbf = '平均故障间隔时间[MTBF] (h)'
|
||||
t.eq.mttr = '平均维修时间[MTTR] (h)'
|
||||
t.eq.efficienttimeh = '有效时间(h)'
|
||||
t.eq.shutdowntimeh = '关机时间(h)'
|
||||
t.eq.worktimeh = '工作时长(h)'
|
||||
t.eq.downtimeh = '故障时长(h)'
|
||||
t.eq.stoptimeh = '停机时长(h)'
|
||||
t.eq.worktime = '工作时长'
|
||||
t.eq.stoptime = '停机时长'
|
||||
t.eq.downtime = '故障时长'
|
||||
t.eq.downcount = '故障次数'
|
||||
t.eq.downrate = '故障比率'
|
||||
t.eq.stoplost = '中断损失'
|
||||
t.eq.ratio = '百分比'
|
||||
t.eq.time = '时间'
|
||||
t.eq.timetrend = '时间区间走势'
|
||||
t.eq.nogap = '无间隔'
|
||||
t.eq.monthgap = '按月'
|
||||
t.eq.daygap = '按天'
|
||||
t.eq.weekgap = '按周'
|
||||
t.eq.hourgap = '按小时'
|
||||
t.eq.workdurationratio = '工作时长比率'
|
||||
t.eq.stopdurationratio = '停机时长比率'
|
||||
t.eq.stopratio = '停机比率'
|
||||
t.eq.downdurationratio = '故障时长比率'
|
||||
t.eq.speedefficiency = '速度开动率'
|
||||
t.eq.speedlost = '速度损失'
|
||||
t.eq.timeefficiency = '时间开动率'
|
||||
t.eq.year='年'
|
||||
t.eq.month='月'
|
||||
t.eq.realyield = '实际加工速度'
|
||||
t.eq.designyield = '理论加工速度'
|
||||
t.eq.viewtrend = '查看趋势'
|
||||
|
||||
|
||||
t.pl = {}
|
||||
t.pl.title = '产线'
|
||||
t.pl.id = '产线ID'
|
||||
t.pl.name = '产线名称'
|
||||
t.pl.code = '产线编码'
|
||||
t.pl.status = '产线状态'
|
||||
t.pl.belong = '所属产线'
|
||||
t.pl.tvalue = '产线TT值(每小时下片数量)'
|
||||
t.pl.factoryHints = '请选择所属工厂'
|
||||
|
||||
t.prompt = {}
|
||||
t.prompt.title = '提示'
|
||||
t.prompt.info = '确定进行[{handle}]操作?'
|
||||
t.prompt.sure = '确定删除这条记录吗?'
|
||||
t.prompt.success = '操作成功'
|
||||
t.prompt.failed = '操作失败'
|
||||
t.prompt.deleteBatch = '请选择删除项'
|
||||
t.prompt.month = '请选择月份'
|
||||
|
||||
t.validate = {}
|
||||
t.validate.required = '必填项不能为空'
|
||||
t.validate.format = '{attr}格式错误'
|
||||
|
||||
t.upload = {}
|
||||
t.upload.title = '上传资料'
|
||||
t.upload.text = '将文件拖到此处,或<em>点击上传</em>'
|
||||
t.upload.tip = '只支持{format}格式文件!'
|
||||
t.upload.button = '点击上传'
|
||||
@@ -42,6 +397,8 @@ t.datePicker = {}
|
||||
t.datePicker.range = '至'
|
||||
t.datePicker.start = '开始日期'
|
||||
t.datePicker.end = '结束日期'
|
||||
t.datePicker.starttime = '开始时间'
|
||||
t.datePicker.endtime = '结束时间'
|
||||
|
||||
t.fullscreen = {}
|
||||
t.fullscreen.prompt = '您的浏览器不支持此操作'
|
||||
@@ -72,7 +429,8 @@ t.login.username = '用户名'
|
||||
t.login.password = '密码'
|
||||
t.login.captcha = '验证码'
|
||||
t.login.demo = '在线演示'
|
||||
t.login.copyright = '人人开源'
|
||||
t.login.copyright = '版权所有:中建材智能自动化研究院有限公司 版本: 1.0'
|
||||
t.login.warning = '已经登录过了'
|
||||
|
||||
t.schedule = {}
|
||||
t.schedule.beanName = 'bean名称'
|
||||
@@ -224,8 +582,13 @@ t.menu.resourceMethod = '请求方式'
|
||||
t.menu.resourceAddItem = '添加一项'
|
||||
|
||||
t.params = {}
|
||||
t.params.name = '参数名称'
|
||||
t.params.code = '参数编码'
|
||||
t.params.paramCode = '编码'
|
||||
t.params.paramValue = '值'
|
||||
t.params.paramStdValue = '参数设定标准值'
|
||||
t.params.plctitle = 'PLC采集参数'
|
||||
t.params.plcid = 'PLC连接表ID'
|
||||
t.params.remark = '备注'
|
||||
|
||||
t.role = {}
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
import './iconfont'
|
||||
import Vue from 'vue'
|
||||
import SvgIcon from '@/components/SvgIcon'// svg component
|
||||
|
||||
// register globally
|
||||
Vue.component('svg-icon', SvgIcon)
|
||||
|
||||
const req = require.context('./svg', false, /\.svg$/)
|
||||
const requireAll = requireContext => requireContext.keys().map(requireContext)
|
||||
requireAll(req)
|
||||
|
||||
const svgFiles = require.context('./svg', true, /\.svg$/)
|
||||
svgFiles.keys().map(item => svgFiles(item))
|
||||
|
||||
export default {
|
||||
// 获取图标icon-(*).svg名称列表, 例如[shouye, xitong, zhedie, ...]
|
||||
getNameList() {
|
||||
return requireAll(req).map(item => item.default.id.replace('icon-', ''))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1
src/icons/svg/eye-open.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
src/icons/svg/eye.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>
|
||||
|
After Width: | Height: | Size: 944 B |
1
src/icons/svg/international.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M83.287 103.01c-1.57-3.84-6.778-10.414-15.447-19.548-2.327-2.444-2.182-4.306-1.338-9.862v-.64c.553-3.81 1.513-6.05 14.313-8.087 6.516-1.018 8.203 1.57 10.589 5.178l.785 1.193a12.625 12.625 0 0 0 6.43 5.207c1.134.524 2.53 1.164 4.421 2.24 4.596 2.53 4.596 5.41 4.596 11.753v.727a26.91 26.91 0 0 1-5.178 17.454 59.055 59.055 0 0 1-19.025 11.026c3.49-6.546.814-14.313 0-16.553l-.146-.087zM64 5.12a58.502 58.502 0 0 1 25.484 5.818 54.313 54.313 0 0 0-12.859 10.327c-.93 1.28-1.716 2.473-2.472 3.579-2.444 3.694-3.637 5.352-5.818 5.614a25.105 25.105 0 0 1-4.219 0c-4.276-.29-10.094-.64-11.956 4.422-1.193 3.23-1.396 11.956 2.444 16.495.66 1.077.778 2.4.32 3.578a7.01 7.01 0 0 1-2.066 3.229 18.938 18.938 0 0 1-2.909-2.91 18.91 18.91 0 0 0-8.32-6.603c-1.25-.349-2.647-.64-3.985-.93-3.782-.786-8.03-1.688-9.019-3.812a14.895 14.895 0 0 1-.727-5.818 21.935 21.935 0 0 0-1.396-9.25 8.873 8.873 0 0 0-5.557-4.946A58.705 58.705 0 0 1 64 5.12zM0 64c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
19
src/icons/svg/table_add.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="10px" height="10px" viewBox="0 0 10 10" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 60 (88103) - https://sketch.com -->
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="11_系统管理" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="11-1用户管理" transform="translate(-1764.000000, -160.000000)">
|
||||
<g id="编组-15" transform="translate(1763.000000, 158.000000)">
|
||||
<g id="编组-18">
|
||||
<g id="icon/界面内/新增" transform="translate(0.000000, 1.000000)">
|
||||
<g id="编组">
|
||||
<rect id="矩形" stroke="#979797" fill="#D8D8D8" opacity="0" x="0.5" y="0.5" width="11" height="11"></rect>
|
||||
<path d="M10.0813953,6.42885117 L6.37790698,6.42885117 L6.37790698,10.0770235 C6.37790698,10.3108355 6.19069767,10.5 5.95930233,10.5 L5.95930233,10.5 C5.72790698,10.5 5.54069767,10.3108355 5.54069767,10.0770235 L5.54069767,6.42885117 L1.91860465,6.42885117 C1.6872093,6.42885117 1.5,6.23968668 1.5,6.00587467 L1.5,6.00587467 C1.5,5.77206266 1.6872093,5.58289817 1.91860465,5.58289817 L5.54069767,5.58289817 L5.54069767,1.9229765 C5.54069767,1.68916449 5.72790698,1.5 5.95930233,1.5 L5.95930233,1.5 C6.19069767,1.5 6.37790698,1.68916449 6.37790698,1.9229765 L6.37790698,5.58289817 L10.0813953,5.58289817 C10.3127907,5.58289817 10.5,5.77206266 10.5,6.00587467 L10.5,6.00587467 C10.5,6.23968668 10.3127907,6.42885117 10.0813953,6.42885117 L10.0813953,6.42885117 Z" id="Shape" fill="#0B58FF" transform="translate(6.000000, 6.000000) scale(1, -1) translate(-6.000000, -6.000000) "></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -31,6 +31,10 @@ Vue.use(renRegionTree)
|
||||
Vue.prototype.$http = http
|
||||
Vue.prototype.$hasPermission = hasPermission
|
||||
Vue.prototype.$getDictLabel = getDictLabel
|
||||
// is auth
|
||||
Vue.prototype.isAuth = permission => {
|
||||
return "正在检查的权限是:" + permission
|
||||
}
|
||||
|
||||
// 保存整站vuex本地储存初始状态
|
||||
window.SITE_CONFIG['storeState'] = cloneDeep(store.state)
|
||||
|
||||
24
src/mixins/dictlist-module.js
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dictList: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initDictList(dictTypeIdList) {
|
||||
const allDictList = JSON.parse(localStorage.getItem('dictList'))
|
||||
if (!Object.keys(allDictList).length) {
|
||||
return this.$message({
|
||||
// TODO: i18n
|
||||
message: '未能获取数据字典',
|
||||
type: 'error',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
dictTypeIdList.forEach(id => {
|
||||
this.dictList[id] = allDictList[id].map(item => ({ label: item.dictLabel, value: item.dictValue }))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import Cookies from 'js-cookie'
|
||||
import qs from 'qs'
|
||||
export default {
|
||||
data () {
|
||||
data() {
|
||||
/* eslint-disable */
|
||||
return {
|
||||
// 设置属性
|
||||
@@ -29,22 +29,24 @@ export default {
|
||||
}
|
||||
/* eslint-enable */
|
||||
},
|
||||
created () {
|
||||
created() {
|
||||
if (this.mixinViewModuleOptions.createdIsNeed) {
|
||||
this.query()
|
||||
}
|
||||
},
|
||||
activated () {
|
||||
activated() {
|
||||
if (this.mixinViewModuleOptions.activatedIsNeed) {
|
||||
this.query()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取数据列表
|
||||
query () {
|
||||
query() {
|
||||
this.dataListLoading = true
|
||||
this.$http.get(
|
||||
this.mixinViewModuleOptions.getDataListURL,
|
||||
this.$http.adornUrl(
|
||||
this.mixinViewModuleOptions.getDataListURL
|
||||
),
|
||||
{
|
||||
params: {
|
||||
order: this.order,
|
||||
@@ -68,11 +70,11 @@ export default {
|
||||
})
|
||||
},
|
||||
// 多选
|
||||
dataListSelectionChangeHandle (val) {
|
||||
dataListSelectionChangeHandle(val) {
|
||||
this.dataListSelections = val
|
||||
},
|
||||
// 排序
|
||||
dataListSortChangeHandle (data) {
|
||||
dataListSortChangeHandle(data) {
|
||||
if (!data.order || !data.prop) {
|
||||
this.order = ''
|
||||
this.orderField = ''
|
||||
@@ -83,13 +85,13 @@ export default {
|
||||
this.query()
|
||||
},
|
||||
// 分页, 每页条数
|
||||
pageSizeChangeHandle (val) {
|
||||
pageSizeChangeHandle(val) {
|
||||
this.page = 1
|
||||
this.limit = val
|
||||
this.query()
|
||||
},
|
||||
// 分页, 当前页
|
||||
pageCurrentChangeHandle (val) {
|
||||
pageCurrentChangeHandle(val) {
|
||||
this.page = val
|
||||
this.query()
|
||||
},
|
||||
@@ -98,7 +100,7 @@ export default {
|
||||
this.query()
|
||||
},
|
||||
// 新增 / 修改
|
||||
addOrUpdateHandle (id) {
|
||||
addOrUpdateHandle(id) {
|
||||
this.addOrUpdateVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.addOrUpdate.dataForm.id = id
|
||||
@@ -106,7 +108,7 @@ export default {
|
||||
})
|
||||
},
|
||||
// 关闭当前窗口
|
||||
closeCurrentTab (data) {
|
||||
closeCurrentTab(data) {
|
||||
var tabName = this.$store.state.contentTabsActiveName
|
||||
this.$store.state.contentTabs = this.$store.state.contentTabs.filter(item => item.name !== tabName)
|
||||
if (this.$store.state.contentTabs.length <= 0) {
|
||||
@@ -118,7 +120,7 @@ export default {
|
||||
}
|
||||
},
|
||||
// 删除
|
||||
deleteHandle (id) {
|
||||
deleteHandle(id) {
|
||||
if (this.mixinViewModuleOptions.deleteIsBatch && !id && this.dataListSelections.length <= 0) {
|
||||
return this.$message({
|
||||
message: this.$t('prompt.deleteBatch'),
|
||||
@@ -132,7 +134,7 @@ export default {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$http.delete(
|
||||
`${this.mixinViewModuleOptions.deleteURL}${this.mixinViewModuleOptions.deleteIsBatch ? '' : '/' + id}`,
|
||||
this.$http.adornUrl(`${this.mixinViewModuleOptions.deleteURL}${this.mixinViewModuleOptions.deleteIsBatch ? '' : '/' + id}`),
|
||||
this.mixinViewModuleOptions.deleteIsBatch ? {
|
||||
'data': id ? [id] : this.dataListSelections.map(item => item[this.mixinViewModuleOptions.deleteIsBatchKey])
|
||||
} : {}
|
||||
@@ -148,11 +150,11 @@ export default {
|
||||
this.query()
|
||||
}
|
||||
})
|
||||
}).catch(() => {})
|
||||
}).catch(() => {})
|
||||
}).catch(() => { })
|
||||
}).catch(() => { })
|
||||
},
|
||||
// 导出
|
||||
exportHandle () {
|
||||
exportHandle() {
|
||||
var params = qs.stringify({
|
||||
'token': Cookies.get('token'),
|
||||
...this.dataForm
|
||||
|
||||
@@ -2,6 +2,8 @@ import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import http from '@/utils/request'
|
||||
import { isURL } from '@/utils/validate'
|
||||
import Cookies from 'js-cookie'
|
||||
import i18n from '@/i18n'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
@@ -12,7 +14,7 @@ export const pageRoutes = [
|
||||
component: () => import('@/views/pages/404'),
|
||||
name: '404',
|
||||
meta: { title: '404未找到' },
|
||||
beforeEnter (to, from, next) {
|
||||
beforeEnter(to, from, next) {
|
||||
// 拦截处理特殊业务场景
|
||||
// 如果, 重定向路由包含__双下划线, 为临时添加路由
|
||||
if (/__.*/.test(to.redirectedFrom)) {
|
||||
@@ -21,7 +23,20 @@ export const pageRoutes = [
|
||||
next()
|
||||
}
|
||||
},
|
||||
{ path: '/login', component: () => import('@/views/pages/login'), name: 'login', meta: { title: '登录' } }
|
||||
{
|
||||
path: '/login',
|
||||
component: () => import('@/views/pages/login'),
|
||||
name: 'login',
|
||||
meta: { title: '登录' },
|
||||
beforeEnter(to, from, next) {
|
||||
if (Cookies.get('token')) {
|
||||
Vue.prototype.$message({ message: $t('login.warning'), type: 'error' })
|
||||
next(false)
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
// 模块路由(基于主入口布局页面)
|
||||
@@ -30,13 +45,15 @@ export const moduleRoutes = {
|
||||
component: () => import('@/views/main'),
|
||||
name: 'main',
|
||||
redirect: { name: 'home' },
|
||||
// redirect: { name: 'sys-log-login' },
|
||||
meta: { title: '主入口布局' },
|
||||
children: [
|
||||
{ path: '/home', component: () => import('@/views/modules/home'), name: 'home', meta: { title: '首页', isTab: true } }
|
||||
// { path: '/sys-log-login', component: () => import('@/views/modules/sys/log-login'), name: 'sys-log-login', meta: { title: '首页', isTab: true } }
|
||||
{ path: '/home', component: () => import('@/views/modules/home'), name: 'home', meta: { title: '首页', isTab: false, hiddenSiderbar: true } }
|
||||
]
|
||||
}
|
||||
|
||||
export function addDynamicRoute (routeParams, router) {
|
||||
export function addDynamicRoute(routeParams, router) {
|
||||
// 组装路由名称, 并判断是否已添加, 如是: 则直接跳转
|
||||
var routeName = routeParams.routeName
|
||||
var dynamicRoute = window.SITE_CONFIG['dynamicRoutes'].filter(item => item.name === routeName)[0]
|
||||
@@ -77,24 +94,30 @@ router.beforeEach((to, from, next) => {
|
||||
if (window.SITE_CONFIG['dynamicMenuRoutesHasAdded'] || fnCurrentRouteIsPageRoute(to, pageRoutes)) {
|
||||
return next()
|
||||
}
|
||||
|
||||
// 获取字典列表, 添加并全局变量保存
|
||||
http.get('/sys/dict/type/all').then(({ data: res }) => {
|
||||
http.get(http.adornUrl('/sys/dict/type/all')).then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return
|
||||
}
|
||||
window.SITE_CONFIG['dictList'] = res.data
|
||||
}).catch(() => {})
|
||||
}).catch((err) => {
|
||||
})
|
||||
// 获取菜单列表, 添加并全局变量保存
|
||||
http.get('/sys/menu/nav').then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
Vue.prototype.$message.error(res.msg)
|
||||
return next({ name: 'login' })
|
||||
}
|
||||
http.get(http.adornUrl('/sys/menu/nav')).then(({ data: res }) => {
|
||||
/** axios 的拦截器已经拦截出错情况,此处只考虑正确情况即可 */
|
||||
window.SITE_CONFIG['menuList'] = res.data
|
||||
// .map(item => {
|
||||
// if (item.name === '产品池') {
|
||||
// console.log('Got you')
|
||||
// item.name =
|
||||
// }
|
||||
// return item
|
||||
// })
|
||||
fnAddDynamicMenuRoutes(window.SITE_CONFIG['menuList'])
|
||||
next({ ...to, replace: true })
|
||||
}).catch(() => {
|
||||
next({ name: 'login' })
|
||||
}).catch((err) => {
|
||||
// Vue.prototype.$message.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -103,7 +126,7 @@ router.beforeEach((to, from, next) => {
|
||||
* @param {*} route 当前路由
|
||||
* @param {*} pageRoutes 页面路由
|
||||
*/
|
||||
function fnCurrentRouteIsPageRoute (route, pageRoutes = []) {
|
||||
function fnCurrentRouteIsPageRoute(route, pageRoutes = []) {
|
||||
var temp = []
|
||||
for (var i = 0; i < pageRoutes.length; i++) {
|
||||
if (route.path === pageRoutes[i].path) {
|
||||
@@ -121,10 +144,13 @@ function fnCurrentRouteIsPageRoute (route, pageRoutes = []) {
|
||||
* @param {*} menuList 菜单列表
|
||||
* @param {*} routes 递归创建的动态(菜单)路由
|
||||
*/
|
||||
function fnAddDynamicMenuRoutes (menuList = [], routes = []) {
|
||||
function fnAddDynamicMenuRoutes(menuList = [], routes = []) {
|
||||
var temp = []
|
||||
|
||||
for (var i = 0; i < menuList.length; i++) {
|
||||
if (menuList[i].children && menuList[i].children.length >= 1) {
|
||||
// 菜单的国际化
|
||||
menuList[i].name = i18n.t(`routes["${menuList[i].name}"]`)
|
||||
temp = temp.concat(menuList[i].children)
|
||||
continue
|
||||
}
|
||||
@@ -136,9 +162,15 @@ function fnAddDynamicMenuRoutes (menuList = [], routes = []) {
|
||||
meta: {
|
||||
...window.SITE_CONFIG['contentTabDefault'],
|
||||
menuId: menuList[i].id,
|
||||
title: menuList[i].name
|
||||
// 菜单的国际化
|
||||
title: i18n.t(`routes["${menuList[i].name}"]`)
|
||||
}
|
||||
}
|
||||
|
||||
// 菜单的国际化
|
||||
menuList[i].name = i18n.t(`routes["${menuList[i].name}"]`)
|
||||
|
||||
// console.log('route ===', route.meta.title)
|
||||
// eslint-disable-next-line
|
||||
let URL = (menuList[i].url || '').replace(/{{([^}}]+)?}}/g, (s1, s2) => eval(s2)) // URL支持{{ window.xxx }}占位符变量
|
||||
if (isURL(URL)) {
|
||||
@@ -151,9 +183,11 @@ function fnAddDynamicMenuRoutes (menuList = [], routes = []) {
|
||||
}
|
||||
routes.push(route)
|
||||
}
|
||||
|
||||
if (temp.length >= 1) {
|
||||
return fnAddDynamicMenuRoutes(temp, routes)
|
||||
}
|
||||
|
||||
// 添加路由
|
||||
router.addRoutes([
|
||||
{
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/*
|
||||
* @Descripttion:
|
||||
* @version:
|
||||
* @Author: fzq
|
||||
* @Date: 2022-12-11 20:33:35
|
||||
* @LastEditors: fzq
|
||||
* @LastEditTime: 2022-12-11 20:43:32
|
||||
*/
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
@@ -9,7 +17,7 @@ export default new Vuex.Store({
|
||||
namespaced: true,
|
||||
state: {
|
||||
// 导航条, 布局风格, default(白色) / colorful(鲜艳)
|
||||
navbarLayoutType: 'colorful',
|
||||
navbarLayoutType: '',
|
||||
// 侧边栏, 布局皮肤, default(白色) / dark(黑色)
|
||||
sidebarLayoutSkin: 'dark',
|
||||
// 侧边栏, 折叠状态
|
||||
@@ -23,11 +31,13 @@ export default new Vuex.Store({
|
||||
contentTabs: [
|
||||
{
|
||||
...window.SITE_CONFIG['contentTabDefault'],
|
||||
// 'name': 'sys-log-login',
|
||||
'name': 'home',
|
||||
'title': 'home'
|
||||
}
|
||||
],
|
||||
contentTabsActiveName: 'home'
|
||||
// contentTabsActiveName: 'sys-log-login'
|
||||
},
|
||||
modules: {
|
||||
user
|
||||
|
||||
24
src/utils/filters.js
Normal file
@@ -0,0 +1,24 @@
|
||||
/** filters */
|
||||
import moment from 'moment'
|
||||
|
||||
export const dictFilter = dictTypeId => {
|
||||
return val => {
|
||||
return JSON.parse(localStorage.getItem('dictList'))[dictTypeId].find(item => item.dictValue === val)?.dictLabel || '-'
|
||||
}
|
||||
}
|
||||
|
||||
export const timeFilter = (val) => {
|
||||
return moment(val).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
||||
export const pick = (obj, paths) => {
|
||||
let result = {}
|
||||
paths.forEach(key => {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
result[key] = obj[key];
|
||||
} else {
|
||||
result[key] = null
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import store from '@/store'
|
||||
* 权限
|
||||
* @param {*} key
|
||||
*/
|
||||
export function hasPermission (key) {
|
||||
export function hasPermission(key) {
|
||||
return window.SITE_CONFIG['permissions'].indexOf(key) !== -1 || false
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ export function hasPermission (key) {
|
||||
* 获取字典数据列表
|
||||
* @param dictType 字典类型
|
||||
*/
|
||||
export function getDictDataList (dictType) {
|
||||
export function getDictDataList(dictType) {
|
||||
const type = window.SITE_CONFIG['dictList'].find((element) => (element.dictType === dictType))
|
||||
if (type) {
|
||||
return type.dataList
|
||||
@@ -27,7 +27,7 @@ export function getDictDataList (dictType) {
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典值
|
||||
*/
|
||||
export function getDictLabel (dictType, dictValue) {
|
||||
export function getDictLabel(dictType, dictValue) {
|
||||
const type = window.SITE_CONFIG['dictList'].find((element) => (element.dictType === dictType))
|
||||
if (type) {
|
||||
const val = type.dataList.find((element) => (element.dictValue === dictValue + ''))
|
||||
@@ -44,16 +44,17 @@ export function getDictLabel (dictType, dictValue) {
|
||||
/**
|
||||
* 清除登录信息
|
||||
*/
|
||||
export function clearLoginInfo () {
|
||||
export function clearLoginInfo() {
|
||||
store.commit('resetStore')
|
||||
Cookies.remove('token')
|
||||
window.SITE_CONFIG['dynamicMenuRoutesHasAdded'] = false
|
||||
window.SITE_CONFIG['dynamicMenuRoutes'] = []
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取uuid
|
||||
*/
|
||||
export function getUUID () {
|
||||
export function getUUID() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
||||
return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
|
||||
})
|
||||
@@ -62,7 +63,7 @@ export function getUUID () {
|
||||
/**
|
||||
* 获取svg图标(id)列表
|
||||
*/
|
||||
export function getIconList () {
|
||||
export function getIconList() {
|
||||
var res = []
|
||||
var list = document.querySelectorAll('svg symbol')
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
@@ -73,12 +74,12 @@ export function getIconList () {
|
||||
}
|
||||
|
||||
/**
|
||||
* 树形数据转换
|
||||
* 树形数据转换,把扁平的数据,转换为树形结构的数据
|
||||
* @param {*} data
|
||||
* @param {*} id
|
||||
* @param {*} pid
|
||||
*/
|
||||
export function treeDataTranslate (data, id = 'id', pid = 'pid') {
|
||||
export function treeDataTranslate(data, id = 'id', pid = 'pid') {
|
||||
var res = []
|
||||
var temp = {}
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
@@ -97,3 +98,24 @@ export function treeDataTranslate (data, id = 'id', pid = 'pid') {
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
/** 计算表格的最大高 */
|
||||
export function calcMaxHeight(num) {
|
||||
const FIXED_HEIGHT = 220
|
||||
let clientHeight = 0
|
||||
const bodyHeight = document.body.clientHeight || null
|
||||
const documentHeight = document.documentElement.clientHeight || null
|
||||
if (bodyHeight && documentHeight) {
|
||||
clientHeight = Math.max(bodyHeight, documentHeight)
|
||||
} else {
|
||||
clientHeight = documentHeight ? documentHeight : bodyHeight
|
||||
}
|
||||
|
||||
const finalHeight = clientHeight - num - FIXED_HEIGHT
|
||||
return finalHeight > 0 ? finalHeight : -finalHeight
|
||||
}
|
||||
|
||||
// tableHeight
|
||||
export function tableHeight(n) {
|
||||
return window.innerHeight - n
|
||||
}
|
||||
|
||||
@@ -4,9 +4,13 @@ import router from '@/router'
|
||||
import qs from 'qs'
|
||||
import { clearLoginInfo } from '@/utils'
|
||||
import isPlainObject from 'lodash/isPlainObject'
|
||||
import merge from 'lodash/merge'
|
||||
|
||||
const http = axios.create({
|
||||
baseURL: window.SITE_CONFIG['apiURL'],
|
||||
// baseURL: window.SITE_CONFIG['apiURL'],
|
||||
baseURL: '/api',
|
||||
// baseURL: '/yd-monitor',
|
||||
// baseURL: process.env.NODE_ENV === 'production' ? '/api' : '/yd-monitor',
|
||||
timeout: 1000 * 180,
|
||||
withCredentials: true
|
||||
})
|
||||
@@ -55,10 +59,54 @@ http.interceptors.response.use(response => {
|
||||
router.replace({ name: 'login' })
|
||||
return Promise.reject(response.data.msg)
|
||||
}
|
||||
// else if (response.data.code === 500) {
|
||||
// return Promise.reject(response.data.msg)
|
||||
// }
|
||||
return response
|
||||
}, error => {
|
||||
console.error(error)
|
||||
return Promise.reject(error)
|
||||
})
|
||||
|
||||
/**
|
||||
* 请求地址处理
|
||||
* @param {*} actionName action方法名称
|
||||
*/
|
||||
http.adornUrl = (actionName) => {
|
||||
// 非生产环境 && 开启代理, 接口前缀统一使用[/proxyApi/]前缀做代理拦截!
|
||||
// return (process.env.NODE_ENV !== 'production' && process.env.OPEN_PROXY ? window.SITE_CONFIG.projURL : '') + actionName
|
||||
// return (process.env.NODE_ENV !== 'production' ? '/yd-monitor' : '/api') + actionName
|
||||
return actionName
|
||||
}
|
||||
|
||||
/**
|
||||
* get请求参数处理
|
||||
* @param {*} params 参数对象
|
||||
* @param {*} openDefultParams 是否开启默认参数?
|
||||
*/
|
||||
http.adornParams = (params = {}, openDefaultParams = true) => {
|
||||
var defaults = {
|
||||
't': new Date().getTime()
|
||||
}
|
||||
return openDefaultParams ? merge(defaults, params) : params
|
||||
}
|
||||
|
||||
/**
|
||||
* post请求数据处理
|
||||
* @param {*} data 数据对象
|
||||
* @param {*} openDefultdata 是否开启默认数据?
|
||||
* @param {*} contentType 数据格式
|
||||
* json: 'application/json; charset=utf-8'
|
||||
* form: 'application/x-www-form-urlencoded; charset=utf-8'
|
||||
*/
|
||||
http.adornData = (data = {}, openDefaultdata = true, contentType = 'json') => {
|
||||
var defaults = {
|
||||
't': new Date().getTime()
|
||||
}
|
||||
data = openDefaultdata ? merge(defaults, data) : data
|
||||
return contentType === 'raw' ? data : contentType === 'json' ? JSON.stringify(data) : qs.stringify(data)
|
||||
// return contentType === 'json' ? JSON.stringify(data, (_, v) => typeof v === 'bigint' ? v.toString() : v) : qs.stringify(data)
|
||||
}
|
||||
|
||||
|
||||
export default http
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/*
|
||||
* @Descripttion:
|
||||
* @version:
|
||||
* @Author: fzq
|
||||
* @Date: 2022-11-25 09:51:46
|
||||
* @LastEditors: fzq
|
||||
* @LastEditTime: 2022-11-30 15:09:05
|
||||
*/
|
||||
/**
|
||||
* 邮箱
|
||||
* @param {*} s
|
||||
@@ -29,3 +37,11 @@ export function isPhone (s) {
|
||||
export function isURL (s) {
|
||||
return /^http[s]?:\/\/.*/.test(s)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isExternal(path) {
|
||||
return /^(https?:|mailto:|tel:)/.test(path)
|
||||
}
|
||||
@@ -1,96 +1,98 @@
|
||||
<template>
|
||||
<main :class="['aui-content', { 'aui-content--tabs': $route.meta.isTab }]">
|
||||
<!-- tab展示内容 -->
|
||||
<template v-if="$route.meta.isTab">
|
||||
<el-dropdown class="aui-content--tabs-tools">
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
<el-dropdown-menu slot="dropdown" :show-timeout="0">
|
||||
<el-dropdown-item @click.native="tabRemoveHandle($store.state.contentTabsActiveName)">{{ $t('contentTabs.closeCurrent') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="tabsCloseOtherHandle()">{{ $t('contentTabs.closeOther') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="tabsCloseAllHandle()">{{ $t('contentTabs.closeAll') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-tabs v-model="$store.state.contentTabsActiveName" @tab-click="tabSelectedHandle" @tab-remove="tabRemoveHandle">
|
||||
<el-tab-pane
|
||||
v-for="item in $store.state.contentTabs"
|
||||
:key="item.name"
|
||||
:name="item.name"
|
||||
:label="item.title"
|
||||
:closable="item.name !== 'home'"
|
||||
:class="{ 'is-iframe': tabIsIframe(item.iframeURL) }">
|
||||
<template v-if="item.name === 'home'">
|
||||
<svg slot="label" class="icon-svg aui-content--tabs-icon-nav" aria-hidden="true"><use xlink:href="#icon-home"></use></svg>
|
||||
</template>
|
||||
<iframe v-if="tabIsIframe(item.iframeURL)" :src="item.iframeURL" width="100%" height="100%" frameborder="0" scrolling="yes"></iframe>
|
||||
<keep-alive v-else>
|
||||
<router-view v-if="item.name === $store.state.contentTabsActiveName" />
|
||||
</keep-alive>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
<!-- 其他方式, 展示内容 -->
|
||||
<template v-else>
|
||||
<keep-alive>
|
||||
<router-view />
|
||||
</keep-alive>
|
||||
</template>
|
||||
</main>
|
||||
<!-- <main :class="['aui-content', { 'aui-content--tabs': $route.meta.isTab }]"> -->
|
||||
<main :class="[this.$route.meta.hiddenSiderbar !== true? ['aui-content', { 'aui-content--tabs': $route.meta.isTab }] : 'aui-sidebar.close']">
|
||||
<!-- tab展示内容 -->
|
||||
<template v-if="$route.meta.isTab">
|
||||
<el-dropdown class="aui-content--tabs-tools">
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
<el-dropdown-menu slot="dropdown" :show-timeout="0">
|
||||
<el-dropdown-item @click.native="tabRemoveHandle($store.state.contentTabsActiveName)">{{ $t('contentTabs.closeCurrent') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="tabsCloseOtherHandle()">{{ $t('contentTabs.closeOther') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="tabsCloseAllHandle()">{{ $t('contentTabs.closeAll') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-tabs v-model="$store.state.contentTabsActiveName" @tab-click="tabSelectedHandle" @tab-remove="tabRemoveHandle">
|
||||
<el-tab-pane
|
||||
v-for="item in $store.state.contentTabs"
|
||||
:key="item.name"
|
||||
:name="item.name"
|
||||
:label="item.title"
|
||||
:closable="item.name !== 'home'"
|
||||
:class="{ 'is-iframe': tabIsIframe(item.iframeURL) }"
|
||||
>
|
||||
<template v-if="item.name === 'home'">
|
||||
<svg slot="label" class="icon-svg aui-content--tabs-icon-nav" aria-hidden="true"><use xlink:href="#icon-home"></use></svg>
|
||||
</template>
|
||||
<iframe v-if="tabIsIframe(item.iframeURL)" :src="item.iframeURL" width="100%" height="100%" frameborder="0" scrolling="yes"></iframe>
|
||||
<keep-alive v-else>
|
||||
<router-view v-if="item.name === $store.state.contentTabsActiveName" />
|
||||
</keep-alive>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
<!-- 其他方式, 展示内容 -->
|
||||
<template v-else>
|
||||
<keep-alive>
|
||||
<router-view />
|
||||
</keep-alive>
|
||||
</template>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isURL } from '@/utils/validate'
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// tabs, 是否通过iframe展示
|
||||
tabIsIframe (url) {
|
||||
return isURL(url)
|
||||
},
|
||||
// tabs, 选中tab
|
||||
tabSelectedHandle (tab) {
|
||||
tab = this.$store.state.contentTabs.filter(item => item.name === tab.name)[0]
|
||||
if (tab) {
|
||||
this.$router.push({
|
||||
'name': tab.name,
|
||||
'params': { ...tab.params },
|
||||
'query': { ...tab.query }
|
||||
})
|
||||
}
|
||||
},
|
||||
// tabs, 删除tab
|
||||
tabRemoveHandle (tabName) {
|
||||
if (tabName === 'home') {
|
||||
return false
|
||||
}
|
||||
this.$store.state.contentTabs = this.$store.state.contentTabs.filter(item => item.name !== tabName)
|
||||
if (this.$store.state.contentTabs.length <= 0) {
|
||||
this.$store.state.sidebarMenuActiveName = this.$store.state.contentTabsActiveName = 'home'
|
||||
return false
|
||||
}
|
||||
// 当前选中tab被删除
|
||||
if (tabName === this.$store.state.contentTabsActiveName) {
|
||||
let tab = this.$store.state.contentTabs[this.$store.state.contentTabs.length - 1]
|
||||
this.$router.push({
|
||||
name: tab.name,
|
||||
params: { ...tab.params },
|
||||
query: { ...tab.query }
|
||||
})
|
||||
}
|
||||
},
|
||||
// tabs, 关闭其它
|
||||
tabsCloseOtherHandle () {
|
||||
this.$store.state.contentTabs = this.$store.state.contentTabs.filter(item => {
|
||||
return item.name === 'home' || item.name === this.$store.state.contentTabsActiveName
|
||||
})
|
||||
},
|
||||
// tabs, 关闭全部
|
||||
tabsCloseAllHandle () {
|
||||
this.$store.state.contentTabs = this.$store.state.contentTabs.filter(item => item.name === 'home')
|
||||
this.$router.push({ name: 'home' })
|
||||
}
|
||||
}
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
// tabs, 是否通过iframe展示
|
||||
tabIsIframe(url) {
|
||||
return isURL(url)
|
||||
},
|
||||
// tabs, 选中tab
|
||||
tabSelectedHandle(tab) {
|
||||
tab = this.$store.state.contentTabs.filter(item => item.name === tab.name)[0]
|
||||
if (tab) {
|
||||
this.$router.push({
|
||||
name: tab.name,
|
||||
params: { ...tab.params },
|
||||
query: { ...tab.query }
|
||||
})
|
||||
}
|
||||
},
|
||||
// tabs, 删除tab
|
||||
tabRemoveHandle(tabName) {
|
||||
if (tabName === 'home') {
|
||||
return false
|
||||
}
|
||||
this.$store.state.contentTabs = this.$store.state.contentTabs.filter(item => item.name !== tabName)
|
||||
if (this.$store.state.contentTabs.length <= 0) {
|
||||
this.$store.state.sidebarMenuActiveName = this.$store.state.contentTabsActiveName = 'home'
|
||||
return false
|
||||
}
|
||||
// 当前选中tab被删除
|
||||
if (tabName === this.$store.state.contentTabsActiveName) {
|
||||
let tab = this.$store.state.contentTabs[this.$store.state.contentTabs.length - 1]
|
||||
this.$router.push({
|
||||
name: tab.name,
|
||||
params: { ...tab.params },
|
||||
query: { ...tab.query }
|
||||
})
|
||||
}
|
||||
},
|
||||
// tabs, 关闭其它
|
||||
tabsCloseOtherHandle() {
|
||||
this.$store.state.contentTabs = this.$store.state.contentTabs.filter(item => {
|
||||
return item.name === 'home' || item.name === this.$store.state.contentTabsActiveName
|
||||
})
|
||||
},
|
||||
// tabs, 关闭全部
|
||||
tabsCloseAllHandle() {
|
||||
this.$store.state.contentTabs = this.$store.state.contentTabs.filter(item => item.name === 'home')
|
||||
// this.$router.push({ name: 'sys-log-login' })
|
||||
this.$router.push({ name: 'home' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,97 +1,95 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:visible.sync="visible"
|
||||
:title="$t('updatePassword.title')"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
:append-to-body="true">
|
||||
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmitHandle()" label-width="120px">
|
||||
<el-form-item :label="$t('updatePassword.username')">
|
||||
<span>{{ $store.state.user.name }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password" :label="$t('updatePassword.password')">
|
||||
<el-input v-model="dataForm.password" type="password" :placeholder="$t('updatePassword.password')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="newPassword" :label="$t('updatePassword.newPassword')">
|
||||
<el-input v-model="dataForm.newPassword" type="password" :placeholder="$t('updatePassword.newPassword')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="confirmPassword" :label="$t('updatePassword.confirmPassword')">
|
||||
<el-input v-model="dataForm.confirmPassword" type="password" :placeholder="$t('updatePassword.confirmPassword')"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template slot="footer">
|
||||
<el-button @click="visible = false">{{ $t('cancel') }}</el-button>
|
||||
<el-button type="primary" @click="dataFormSubmitHandle()">{{ $t('confirm') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog :visible.sync="visible" :title="$t('updatePassword.title')" :close-on-click-modal="false" :close-on-press-escape="false" :append-to-body="true">
|
||||
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmitHandle()" label-width="120px">
|
||||
<el-form-item :label="$t('updatePassword.username')">
|
||||
<span>{{ $store.state.user.name }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password" :label="$t('updatePassword.password')">
|
||||
<el-input v-model="dataForm.password" type="password" :placeholder="$t('updatePassword.password')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="newPassword" :label="$t('updatePassword.newPassword')">
|
||||
<el-input v-model="dataForm.newPassword" type="password" :placeholder="$t('updatePassword.newPassword')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="confirmPassword" :label="$t('updatePassword.confirmPassword')">
|
||||
<el-input v-model="dataForm.confirmPassword" type="password" :placeholder="$t('updatePassword.confirmPassword')"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template slot="footer">
|
||||
<el-button @click="visible = false">{{ $t('cancel') }}</el-button>
|
||||
<el-button type="primary" @click="dataFormSubmitHandle()">{{ $t('confirm') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import debounce from 'lodash/debounce'
|
||||
import { clearLoginInfo } from '@/utils'
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
visible: false,
|
||||
dataForm: {
|
||||
password: '',
|
||||
newPassword: '',
|
||||
confirmPassword: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dataRule () {
|
||||
var validateConfirmPassword = (rule, value, callback) => {
|
||||
if (this.dataForm.newPassword !== value) {
|
||||
return callback(new Error(this.$t('updatePassword.validate.confirmPassword')))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
return {
|
||||
password: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||
],
|
||||
newPassword: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
|
||||
{ validator: validateConfirmPassword, trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init () {
|
||||
this.visible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].resetFields()
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
dataFormSubmitHandle: debounce(function () {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
this.$http.put('/sys/user/password', this.dataForm).then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
this.$message({
|
||||
message: this.$t('prompt.success'),
|
||||
type: 'success',
|
||||
duration: 500,
|
||||
onClose: () => {
|
||||
this.visible = false
|
||||
clearLoginInfo()
|
||||
this.$router.replace({ name: 'login' })
|
||||
}
|
||||
})
|
||||
}).catch(() => {})
|
||||
})
|
||||
}, 1000, { 'leading': true, 'trailing': false })
|
||||
}
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
dataForm: {
|
||||
password: '',
|
||||
newPassword: '',
|
||||
confirmPassword: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dataRule() {
|
||||
var validateConfirmPassword = (rule, value, callback) => {
|
||||
if (this.dataForm.newPassword !== value) {
|
||||
return callback(new Error(this.$t('updatePassword.validate.confirmPassword')))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
return {
|
||||
password: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
|
||||
newPassword: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
|
||||
confirmPassword: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
|
||||
{ validator: validateConfirmPassword, trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.visible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].resetFields()
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
dataFormSubmitHandle: debounce(
|
||||
function() {
|
||||
this.$refs['dataForm'].validate(valid => {
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
this.$http
|
||||
.put('/sys/user/password', this.dataForm)
|
||||
.then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
this.$message({
|
||||
message: this.$t('prompt.success'),
|
||||
type: 'success',
|
||||
duration: 500,
|
||||
onClose: () => {
|
||||
this.visible = false
|
||||
clearLoginInfo()
|
||||
this.$router.replace({ name: 'login' })
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
})
|
||||
},
|
||||
1000,
|
||||
{ leading: true, trailing: false }
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,103 +1,178 @@
|
||||
<template>
|
||||
<nav class="aui-navbar" :class="`aui-navbar--${$store.state.navbarLayoutType}`">
|
||||
<div class="aui-navbar__header">
|
||||
<h1 class="aui-navbar__brand" @click="$router.push({ name: 'home' })">
|
||||
<a class="aui-navbar__brand-lg" href="javascript:;">{{ $t('brand.lg') }}</a>
|
||||
<a class="aui-navbar__brand-mini" href="javascript:;">{{ $t('brand.mini') }}</a>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="aui-navbar__body">
|
||||
<el-menu class="aui-navbar__menu mr-auto" mode="horizontal">
|
||||
<el-menu-item index="1" @click="$store.state.sidebarFold = !$store.state.sidebarFold">
|
||||
<svg class="icon-svg aui-navbar__icon-menu aui-navbar__icon-menu--switch" aria-hidden="true"><use xlink:href="#icon-outdent"></use></svg>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="2" @click="refresh()">
|
||||
<svg class="icon-svg aui-navbar__icon-menu aui-navbar__icon-menu--refresh" aria-hidden="true"><use xlink:href="#icon-sync"></use></svg>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<el-menu class="aui-navbar__menu" mode="horizontal">
|
||||
<el-menu-item index="2">
|
||||
<a href="https://www.renren.io/" target="_blank">
|
||||
<svg class="icon-svg aui-navbar__icon-menu" aria-hidden="true"><use xlink:href="#icon-earth"></use></svg>
|
||||
</a>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="2">
|
||||
<a href="https://gitee.com/renrenio/renren-security" target="_blank">
|
||||
<svg class="icon-svg aui-navbar__icon-menu" aria-hidden="true"><use xlink:href="#gitee"></use></svg>
|
||||
</a>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="4" @click="fullscreenHandle()">
|
||||
<svg class="icon-svg aui-navbar__icon-menu" aria-hidden="true"><use xlink:href="#icon-fullscreen"></use></svg>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="5" class="aui-navbar__avatar">
|
||||
<el-dropdown placement="bottom" :show-timeout="0">
|
||||
<span class="el-dropdown-link">
|
||||
<img src="~@/assets/img/avatar.png">
|
||||
<span>{{ $store.state.user.name }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="updatePasswordHandle()">{{ $t('updatePassword.title') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="logoutHandle()">{{ $t('logout') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
<!-- 弹窗, 修改密码 -->
|
||||
<update-password v-if="updatePasswordVisible" ref="updatePassword"></update-password>
|
||||
</nav>
|
||||
<nav
|
||||
class="aui-navbar"
|
||||
:class="[this.$route.meta.hiddenSiderbar !== true ? `aui-navbar--${$store.state.navbarLayoutType}` : 'aui-navbar.home']"
|
||||
:style="{
|
||||
backgroundColor: this.$route.meta.hiddenSiderbar !== true ? '#001529' : 'rgb(13,43,104)'
|
||||
}">
|
||||
<!-- <hamburger v-if="showhome" id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> -->
|
||||
<div class="aui-navbar__header">
|
||||
<h1 class="aui-navbar__brand" @click="$router.push({ name: 'home' })">
|
||||
<a class="aui-navbar__brand-lg" href="javascript:;">
|
||||
<img src="../assets/img/cnbm.png" style="width: 36px; height: 36px; position: relative; top: 0em; margin-right: 12px" alt="" />
|
||||
{{ $t('brand.lg') }}
|
||||
</a>
|
||||
<!-- <a class="aui-navbar__brand-mini" href="javascript:;">{{ $t('brand.mini') }}</a> -->
|
||||
<!-- 缩放时LOGO -->
|
||||
<!-- <a class="aui-navbar__brand-mini" href="javascript:;"> -->
|
||||
<a class="aui-navbar__brand-mini" href="javascript:;">
|
||||
<img src="../assets/img/cnbm.png" style="width: 36px; height: 36px; position: relative; top: 0em" alt="" />
|
||||
</a>
|
||||
</h1>
|
||||
</div>
|
||||
<!-- <breadcrumb id="breadcrumb-container" class="breadcrumb-container" /> -->
|
||||
<div
|
||||
class="aui-navbar__body"
|
||||
:style="{
|
||||
backgroundColor: this.$route.meta.hiddenSiderbar !== true ? '#fff' : 'rgb(13,43,104)'
|
||||
}">
|
||||
<el-menu class="aui-navbar__menu mr-auto" mode="horizontal">
|
||||
<el-menu-item v-if="this.$route.meta.hiddenSiderbar !== true" index="1" @click="$store.state.sidebarFold = !$store.state.sidebarFold">
|
||||
<svg class="icon-svg aui-navbar__icon-menu aui-navbar__icon-menu--switch" aria-hidden="true">
|
||||
<use xlink:href="#icon-outdent"></use>
|
||||
</svg>
|
||||
</el-menu-item>
|
||||
<el-menu-item v-if="this.$route.meta.hiddenSiderbar !== true" index="2" @click="refresh()">
|
||||
<svg class="icon-svg aui-navbar__icon-menu aui-navbar__icon-menu--refresh" aria-hidden="true">
|
||||
<use xlink:href="#icon-sync"></use>
|
||||
</svg>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<el-menu class="aui-navbar__menu" mode="horizontal">
|
||||
<!-- <el-menu-item index="2">
|
||||
<a href="https://www.renren.io/" target="_blank">
|
||||
<svg class="icon-svg aui-navbar__icon-menu" aria-hidden="true"><use xlink:href="#icon-earth"></use></svg>
|
||||
</a>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="2">
|
||||
<a href="https://gitee.com/renrenio/renren-security" target="_blank">
|
||||
<svg class="icon-svg aui-navbar__icon-menu" aria-hidden="true"><use xlink:href="#gitee"></use></svg>
|
||||
</a>
|
||||
</el-menu-item> -->
|
||||
<el-menu-item index="3">
|
||||
<!-- <el-dropdown :style="showTitle ? 'color: #fff' : '#000'" class="hover-effect" trigger="click">
|
||||
<el-badge :hidden="alarmNum > 0 ? false : true" :value="alarmNum" class="item" style="line-height: 0; margin: 0 10px; vertical-align: -3px" @click.native="handleAlarm">
|
||||
<svg-icon style="width: 24px; height: 24px" class="item-icon" icon-class="alarm" />
|
||||
</el-badge>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item>暂无数据</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown> -->
|
||||
<el-dropdown placement="bottom" :show-timeout="0" @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
<svg class="icon-svg aui-navbar__icon-menu" aria-hidden="true">
|
||||
<use xlink:href="#icon-earth"></use>
|
||||
</svg>
|
||||
<!-- <i class="el-icon-arrow-down el-icon--right"></i> -->
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :disabled="getLang() === 'zh-CN'" command="toCN">中文</el-dropdown-item>
|
||||
<el-dropdown-item :disabled="getLang() === 'en'" command="toEN">En</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="4" @click="fullscreenHandle()">
|
||||
<svg class="icon-svg aui-navbar__icon-menu" aria-hidden="true">
|
||||
<use xlink:href="#icon-fullscreen"></use>
|
||||
</svg>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="5" class="aui-navbar__avatar">
|
||||
<el-dropdown placement="bottom" :show-timeout="0">
|
||||
<span class="el-dropdown-link">
|
||||
<img src="~@/assets/img/avatar.png" />
|
||||
<span>{{ $store.state.user.name }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="updatePasswordHandle()">{{ $t('updatePassword.title') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="logoutHandle()">{{ $t('logout') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
<!-- 弹窗, 修改密码 -->
|
||||
<update-password v-if="updatePasswordVisible" ref="updatePassword"></update-password>
|
||||
</nav>
|
||||
</template>
|
||||
<script>
|
||||
// import Hamburger from '@/components/Hamburger'
|
||||
import Cookies from 'js-cookie'
|
||||
import screenfull from 'screenfull'
|
||||
import UpdatePassword from './main-navbar-update-password'
|
||||
import { clearLoginInfo } from '@/utils'
|
||||
export default {
|
||||
inject: ['refresh'],
|
||||
data () {
|
||||
return {
|
||||
updatePasswordVisible: false,
|
||||
messageTip: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
UpdatePassword
|
||||
},
|
||||
methods: {
|
||||
// 全屏
|
||||
fullscreenHandle () {
|
||||
if (!screenfull.enabled) {
|
||||
return this.$message({
|
||||
message: this.$t('fullscreen.prompt'),
|
||||
type: 'warning',
|
||||
duration: 500
|
||||
})
|
||||
}
|
||||
screenfull.toggle()
|
||||
},
|
||||
// 修改密码
|
||||
updatePasswordHandle () {
|
||||
this.updatePasswordVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.updatePassword.init()
|
||||
})
|
||||
},
|
||||
// 退出
|
||||
logoutHandle () {
|
||||
this.$confirm(this.$t('prompt.info', { 'handle': this.$t('logout') }), this.$t('prompt.title'), {
|
||||
confirmButtonText: this.$t('confirm'),
|
||||
cancelButtonText: this.$t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$http.post('/logout').then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
clearLoginInfo()
|
||||
this.$router.push({ name: 'login' })
|
||||
}).catch(() => {})
|
||||
}).catch(() => {})
|
||||
}
|
||||
}
|
||||
inject: ['refresh'],
|
||||
data() {
|
||||
return {
|
||||
updatePasswordVisible: false,
|
||||
messageTip: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
UpdatePassword
|
||||
// Hamburger
|
||||
},
|
||||
methods: {
|
||||
// 获取当前语言环境
|
||||
getLang() {
|
||||
return Cookies.get('language')
|
||||
},
|
||||
// 切换语言环境
|
||||
handleCommand(command) {
|
||||
// 切换语言选项时,可能需要手动刷新页面
|
||||
switch (command) {
|
||||
case 'toCN':
|
||||
this.$root.$i18n.locale = 'zh-CN'
|
||||
window.navigator.language = 'zh-cn'
|
||||
break
|
||||
case 'toEN':
|
||||
console.log('root', this.$root.$i18n.locale)
|
||||
this.$root.$i18n.locale = 'en'
|
||||
location.reload()
|
||||
window.navigator.language = 'en-US'
|
||||
break
|
||||
}
|
||||
},
|
||||
// 全屏
|
||||
fullscreenHandle() {
|
||||
if (!screenfull.enabled) {
|
||||
return this.$message({
|
||||
message: this.$t('fullscreen.prompt'),
|
||||
type: 'warning',
|
||||
duration: 500
|
||||
})
|
||||
}
|
||||
screenfull.toggle()
|
||||
},
|
||||
// 修改密码
|
||||
updatePasswordHandle() {
|
||||
this.updatePasswordVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.updatePassword.init()
|
||||
})
|
||||
},
|
||||
// 退出
|
||||
logoutHandle() {
|
||||
this.$confirm(this.$t('prompt.info', { handle: this.$t('logout') }), this.$t('prompt.title'), {
|
||||
confirmButtonText: this.$t('confirm'),
|
||||
cancelButtonText: this.$t('cancel'),
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
this.$http
|
||||
.post(this.$http.adornUrl('/logout'))
|
||||
.then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
clearLoginInfo()
|
||||
this.$router.push({ name: 'Login' })
|
||||
})
|
||||
.catch(() => {})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
<template>
|
||||
<el-submenu v-if="menu.children && menu.children.length >= 1" :index="menu.id" :popper-append-to-body="false">
|
||||
<template slot="title">
|
||||
<svg class="icon-svg aui-sidebar__menu-icon" aria-hidden="true"><use :xlink:href="`#${menu.icon}`"></use></svg>
|
||||
<span>{{ menu.name }}</span>
|
||||
</template>
|
||||
<sub-menu v-for="item in menu.children" :key="item.id" :menu="item"></sub-menu>
|
||||
</el-submenu>
|
||||
<el-menu-item v-else :index="menu.id" @click="gotoRouteHandle(menu.id)">
|
||||
<svg class="icon-svg aui-sidebar__menu-icon" aria-hidden="true"><use :xlink:href="`#${menu.icon}`"></use></svg>
|
||||
<span>{{ menu.name }}</span>
|
||||
</el-menu-item>
|
||||
<el-submenu v-if="menu.children && menu.children.length >= 1" :index="menu.id" :popper-append-to-body="false">
|
||||
<template slot="title">
|
||||
<svg class="icon-svg aui-sidebar__menu-icon" aria-hidden="true"><use :xlink:href="`#${menu.icon}`"></use></svg>
|
||||
<span>{{ menu.name }}</span>
|
||||
</template>
|
||||
<sub-menu v-for="item in menu.children" :key="item.id" :menu="item"></sub-menu>
|
||||
</el-submenu>
|
||||
<el-menu-item v-else :index="menu.id" @click="gotoRouteHandle(menu.id)">
|
||||
<svg class="icon-svg aui-sidebar__menu-icon" aria-hidden="true"><use :xlink:href="`#${menu.icon}`"></use></svg>
|
||||
<span>{{ menu.name }}</span>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SubMenu from './main-sidebar-sub-menu'
|
||||
export default {
|
||||
name: 'sub-menu',
|
||||
props: {
|
||||
menu: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
SubMenu
|
||||
},
|
||||
methods: {
|
||||
// 通过menuId与动态(菜单)路由进行匹配跳转至指定路由
|
||||
gotoRouteHandle (menuId) {
|
||||
var route = window.SITE_CONFIG['dynamicMenuRoutes'].filter(item => item.meta.menuId === menuId)[0]
|
||||
if (route) {
|
||||
this.$router.push({ name: route.name })
|
||||
}
|
||||
}
|
||||
}
|
||||
name: 'sub-menu',
|
||||
props: {
|
||||
menu: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
SubMenu
|
||||
},
|
||||
methods: {
|
||||
// 通过menuId与动态(菜单)路由进行匹配跳转至指定路由
|
||||
gotoRouteHandle(menuId) {
|
||||
var route = window.SITE_CONFIG['dynamicMenuRoutes'].filter(item => item.meta.menuId === menuId)[0]
|
||||
if (route) {
|
||||
this.$router.push({ name: route.name })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,30 +1,59 @@
|
||||
<template>
|
||||
<aside :class="['aui-sidebar', `aui-sidebar--${$store.state.sidebarLayoutSkin}`]">
|
||||
<div class="aui-sidebar__inner">
|
||||
<el-menu
|
||||
:default-active="$store.state.sidebarMenuActiveName"
|
||||
:collapse="$store.state.sidebarFold"
|
||||
:unique-opened="true"
|
||||
:collapseTransition="false"
|
||||
class="aui-sidebar__menu">
|
||||
<sub-menu v-for="menu in $store.state.sidebarMenuList" :key="menu.id" :menu="menu" />
|
||||
</el-menu>
|
||||
</div>
|
||||
</aside>
|
||||
<!-- <aside :class="['aui-sidebar', `aui-sidebar--${$store.state.sidebarLayoutSkin}`]"> -->
|
||||
<aside v-if="this.$route.meta.hiddenSiderbar !== true" :class="[this.$route.meta.hiddenSiderbar !== true? ['aui-sidebar',`aui-sidebar--${$store.state.sidebarLayoutSkin}`]:'aui-sidebar.close']">
|
||||
<div v-if="this.$route.meta.hiddenSiderbar !== true" :class="[this.$route.meta.hiddenSiderbar !== true? 'aui-sidebar__inner':'aui-sidebar.close']">
|
||||
<el-menu
|
||||
:default-active="$store.state.sidebarMenuActiveName"
|
||||
:collapse="$store.state.sidebarFold"
|
||||
:unique-opened="true"
|
||||
:collapseTransition="false"
|
||||
class="aui-sidebar__menu"
|
||||
>
|
||||
<sub-menu v-for="menu in unhiddenMenuList" :key="menu.id" :menu="menu" />
|
||||
</el-menu>
|
||||
</div>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SubMenu from './main-sidebar-sub-menu'
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
},
|
||||
components: {
|
||||
SubMenu
|
||||
},
|
||||
created () {
|
||||
this.$store.state.sidebarMenuList = window.SITE_CONFIG['menuList']
|
||||
}
|
||||
data() {
|
||||
return {
|
||||
unhiddenMenuList: []
|
||||
}
|
||||
},
|
||||
components: {
|
||||
SubMenu
|
||||
},
|
||||
mounted() {
|
||||
// this.$store.state.sidebarMenuList = window.SITE_CONFIG['menuList']
|
||||
this.$nextTick(() => {
|
||||
console.log(`window.SITE_CONFIG['menuList']`, window.SITE_CONFIG['menuList'])
|
||||
this.unhiddenMenuList = this.getUnhiddenRoutesListFrom(window.SITE_CONFIG['menuList'])
|
||||
/** 本地保存一份,store保存一份,感觉 store 都不需要保存... */
|
||||
this.$store.state.sidebarMenuList = this.unhiddenMenuList
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getUnhiddenRoutesListFrom(fullList) {
|
||||
const list = []
|
||||
if (fullList.length) {
|
||||
fullList.forEach(menu => {
|
||||
if (menu.sort !== 99) {
|
||||
/** 前后端约定,路由排序值为 99 时不在前端的侧边栏展示该路由 */
|
||||
const newRouteItem = JSON.parse(JSON.stringify(menu))
|
||||
if (menu.children) {
|
||||
newRouteItem.children = this.getUnhiddenRoutesListFrom(menu.children)
|
||||
}
|
||||
list.push(newRouteItem)
|
||||
} else {
|
||||
// console.log(menu.name, '是应该被隐藏的路由')
|
||||
}
|
||||
})
|
||||
}
|
||||
return list
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div v-loading.fullscreen.lock="loading" :element-loading-text="$t('loading')" :class="['aui-wrapper', { 'aui-sidebar--fold': $store.state.sidebarFold }]">
|
||||
<template v-if="!loading">
|
||||
<main-navbar />
|
||||
<main-sidebar />
|
||||
<div class="aui-content__wrapper">
|
||||
<main-content v-if="!$store.state.contentIsNeedRefresh" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div v-loading.fullscreen.lock="loading" :element-loading-text="$t('loading')" :class="['aui-wrapper', { 'aui-sidebar--fold': $store.state.sidebarFold }]">
|
||||
<template v-if="!loading">
|
||||
<main-navbar/>
|
||||
<main-sidebar v-if="this.$route.meta.hiddenSiderbar !== true"/>
|
||||
<div :class="[this.$route.meta.hiddenSiderbar !== true? 'aui-content__wrapper':'aui-sidebar.close']">
|
||||
<main-content v-if="!$store.state.contentIsNeedRefresh" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -16,87 +16,95 @@ import MainSidebar from './main-sidebar'
|
||||
import MainContent from './main-content'
|
||||
import debounce from 'lodash/debounce'
|
||||
export default {
|
||||
provide () {
|
||||
return {
|
||||
// 刷新
|
||||
refresh () {
|
||||
this.$store.state.contentIsNeedRefresh = true
|
||||
this.$nextTick(() => {
|
||||
this.$store.state.contentIsNeedRefresh = false
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
loading: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
MainNavbar,
|
||||
MainSidebar,
|
||||
MainContent
|
||||
},
|
||||
watch: {
|
||||
$route: 'routeHandle'
|
||||
},
|
||||
created () {
|
||||
this.windowResizeHandle()
|
||||
this.routeHandle(this.$route)
|
||||
Promise.all([
|
||||
this.getUserInfo(),
|
||||
this.getPermissions()
|
||||
]).then(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 窗口改变大小
|
||||
windowResizeHandle () {
|
||||
this.$store.state.sidebarFold = document.documentElement['clientWidth'] <= 992 || false
|
||||
window.addEventListener('resize', debounce(() => {
|
||||
this.$store.state.sidebarFold = document.documentElement['clientWidth'] <= 992 || false
|
||||
}, 150))
|
||||
},
|
||||
// 路由, 监听
|
||||
routeHandle (route) {
|
||||
if (!route.meta.isTab) {
|
||||
return false
|
||||
}
|
||||
var tab = this.$store.state.contentTabs.filter(item => item.name === route.name)[0]
|
||||
if (!tab) {
|
||||
tab = {
|
||||
...window.SITE_CONFIG['contentTabDefault'],
|
||||
...route.meta,
|
||||
'name': route.name,
|
||||
'params': { ...route.params },
|
||||
'query': { ...route.query }
|
||||
}
|
||||
this.$store.state.contentTabs = this.$store.state.contentTabs.concat(tab)
|
||||
}
|
||||
this.$store.state.sidebarMenuActiveName = tab.menuId
|
||||
this.$store.state.contentTabsActiveName = tab.name
|
||||
},
|
||||
// 获取当前管理员信息
|
||||
getUserInfo () {
|
||||
return this.$http.get('/sys/user/info').then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
this.$store.state.user.id = res.data.id
|
||||
this.$store.state.user.name = res.data.username
|
||||
this.$store.state.user.superAdmin = res.data.superAdmin
|
||||
}).catch(() => {})
|
||||
},
|
||||
// 获取权限
|
||||
getPermissions () {
|
||||
return this.$http.get('/sys/menu/permissions').then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
window.SITE_CONFIG['permissions'] = res.data
|
||||
}).catch(() => {})
|
||||
}
|
||||
}
|
||||
provide() {
|
||||
return {
|
||||
// 刷新
|
||||
refresh() {
|
||||
this.$store.state.contentIsNeedRefresh = true
|
||||
this.$nextTick(() => {
|
||||
this.$store.state.contentIsNeedRefresh = false
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
MainNavbar,
|
||||
MainSidebar,
|
||||
MainContent
|
||||
},
|
||||
watch: {
|
||||
$route: 'routeHandle'
|
||||
},
|
||||
created() {
|
||||
this.windowResizeHandle()
|
||||
this.routeHandle(this.$route)
|
||||
Promise.all([this.getUserInfo(), this.getPermissions()]).then(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 窗口改变大小
|
||||
windowResizeHandle() {
|
||||
this.$store.state.sidebarFold = ((document.documentElement['clientWidth'] <= 992) && (this.$route.name !== "home")) || false
|
||||
window.addEventListener(
|
||||
'resize',
|
||||
// 防抖
|
||||
debounce(() => {
|
||||
// this.$store.state.sidebarFold = document.documentElement['clientWidth'] <= 992 || false
|
||||
this.$store.state.sidebarFold = ((document.documentElement['clientWidth'] <= 992) && (this.$route.name !== "home")) || false
|
||||
}, 150)
|
||||
)
|
||||
},
|
||||
// 路由, 监听
|
||||
routeHandle(route) {
|
||||
if (!route.meta.isTab) {
|
||||
return false
|
||||
}
|
||||
var tab = this.$store.state.contentTabs.filter(item => item.name === route.name)[0]
|
||||
if (!tab) {
|
||||
tab = {
|
||||
...window.SITE_CONFIG['contentTabDefault'],
|
||||
...route.meta,
|
||||
name: route.name,
|
||||
params: { ...route.params },
|
||||
query: { ...route.query }
|
||||
}
|
||||
this.$store.state.contentTabs = this.$store.state.contentTabs.concat(tab)
|
||||
}
|
||||
this.$store.state.sidebarMenuActiveName = tab.menuId
|
||||
this.$store.state.contentTabsActiveName = tab.name
|
||||
},
|
||||
// 获取当前管理员信息
|
||||
getUserInfo() {
|
||||
return this.$http
|
||||
.get(this.$http.adornUrl('/sys/user/info'))
|
||||
.then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
this.$store.state.user.id = res.data.id
|
||||
this.$store.state.user.name = res.data.username
|
||||
this.$store.state.user.superAdmin = res.data.superAdmin
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
// 获取权限
|
||||
getPermissions() {
|
||||
return this.$http
|
||||
.get(this.$http.adornUrl('/sys/menu/permissions'))
|
||||
.then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
window.SITE_CONFIG['permissions'] = res.data
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,31 +1,244 @@
|
||||
<template>
|
||||
<el-card shadow="never" class="aui-card--fill">
|
||||
<div class="mod-home">
|
||||
<h3>项目介绍</h3>
|
||||
<ul>
|
||||
<li>renren-ui基于vue、element-ui构建开发,实现<a href="https://gitee.com/renrenio/renren-ui" target="_blank">renren-security</a>后台管理前端功能,提供一套更优的前端解决方案</li>
|
||||
<li>前后端分离,通过token进行数据交互,可独立部署</li>
|
||||
<li>动态菜单,通过菜单管理统一管理访问路由</li>
|
||||
<li>演示地址:<a href="http://demo.open.renren.io/renren-security" target="_blank">http://demo.open.renren.io/renren-security</a> (账号密码:admin/admin)</li>
|
||||
</ul>
|
||||
<h3>获取帮助</h3>
|
||||
<ul>
|
||||
<li>官方社区:<a href="https://www.renren.io/community" target="_blank">https://www.renren.io/community</a></li>
|
||||
<li>前端Git地址:<a href="https://gitee.com/renrenio/renren-ui" target="_blank">https://gitee.com/renrenio/renren-ui</a></li>
|
||||
<li>后台Git地址:<a href="https://gitee.com/renrenio/renren-security" target="_blank">https://gitee.com/renrenio/renren-security</a></li>
|
||||
<li>如需关注项目最新动态,请Watch、Star项目,同时也是对项目最好的支持</li>
|
||||
</ul>
|
||||
<h3>官方微信群</h3>
|
||||
<ul>
|
||||
<li>扫码下面的二维码,关注【人人开源】公众号,回复【加群】,即可根据提示加入微信群!</li>
|
||||
<li><img src="https://cdn.renren.io/f5cef202207132229319338.jpg" alt="微信群" /></li>
|
||||
</ul>
|
||||
<div class="choicepart-container">
|
||||
<!-- <div class="choicepat-navbar">
|
||||
<navbar :showhome="false" :show-title="true" />
|
||||
</div> -->
|
||||
<div class="choicepart-box">
|
||||
<div
|
||||
v-for="(item, index) in routeList"
|
||||
:key="item.path"
|
||||
class="choicepart-item"
|
||||
@click="handelClick(item, index)"
|
||||
>
|
||||
<!-- :style="{ background: colorArr.colorList[index % 9] }" -->
|
||||
<div class="choicepart-item-border">
|
||||
<img :src="require(`../../assets/img/choicepart/${item.name}.png`)" alt="">
|
||||
</div>
|
||||
<div class="choicepart-item-title" :title="item.name">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.mod-home {
|
||||
line-height: 1.5;
|
||||
<script>
|
||||
// import db from '@/utils/indexDB'
|
||||
// import { mapGetters } from 'vuex'
|
||||
// import { constantRoutes } from '@/router'
|
||||
// import { Navbar } from '@/layout/components'
|
||||
// import { downLoadBGP } from '@/api/user'
|
||||
import store from '@/store'
|
||||
// import { blobToBase64 } from '@/utils/blobToBase64'
|
||||
const colorList = ['#8080ff', '#ff8080', '#b004fb', '#ff409f', '#00caca', '#8080c0', '#cccc00', '#ff8040', '#0c4d9e']
|
||||
const colorList1 = ['#b4b4ff', '#ffb4b4', '#c648fb', '#ff86c2', '#66f6f6', '#a2a2f3', '#ffff9a', '#ffc3a5', '#367cd4']
|
||||
|
||||
export default {
|
||||
name: 'ChoicePart',
|
||||
// components: { Navbar },
|
||||
data() {
|
||||
return {
|
||||
baseImg: require('../../assets/img/login-back.jpg'),
|
||||
coverImgUrl: localStorage.getItem('backImg') || '',
|
||||
rowNum: 1,
|
||||
colorArr: {
|
||||
colorList,
|
||||
colorList1
|
||||
},
|
||||
windowWidth: 0,
|
||||
dbConnect: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
routeList() {
|
||||
// const cangoList = []
|
||||
// const permission_routes = store.getters.permission_routes
|
||||
// console.log(permission_routes)
|
||||
// permission_routes.map(item => {
|
||||
// if (!item.hidden && item.meta) {
|
||||
// cangoList.push(item)
|
||||
// }
|
||||
// })
|
||||
// const formatList = cangoList.map((item, index) => {
|
||||
// return this.setIndex(item, index)
|
||||
// })
|
||||
// console.log(formatList)
|
||||
return window.SITE_CONFIG['menuList']
|
||||
},
|
||||
// ...mapGetters(['language', 'dictList', 'dictObj'])
|
||||
},
|
||||
created() {
|
||||
// 确保小图标点回来依然带字符
|
||||
this.$store.state.sidebarFold = false
|
||||
this.windowWidth = window.innerWidth
|
||||
console.log(this.$route)
|
||||
// this.dbConnect = db({
|
||||
// DBName: 'back_img',
|
||||
// version: '1.0',
|
||||
// params: [
|
||||
// { name: 'id', unique: true },
|
||||
// { name: 'imgUrl', unique: true }
|
||||
// ]
|
||||
// })
|
||||
// const request = this.dbConnect.openDB()
|
||||
// request.onsuccess = () => {
|
||||
// // const result = this.dbConnect.search('back_img', 'id', 1)
|
||||
// }
|
||||
},
|
||||
mounted() {
|
||||
// console.log(this.dictList, this.dictObj)
|
||||
// this.getPic()
|
||||
},
|
||||
methods: {
|
||||
// getPic() {
|
||||
// // edit here
|
||||
// downLoadBGP().then(response => {
|
||||
// if (response.data.size) {
|
||||
// blobToBase64(response.data).then(res => {
|
||||
// this.coverImgUrl = res
|
||||
// localStorage.setItem('backImg', res)
|
||||
// console.log(res)
|
||||
// // const result = this.dbConnect.search('back_img', 'id', 1)
|
||||
// // if (result.result) {
|
||||
// // this.dbConnect.update({
|
||||
// // id: 1,
|
||||
// // imgUrl: res
|
||||
// // })
|
||||
// // } else {
|
||||
// // this.dbConnect.add({
|
||||
// // id: 1,
|
||||
// // imgUrl: res
|
||||
// // })
|
||||
// // }
|
||||
// })
|
||||
// // this.coverImgUrl = response.data
|
||||
// // const temp = response.data.split('/')
|
||||
// // temp.splice(0, 2)
|
||||
// // this.coverImgUrl = 'http://zzdhg.mes.picaiba.com/' + temp.join('/')
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
resize() {},
|
||||
handelClick(item, index) {
|
||||
// this.$store.dispatch('app/setChoicepart', index)
|
||||
// if (item.meta.unuse) {
|
||||
// this.$message.warning(this.$t('choisePart.module'))
|
||||
// } else {
|
||||
// this.toRouter(item)
|
||||
// }
|
||||
this.toRouter(item)
|
||||
},
|
||||
toRouter(item) {
|
||||
console.log(item.children[0].url)
|
||||
if (item.children) {
|
||||
this.$router.push({name: item.children[0].url.replace(new RegExp('/','g'),'-')})
|
||||
} else {
|
||||
this.$router.push({name: item.children[0].url.replace(new RegExp('/','g'),'-')})
|
||||
}
|
||||
},
|
||||
setIndex(list, index) {
|
||||
list.meta.routeIndex = index
|
||||
if (list.children) {
|
||||
list.children.map(item => {
|
||||
this.setIndex(item, index)
|
||||
})
|
||||
}
|
||||
return list
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.choicepart-container {
|
||||
min-width: 100%;
|
||||
min-height: 100vh;
|
||||
// background: linear-gradient(-45deg, rgb(25, 25, 200), rgb(0, 100, 200));
|
||||
background: url('../../assets/img/choicepart/choicepart-back.png') repeat;
|
||||
background-size: cover;
|
||||
overflow-x: scroll;
|
||||
.choicepart-box {
|
||||
width: 1440px;
|
||||
margin: 0 auto;
|
||||
margin: 0 auto;
|
||||
// 距离上面边距
|
||||
padding-top: 8vh;
|
||||
min-height: 100vh;
|
||||
.choicepart-item {
|
||||
display: inline-block;
|
||||
width: 208px;
|
||||
height: 258px;
|
||||
margin: 40px;
|
||||
background: url('../../assets/img/choicepart/choice-item-back.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
// border: 1px dashed #fff;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
|
||||
top: 0;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
img {
|
||||
width: 208px;
|
||||
height: 258px;
|
||||
}
|
||||
.choicepart-item-border {
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
padding: 0 5px;
|
||||
line-height: 32px;
|
||||
font-size: 28px;
|
||||
font-weight: lighter;
|
||||
color: #2c6bd8;
|
||||
overflow: hidden;
|
||||
}
|
||||
.choicepart-item-title {
|
||||
overflow: hidden;
|
||||
padding: 0 10px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 2px;
|
||||
right: 2px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
line-height: 48px;
|
||||
height: 48px;
|
||||
letter-spacing: 2px;
|
||||
background-color: rgba($color: #0b58ff, $alpha: 0.45);
|
||||
}
|
||||
}
|
||||
.choicepart-item:hover {
|
||||
.choicepart-item-title {
|
||||
background-color: rgba($color: #0b58ff, $alpha: 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.choicepat-navbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
::-webkit-scrollbar-track-piece {
|
||||
//滚动条凹槽的颜色,还可以设置边框属性
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
//滚动条的宽度
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
//滚动条的设置
|
||||
background-color: #dddddd;
|
||||
background-clip: padding-box;
|
||||
min-height: 28px;
|
||||
border-radius: 9px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #bbb;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -58,6 +58,12 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// destroy dialog
|
||||
handleDestroyDialog() {
|
||||
setTimeout(() => {
|
||||
this.addOrUpdateVisible= false
|
||||
}, /** after dialog animated */ 200);
|
||||
},
|
||||
init () {
|
||||
this.visible = true
|
||||
this.$nextTick(() => {
|
||||
@@ -72,7 +78,7 @@ export default {
|
||||
},
|
||||
// 获取信息
|
||||
getInfo () {
|
||||
this.$http.get(`/sys/schedule/${this.dataForm.id}`).then(({ data: res }) => {
|
||||
this.$http.get(this.$http.adornUrl(`/sys/schedule/${this.dataForm.id}`)).then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
@@ -85,7 +91,7 @@ export default {
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
this.$http[!this.dataForm.id ? 'post' : 'put']('/sys/schedule', this.dataForm).then(({ data: res }) => {
|
||||
this.$http[!this.dataForm.id ? 'post' : 'put'](this.$http.adornUrl('/sys/schedule'), this.dataForm).then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<el-dialog :visible.sync="visible" :title="$t('schedule.log')" :close-on-click-modal="false" :close-on-press-escape="false" width="75%">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="currentChangeHandle(1)">
|
||||
<el-form-item>
|
||||
<el-input v-model="dataForm.jobId" :placeholder="$t('schedule.jobId')" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="getDataList()">{{ $t('query') }}</el-button>
|
||||
<el-button @click="currentChangeHandle(1)">{{ $t('query') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table
|
||||
@@ -56,13 +56,19 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// destroy dialog
|
||||
handleDestroyDialog() {
|
||||
setTimeout(() => {
|
||||
this.addOrUpdateVisible= false
|
||||
}, /** after dialog animated */ 200);
|
||||
},
|
||||
init () {
|
||||
this.visible = true
|
||||
this.getDataList()
|
||||
},
|
||||
// 失败信息
|
||||
showErrorInfo (id) {
|
||||
this.$http.get(`/sys/scheduleLog/${id}`).then(({ data: res }) => {
|
||||
this.$http.get(this.$http.adornUrl(`/sys/scheduleLog/${id}`)).then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<el-card shadow="never" class="aui-card--fill">
|
||||
<div class="mod-job__schedule">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="currentChangeHandle(1)">
|
||||
<el-form-item>
|
||||
<el-input v-model="dataForm.beanName" :placeholder="$t('schedule.beanName')" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="getDataList()">{{ $t('query') }}</el-button>
|
||||
<el-button @click="currentChangeHandle(1)">{{ $t('query') }}</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button v-if="$hasPermission('sys:schedule:save')" type="primary" @click="addOrUpdateHandle()">{{ $t('add') }}</el-button>
|
||||
@@ -97,6 +97,12 @@ export default {
|
||||
Log
|
||||
},
|
||||
methods: {
|
||||
// destroy dialog
|
||||
handleDestroyDialog() {
|
||||
setTimeout(() => {
|
||||
this.addOrUpdateVisible= false
|
||||
}, /** after dialog animated */ 200);
|
||||
},
|
||||
// 暂停
|
||||
pauseHandle (id) {
|
||||
if (!id && this.dataListSelections.length <= 0) {
|
||||
@@ -111,7 +117,7 @@ export default {
|
||||
cancelButtonText: this.$t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$http.put('/sys/schedule/pause', id ? [id] : this.dataListSelections.map(item => item.id)).then(({ data: res }) => {
|
||||
this.$http.put(this.$http.adornUrl('/sys/schedule/pause'), id ? [id] : this.dataListSelections.map(item => item.id)).then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
@@ -140,7 +146,7 @@ export default {
|
||||
cancelButtonText: this.$t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$http.put('/sys/schedule/resume', id ? [id] : this.dataListSelections.map(item => item.id)).then(({ data: res }) => {
|
||||
this.$http.put(this.$http.adornUrl('/sys/schedule/resume'), id ? [id] : this.dataListSelections.map(item => item.id)).then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
@@ -169,7 +175,7 @@ export default {
|
||||
cancelButtonText: this.$t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$http.put('/sys/schedule/run', id ? [id] : this.dataListSelections.map(item => item.id)).then(({ data: res }) => {
|
||||
this.$http.put(this.$http.adornUrl('/sys/schedule/run'), id ? [id] : this.dataListSelections.map(item => item.id)).then(({ data: res }) => {
|
||||
if (res.code !== 0) {
|
||||
return this.$message.error(res.msg)
|
||||
}
|
||||
|
||||
563
src/views/modules/monitoring/equipment.vue
Normal file
@@ -0,0 +1,563 @@
|
||||
<template>
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="currentChangeHandle(1)" class="blueTip" size="small">
|
||||
<el-form-item>
|
||||
<el-input v-model="dataForm.key" :placeholder="$t('eq.name') + ' / ' + $t('eq.code')" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="buttonColor" @click="currentChangeHandle(1)">{{ $t('search') }}</el-button>
|
||||
<!-- <el-button v-if="$hasPermission('monitoring:equipment:save')" type="primary" @click="addOrUpdateHandle()">{{ $t('add') }}</el-button> -->
|
||||
<el-button v-if="$hasPermission('monitoring:equipment:export')" @click="exportHandle()">{{ $t('export') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<base-table
|
||||
:top-btn-config="topBtnConfig"
|
||||
:page="pageIndex"
|
||||
:size="pageSize"
|
||||
:data="dataList"
|
||||
:table-head-configs="tableConfigs"
|
||||
:max-height="calcMaxHeight(8)"
|
||||
@operate-event="handleOperations"
|
||||
@refreshDataList="getDataList"
|
||||
@clickTopBtn="clickTopBtn"
|
||||
/>
|
||||
<el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
<!-- 弹窗, 新增 / 修改 -->
|
||||
<add-or-update
|
||||
v-if="addOrUpdateVisible"
|
||||
ref="addOrUpdate"
|
||||
:configs="addOrUpdateConfigs"
|
||||
@refreshDataList="getDataList"
|
||||
@select-change="handleDialogSelectChange"
|
||||
@destory-dialog="handleDestroyDialog"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import i18n from '@/i18n'
|
||||
import AddOrUpdate from '@/components/base-dialog/addOrUpdate'
|
||||
// import AddOrUpdate from './equipment-add-or-update'
|
||||
import BaseTable from '@/components/base-table'
|
||||
import TableOperateComponent from '@/components/base-table/components/operationComponent'
|
||||
import TableTextComponent from '@/components/base-table/components/detailComponent'
|
||||
import CKEditor from 'ckeditor4-vue'
|
||||
import { calcMaxHeight } from '@/utils'
|
||||
import { timeFilter } from '@/utils/filters'
|
||||
import Cookies from 'js-cookie'
|
||||
const topBtnConfig = [
|
||||
{
|
||||
type: 'add',
|
||||
btnName: i18n.t('add')
|
||||
}
|
||||
]
|
||||
const tableConfigs = [
|
||||
{
|
||||
type: 'index',
|
||||
name: i18n.t('index')
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
name: i18n.t('createTime'),
|
||||
filter: timeFilter
|
||||
},
|
||||
{ prop: 'name', name: i18n.t('eq.name') },
|
||||
{ prop: 'code', name: i18n.t('eq.code') },
|
||||
{ prop: 'equipmentTypeName', name: i18n.t('eq.type') },
|
||||
{ prop: 'groupName', name: i18n.t('eq.group') },
|
||||
{ prop: 'enName', name: i18n.t('enname') },
|
||||
{ prop: 'abbr', name: i18n.t('abbr') },
|
||||
{ prop: 'lineName', name: i18n.t('pl.title') },
|
||||
{ prop: 'sectionName', name: i18n.t('ws.title') },
|
||||
{
|
||||
prop: 'details',
|
||||
name: i18n.t('detail'),
|
||||
subcomponent: TableTextComponent,
|
||||
actionName: 'view-detail'
|
||||
},
|
||||
{
|
||||
prop: 'operations',
|
||||
name: i18n.t('handle'),
|
||||
fixed: 'right',
|
||||
width: 180,
|
||||
subcomponent: TableOperateComponent,
|
||||
options: ['edit', 'delete']
|
||||
}
|
||||
]
|
||||
|
||||
const addOrUpdateConfigs = {
|
||||
type: 'dialog',
|
||||
infoUrl: '/monitoring/equipment',
|
||||
fields: [
|
||||
{ name: 'name', label: i18n.t('eq.name'), required: true },
|
||||
{ name: 'code', label: i18n.t('eq.code'), required: true, api: '/monitoring/equipment/getCode' },
|
||||
{ name: 'enName', label: i18n.t('enname') },
|
||||
{ name: 'abbr', label: i18n.t('abbr') },
|
||||
{
|
||||
name: 'equipmentTypeId',
|
||||
label: i18n.t('eq.type'),
|
||||
required: true,
|
||||
type: 'select',
|
||||
options: []
|
||||
},
|
||||
{
|
||||
name: 'lineId',
|
||||
label: i18n.t('pl.title'),
|
||||
required: true,
|
||||
type: 'select',
|
||||
options: [],
|
||||
relatedField: 'sectionId' // 关联下面的id,在更换lineId时,会清空相应的sectionId选择结果
|
||||
},
|
||||
{
|
||||
name: 'sectionId',
|
||||
label: i18n.t('ws.title'),
|
||||
required: true,
|
||||
type: 'select',
|
||||
options: []
|
||||
},
|
||||
{
|
||||
name: 'sort',
|
||||
label: i18n.t('ws.sort'),
|
||||
type: 'number',
|
||||
rules: [{ type: 'number', message: i18n.t('hints.number'), trigger: 'blur', transform: val => Number(val) }]
|
||||
},
|
||||
{
|
||||
name: 'groupId',
|
||||
label: i18n.t('eq.group'),
|
||||
required: true,
|
||||
type: 'select',
|
||||
options: []
|
||||
},
|
||||
{
|
||||
name: 'productionTime',
|
||||
label: i18n.t('produceTime'),
|
||||
type: 'date',
|
||||
props: {
|
||||
'type': 'date', // element-ui 的配置
|
||||
'placeholder': i18n.t('hints.date'),
|
||||
'value-format': 'yyyy-MM-ddTHH:mm:ss',
|
||||
'style': {
|
||||
width: '100%'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'enterTime',
|
||||
label: i18n.t('enterTime'),
|
||||
type: 'date',
|
||||
props: {
|
||||
'type': 'date', // element-ui 的配置
|
||||
'placeholder': i18n.t('hints.date'),
|
||||
'value-format': 'yyyy-MM-ddTHH:mm:ss',
|
||||
'style': {
|
||||
width: '100%'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'tvalue',
|
||||
label: i18n.t('eq.tvalue'),
|
||||
required: true,
|
||||
rules: [
|
||||
{
|
||||
type: 'number',
|
||||
message: i18n.t('hints.number'),
|
||||
trigger: 'blur',
|
||||
transform: val => Number(val)
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'processingTime',
|
||||
label: i18n.t('eq.processingTime'),
|
||||
rules: [
|
||||
{
|
||||
type: 'number',
|
||||
message: i18n.t('hints.number'),
|
||||
trigger: 'blur',
|
||||
transform: val => Number(val)
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'manufacturer', label: i18n.t('manufacturer') },
|
||||
{ name: 'spec', label: i18n.t('eq.grade') },
|
||||
{
|
||||
name: 'dataType',
|
||||
label: i18n.t('eq.dtype'),
|
||||
required: true,
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: 0, label: i18n.t('eq.dtypenone') },
|
||||
{ value: 1, label: i18n.t('eq.dtypeinput') },
|
||||
{ value: 2, label: i18n.t('eq.dtypeoutput') }
|
||||
]
|
||||
},
|
||||
{ name: 'remark', label: i18n.t('remark') }
|
||||
],
|
||||
extraComponents: [
|
||||
{
|
||||
name: 'description',
|
||||
hasModel: true,
|
||||
label: i18n.t('desc'),
|
||||
fieldType: 'string',
|
||||
component: CKEditor.component,
|
||||
props: {
|
||||
// value: 'tests',
|
||||
config: {
|
||||
// ckeditor 的配置: https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html
|
||||
// toolbar: [['Bold']]
|
||||
language: Cookies.get('language') || 'en'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'files',
|
||||
label: i18n.t('upload.title'),
|
||||
fieldType: 'array',
|
||||
component: () => import('@/components/base-upload'),
|
||||
props: {
|
||||
// 上传组件需要的 props
|
||||
url: '/monitoring/attachment/uploadFileFormData',
|
||||
extraParams: { typeCode: 'EquipmentInfoFile' },
|
||||
buttonContent: i18n.t('upload.button'),
|
||||
tip: i18n.t('hints.upload2m')
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'files',
|
||||
label: i18n.t('eq.image'),
|
||||
fieldType: 'array',
|
||||
component: () => import('@/components/base-upload'),
|
||||
props: {
|
||||
// 上传组件需要的 props
|
||||
url: '/monitoring/attachment/uploadFileFormData',
|
||||
extraParams: { typeCode: 'EquipmentInfoImage' },
|
||||
buttonContent: i18n.t('upload.button'),
|
||||
tip: i18n.t('hints.upload2mPic')
|
||||
}
|
||||
}
|
||||
],
|
||||
subtable: {
|
||||
title: i18n.t('eq.viewattr'),
|
||||
url: '/monitoring/equipmentAttr',
|
||||
relatedField: 'equipmentId',
|
||||
tableConfigs: [
|
||||
{ type: 'index', width: 100, name: i18n.t('index') },
|
||||
{ prop: 'createTime', name: i18n.t('createTime'), filter: timeFilter },
|
||||
{ prop: 'attrName', name: i18n.t('attrName'), formField: true },
|
||||
{ prop: 'attrValue', name: i18n.t('attrValue'), formField: true },
|
||||
{
|
||||
prop: 'operations',
|
||||
name: i18n.t('handle'),
|
||||
fixed: 'right',
|
||||
width: 180,
|
||||
subcomponent: TableOperateComponent,
|
||||
options: ['edit', 'delete']
|
||||
}
|
||||
]
|
||||
},
|
||||
operations: [
|
||||
{ name: 'cancel', showAlways: true },
|
||||
{
|
||||
name: 'save',
|
||||
url: '/monitoring/equipment',
|
||||
permission: 'monitoring:equipment:save',
|
||||
showOnEdit: false
|
||||
},
|
||||
{
|
||||
name: 'update',
|
||||
url: '/monitoring/equipment',
|
||||
permission: 'monitoring:equipment:update',
|
||||
showOnEdit: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
topBtnConfig,
|
||||
calcMaxHeight,
|
||||
tableConfigs,
|
||||
addOrUpdateConfigs,
|
||||
dataForm: {
|
||||
key: ''
|
||||
},
|
||||
dataList: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
dataListLoading: false,
|
||||
dataListSelections: [],
|
||||
addOrUpdateVisible: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
AddOrUpdate,
|
||||
BaseTable
|
||||
},
|
||||
activated() {
|
||||
console.log('activated')
|
||||
this.getDataList()
|
||||
this.getGroupList()
|
||||
this.getPlList()
|
||||
this.getTypeList()
|
||||
},
|
||||
methods: {
|
||||
// destroy dialog
|
||||
handleDestroyDialog() {
|
||||
setTimeout(() => {
|
||||
this.addOrUpdateVisible = false
|
||||
}, /** after dialog animated */ 200)
|
||||
},
|
||||
// 获取产线列表,用于刷新工段列表
|
||||
getPlList() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/productionLine/list'),
|
||||
method: 'get'
|
||||
}).then(({ data: res }) => {
|
||||
const plConfig = this.addOrUpdateConfigs.fields.find(item => item.name === 'lineId')
|
||||
plConfig.options =
|
||||
res.data?.map(item => ({
|
||||
value: item.id,
|
||||
label: item.name
|
||||
})) || []
|
||||
})
|
||||
},
|
||||
// 获取工段列表
|
||||
getWsList(id) {
|
||||
let params = {
|
||||
page: 1,
|
||||
limit: 999
|
||||
}
|
||||
if (id) {
|
||||
params.lineId = id
|
||||
}
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/workshopSection/page'),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams(params)
|
||||
}).then(({ data: res }) => {
|
||||
const wsConfig = this.addOrUpdateConfigs.fields.find(item => item.name === 'sectionId')
|
||||
wsConfig.options =
|
||||
res.data?.list?.map(item => ({
|
||||
value: item.id,
|
||||
label: item.name
|
||||
})) || []
|
||||
})
|
||||
},
|
||||
// 获取设备类型列表
|
||||
getTypeList() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/equipmentType/page'),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams({
|
||||
// page: this.pageIndex,
|
||||
// limit: this.pageSize,
|
||||
// key: this.dataForm.key
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
const eqTypeConfig = this.addOrUpdateConfigs.fields.find(item => item.name === 'equipmentTypeId')
|
||||
eqTypeConfig.options =
|
||||
data.data?.list?.map(item => ({
|
||||
value: item.id,
|
||||
label: item.name
|
||||
})) || []
|
||||
})
|
||||
},
|
||||
// 获取设备分组列表
|
||||
getGroupList() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/equipmentGroup/page'),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams({
|
||||
// page: this.pageIndex,
|
||||
// limit: this.pageSize,
|
||||
// key: this.dataForm.key
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
const groupConfig = this.addOrUpdateConfigs.fields.find(item => item.name === 'groupId')
|
||||
groupConfig.options =
|
||||
data.data?.list?.map(item => ({
|
||||
value: item.id,
|
||||
label: item.name
|
||||
})) || []
|
||||
})
|
||||
},
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.dataListLoading = true
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/equipment/page'),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams({
|
||||
page: this.pageIndex,
|
||||
limit: this.pageSize,
|
||||
key: this.dataForm.key
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataList = data.data.list
|
||||
// this.dataList = new Array(20).fill('1')
|
||||
// console.log('data list', this.dataList)
|
||||
this.totalPage = data.data.total
|
||||
} else {
|
||||
this.dataList = []
|
||||
this.totalPage = 0
|
||||
}
|
||||
this.dataListLoading = false
|
||||
})
|
||||
},
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val
|
||||
this.pageIndex = 1
|
||||
this.getDataList()
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val
|
||||
this.getDataList()
|
||||
},
|
||||
// 多选
|
||||
selectionChangeHandle(val) {
|
||||
this.dataListSelections = val
|
||||
},
|
||||
// 对话框里的某个选择改变了
|
||||
handleDialogSelectChange({ name, id }) {
|
||||
switch (name) {
|
||||
case 'lineId':
|
||||
this.getWsList(id)
|
||||
}
|
||||
},
|
||||
handleOperations({ type, data: id }) {
|
||||
switch (type) {
|
||||
case 'view-detail':
|
||||
// const { name, code } = this.dataList.find(item => item.id === id)
|
||||
// this.$router.push({
|
||||
// name: 'monitoring-equipmentAdd',
|
||||
// params: {
|
||||
// isdetail: true,
|
||||
// equipmentId: id
|
||||
// }
|
||||
// })
|
||||
// break
|
||||
return this.addOrUpdateHandle(id, true)
|
||||
case 'edit':
|
||||
return this.addOrUpdateHandle(id)
|
||||
case 'delete':
|
||||
return this.deleteHandle(id)
|
||||
}
|
||||
},
|
||||
exportHandle() {
|
||||
// this.$http.get(this.$http.adornUrl('/monitoring/equipment/export')).then(({ data: res }) => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/equipment/export'),
|
||||
method: 'get',
|
||||
responseType: 'blob'
|
||||
}).then(res => {
|
||||
let fileName = 'equipment-list.xls'
|
||||
if (res.headers['content-disposition']) {
|
||||
const contentDisposition = res.headers['content-disposition']
|
||||
fileName = contentDisposition.slice(contentDisposition.indexOf('filename=') + 9)
|
||||
}
|
||||
|
||||
fileName = decodeURIComponent(fileName)
|
||||
|
||||
const blob = new Blob([res.data])
|
||||
|
||||
if ('download' in document.createElement('a')) {
|
||||
const alink = document.createElement('a')
|
||||
alink.download = fileName
|
||||
alink.style.display = 'none'
|
||||
alink.target = '_blank'
|
||||
alink.href = URL.createObjectURL(blob)
|
||||
document.body.appendChild(alink)
|
||||
alink.click()
|
||||
URL.revokeObjectURL(alink.href)
|
||||
document.body.removeChild(alink)
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName)
|
||||
}
|
||||
})
|
||||
},
|
||||
// 新增 / 修改
|
||||
addOrUpdateHandle(id, isdetail = false) {
|
||||
this.addOrUpdateVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.addOrUpdate.init(id, isdetail)
|
||||
})
|
||||
// this.$router.push({
|
||||
// name: 'monitoring-equipmentAdd',
|
||||
// params: {
|
||||
// equipmentId: id
|
||||
// }
|
||||
// })
|
||||
},
|
||||
clickTopBtn() {
|
||||
this.addOrUpdateVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.addOrUpdate.init()
|
||||
})
|
||||
},
|
||||
// 删除
|
||||
deleteHandle(id) {
|
||||
var ids = id
|
||||
? [id]
|
||||
: this.dataListSelections.map(item => {
|
||||
return item.id
|
||||
})
|
||||
this.$confirm(`${i18n.t('prompt.info', { handle: id ? i18n.t('delete').toLowerCase() : i18n.t('deleteBatch').toLowerCase() })}`, i18n.t('prompt.title'), {
|
||||
confirmButtonText: i18n.t('confirm'),
|
||||
cancelButtonText: i18n.t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/equipment'),
|
||||
method: 'delete',
|
||||
data: this.$http.adornData(ids, false, 'raw')
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: i18n.t('prompt.success'),
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.getDataList()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.error(data.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.blueTip::before {
|
||||
display: inline-block;
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background: #0b58ff;
|
||||
border-radius: 1px;
|
||||
margin-right: 8px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.buttonColor {
|
||||
color: #fff;
|
||||
background: #0b58ff;
|
||||
}
|
||||
</style>
|
||||
163
src/views/modules/monitoring/equipmentAlarmLog-add-or-update.vue
Normal file
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<el-dialog :title="!dataForm.id ? i18n.t('add') : i18n.t('update')" :close-on-click-modal="false" :visible.sync="visible">
|
||||
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="80px">
|
||||
<el-form-item label="报警信息ID,关联T_equipment_group_alarm表" prop="alarmId">
|
||||
<el-input v-model="dataForm.alarmId" placeholder="报警信息ID,关联T_equipment_group_alarm表"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="报警来源" prop="alarmSource">
|
||||
<el-input v-model="dataForm.alarmSource" placeholder="报警来源"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="报警详细内容" prop="alarmContent">
|
||||
<el-input v-model="dataForm.alarmContent" placeholder="报警详细内容"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="报警设备id 关联equipment表" prop="alarmEquipmentId">
|
||||
<el-input v-model="dataForm.alarmEquipmentId" placeholder="报警设备id 关联equipment表"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="dataForm.remark" placeholder="备注"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="删除标志,是否有效:1 可用 0不可用" prop="valid">
|
||||
<el-input v-model="dataForm.valid" placeholder="删除标志,是否有效:1 可用 0不可用"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('creator')" prop="creatorId">
|
||||
<el-input v-model="dataForm.creatorId" :placeholder="$t('creator')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('creatorName')" prop="creatorName">
|
||||
<el-input v-model="dataForm.creatorName" :placeholder="$t('creatorName')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-input v-model="dataForm.createTime" placeholder="创建时间"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('updator')" prop="updaterId">
|
||||
<el-input v-model="dataForm.updaterId" :placeholder="$t('updator')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('updatorName')" prop="updaterName">
|
||||
<el-input v-model="dataForm.updaterName" :placeholder="$t('updatorName')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('updateTime')" prop="updateTime">
|
||||
<el-input v-model="dataForm.updateTime" :placeholder="$t('updateTime')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('version')" prop="version">
|
||||
<el-input v-model="dataForm.version" :placeholder="$t('version')"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="visible = false">{{ $t('cancel') }}</el-button>
|
||||
<el-button type="primary" @click="dataFormSubmit()">{{ $t('confirm') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
dataForm: {
|
||||
id: 0,
|
||||
alarmId: '',
|
||||
alarmSource: '',
|
||||
alarmContent: '',
|
||||
alarmEquipmentId: '',
|
||||
remark: '',
|
||||
valid: '',
|
||||
creatorId: '',
|
||||
creatorName: '',
|
||||
createTime: '',
|
||||
updaterId: '',
|
||||
updaterName: '',
|
||||
updateTime: '',
|
||||
version: ''
|
||||
},
|
||||
dataRule: {
|
||||
alarmId: [{ required: true, message: '报警信息ID,关联T_equipment_group_alarm表不能为空', trigger: 'blur' }],
|
||||
alarmSource: [{ required: true, message: '报警来源不能为空', trigger: 'blur' }],
|
||||
alarmContent: [{ required: true, message: '报警详细内容不能为空', trigger: 'blur' }],
|
||||
alarmEquipmentId: [{ required: true, message: '报警设备id 关联equipment表不能为空', trigger: 'blur' }],
|
||||
remark: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
|
||||
valid: [{ required: true, message: '删除标志,是否有效:1 可用 0不可用不能为空', trigger: 'blur' }],
|
||||
creatorId: [{ required: true, message: '创建人不能为空', trigger: 'blur' }],
|
||||
creatorName: [{ required: true, message: '创建人姓名不能为空', trigger: 'blur' }],
|
||||
createTime: [{ required: true, message: '创建时间不能为空', trigger: 'blur' }],
|
||||
updaterId: [{ required: true, message: '更新人不能为空', trigger: 'blur' }],
|
||||
updaterName: [{ required: true, message: '更新人姓名不能为空', trigger: 'blur' }],
|
||||
updateTime: [{ required: true, message: '更新时间不能为空', trigger: 'blur' }],
|
||||
version: [{ required: true, message: '版本号不能为空', trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init(id) {
|
||||
this.dataForm.id = id || 0
|
||||
this.visible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].resetFields()
|
||||
if (this.dataForm.id) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`/monitoring/equipmentAlarmLog/${this.dataForm.id}`),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams()
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataForm.alarmId = data.equipmenalarmLog.alarmId
|
||||
this.dataForm.alarmSource = data.equipmenalarmLog.alarmSource
|
||||
this.dataForm.alarmContent = data.equipmenalarmLog.alarmContent
|
||||
this.dataForm.alarmEquipmentId = data.equipmenalarmLog.alarmEquipmentId
|
||||
this.dataForm.remark = data.equipmenalarmLog.remark
|
||||
this.dataForm.valid = data.equipmenalarmLog.valid
|
||||
this.dataForm.creatorId = data.equipmenalarmLog.creatorId
|
||||
this.dataForm.creatorName = data.equipmenalarmLog.creatorName
|
||||
this.dataForm.createTime = data.equipmenalarmLog.createTime
|
||||
this.dataForm.updaterId = data.equipmenalarmLog.updaterId
|
||||
this.dataForm.updaterName = data.equipmenalarmLog.updaterName
|
||||
this.dataForm.updateTime = data.equipmenalarmLog.updateTime
|
||||
this.dataForm.version = data.equipmenalarmLog.version
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
dataFormSubmit() {
|
||||
this.$refs['dataForm'].validate(valid => {
|
||||
if (valid) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`/monitoring/equipmentAlarmLog/${!this.dataForm.id ? '' : this.dataForm.id}`),
|
||||
method: this.dataForm.id ? 'put' : 'post',
|
||||
data: this.$http.adornData({
|
||||
id: this.dataForm.id || undefined,
|
||||
alarmId: this.dataForm.alarmId,
|
||||
alarmSource: this.dataForm.alarmSource,
|
||||
alarmContent: this.dataForm.alarmContent,
|
||||
alarmEquipmentId: this.dataForm.alarmEquipmentId,
|
||||
remark: this.dataForm.remark,
|
||||
valid: this.dataForm.valid,
|
||||
creatorId: this.dataForm.creatorId,
|
||||
creatorName: this.dataForm.creatorName,
|
||||
createTime: this.dataForm.createTime,
|
||||
updaterId: this.dataForm.updaterId,
|
||||
updaterName: this.dataForm.updaterName,
|
||||
updateTime: this.dataForm.updateTime,
|
||||
version: this.dataForm.version
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: i18n.t('prompt.success'),
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.visible = false
|
||||
this.$emit('refreshDataList')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.error(data.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
164
src/views/modules/monitoring/equipmentAlarmLog.vue
Normal file
@@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="currentChangeHandle(1)">
|
||||
<el-form-item>
|
||||
<el-input v-model="dataForm.key" :placeholder="$t('parameter')" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="currentChangeHandle(1)">{{ $t('query') }}</el-button>
|
||||
<el-button v-if="$hasPermission('monitoring:equipmenalarmlog:save')" type="primary" @click="addOrUpdateHandle()">{{ $t('add') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<base-table :page="pageIndex" :size="pageSize" :data="dataList" :table-head-configs="tableConfigs" :max-height="calcMaxHeight(8)" />
|
||||
<el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
>
|
||||
</el-pagination>
|
||||
<!-- 弹窗, 新增 / 修改 -->
|
||||
<add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AddOrUpdate from './equipmentAlarmLog-add-or-update'
|
||||
import i18n from '@/i18n'
|
||||
import BaseTable from '@/components/base-table'
|
||||
import TableOperateComponent from '@/components/base-table/components/operationComponent'
|
||||
import TableTextComponent from '@/components/base-table/components/detailComponent'
|
||||
import { calcMaxHeight } from '@/utils'
|
||||
import { timeFilter } from '@/utils/filters'
|
||||
const tableConfigs = [
|
||||
{ prop: 'id', name: 'ID' },
|
||||
{ prop: 'alarmId', name: '报警信息ID,关联T_equipment_group_alarm表' },
|
||||
{ prop: 'alarmSource', name: '报警来源' },
|
||||
{ prop: 'alarmContent', name: '报警详细内容' },
|
||||
{ prop: 'alarmEquipmentId', name: '报警设备id 关联equipment表' },
|
||||
{ prop: 'remark', name: i18n.t('remark') },
|
||||
{ prop: 'valid', name: i18n.t('delMark') },
|
||||
{ prop: 'creatorId', name: i18n.t('creator') },
|
||||
{ prop: 'creatorName', name: i18n.t('creatorName') },
|
||||
{ prop: 'createTime', name: i18n.t('createTime'), filter: timeFilter },
|
||||
{ prop: 'updaterId', name: i18n.t('updator') },
|
||||
{ prop: 'updaterName', name: i18n.t('updatorName') },
|
||||
{ prop: 'updateTime', name: i18n.t('updateTime'), filter: timeFilter },
|
||||
{ prop: 'version', name: i18n.t('version') },
|
||||
{ prop: 'operations', name: i18n.t('handle'), fixed: 'right', width: 180, subcomponent: TableOperateComponent, options: ['edit', 'delete'] }
|
||||
]
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableConfigs,
|
||||
calcMaxHeight,
|
||||
dataForm: {
|
||||
key: ''
|
||||
},
|
||||
dataList: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
dataListLoading: false,
|
||||
dataListSelections: [],
|
||||
addOrUpdateVisible: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
AddOrUpdate,
|
||||
BaseTable
|
||||
},
|
||||
activated() {
|
||||
this.getDataList()
|
||||
},
|
||||
methods: {
|
||||
// destroy dialog
|
||||
handleDestroyDialog() {
|
||||
setTimeout(() => {
|
||||
this.addOrUpdateVisible= false
|
||||
}, /** after dialog animated */ 200);
|
||||
},
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.dataListLoading = true
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/equipmentAlarmLog/page'),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams({
|
||||
page: this.pageIndex,
|
||||
limit: this.pageSize,
|
||||
key: this.dataForm.key
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataList = data.data.list
|
||||
this.totalPage = data.data.total
|
||||
} else {
|
||||
this.dataList = []
|
||||
this.totalPage = 0
|
||||
}
|
||||
this.dataListLoading = false
|
||||
})
|
||||
},
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val
|
||||
this.pageIndex = 1
|
||||
this.getDataList()
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val
|
||||
this.getDataList()
|
||||
},
|
||||
// 多选
|
||||
selectionChangeHandle(val) {
|
||||
this.dataListSelections = val
|
||||
},
|
||||
// 新增 / 修改
|
||||
addOrUpdateHandle(id) {
|
||||
this.addOrUpdateVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.addOrUpdate.init(id)
|
||||
})
|
||||
},
|
||||
// 删除
|
||||
deleteHandle(id) {
|
||||
var ids = id
|
||||
? [id]
|
||||
: this.dataListSelections.map(item => {
|
||||
return item.id
|
||||
})
|
||||
this.$confirm(`${ i18n.t('prompt.info', { handle: id ? i18n.t('delete').toLowerCase() : i18n.t('deleteBatch').toLowerCase() }) }`, i18n.t('prompt.title'), {
|
||||
confirmButtonText: i18n.t('confirm'),
|
||||
cancelButtonText: i18n.t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/equipmentAlarmLog'),
|
||||
method: 'delete',
|
||||
data: this.$http.adornData(ids, false, 'raw')
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: i18n.t('prompt.success'),
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.getDataList()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.error(data.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
156
src/views/modules/monitoring/equipmentAttr-add-or-update.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<el-dialog :title="!dataForm.id ? i18n.t('add') : i18n.t('update')" :close-on-click-modal="false" :visible.sync="visible">
|
||||
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="80px">
|
||||
<el-form-item label="设备ID" prop="equipmentId">
|
||||
<el-input v-model="dataForm.equipmentId" placeholder="设备ID"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="属性名称" prop="attrName">
|
||||
<el-input v-model="dataForm.attrName" placeholder="属性名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="属性值" prop="attrValue">
|
||||
<el-input v-model="dataForm.attrValue" placeholder="属性值"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="dataForm.remark" placeholder="备注"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="删除标志,是否有效:1 可用 0不可用" prop="valid">
|
||||
<el-input v-model="dataForm.valid" placeholder="删除标志,是否有效:1 可用 0不可用"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('creator')" prop="creatorId">
|
||||
<el-input v-model="dataForm.creatorId" :placeholder="$t('creator')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('creatorName')" prop="creatorName">
|
||||
<el-input v-model="dataForm.creatorName" :placeholder="$t('creatorName')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-input v-model="dataForm.createTime" placeholder="创建时间"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('updator')" prop="updaterId">
|
||||
<el-input v-model="dataForm.updaterId" :placeholder="$t('updator')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('updatorName')" prop="updaterName">
|
||||
<el-input v-model="dataForm.updaterName" :placeholder="$t('updatorName')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('updateTime')" prop="updateTime">
|
||||
<el-input v-model="dataForm.updateTime" :placeholder="$t('updateTime')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('version')" prop="version">
|
||||
<el-input v-model="dataForm.version" :placeholder="$t('version')"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="visible = false">{{ $t('cancel') }}</el-button>
|
||||
<el-button type="primary" @click="dataFormSubmit()">{{ $t('confirm') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
dataForm: {
|
||||
id: 0,
|
||||
equipmentId: '',
|
||||
attrName: '',
|
||||
attrValue: '',
|
||||
remark: '',
|
||||
valid: '',
|
||||
creatorId: '',
|
||||
creatorName: '',
|
||||
createTime: '',
|
||||
updaterId: '',
|
||||
updaterName: '',
|
||||
updateTime: '',
|
||||
version: ''
|
||||
},
|
||||
dataRule: {
|
||||
equipmentId: [{ required: true, message: '设备ID不能为空', trigger: 'blur' }],
|
||||
attrName: [{ required: true, message: '属性名称不能为空', trigger: 'blur' }],
|
||||
attrValue: [{ required: true, message: '属性值不能为空', trigger: 'blur' }],
|
||||
remark: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
|
||||
valid: [{ required: true, message: '删除标志,是否有效:1 可用 0不可用不能为空', trigger: 'blur' }],
|
||||
creatorId: [{ required: true, message: '创建人不能为空', trigger: 'blur' }],
|
||||
creatorName: [{ required: true, message: '创建人姓名不能为空', trigger: 'blur' }],
|
||||
createTime: [{ required: true, message: '创建时间不能为空', trigger: 'blur' }],
|
||||
updaterId: [{ required: true, message: '更新人不能为空', trigger: 'blur' }],
|
||||
updaterName: [{ required: true, message: '更新人姓名不能为空', trigger: 'blur' }],
|
||||
updateTime: [{ required: true, message: '更新时间不能为空', trigger: 'blur' }],
|
||||
version: [{ required: true, message: '版本号不能为空', trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init(id) {
|
||||
this.dataForm.id = id || 0
|
||||
this.visible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].resetFields()
|
||||
if (this.dataForm.id) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`/monitoring/equipmentAttr/${this.dataForm.id}`),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams()
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataForm.equipmentId = data.equipmenattr.equipmentId
|
||||
this.dataForm.attrName = data.equipmenattr.attrName
|
||||
this.dataForm.attrValue = data.equipmenattr.attrValue
|
||||
this.dataForm.remark = data.equipmenattr.remark
|
||||
this.dataForm.valid = data.equipmenattr.valid
|
||||
this.dataForm.creatorId = data.equipmenattr.creatorId
|
||||
this.dataForm.creatorName = data.equipmenattr.creatorName
|
||||
this.dataForm.createTime = data.equipmenattr.createTime
|
||||
this.dataForm.updaterId = data.equipmenattr.updaterId
|
||||
this.dataForm.updaterName = data.equipmenattr.updaterName
|
||||
this.dataForm.updateTime = data.equipmenattr.updateTime
|
||||
this.dataForm.version = data.equipmenattr.version
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
dataFormSubmit() {
|
||||
this.$refs['dataForm'].validate(valid => {
|
||||
if (valid) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`/monitoring/equipmentAttr/${!this.dataForm.id ? '' : this.dataForm.id}`),
|
||||
method: this.dataForm.id ? 'put' : 'post',
|
||||
data: this.$http.adornData({
|
||||
id: this.dataForm.id || undefined,
|
||||
equipmentId: this.dataForm.equipmentId,
|
||||
attrName: this.dataForm.attrName,
|
||||
attrValue: this.dataForm.attrValue,
|
||||
remark: this.dataForm.remark,
|
||||
valid: this.dataForm.valid,
|
||||
creatorId: this.dataForm.creatorId,
|
||||
creatorName: this.dataForm.creatorName,
|
||||
createTime: this.dataForm.createTime,
|
||||
updaterId: this.dataForm.updaterId,
|
||||
updaterName: this.dataForm.updaterName,
|
||||
updateTime: this.dataForm.updateTime,
|
||||
version: this.dataForm.version
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: i18n.t('prompt.success'),
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.visible = false
|
||||
this.$emit('refreshDataList')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.error(data.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
258
src/views/modules/monitoring/equipmentCurrentState.vue
Normal file
@@ -0,0 +1,258 @@
|
||||
<template>
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="currentChangeHandle(1)">
|
||||
<el-form-item>
|
||||
<el-select v-model="dataForm.lineId" :placeholder="'产线'" clearable>
|
||||
<el-option v-for="line in lineList" :key="line.code" :value="line.id" :label="line.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="dataForm.equipmentId" :placeholder="'设备名称'" clearable>
|
||||
<el-option v-for="eq in eqList" :key="eq.code" :value="eq.id" :label="eq.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="currentChangeHandle(1)">{{ $t('query') }}</el-button>
|
||||
<!-- <el-button v-if="$hasPermission('monitoring:equipmentgroup:save')" type="primary" @click="addOrUpdateHandle()">{{ $t('add') }}</el-button> -->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<base-table :page="pageIndex" :size="pageSize" :data="dataList" :table-head-configs="tableConfigs" :max-height="calcMaxHeight(8)" @operate-event="handleOperations" @refreshDataList="getDataList" />
|
||||
<el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
>
|
||||
</el-pagination>
|
||||
<!-- 弹窗, 新增 / 修改 -->
|
||||
<add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" :configs="addOrUpdateConfigs" @refreshDataList="getDataList" @destory-dialog="handleDestroyDialog" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { calcMaxHeight } from '@/utils'
|
||||
import { timeFilter } from '@/utils/filters'
|
||||
import AddOrUpdate from '@/components/base-dialog/addOrUpdate'
|
||||
// import AddOrUpdate from './equipmentGroup-add-or-update'
|
||||
import i18n from '@/i18n'
|
||||
import BaseTable from '@/components/base-table'
|
||||
// import TableOperateComponent from '@/components/base-table/components/operationComponent'
|
||||
import TableTextComponent from '@/components/base-table/components/detailComponent'
|
||||
|
||||
const tableConfigs = [
|
||||
{
|
||||
type: 'index',
|
||||
name: i18n.t('index')
|
||||
},
|
||||
{ prop: 'equipmentName', name: i18n.t('realtime.eqName') },
|
||||
{ prop: 'equipmentCode', name: i18n.t('realtime.eqCode') },
|
||||
{ prop: 'inputNum', name: i18n.t('realtime.input') },
|
||||
{ prop: 'outputNum', name: i18n.t('realtime.output') },
|
||||
{
|
||||
prop: 'run',
|
||||
name: i18n.t('realtime.runState'),
|
||||
filter: val => {
|
||||
if (val !== null && val !== undefined) return val ? '是' : '否'
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
name: i18n.t('realtime.state'),
|
||||
filter: val => {
|
||||
if (val !== null && val !== undefined) return ['正常', '计划停机', '故障'][+val]
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'error',
|
||||
name: i18n.t('realtime.hasFault'),
|
||||
filter: val => {
|
||||
if (val !== null && val !== undefined) return val ? '是' : '否'
|
||||
}
|
||||
},
|
||||
{ prop: 'quantityTime', name: i18n.t('realtime.productionSnapshotTime'), filter: timeFilter },
|
||||
{ prop: 'statusTime', name: i18n.t('realtime.statusSnapshotTime'), filter: timeFilter },
|
||||
{
|
||||
prop: 'alarm',
|
||||
name: i18n.t('realtime.recentParamValue'),
|
||||
buttonContent: i18n.t('realtime.view'),
|
||||
subcomponent: TableTextComponent,
|
||||
emitFullData: true,
|
||||
actionName: 'view-alarm'
|
||||
}
|
||||
// { prop: 'operations', name: i18n.t('handle'), fixed: 'right', width: 180, subcomponent: TableOperateComponent, options: ['edit', 'delete'] }
|
||||
]
|
||||
|
||||
const addOrUpdateConfigs = {
|
||||
type: 'dialog',
|
||||
infoUrl: '/monitoring/equipmentGroup',
|
||||
fields: [{ name: 'name', label: i18n.t('eq.groupname') }, { name: 'code', label: i18n.t('eq.groupcode') }, 'remark'],
|
||||
operations: [
|
||||
{ name: 'cancel', showAlways: true },
|
||||
{ name: 'save', url: '/monitoring/equipmentGroup', permission: 'monitoring:equipmentgroup:save', showOnEdit: false },
|
||||
{ name: 'update', url: '/monitoring/equipmentGroup', permission: 'monitoring:equipmentgroup:update', showOnEdit: true }
|
||||
]
|
||||
}
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
addOrUpdateConfigs,
|
||||
calcMaxHeight,
|
||||
tableConfigs,
|
||||
dataForm: {
|
||||
equipmentId: '',
|
||||
lineId: ''
|
||||
},
|
||||
dataList: [],
|
||||
eqList: [],
|
||||
lineList: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
dataListLoading: false,
|
||||
dataListSelections: [],
|
||||
addOrUpdateVisible: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
AddOrUpdate,
|
||||
BaseTable
|
||||
},
|
||||
activated() {
|
||||
this.getEqList()
|
||||
this.getLineList()
|
||||
this.getDataList()
|
||||
},
|
||||
methods: {
|
||||
// destroy dialog
|
||||
handleDestroyDialog() {
|
||||
setTimeout(() => {
|
||||
this.addOrUpdateVisible= false
|
||||
}, /** after dialog animated */ 200);
|
||||
},
|
||||
// 设备
|
||||
getEqList() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/equipment/page'),
|
||||
method: 'get'
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.eqList = data.data.list
|
||||
} else {
|
||||
this.eqList = []
|
||||
}
|
||||
})
|
||||
},
|
||||
// 产线
|
||||
getLineList() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/productionLine/list'),
|
||||
method: 'get'
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.lineList = data.data
|
||||
} else {
|
||||
this.lineList = []
|
||||
}
|
||||
})
|
||||
},
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.addOrUpdateVisible = false
|
||||
this.dataListLoading = true
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/equipmentValueMonitor/realTimePage'),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams({
|
||||
page: this.pageIndex,
|
||||
limit: this.pageSize,
|
||||
equipmentId: this.dataForm.equipmentId,
|
||||
lineId: this.dataForm.lineId
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataList = data.data.list
|
||||
this.totalPage = data.data.total
|
||||
} else {
|
||||
this.dataList = []
|
||||
this.totalPage = 0
|
||||
}
|
||||
this.dataListLoading = false
|
||||
})
|
||||
},
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val
|
||||
this.pageIndex = 1
|
||||
this.getDataList()
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val
|
||||
this.getDataList()
|
||||
},
|
||||
// 多选
|
||||
selectionChangeHandle(val) {
|
||||
this.dataListSelections = val
|
||||
},
|
||||
handleOperations({ type, data }) {
|
||||
switch (type) {
|
||||
case 'view-alarm':
|
||||
const { equipmentId: id } = data
|
||||
this.$router.push({
|
||||
name: 'monitoring-equipmentHistoricalParameters',
|
||||
params: { id }
|
||||
})
|
||||
break
|
||||
// case 'edit':
|
||||
// return this.addOrUpdateHandle(id)
|
||||
// case 'delete':
|
||||
// return this.deleteHandle(id)
|
||||
}
|
||||
},
|
||||
// 新增 / 修改
|
||||
addOrUpdateHandle(id) {
|
||||
this.addOrUpdateVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.addOrUpdate.init(id)
|
||||
})
|
||||
},
|
||||
// 删除
|
||||
deleteHandle(id) {
|
||||
var ids = id
|
||||
? [id]
|
||||
: this.dataListSelections.map(item => {
|
||||
return item.id
|
||||
})
|
||||
this.$confirm(`${i18n.t('prompt.info', { handle: id ? i18n.t('delete').toLowerCase() : i18n.t('deleteBatch').toLowerCase() })}`, i18n.t('prompt.title'), {
|
||||
confirmButtonText: i18n.t('confirm'),
|
||||
cancelButtonText: i18n.t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/equipmentGroup'),
|
||||
method: 'delete',
|
||||
data: this.$http.adornData(ids, false, 'raw')
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: i18n.t('prompt.success'),
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.getDataList()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.error(data.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
375
src/views/modules/monitoring/equipmentEfficiency.vue
Normal file
@@ -0,0 +1,375 @@
|
||||
<template>
|
||||
<!-- 设备效率分析 -->
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="currentChangeHandle(1)">
|
||||
<!-- 工厂 -->
|
||||
<el-form-item>
|
||||
<!-- <el-select v-model="dataForm.factoryId" :placeholder="$t('eq.name') + ' / ' + $t('eq.code')" clearable></el-select> -->
|
||||
<el-select v-model="dataForm.ftId" :placeholder="$t('factory.title')" clearable>
|
||||
<el-option v-for="factory in factoryList" :key="factory.id" :value="factory.id" :label="factory.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 产线 -->
|
||||
<el-form-item>
|
||||
<el-select v-model="dataForm.productlines" :placeholder="$t('pl.title')" multiple clearable>
|
||||
<el-option v-for="productLine in productLineList" :key="productLine.id" :value="productLine.id" :label="productLine.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 时间类型 -->
|
||||
<!-- 按时间段 -->
|
||||
<el-form-item>
|
||||
<el-select v-model="timeType" :placeholder="$t('timetype')" clearable>
|
||||
<el-option value="range" :label="$t('reftimerange')" />
|
||||
<el-option value="date" :label="$t('refdate')" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 日期选择 -->
|
||||
<el-form-item v-if="timeType === 'date'">
|
||||
<el-date-picker key="range-picker" v-model="rawTime" type="date" :placeholder="$t('hints.date')" format="yyyy-MM-dd" />
|
||||
</el-form-item>
|
||||
<!-- 时间段选择 -->
|
||||
<el-form-item v-else>
|
||||
<el-date-picker
|
||||
key="time-picker"
|
||||
v-model="rawTime"
|
||||
type="daterange"
|
||||
:range-separator="$t('datePicker.range')"
|
||||
:start-placeholder="$t('datePicker.starttime')"
|
||||
:end-placeholder="$t('datePicker.endtime')"
|
||||
format="yyyy-MM-dd"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- 按钮 -->
|
||||
<el-form-item>
|
||||
<el-button @click="currentChangeHandle(1)">{{ $t('search') }}</el-button>
|
||||
<!-- <el-button v-if="$hasPermission('monitoring:equipmentEffiency:save')" type="primary" @click="addOrUpdateHandle()">{{ $t('add') }}</el-button> -->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<transition mode="out-in" name="slide-to-left">
|
||||
<equipment-efficiency-graph v-if="showGraph" key="graph" ref="eegraph" @close-graph="showGraph = false" />
|
||||
<base-table v-else :data="dataList" :table-head-configs="tableConfigs" :max-height="calcMaxHeight(8)"
|
||||
@operate-event="handleOperations" @refreshDataList="getDataList" />
|
||||
<!-- v-loading="dataIsLoading " -->
|
||||
</transition>
|
||||
<!-- <el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import i18n from '@/i18n'
|
||||
import BaseTable from '@/components/base-table'
|
||||
// import TableOperateComponent from '@/components/base-table/components/operationComponent'
|
||||
import TableTextComponent from '@/components/base-table/components/detailComponent'
|
||||
import EquipmentEfficiencyGraph from './equipmentEfficiencyGraph.vue'
|
||||
import { calcMaxHeight } from '@/utils'
|
||||
// import { timeFilter } from '@/utils/filters'
|
||||
import moment from 'moment'
|
||||
|
||||
const tableConfigs = [
|
||||
{
|
||||
type: 'index',
|
||||
name: i18n.t('index')
|
||||
},
|
||||
{
|
||||
// name: i18n.t('createTime'),
|
||||
prop: 'factoryName',
|
||||
name: i18n.t('factory.title')
|
||||
},
|
||||
{ prop: 'pdName', name: i18n.t('pl.title') },
|
||||
{ prop: 'wsName', name: i18n.t('ws.title') },
|
||||
{ prop: 'eqName', name: i18n.t('eq.title') },
|
||||
{
|
||||
name: i18n.t('eq.efficienttimeh'),
|
||||
children: [
|
||||
{ prop: 'workTime', name: i18n.t('eq.worktimeh'), width: 120, filter: val => `${val} `+i18n.t('hour') },
|
||||
{ prop: 'workRate', name: i18n.t('eq.workdurationratio'), width: 120, filter: val => (val * 100).toFixed(2) + '%' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: i18n.t('eq.shutdowntimeh'),
|
||||
children: [
|
||||
{ prop: 'stopTime', name: i18n.t('eq.stoptimeh'), width: 120, filter: val => `${val} `+i18n.t('hour') },
|
||||
{ prop: 'stopRate', name: i18n.t('eq.stopratio'), width: 120, filter: val => (val * 100).toFixed(2) + '%' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: i18n.t('eq.stoplost'),
|
||||
children: [
|
||||
{ prop: 'downTime', name: i18n.t('eq.downtimeh'), width: 120, filter: val => `${val} `+i18n.t('hour') },
|
||||
{ prop: 'downRate', name: i18n.t('eq.downrate'), width: 120, filter: val => (val * 100).toFixed(2) + '%' },
|
||||
{ prop: 'timeEfficiency', name: i18n.t('eq.timeefficiency'), width: 120, filter: val => (val * 100).toFixed(2) + '%' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: i18n.t('eq.speedlost'),
|
||||
children: [
|
||||
{ prop: 'realYield', name: i18n.t('eq.realyield'), width: 120, filter: val => `${val} `+i18n.t('hour') },
|
||||
{ prop: 'designYield', name: i18n.t('eq.designyield'), width: 120, filter: val => `${val} `+i18n.t('hour') },
|
||||
{ prop: 'peEfficiency', name: i18n.t('eq.speedefficiency'), width: 120, filter: val => (val * 100).toFixed(2) + '%' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'OEE',
|
||||
prop: 'oee',
|
||||
filter: val => (val * 100).toFixed(2) + '%'
|
||||
},
|
||||
{
|
||||
name: 'TEEP',
|
||||
prop: 'teep',
|
||||
filter: val => (val * 100).toFixed(2) + '%'
|
||||
},
|
||||
{
|
||||
prop: 'operations',
|
||||
name: i18n.t('handle'),
|
||||
fixed: 'right',
|
||||
width: 120,
|
||||
subcomponent: TableTextComponent,
|
||||
// options: ['edit', 'delete']
|
||||
// options: ['view-trend'] // 查看趋势
|
||||
buttonContent: i18n.t('eq.viewtrend'),
|
||||
actionName: 'view-trend',
|
||||
emitFullData: true
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
/** hfxny part */
|
||||
factoryList: [],
|
||||
productLineList: [],
|
||||
showGraph: false,
|
||||
/** */
|
||||
calcMaxHeight,
|
||||
tableConfigs,
|
||||
timeType: 'date',
|
||||
rawTime: null, // [] or datetime
|
||||
dataForm: {
|
||||
type: 1,
|
||||
ftId: null,
|
||||
productlines: [],
|
||||
startTime: null,
|
||||
entTime: null
|
||||
},
|
||||
dataList: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
dataListLoading: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
BaseTable,
|
||||
EquipmentEfficiencyGraph
|
||||
},
|
||||
|
||||
activated() {
|
||||
this.getFactoryList().then(() => {
|
||||
this.getProductLineList()
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
timeType() {
|
||||
// 防止切换日期类型时报错
|
||||
this.rawTime = null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取工厂列表
|
||||
getFactoryList() {
|
||||
return this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/factory/list'),
|
||||
method: 'get'
|
||||
}).then(({ data: res }) => {
|
||||
if (res && res.code === 0) {
|
||||
this.factoryList = res.data
|
||||
/** set default */
|
||||
if (this.factoryList.length) {
|
||||
this.dataForm.ftId = this.factoryList[0].id
|
||||
}
|
||||
} else {
|
||||
this.factoryList = []
|
||||
this.dataForm.ftId = null
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 选择工厂时
|
||||
handleFactoryChange(val) {
|
||||
this.getProductLineList()
|
||||
},
|
||||
|
||||
// 获取产线列表
|
||||
getProductLineList() {
|
||||
const query = {
|
||||
url: this.$http.adornUrl('/monitoring/productionLine/list'),
|
||||
method: 'get'
|
||||
}
|
||||
if (this.dataForm.ftId) {
|
||||
query.params = this.$http.adornParams({
|
||||
factoryId: this.dataForm.ftId
|
||||
});
|
||||
}
|
||||
this.$http(query).then(({ data: res }) => {
|
||||
if (res && res.code === 0 && res.data.length) {
|
||||
this.productLineList = res.data
|
||||
/** set default */
|
||||
this.dataForm.productlines = [this.productLineList[0].id]
|
||||
} else {
|
||||
this.productLineList = []
|
||||
this.dataForm.productlines = []
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 时间类型预处理
|
||||
getTimeRange() {
|
||||
let startTime
|
||||
let endTime
|
||||
if (this.rawTime instanceof Array) {
|
||||
startTime = this.rawTime[0] ? moment(this.rawTime[0]).format('YYYY-MM-DDTHH:mm:ss') : '' // 强制axios使用北京时间
|
||||
endTime = this.rawTime[1] ? moment(this.rawTime[1]).format('YYYY-MM-DDTHH:mm:ss') : ''
|
||||
} else {
|
||||
if (this.rawTime) {
|
||||
startTime = moment(this.rawTime).format('YYYY-MM-DDTHH:mm:ss')
|
||||
endTime = moment(startTime)
|
||||
.add(1, 'd')
|
||||
.format('YYYY-MM-DDTHH:mm:ss')
|
||||
} else {
|
||||
startTime = ''
|
||||
endTime = ''
|
||||
}
|
||||
}
|
||||
return { startTime, endTime }
|
||||
},
|
||||
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
const { startTime, endTime } = this.getTimeRange()
|
||||
this.showGraph = false
|
||||
// this.dataListLoading = true
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/eqAnalysis/oee'),
|
||||
method: 'post',
|
||||
data: {
|
||||
startTime,
|
||||
endTime,
|
||||
ftId: this.dataForm.ftId,
|
||||
productlines: this.dataForm.productlines,
|
||||
// limit: this.pageIndex,
|
||||
// page: this.pageSize,
|
||||
type: 1
|
||||
}
|
||||
}).then(({ data: res }) => {
|
||||
if (res.data && res.code !== 500) {
|
||||
console.log('oee data:', res)
|
||||
if (res.data.length) {
|
||||
this.dataList = res.data
|
||||
// this.dataList = Array(20).fill(1)
|
||||
} else {
|
||||
this.dataList.splice(0)
|
||||
}
|
||||
} else {
|
||||
this.dataList.splice(0)
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 查看趋势
|
||||
viewTrend(data) {
|
||||
const { startTime, endTime } = this.getTimeRange()
|
||||
const injectData = {
|
||||
// 时间段
|
||||
startTime,
|
||||
endTime,
|
||||
// 设备id
|
||||
equipmentId: data.eqId,
|
||||
equipmentName: data.eqName,
|
||||
// 时间类型, type 按年,按月,按日等
|
||||
type: 1, // 默认 type 1, 1无间隔;2按月分隔;3按周分隔;4按天分隔
|
||||
// 时长数据: 工作时长, 停机时长,故障时长
|
||||
workTime: data.workTime,
|
||||
stopTime: data.stopTime,
|
||||
downTime: data.downTime,
|
||||
// 比例数据: 工作时长比率,停机时长比率,故障时长比率,速度开动率,OEE,TEEP
|
||||
workRate: data.workRate,
|
||||
stopRate: data.stopRate,
|
||||
downRate: data.downRate,
|
||||
peEfficiency: data.peEfficiency,
|
||||
timeEfficiency: data.timeEfficiency
|
||||
}
|
||||
// console.log('trends data: ', data)
|
||||
|
||||
this.showGraph = true
|
||||
|
||||
console.clear()
|
||||
console.log('inject data: ', injectData)
|
||||
|
||||
setTimeout(() => {
|
||||
// console.log('befoer graph: ', this.$refs.eegraph)
|
||||
this.$refs.eegraph.init(injectData) // 注入初始数据,这些数据在组件内部用作条件,有可能会被更改
|
||||
}, 600) // 动画是500ms
|
||||
},
|
||||
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val
|
||||
this.pageIndex = 1
|
||||
this.getDataList()
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val
|
||||
this.getDataList()
|
||||
},
|
||||
// 多选
|
||||
selectionChangeHandle(val) {
|
||||
this.dataListSelections = val
|
||||
},
|
||||
|
||||
handleOperations({ type, data }) {
|
||||
switch (type) {
|
||||
case 'view-trend':
|
||||
return this.viewTrend(data)
|
||||
// return this.addOrUpdateHandle(id, true)
|
||||
// case 'edit':
|
||||
// return this.addOrUpdateHandle(id)
|
||||
// case 'delete':
|
||||
// return this.deleteHandle(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.slide-to-left-enter-active,
|
||||
.slide-to-left-leave-active {
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.slide-to-left-enter {
|
||||
transform: translateX(10px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slide-to-left-leave-to {
|
||||
transform: translateX(-10px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slide-to-left-leave,
|
||||
.slide-to-left-enter-to {
|
||||
transform: translateX(0);
|
||||
}
|
||||
</style>
|
||||
330
src/views/modules/monitoring/equipmentEfficiencyGraph.vue
Normal file
@@ -0,0 +1,330 @@
|
||||
<!--
|
||||
/*
|
||||
* @Author: lb
|
||||
* @Date: 2022-07-24 13:30:00
|
||||
* @LastEditTime: 2022-07-28 09:30:00
|
||||
* @LastEditors: lb
|
||||
* @Description: 设备效率分析-echarts图
|
||||
*/
|
||||
-->
|
||||
<template>
|
||||
<div class="graph-area">
|
||||
<span class="close-btn" @click="close">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="height: 100%; width: 100%;" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
<div class="close-row">
|
||||
<el-radio-group v-model="dataType" class="head-radio-group" size="small" @change="setLegend">
|
||||
<el-radio-button :label="$t('eq.ratio')" />
|
||||
<el-radio-button :label="$t('eq.time')" />
|
||||
</el-radio-group>
|
||||
|
||||
<el-radio-group v-if="1" v-model="searchType" class="head-radio-group" style="margin-left: 8px;" size="small" @change="handleRadioGroupChanged">
|
||||
<el-radio-button v-for="(opt, index) in searchRadioOptions" :key="index" :label="opt" />
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
||||
<div id="trend-graph" class="real-graph" style="width: 100%; height: 500px;" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import moment from 'moment'
|
||||
import { pick } from 'lodash/object'
|
||||
import i18n from '../../../i18n'
|
||||
|
||||
class EchartConfigs {
|
||||
constructor() {
|
||||
this.color = ['#e91e63', '#4caf50', '#3f51b5', '#ffc107', '#607d8b']
|
||||
this.title = {
|
||||
text: i18n.t('eq.timetrend'),
|
||||
top: 0,
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
fontWeight: 'bold',
|
||||
fontSize: 18,
|
||||
lineHeight: 18
|
||||
}
|
||||
}
|
||||
this.tooltip = {
|
||||
trigger: 'axis',
|
||||
// 将axisPointer设置得更显眼一点
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
}
|
||||
// legend
|
||||
this.legend = {
|
||||
icon: 'circle',
|
||||
top: 24,
|
||||
left: 'center',
|
||||
padding: 8,
|
||||
itemGap: 8,
|
||||
data: [] // 动态设置
|
||||
}
|
||||
this.xAxis = {
|
||||
type: 'category',
|
||||
data: [] // 动态设置
|
||||
// https://tushuo.baidu.com/wave/index#/manufacture/dta9pydmexfdhc0sg/999
|
||||
}
|
||||
this.yAxis = {
|
||||
type: 'value'
|
||||
}
|
||||
this.series = [] // 动态设置
|
||||
}
|
||||
|
||||
setTitle(val) {
|
||||
this.title.text = val
|
||||
}
|
||||
|
||||
setLegend(val) {
|
||||
this.legend.data.splice(0)
|
||||
if (Array.isArray(val)) {
|
||||
this.legend.data = val
|
||||
} else {
|
||||
console.error('setLegend() 只接受数组参数')
|
||||
}
|
||||
}
|
||||
|
||||
setXAxis(val) {
|
||||
// console.log('in setXAxis(): ', val)
|
||||
this.xAxis.data.splice(0)
|
||||
if (Array.isArray(val)) {
|
||||
this.xAxis.data = val
|
||||
} else {
|
||||
console.error('setXAxis() 只接受数组参数')
|
||||
}
|
||||
}
|
||||
|
||||
setSeries(val) {
|
||||
this.series.splice(0)
|
||||
if (Array.isArray(val) && this.series.length === 0) {
|
||||
this.series = val
|
||||
} else {
|
||||
console.error('setSeries() 只接受数组参数')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'EquipmentEfficiencyGraph',
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
searchType: i18n.t('eq.nogap'),
|
||||
searchRadioOptions: [i18n.t('eq.nogap'), i18n.t('eq.monthgap'), i18n.t('eq.weekgap'), i18n.t('eq.daygap')],
|
||||
dataType: i18n.t('eq.time'),
|
||||
dataRadioOptions: [i18n.t('eq.time'), i18n.t('eq.ratio')],
|
||||
config: new EchartConfigs(),
|
||||
chart: null,
|
||||
rateList: [], // 对请求来的数据分流
|
||||
timeList: [],
|
||||
xAxis: [], // 动态设置
|
||||
injectData: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async initChart() {
|
||||
this.config.setTitle(this.injectData.equipmentName + i18n.t('eq.timetrend'))
|
||||
await this.getList()
|
||||
this.setLegend()
|
||||
},
|
||||
|
||||
init(data) {
|
||||
this.injectData = data
|
||||
if (!this.chart) {
|
||||
this.chart = echarts.init(document.getElementById('trend-graph'))
|
||||
// this.chart.setOption(this.config)
|
||||
this.initChart()
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.$emit('close-graph')
|
||||
},
|
||||
|
||||
makeQuerys() {
|
||||
const searchTypeMap = {
|
||||
[i18n.t('eq.nogap')]: 1,
|
||||
[i18n.t('eq.monthgap')]: 2,
|
||||
[i18n.t('eq.weekgap')]: 3,
|
||||
[i18n.t('eq.daygap')]: 4,
|
||||
[i18n.t('eq.hourgap')]: 5
|
||||
}
|
||||
|
||||
return {
|
||||
type: searchTypeMap[this.searchType],
|
||||
eqId: this.injectData.equipmentId,
|
||||
startTime: this.injectData.startTime, // '2022-06-14T00:00:00'
|
||||
endTime: this.injectData.endTime
|
||||
}
|
||||
},
|
||||
|
||||
// getOEE
|
||||
getOEE(params) {
|
||||
return this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/eqAnalysis/oee'),
|
||||
method: 'post',
|
||||
data: params
|
||||
}).then(({ data: res }) => {
|
||||
if (!res.data || res.code === 500) {
|
||||
this.dataList.splice(0)
|
||||
this.$message.error(res.msg)
|
||||
return { data: null }
|
||||
}
|
||||
return res.data
|
||||
})
|
||||
},
|
||||
|
||||
getList() {
|
||||
const params = this.makeQuerys()
|
||||
// 发起请求
|
||||
return this.getOEE(params).then(datalist => {
|
||||
console.log('getOEE res:', datalist)
|
||||
this.timeList.splice(0)
|
||||
this.rateList.splice(0)
|
||||
this.xAxis.splice(0)
|
||||
if (datalist.length) {
|
||||
// 分流
|
||||
datalist.map(item => {
|
||||
const time = moment(item.time)
|
||||
if (this.searchType === i18n.t('eq.monthgap')) {
|
||||
this.xAxis.push(`${time.year()}${i18n.t('eq.year')}${time.month() + 1}${i18n.t('eq.month')}`)
|
||||
} else if (this.searchType === i18n.t('eq.weekgap')) {
|
||||
this.xAxis.push(`${time.format('YYYY-MM-DD')}`)
|
||||
} else if (this.searchType === i18n.t('eq.daygap')) {
|
||||
this.xAxis.push(`${time.format('YY-M-D')}`)
|
||||
} else {
|
||||
this.xAxis.push(`${time.format('YYYY-MM-DD')}`)
|
||||
}
|
||||
this.timeList.push(pick(item, ['workTime', 'stopTime', 'downTime']))
|
||||
this.rateList.push(pick(item, ['workRate', 'stopRate', 'downRate', 'peEfficiency', 'timeEfficiency', 'oee', 'teep']))
|
||||
})
|
||||
|
||||
// 设置横轴
|
||||
this.config.setXAxis(JSON.parse(JSON.stringify(this.xAxis)))
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
async handleRadioGroupChanged() {
|
||||
// 获取数据且设置横轴
|
||||
await this.getList()
|
||||
// 设置legend和数据
|
||||
this.setLegend()
|
||||
},
|
||||
|
||||
setLegend() {
|
||||
// 设置legend
|
||||
const legendMap = {
|
||||
[i18n.t('eq.ratio')]: [
|
||||
i18n.t('eq.workdurationratio'),
|
||||
i18n.t('eq.stopdurationratio'),
|
||||
i18n.t('eq.downdurationratio'),
|
||||
i18n.t('eq.speedefficiency'),
|
||||
i18n.t('eq.timeefficiency'),
|
||||
'OEE',
|
||||
'TEEP'
|
||||
],
|
||||
[i18n.t('eq.time')]: [i18n.t('eq.worktime'), i18n.t('eq.stoptime'), i18n.t('eq.downtime')]
|
||||
}
|
||||
this.config.setLegend(legendMap[this.dataType])
|
||||
this.setData()
|
||||
// 重新绘制
|
||||
this.renderGraph()
|
||||
},
|
||||
|
||||
setData() {
|
||||
if (this.dataType === i18n.t('eq.time')) {
|
||||
const workTimeList = []
|
||||
const stopTimeList = []
|
||||
const downTimeList = []
|
||||
this.timeList.map(item => {
|
||||
workTimeList.push(item.workTime)
|
||||
stopTimeList.push(item.stopTime)
|
||||
downTimeList.push(item.downTime)
|
||||
})
|
||||
this.config.setSeries([
|
||||
{ name: i18n.t('eq.worktime'), type: 'bar', data: workTimeList },
|
||||
{ name: i18n.t('eq.stoptime'), type: 'bar', data: stopTimeList },
|
||||
{ name: i18n.t('eq.downtime'), type: 'bar', data: downTimeList }
|
||||
])
|
||||
} else {
|
||||
// 百分比
|
||||
const workRateList = []
|
||||
const stopRateList = []
|
||||
const downRateList = []
|
||||
const peEfficiencyList = []
|
||||
const timeEfficiencyList = []
|
||||
const oeeList = []
|
||||
const teepList = []
|
||||
this.rateList.map(item => {
|
||||
workRateList.push(item.workRate)
|
||||
stopRateList.push(item.stopRate)
|
||||
downRateList.push(item.downRate)
|
||||
peEfficiencyList.push(item.peEfficiency)
|
||||
timeEfficiencyList.push(item.timeEfficiency)
|
||||
oeeList.push(item.oee)
|
||||
teepList.push(item.teep)
|
||||
})
|
||||
this.config.setSeries([
|
||||
{ name: i18n.t('eq.workdurationratio'), type: 'bar', data: workRateList },
|
||||
{ name: i18n.t('eq.stopdurationratio'), type: 'bar', data: stopRateList },
|
||||
{ name: i18n.t('eq.downdurationratio'), type: 'bar', data: downRateList },
|
||||
{ name: i18n.t('eq.speedefficiency'), type: 'bar', data: peEfficiencyList },
|
||||
{ name: i18n.t('eq.timeefficiency'), type: 'bar', data: timeEfficiencyList },
|
||||
{ name: 'OEE', type: 'bar', data: oeeList },
|
||||
{ name: 'TEEP', type: 'bar', data: teepList }
|
||||
])
|
||||
}
|
||||
},
|
||||
|
||||
// 重新绘制图形
|
||||
renderGraph() {
|
||||
console.log('latest config: ', JSON.stringify(this.config))
|
||||
this.$nextTick(() => {
|
||||
// this.chart.setOption(this.config)
|
||||
this.chart.setOption(this.config, {
|
||||
notMerge: true
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.graph-area {
|
||||
width: 100%;
|
||||
min-height: 200px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.close-row {
|
||||
position: relative;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s linear;
|
||||
}
|
||||
|
||||
.close-btn:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.head-radio-group >>> .el-radio-button__orig-radio:checked + .el-radio-button__inner {
|
||||
background-color: #409eff;
|
||||
border-color: #409eff;
|
||||
}
|
||||
</style>
|
||||
204
src/views/modules/monitoring/equipmentException.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<!-- 设备效率分析 -->
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="currentChangeHandle(1)">
|
||||
<!-- 月份 -->
|
||||
<el-form-item>
|
||||
<el-date-picker key="month-picker" v-model="rawTime" type="month" :placeholder="$t('prompt.month')" format="yyyy-MM" />
|
||||
</el-form-item>
|
||||
<!-- 产线 -->
|
||||
<el-form-item>
|
||||
<el-select v-model="dataForm.productlines" :placeholder="$t('pl.title')" multiple clearable>
|
||||
<el-option v-for="productLine in productLineList" :key="productLine.id" :value="productLine.id" :label="productLine.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 按钮 -->
|
||||
<el-form-item>
|
||||
<el-button @click="currentChangeHandle(1)">{{ $t('search') }}</el-button>
|
||||
<!-- <el-button v-if="$hasPermission('monitoring:equipmentEffiency:save')" type="primary" @click="addOrUpdateHandle()">{{ $t('add') }}</el-button> -->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<base-table :data="dataList" :table-head-configs="tableConfigs" :max-height="calcMaxHeight(8)" @operate-event="handleOperations" @refreshDataList="getDataList" />
|
||||
|
||||
<!-- <el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import i18n from '@/i18n'
|
||||
import BaseTable from '@/components/base-table'
|
||||
// import TableOperateComponent from '@/components/base-table/components/operationComponent'
|
||||
import TableTextComponent from '@/components/base-table/components/detailComponent'
|
||||
import { timeFilter } from '@/utils/filters'
|
||||
import { calcMaxHeight } from '@/utils'
|
||||
import moment from 'moment'
|
||||
|
||||
const tableConfigs = [
|
||||
{
|
||||
type: 'index',
|
||||
name: i18n.t('index')
|
||||
},
|
||||
// { prop: 'time', name: '时间', filter: timeFilter },
|
||||
{ prop: 'pdName', name: i18n.t('pl.name') },
|
||||
{ prop: 'wsName', name: i18n.t('ws.title') },
|
||||
{ prop: 'eqName', name: i18n.t('eq.title') },
|
||||
{ prop: 'mtbf', name: i18n.t('eq.mtbf'), width: 220 },
|
||||
{ prop: 'mttr', name: i18n.t('eq.mttr'), width: 190 },
|
||||
{ prop: 'workTime', name: i18n.t('eq.worktimeh') },
|
||||
{ prop: 'downTime', name: i18n.t('eq.downtimeh') },
|
||||
{ prop: 'downCount', name: i18n.t('eq.downcount') }
|
||||
// {
|
||||
// prop: 'operations',
|
||||
// name: i18n.t('handle'),
|
||||
// fixed: 'right',
|
||||
// width: 120,
|
||||
// subcomponent: TableTextComponent,
|
||||
// buttonContent: '查看详情', // 会转到“设备报警”
|
||||
// emitFullData: true
|
||||
// }
|
||||
]
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
/** hfxny part */
|
||||
factoryList: [],
|
||||
productLineList: [],
|
||||
/** */
|
||||
calcMaxHeight,
|
||||
tableConfigs,
|
||||
timeType: 'range',
|
||||
rawTime: new Date(),
|
||||
dataForm: {
|
||||
type: 1,
|
||||
productlines: [],
|
||||
startTime: null,
|
||||
entTime: null
|
||||
},
|
||||
dataList: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
dataListLoading: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
BaseTable
|
||||
},
|
||||
|
||||
activated() {
|
||||
// this.getFactoryList()
|
||||
this.getProductLineList()
|
||||
},
|
||||
watch: {},
|
||||
methods: {
|
||||
// 获取工厂列表
|
||||
// getFactoryList() {
|
||||
// this.$http({
|
||||
// url: this.$http.adornUrl('/monitoring/factory/page'),
|
||||
// method: 'get'
|
||||
// }).then(({ data }) => {
|
||||
// if (data && data.code === 0) {
|
||||
// this.factoryList = data.data.list
|
||||
// /** set default */
|
||||
// if (this.factoryList.length) {
|
||||
// this.dataForm.ftId = this.factoryList[0].id
|
||||
// }
|
||||
// } else {
|
||||
// this.factoryList = []
|
||||
// this.dataForm.ftId = null
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
// 获取产线列表
|
||||
getProductLineList() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/productionLine/list'),
|
||||
method: 'get'
|
||||
}).then(({ data: res }) => {
|
||||
if (res && res.code === 0) {
|
||||
this.productLineList = res.data
|
||||
/** set default */
|
||||
if (this.productLineList.length) {
|
||||
this.dataForm.productlines = [this.productLineList[0].id]
|
||||
}
|
||||
} else {
|
||||
this.productLineList = []
|
||||
this.dataForm.productlines = []
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
// this.dataList = Array(10).fill(1)
|
||||
// return
|
||||
let startTime = this.rawTime
|
||||
? moment(this.rawTime)
|
||||
.set({ date: 1, hour: 0, minute: 0, second: 0, millisecond: 0 })
|
||||
.format('YYYY-MM-DDTHH:mm:ss')
|
||||
: ''
|
||||
let endTime = startTime
|
||||
? moment(startTime)
|
||||
.add(1, 'M')
|
||||
.format('YYYY-MM-DDTHH:mm:ss')
|
||||
: ''
|
||||
|
||||
this.dataListLoading = true
|
||||
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/eqAnalysis/mtbrAndMtbr'),
|
||||
method: 'post',
|
||||
data: {
|
||||
startTime,
|
||||
endTime,
|
||||
productlines: this.dataForm.productlines,
|
||||
type: 1
|
||||
}
|
||||
}).then(({ data: res }) => {
|
||||
if (res.code === 500) {
|
||||
this.dataList.splice(0)
|
||||
this.$message.error(res.msg)
|
||||
} else {
|
||||
this.dataList = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val
|
||||
this.pageIndex = 1
|
||||
this.getDataList()
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val
|
||||
this.getDataList()
|
||||
},
|
||||
// 多选
|
||||
selectionChangeHandle(val) {
|
||||
this.dataListSelections = val
|
||||
},
|
||||
handleOperations({ type, data: id }) {
|
||||
switch (type) {
|
||||
case 'view-detail':
|
||||
return this.addOrUpdateHandle(id, true)
|
||||
case 'edit':
|
||||
return this.addOrUpdateHandle(id)
|
||||
case 'delete':
|
||||
return this.deleteHandle(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
184
src/views/modules/monitoring/equipmentFile-add-or-update.vue
Normal file
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<el-dialog :title="!dataForm.id ? i18n.t('add') : i18n.t('update')" :close-on-click-modal="false" :visible.sync="visible">
|
||||
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="80px">
|
||||
<el-form-item label="设备ID" prop="equipmentId">
|
||||
<el-input v-model="dataForm.equipmentId" placeholder="设备ID"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="文件ID" prop="fileId">
|
||||
<el-input v-model="dataForm.fileId" placeholder="文件ID"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('desc')" prop="description">
|
||||
<el-input v-model="dataForm.description" :placeholder="$t('desc')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="启用状态:0 、停用,1、启用" prop="enabled">
|
||||
<el-input v-model="dataForm.enabled" placeholder="启用状态:0 、停用,1、启用"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="dataForm.remark" placeholder="备注"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="删除标志,是否有效:1 可用 0不可用" prop="valid">
|
||||
<el-input v-model="dataForm.valid" placeholder="删除标志,是否有效:1 可用 0不可用"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('creator')" prop="creatorId">
|
||||
<el-input v-model="dataForm.creatorId" :placeholder="$t('creator')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('creatorName')" prop="creatorName">
|
||||
<el-input v-model="dataForm.creatorName" :placeholder="$t('creatorName')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-input v-model="dataForm.createTime" placeholder="创建时间"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('updator')" prop="updaterId">
|
||||
<el-input v-model="dataForm.updaterId" :placeholder="$t('updator')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('updatorName')" prop="updaterName">
|
||||
<el-input v-model="dataForm.updaterName" :placeholder="$t('updatorName')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('updateTime')" prop="updateTime">
|
||||
<el-input v-model="dataForm.updateTime" :placeholder="$t('updateTime')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('version')" prop="version">
|
||||
<el-input v-model="dataForm.version" :placeholder="$t('version')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="文件类型编号" prop="typeCode">
|
||||
<el-input v-model="dataForm.typeCode" placeholder="文件类型编号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="文件名字" prop="fileName">
|
||||
<el-input v-model="dataForm.fileName" placeholder="文件名字"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="下载地址" prop="fileUrl">
|
||||
<el-input v-model="dataForm.fileUrl" placeholder="下载地址"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="visible = false">{{ $t('cancel') }}</el-button>
|
||||
<el-button type="primary" @click="dataFormSubmit()">{{ $t('confirm') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
dataForm: {
|
||||
id: 0,
|
||||
equipmentId: '',
|
||||
fileId: '',
|
||||
description: '',
|
||||
enabled: '',
|
||||
remark: '',
|
||||
valid: '',
|
||||
creatorId: '',
|
||||
creatorName: '',
|
||||
createTime: '',
|
||||
updaterId: '',
|
||||
updaterName: '',
|
||||
updateTime: '',
|
||||
version: '',
|
||||
typeCode: '',
|
||||
fileName: '',
|
||||
fileUrl: ''
|
||||
},
|
||||
dataRule: {
|
||||
equipmentId: [{ required: true, message: '设备ID不能为空', trigger: 'blur' }],
|
||||
fileId: [{ required: true, message: '文件ID不能为空', trigger: 'blur' }],
|
||||
description: [{ required: true, message: '描述不能为空', trigger: 'blur' }],
|
||||
enabled: [{ required: true, message: '启用状态:0 、停用,1、启用不能为空', trigger: 'blur' }],
|
||||
remark: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
|
||||
valid: [{ required: true, message: '删除标志,是否有效:1 可用 0不可用不能为空', trigger: 'blur' }],
|
||||
creatorId: [{ required: true, message: '创建人不能为空', trigger: 'blur' }],
|
||||
creatorName: [{ required: true, message: '创建人姓名不能为空', trigger: 'blur' }],
|
||||
createTime: [{ required: true, message: '创建时间不能为空', trigger: 'blur' }],
|
||||
updaterId: [{ required: true, message: '更新人不能为空', trigger: 'blur' }],
|
||||
updaterName: [{ required: true, message: '更新人姓名不能为空', trigger: 'blur' }],
|
||||
updateTime: [{ required: true, message: '更新时间不能为空', trigger: 'blur' }],
|
||||
version: [{ required: true, message: '版本号不能为空', trigger: 'blur' }],
|
||||
typeCode: [{ required: true, message: '文件类型编号不能为空', trigger: 'blur' }],
|
||||
fileName: [{ required: true, message: '文件名字不能为空', trigger: 'blur' }],
|
||||
fileUrl: [{ required: true, message: '下载地址不能为空', trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init(id) {
|
||||
this.dataForm.id = id || 0
|
||||
this.visible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].resetFields()
|
||||
if (this.dataForm.id) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`/monitoring/equipmentFile/${this.dataForm.id}`),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams()
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataForm.equipmentId = data.equipmenfile.equipmentId
|
||||
this.dataForm.fileId = data.equipmenfile.fileId
|
||||
this.dataForm.description = data.equipmenfile.description
|
||||
this.dataForm.enabled = data.equipmenfile.enabled
|
||||
this.dataForm.remark = data.equipmenfile.remark
|
||||
this.dataForm.valid = data.equipmenfile.valid
|
||||
this.dataForm.creatorId = data.equipmenfile.creatorId
|
||||
this.dataForm.creatorName = data.equipmenfile.creatorName
|
||||
this.dataForm.createTime = data.equipmenfile.createTime
|
||||
this.dataForm.updaterId = data.equipmenfile.updaterId
|
||||
this.dataForm.updaterName = data.equipmenfile.updaterName
|
||||
this.dataForm.updateTime = data.equipmenfile.updateTime
|
||||
this.dataForm.version = data.equipmenfile.version
|
||||
this.dataForm.typeCode = data.equipmenfile.typeCode
|
||||
this.dataForm.fileName = data.equipmenfile.fileName
|
||||
this.dataForm.fileUrl = data.equipmenfile.fileUrl
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
dataFormSubmit() {
|
||||
this.$refs['dataForm'].validate(valid => {
|
||||
if (valid) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`/monitoring/equipmentFile/${!this.dataForm.id ? '' : this.dataForm.id}`),
|
||||
method: this.dataForm.id ? 'put' : 'post',
|
||||
data: this.$http.adornData({
|
||||
id: this.dataForm.id || undefined,
|
||||
equipmentId: this.dataForm.equipmentId,
|
||||
fileId: this.dataForm.fileId,
|
||||
description: this.dataForm.description,
|
||||
enabled: this.dataForm.enabled,
|
||||
remark: this.dataForm.remark,
|
||||
valid: this.dataForm.valid,
|
||||
creatorId: this.dataForm.creatorId,
|
||||
creatorName: this.dataForm.creatorName,
|
||||
createTime: this.dataForm.createTime,
|
||||
updaterId: this.dataForm.updaterId,
|
||||
updaterName: this.dataForm.updaterName,
|
||||
updateTime: this.dataForm.updateTime,
|
||||
version: this.dataForm.version,
|
||||
typeCode: this.dataForm.typeCode,
|
||||
fileName: this.dataForm.fileName,
|
||||
fileUrl: this.dataForm.fileUrl
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: i18n.t('prompt.success'),
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.visible = false
|
||||
this.$emit('refreshDataList')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.error(data.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||