This commit is contained in:
23688nl 2021-05-14 17:29:13 +08:00
parent 7a6d58607a
commit 71061674db
179 changed files with 0 additions and 51567 deletions

View File

@ -1,209 +0,0 @@
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
import ParentView from '@/components/ParentView';
/**
* Note: 路由配置项
*
* hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401login等页面或者如一些编辑页面/edit/1
* alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时自动会变成嵌套的模式--如组件页面
* // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
* // 若你想不管路由下面的 children 声明的个数都显示你的根路由
* // 你可以设置 alwaysShow: true这样它就会忽略之前定义的规则一直显示根路由
* redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
* name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
* meta : {
noCache: true // 如果设置为true则不会被 <keep-alive> 缓存(默认 false)
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
icon: 'svg-name' // 设置该路由的图标对应路径src/assets/icons/svg
breadcrumb: false // 如果设置为false则不会在breadcrumb面包屑中显示
}
*/
// 公共路由
export const constantRoutes = [
{
path: '/redirect',
component: Layout,
hidden: true,
children: [
{
path: '/redirect/:path(.*)',
component: (resolve) => require(['@/views/redirect'], resolve)
}
]
},
{
path: '/login',
component: (resolve) => require(['@/views/login'], resolve),
hidden: true
},
{
path: '/404',
component: (resolve) => require(['@/views/error/404'], resolve),
hidden: true
},
{
path: '/401',
component: (resolve) => require(['@/views/error/401'], resolve),
hidden: true
},
{
path: '',
component: Layout,
redirect: 'bigsc',
children: [
{
path: '/bigsc',
component: (resolve) => require(['@/views/bigScreen/v1/index'], resolve),
name: 'BigScreen',
meta: {
title: '数据总览', icon: 'dashboard', noCache: true, affix: true
}
},
]},
{
path: '',
component: Layout,
redirect: 'bigsc',
children: [
{
path: 'index',
component: (resolve) => require(['@/views/index'], resolve),
name: '系统概览',
meta: { title: '系统概览', icon: 'button', noCache: true, affix: true }
},
{
path: '/news',
component: (resolve) => require(['@/views/bashboardcom/newsTable'], resolve),
name: 'NewsTable',
hidden: true,
meta: {
title: '新闻列表',
icon: 'dashboard',
noCache: false,
affix: false
}
},
{
path: '/newdestail',
component: (resolve) => require(['@/views/bashboardcom/newDestail'], resolve),
name: 'NewDestail',
hidden: true,
meta: {
title: '新闻查看',
icon: 'dashboard',
noCache: false,
affix: false
}
},
{
path: '/uplog/list',
component: (resolve) => require(['@/views/system/uplog/index'], resolve),
name: 'Uplogs',
hidden: true,
meta: {
title: '升级日志',
icon: 'dashboard',
noCache: false,
affix: false
}
},
]
},
{
path: '/user',
component: Layout,
hidden: true,
redirect: 'noredirect',
children: [
{
path: 'profile',
component: (resolve) => require(['@/views/system/user/profile/index'], resolve),
name: 'Profile',
meta: { title: '个人中心', icon: 'user' }
}
]
},
{
path: '/dict',
component: Layout,
hidden: true,
children: [
{
path: 'type/data/:dictId(\\d+)',
component: (resolve) => require(['@/views/system/dict/data'], resolve),
name: 'Data',
meta: { title: '字典数据', icon: '' }
}
]
},
{
path: '/job',
component: Layout,
hidden: true,
children: [
{
path: 'log',
component: (resolve) => require(['@/views/monitor/job/log'], resolve),
name: 'JobLog',
meta: { title: '调度日志' }
},
{
path: 'device/log',
component: (resolve) => require(['@/views/profile/autocontrol/jobLog/index'], resolve),
name: 'JobLog',
meta: { title: '调度日志' }
}
]
},
// {
// path: '/job',
// component: Layout,
// hidden: true,
// children: [
// {
// path: 'system/log',
// component: (resolve) => require(['@/views/iot/autocontrol/jobLog/index'], resolve),
// name: 'JobLog',
// meta: { title: '调度日志' }
// },
// {
// path: 'tenant/log',
// component: (resolve) => require(['@/views/monitor/job/log'], resolve),
// name: 'JobLog',
// meta: { title: '调度日志' }
// },
// {
// path: 'personal/log',
// component: (resolve) => require(['@/views/monitor/job/log'], resolve),
// name: 'JobLog',
// meta: { title: '调度日志' }
// }
// ]
// },
{
path: '/gen',
component: Layout,
hidden: true,
children: [
{
path: 'edit/:tableId(\\d+)',
component: (resolve) => require(['@/views/tool/gen/editTable'], resolve),
name: 'GenEdit',
meta: { title: '修改生成配置' }
}
]
}
]
export default new Router({
mode: 'history', // 去掉url中的#
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})

View File

@ -1,19 +0,0 @@
const getters = {
sidebar: state => state.app.sidebar,
size: state => state.app.size,
device: state => state.app.device,
visitedViews: state => state.tagsView.visitedViews,
cachedViews: state => state.tagsView.cachedViews,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
tenantId: state => state.user.tenantId,
userType: state => state.user.userType,
introduction: state => state.user.introduction,
roles: state => state.user.roles,
permissions: state => state.user.permissions,
permission_routes: state => state.permission.routes,
sidebarRouters:state => state.permission.sidebarRouters,
userId: state => state.user.userId
}
export default getters

View File

@ -1,23 +0,0 @@
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import user from './modules/user'
import tagsView from './modules/tagsView'
import permission from './modules/permission'
import settings from './modules/settings'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
app,
user,
tagsView,
permission,
settings
},
getters
})
export default store

View File

@ -1,56 +0,0 @@
import Cookies from 'js-cookie'
const state = {
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false
},
device: 'desktop',
size: Cookies.get('size') || 'medium'
}
const mutations = {
TOGGLE_SIDEBAR: state => {
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
}
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 0)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
},
TOGGLE_DEVICE: (state, device) => {
state.device = device
},
SET_SIZE: (state, size) => {
state.size = size
Cookies.set('size', size)
}
}
const actions = {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@ -1,89 +0,0 @@
import { constantRoutes } from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index'
import ParentView from '@/components/ParentView';
const permission = {
state: {
routes: [],
addRoutes: [],
sidebarRouters: []
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
},
SET_SIDEBAR_ROUTERS: (state, routers) => {
state.sidebarRouters = constantRoutes.concat(routers)
},
},
actions: {
// 生成路由
GenerateRoutes({ commit }) {
return new Promise(resolve => {
// 向后端请求路由数据
getRouters().then(res => {
const sdata = JSON.parse(JSON.stringify(res.data))
const rdata = JSON.parse(JSON.stringify(res.data))
const sidebarRoutes = filterAsyncRouter(sdata)
const rewriteRoutes = filterAsyncRouter(rdata, true)
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
commit('SET_ROUTES', rewriteRoutes)
commit('SET_SIDEBAR_ROUTERS', sidebarRoutes)
resolve(rewriteRoutes)
})
})
}
}
}
// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap, isRewrite = false) {
return asyncRouterMap.filter(route => {
if (isRewrite && route.children) {
route.children = filterChildren(route.children)
}
if (route.component) {
// Layout ParentView 组件特殊处理
if (route.component === 'Layout') {
route.component = Layout
} else if (route.component === 'ParentView') {
route.component = ParentView
} else {
route.component = loadView(route.component)
}
}
if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, route, isRewrite)
}
return true
})
}
function filterChildren(childrenMap) {
var children = []
childrenMap.forEach((el, index) => {
if (el.children && el.children.length) {
if (el.component === 'ParentView') {
el.children.forEach(c => {
c.path = el.path + '/' + c.path
if (c.children && c.children.length) {
children = children.concat(filterChildren(c.children, c))
return
}
children.push(c)
})
return
}
}
children = children.concat(el)
})
return children
}
export const loadView = (view) => { // 路由懒加载
return (resolve) => require([`@/views/${view}`], resolve)
}
export default permission

View File

@ -1,35 +0,0 @@
import variables from '@/assets/styles/element-variables.scss'
import defaultSettings from '@/settings'
const { sideTheme, showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings
const state = {
theme: variables.theme,
sideTheme: sideTheme,
showSettings: showSettings,
tagsView: tagsView,
fixedHeader: fixedHeader,
sidebarLogo: sidebarLogo
}
const mutations = {
CHANGE_SETTING: (state, { key, value }) => {
if (state.hasOwnProperty(key)) {
state[key] = value
}
}
}
const actions = {
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@ -1,159 +0,0 @@
const state = {
visitedViews: [],
cachedViews: []
}
const mutations = {
ADD_VISITED_VIEW: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
},
ADD_CACHED_VIEW: (state, view) => {
if (state.cachedViews.includes(view.name)) return
if (!view.meta.noCache) {
state.cachedViews.push(view.name)
}
},
DEL_VISITED_VIEW: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews.splice(i, 1)
break
}
}
},
DEL_CACHED_VIEW: (state, view) => {
const index = state.cachedViews.indexOf(view.name)
index > -1 && state.cachedViews.splice(index, 1)
},
DEL_OTHERS_VISITED_VIEWS: (state, view) => {
state.visitedViews = state.visitedViews.filter(v => {
return v.meta.affix || v.path === view.path
})
},
DEL_OTHERS_CACHED_VIEWS: (state, view) => {
const index = state.cachedViews.indexOf(view.name)
if (index > -1) {
state.cachedViews = state.cachedViews.slice(index, index + 1)
} else {
state.cachedViews = []
}
},
DEL_ALL_VISITED_VIEWS: state => {
// keep affix tags
const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
state.visitedViews = affixTags
},
DEL_ALL_CACHED_VIEWS: state => {
state.cachedViews = []
},
UPDATE_VISITED_VIEW: (state, view) => {
for (let v of state.visitedViews) {
if (v.path === view.path) {
v = Object.assign(v, view)
break
}
}
}
}
const actions = {
addView({ dispatch }, view) {
dispatch('addVisitedView', view)
dispatch('addCachedView', view)
},
addVisitedView({ commit }, view) {
commit('ADD_VISITED_VIEW', view)
},
addCachedView({ commit }, view) {
commit('ADD_CACHED_VIEW', view)
},
delView({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delVisitedView', view)
dispatch('delCachedView', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delVisitedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_VISITED_VIEW', view)
resolve([...state.visitedViews])
})
},
delCachedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_CACHED_VIEW', view)
resolve([...state.cachedViews])
})
},
delOthersViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delOthersVisitedViews', view)
dispatch('delOthersCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delOthersVisitedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_VISITED_VIEWS', view)
resolve([...state.visitedViews])
})
},
delOthersCachedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_CACHED_VIEWS', view)
resolve([...state.cachedViews])
})
},
delAllViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delAllVisitedViews', view)
dispatch('delAllCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delAllVisitedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_VISITED_VIEWS')
resolve([...state.visitedViews])
})
},
delAllCachedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_CACHED_VIEWS')
resolve([...state.cachedViews])
})
},
updateVisitedView({ commit }, view) {
commit('UPDATE_VISITED_VIEW', view)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@ -1,114 +0,0 @@
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { startInterval } from '@/api/thirdApi'
const user = {
state: {
token: getToken(),
name: '',
avatar: '',
tenantId: '',
userType: '',
roles: [],
permissions: [],
userId: ''
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
},
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
},
SET_TENANTID: (state, tenantId) => {
state.tenantId = tenantId
},
SET_USERTYPE: (state, userType) => {
state.userType = userType
},
SET_USERID: (state, userId) => {
state.userId = userId
}
},
actions: {
// 登录
Login({ commit }, userInfo) {
const username = userInfo.username.trim()
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
const userType = userInfo.userType
return new Promise((resolve, reject) => {
login(username, password, code, uuid, userType).then(res => {
setToken(res.token)
commit('SET_TOKEN', res.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(res => {
const user = res.user
const avatar = user.avatar == "" ? require("@/assets/images/defaultAvatar.png") : user.avatar;
startInterval();
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', res.roles)
commit('SET_PERMISSIONS', res.permissions)
} else {
commit('SET_ROLES', ['ROLE_DEFAULT'])
}
commit('SET_USERID', user.userId)
commit('SET_NAME', user.userName)
commit('SET_TENANTID', user.tenantId)
commit('SET_USERTYPE', user.userType)
commit('SET_AVATAR', avatar)
resolve(res)
}).catch(error => {
reject(error)
})
})
},
// 退出系统
LogOut({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
commit('SET_PERMISSIONS', [])
removeToken()
resolve()
}).catch(error => {
reject(error)
})
})
},
// 前端 登出
FedLogOut({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
removeToken()
resolve()
})
}
}
}
export default user

View File

@ -1,15 +0,0 @@
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}

View File

@ -1,36 +0,0 @@
// 设置cookie
const setCookie = (name, value, day) => {
var date = new Date();
date.setDate(date.getDate() + day);
document.cookie = name + "=" + value + ";expires=" + date;
}
// 获取cookie
const getCookie = (name) => {
var reg = RegExp(name + "=([^;]+)");
var arr = document.cookie.match(reg);
if (arr) {
return arr[1];
} else {
return "";
}
}
// 记录登录用户和密码赋值
export const isRememberLogin = () => {
return {
loginName: getCookie('username'),
password: getCookie('password'),
isRemPass: getCookie('isRemPass')
}
};
// 记住密码设置
export const rememberLogin = (username, password, keeplogin, day) => {
setCookie('isRemPass', keeplogin, day );
setCookie('username', username, day );
setCookie('password', password, day );
}

View File

@ -1,6 +0,0 @@
export default {
'401': '认证失败,无法访问系统资源',
'403': '当前操作没有权限',
'404': '访问资源不存在',
'default': '系统未知错误,请反馈给管理员'
}

View File

@ -1,438 +0,0 @@
export const formConf = {
formRef: 'elForm',
formModel: 'formData',
size: 'medium',
labelPosition: 'right',
labelWidth: 100,
formRules: 'rules',
gutter: 15,
disabled: false,
span: 24,
formBtns: true
}
export const inputComponents = [
{
label: '单行文本',
tag: 'el-input',
tagIcon: 'input',
placeholder: '请输入',
defaultValue: undefined,
span: 24,
labelWidth: null,
style: { width: '100%' },
clearable: true,
prepend: '',
append: '',
'prefix-icon': '',
'suffix-icon': '',
maxlength: null,
'show-word-limit': false,
readonly: false,
disabled: false,
required: true,
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/input'
},
{
label: '多行文本',
tag: 'el-input',
tagIcon: 'textarea',
type: 'textarea',
placeholder: '请输入',
defaultValue: undefined,
span: 24,
labelWidth: null,
autosize: {
minRows: 4,
maxRows: 4
},
style: { width: '100%' },
maxlength: null,
'show-word-limit': false,
readonly: false,
disabled: false,
required: true,
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/input'
},
{
label: '密码',
tag: 'el-input',
tagIcon: 'password',
placeholder: '请输入',
defaultValue: undefined,
span: 24,
'show-password': true,
labelWidth: null,
style: { width: '100%' },
clearable: true,
prepend: '',
append: '',
'prefix-icon': '',
'suffix-icon': '',
maxlength: null,
'show-word-limit': false,
readonly: false,
disabled: false,
required: true,
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/input'
},
{
label: '计数器',
tag: 'el-input-number',
tagIcon: 'number',
placeholder: '',
defaultValue: undefined,
span: 24,
labelWidth: null,
min: undefined,
max: undefined,
step: undefined,
'step-strictly': false,
precision: undefined,
'controls-position': '',
disabled: false,
required: true,
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/input-number'
}
]
export const selectComponents = [
{
label: '下拉选择',
tag: 'el-select',
tagIcon: 'select',
placeholder: '请选择',
defaultValue: undefined,
span: 24,
labelWidth: null,
style: { width: '100%' },
clearable: true,
disabled: false,
required: true,
filterable: false,
multiple: false,
options: [{
label: '选项一',
value: 1
}, {
label: '选项二',
value: 2
}],
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/select'
},
{
label: '级联选择',
tag: 'el-cascader',
tagIcon: 'cascader',
placeholder: '请选择',
defaultValue: [],
span: 24,
labelWidth: null,
style: { width: '100%' },
props: {
props: {
multiple: false
}
},
'show-all-levels': true,
disabled: false,
clearable: true,
filterable: false,
required: true,
options: [{
id: 1,
value: 1,
label: '选项1',
children: [{
id: 2,
value: 2,
label: '选项1-1'
}]
}],
dataType: 'dynamic',
labelKey: 'label',
valueKey: 'value',
childrenKey: 'children',
separator: '/',
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/cascader'
},
{
label: '单选框组',
tag: 'el-radio-group',
tagIcon: 'radio',
defaultValue: undefined,
span: 24,
labelWidth: null,
style: {},
optionType: 'default',
border: false,
size: 'medium',
disabled: false,
required: true,
options: [{
label: '选项一',
value: 1
}, {
label: '选项二',
value: 2
}],
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/radio'
},
{
label: '多选框组',
tag: 'el-checkbox-group',
tagIcon: 'checkbox',
defaultValue: [],
span: 24,
labelWidth: null,
style: {},
optionType: 'default',
border: false,
size: 'medium',
disabled: false,
required: true,
options: [{
label: '选项一',
value: 1
}, {
label: '选项二',
value: 2
}],
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/checkbox'
},
{
label: '开关',
tag: 'el-switch',
tagIcon: 'switch',
defaultValue: false,
span: 24,
labelWidth: null,
style: {},
disabled: false,
required: true,
'active-text': '',
'inactive-text': '',
'active-color': null,
'inactive-color': null,
'active-value': true,
'inactive-value': false,
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/switch'
},
{
label: '滑块',
tag: 'el-slider',
tagIcon: 'slider',
defaultValue: null,
span: 24,
labelWidth: null,
disabled: false,
required: true,
min: 0,
max: 100,
step: 1,
'show-stops': false,
range: false,
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/slider'
},
{
label: '时间选择',
tag: 'el-time-picker',
tagIcon: 'time',
placeholder: '请选择',
defaultValue: null,
span: 24,
labelWidth: null,
style: { width: '100%' },
disabled: false,
clearable: true,
required: true,
'picker-options': {
selectableRange: '00:00:00-23:59:59'
},
format: 'HH:mm:ss',
'value-format': 'HH:mm:ss',
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
},
{
label: '时间范围',
tag: 'el-time-picker',
tagIcon: 'time-range',
defaultValue: null,
span: 24,
labelWidth: null,
style: { width: '100%' },
disabled: false,
clearable: true,
required: true,
'is-range': true,
'range-separator': '至',
'start-placeholder': '开始时间',
'end-placeholder': '结束时间',
format: 'HH:mm:ss',
'value-format': 'HH:mm:ss',
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
},
{
label: '日期选择',
tag: 'el-date-picker',
tagIcon: 'date',
placeholder: '请选择',
defaultValue: null,
type: 'date',
span: 24,
labelWidth: null,
style: { width: '100%' },
disabled: false,
clearable: true,
required: true,
format: 'yyyy-MM-dd',
'value-format': 'yyyy-MM-dd',
readonly: false,
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
},
{
label: '日期范围',
tag: 'el-date-picker',
tagIcon: 'date-range',
defaultValue: null,
span: 24,
labelWidth: null,
style: { width: '100%' },
type: 'daterange',
'range-separator': '至',
'start-placeholder': '开始日期',
'end-placeholder': '结束日期',
disabled: false,
clearable: true,
required: true,
format: 'yyyy-MM-dd',
'value-format': 'yyyy-MM-dd',
readonly: false,
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
},
{
label: '评分',
tag: 'el-rate',
tagIcon: 'rate',
defaultValue: 0,
span: 24,
labelWidth: null,
style: {},
max: 5,
'allow-half': false,
'show-text': false,
'show-score': false,
disabled: false,
required: true,
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/rate'
},
{
label: '颜色选择',
tag: 'el-color-picker',
tagIcon: 'color',
defaultValue: null,
labelWidth: null,
'show-alpha': false,
'color-format': '',
disabled: false,
required: true,
size: 'medium',
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/color-picker'
},
{
label: '上传',
tag: 'el-upload',
tagIcon: 'upload',
action: 'https://jsonplaceholder.typicode.com/posts/',
defaultValue: null,
labelWidth: null,
disabled: false,
required: true,
accept: '',
name: 'file',
'auto-upload': true,
showTip: false,
buttonText: '点击上传',
fileSize: 2,
sizeUnit: 'MB',
'list-type': 'text',
multiple: false,
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/upload'
}
]
export const layoutComponents = [
{
layout: 'rowFormItem',
tagIcon: 'row',
type: 'default',
justify: 'start',
align: 'top',
label: '行容器',
layoutTree: true,
children: [],
document: 'https://element.eleme.cn/#/zh-CN/component/layout'
},
{
layout: 'colFormItem',
label: '按钮',
changeTag: true,
labelWidth: null,
tag: 'el-button',
tagIcon: 'button',
span: 24,
default: '主要按钮',
type: 'primary',
icon: 'el-icon-search',
size: 'medium',
disabled: false,
document: 'https://element.eleme.cn/#/zh-CN/component/button'
}
]
// 组件rule的触发方式无触发方式的组件不生成rule
export const trigger = {
'el-input': 'blur',
'el-input-number': 'blur',
'el-select': 'change',
'el-radio-group': 'change',
'el-checkbox-group': 'change',
'el-cascader': 'change',
'el-time-picker': 'change',
'el-date-picker': 'change',
'el-rate': 'change'
}

View File

@ -1,18 +0,0 @@
const styles = {
'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}',
'el-upload': '.el-upload__tip{line-height: 1.2;}'
}
function addCss(cssList, el) {
const css = styles[el.tag]
css && cssList.indexOf(css) === -1 && cssList.push(css)
if (el.children) {
el.children.forEach(el2 => addCss(cssList, el2))
}
}
export function makeUpCss(conf) {
const cssList = []
conf.fields.forEach(el => addCss(cssList, el))
return cssList.join('\n')
}

View File

@ -1,29 +0,0 @@
export default [
{
layout: 'colFormItem',
tagIcon: 'input',
label: '手机号',
vModel: 'mobile',
formId: 6,
tag: 'el-input',
placeholder: '请输入手机号',
defaultValue: '',
span: 24,
style: { width: '100%' },
clearable: true,
prepend: '',
append: '',
'prefix-icon': 'el-icon-mobile',
'suffix-icon': '',
maxlength: 11,
'show-word-limit': true,
readonly: false,
disabled: false,
required: true,
changeTag: true,
regList: [{
pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
message: '手机号格式错误'
}]
}
]

View File

@ -1,359 +0,0 @@
/* eslint-disable max-len */
import { trigger } from './config'
let confGlobal
let someSpanIsNot24
export function dialogWrapper(str) {
return `<el-dialog v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" title="Dialog Titile">
${str}
<div slot="footer">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="handelConfirm">确定</el-button>
</div>
</el-dialog>`
}
export function vueTemplate(str) {
return `<template>
<div>
${str}
</div>
</template>`
}
export function vueScript(str) {
return `<script>
${str}
</script>`
}
export function cssStyle(cssStr) {
return `<style>
${cssStr}
</style>`
}
function buildFormTemplate(conf, child, type) {
let labelPosition = ''
if (conf.labelPosition !== 'right') {
labelPosition = `label-position="${conf.labelPosition}"`
}
const disabled = conf.disabled ? `:disabled="${conf.disabled}"` : ''
let str = `<el-form ref="${conf.formRef}" :model="${conf.formModel}" :rules="${conf.formRules}" size="${conf.size}" ${disabled} label-width="${conf.labelWidth}px" ${labelPosition}>
${child}
${buildFromBtns(conf, type)}
</el-form>`
if (someSpanIsNot24) {
str = `<el-row :gutter="${conf.gutter}">
${str}
</el-row>`
}
return str
}
function buildFromBtns(conf, type) {
let str = ''
if (conf.formBtns && type === 'file') {
str = `<el-form-item size="large">
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>`
if (someSpanIsNot24) {
str = `<el-col :span="24">
${str}
</el-col>`
}
}
return str
}
// span不为24的用el-col包裹
function colWrapper(element, str) {
if (someSpanIsNot24 || element.span !== 24) {
return `<el-col :span="${element.span}">
${str}
</el-col>`
}
return str
}
const layouts = {
colFormItem(element) {
let labelWidth = ''
if (element.labelWidth && element.labelWidth !== confGlobal.labelWidth) {
labelWidth = `label-width="${element.labelWidth}px"`
}
const required = !trigger[element.tag] && element.required ? 'required' : ''
const tagDom = tags[element.tag] ? tags[element.tag](element) : null
let str = `<el-form-item ${labelWidth} label="${element.label}" prop="${element.vModel}" ${required}>
${tagDom}
</el-form-item>`
str = colWrapper(element, str)
return str
},
rowFormItem(element) {
const type = element.type === 'default' ? '' : `type="${element.type}"`
const justify = element.type === 'default' ? '' : `justify="${element.justify}"`
const align = element.type === 'default' ? '' : `align="${element.align}"`
const gutter = element.gutter ? `gutter="${element.gutter}"` : ''
const children = element.children.map(el => layouts[el.layout](el))
let str = `<el-row ${type} ${justify} ${align} ${gutter}>
${children.join('\n')}
</el-row>`
str = colWrapper(element, str)
return str
}
}
const tags = {
'el-button': el => {
const {
tag, disabled
} = attrBuilder(el)
const type = el.type ? `type="${el.type}"` : ''
const icon = el.icon ? `icon="${el.icon}"` : ''
const size = el.size ? `size="${el.size}"` : ''
let child = buildElButtonChild(el)
if (child) child = `\n${child}\n` // 换行
return `<${el.tag} ${type} ${icon} ${size} ${disabled}>${child}</${el.tag}>`
},
'el-input': el => {
const {
disabled, vModel, clearable, placeholder, width
} = attrBuilder(el)
const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : ''
const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : ''
const readonly = el.readonly ? 'readonly' : ''
const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : ''
const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : ''
const showPassword = el['show-password'] ? 'show-password' : ''
const type = el.type ? `type="${el.type}"` : ''
const autosize = el.autosize && el.autosize.minRows
? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"`
: ''
let child = buildElInputChild(el)
if (child) child = `\n${child}\n` // 换行
return `<${el.tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}</${el.tag}>`
},
'el-input-number': el => {
const { disabled, vModel, placeholder } = attrBuilder(el)
const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : ''
const min = el.min ? `:min='${el.min}'` : ''
const max = el.max ? `:max='${el.max}'` : ''
const step = el.step ? `:step='${el.step}'` : ''
const stepStrictly = el['step-strictly'] ? 'step-strictly' : ''
const precision = el.precision ? `:precision='${el.precision}'` : ''
return `<${el.tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}></${el.tag}>`
},
'el-select': el => {
const {
disabled, vModel, clearable, placeholder, width
} = attrBuilder(el)
const filterable = el.filterable ? 'filterable' : ''
const multiple = el.multiple ? 'multiple' : ''
let child = buildElSelectChild(el)
if (child) child = `\n${child}\n` // 换行
return `<${el.tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}</${el.tag}>`
},
'el-radio-group': el => {
const { disabled, vModel } = attrBuilder(el)
const size = `size="${el.size}"`
let child = buildElRadioGroupChild(el)
if (child) child = `\n${child}\n` // 换行
return `<${el.tag} ${vModel} ${size} ${disabled}>${child}</${el.tag}>`
},
'el-checkbox-group': el => {
const { disabled, vModel } = attrBuilder(el)
const size = `size="${el.size}"`
const min = el.min ? `:min="${el.min}"` : ''
const max = el.max ? `:max="${el.max}"` : ''
let child = buildElCheckboxGroupChild(el)
if (child) child = `\n${child}\n` // 换行
return `<${el.tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}</${el.tag}>`
},
'el-switch': el => {
const { disabled, vModel } = attrBuilder(el)
const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : ''
const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : ''
const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : ''
const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : ''
const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : ''
const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : ''
return `<${el.tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}></${el.tag}>`
},
'el-cascader': el => {
const {
disabled, vModel, clearable, placeholder, width
} = attrBuilder(el)
const options = el.options ? `:options="${el.vModel}Options"` : ''
const props = el.props ? `:props="${el.vModel}Props"` : ''
const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"'
const filterable = el.filterable ? 'filterable' : ''
const separator = el.separator === '/' ? '' : `separator="${el.separator}"`
return `<${el.tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}></${el.tag}>`
},
'el-slider': el => {
const { disabled, vModel } = attrBuilder(el)
const min = el.min ? `:min='${el.min}'` : ''
const max = el.max ? `:max='${el.max}'` : ''
const step = el.step ? `:step='${el.step}'` : ''
const range = el.range ? 'range' : ''
const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : ''
return `<${el.tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}></${el.tag}>`
},
'el-time-picker': el => {
const {
disabled, vModel, clearable, placeholder, width
} = attrBuilder(el)
const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
const isRange = el['is-range'] ? 'is-range' : ''
const format = el.format ? `format="${el.format}"` : ''
const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : ''
return `<${el.tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}></${el.tag}>`
},
'el-date-picker': el => {
const {
disabled, vModel, clearable, placeholder, width
} = attrBuilder(el)
const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
const format = el.format ? `format="${el.format}"` : ''
const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
const type = el.type === 'date' ? '' : `type="${el.type}"`
const readonly = el.readonly ? 'readonly' : ''
return `<${el.tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}></${el.tag}>`
},
'el-rate': el => {
const { disabled, vModel } = attrBuilder(el)
const max = el.max ? `:max='${el.max}'` : ''
const allowHalf = el['allow-half'] ? 'allow-half' : ''
const showText = el['show-text'] ? 'show-text' : ''
const showScore = el['show-score'] ? 'show-score' : ''
return `<${el.tag} ${vModel} ${allowHalf} ${showText} ${showScore} ${disabled}></${el.tag}>`
},
'el-color-picker': el => {
const { disabled, vModel } = attrBuilder(el)
const size = `size="${el.size}"`
const showAlpha = el['show-alpha'] ? 'show-alpha' : ''
const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : ''
return `<${el.tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}></${el.tag}>`
},
'el-upload': el => {
const disabled = el.disabled ? ':disabled=\'true\'' : ''
const action = el.action ? `:action="${el.vModel}Action"` : ''
const multiple = el.multiple ? 'multiple' : ''
const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : ''
const accept = el.accept ? `accept="${el.accept}"` : ''
const name = el.name !== 'file' ? `name="${el.name}"` : ''
const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : ''
const beforeUpload = `:before-upload="${el.vModel}BeforeUpload"`
const fileList = `:file-list="${el.vModel}fileList"`
const ref = `ref="${el.vModel}"`
let child = buildElUploadChild(el)
if (child) child = `\n${child}\n` // 换行
return `<${el.tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}</${el.tag}>`
}
}
function attrBuilder(el) {
return {
vModel: `v-model="${confGlobal.formModel}.${el.vModel}"`,
clearable: el.clearable ? 'clearable' : '',
placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '',
width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '',
disabled: el.disabled ? ':disabled=\'true\'' : ''
}
}
// el-buttin 子级
function buildElButtonChild(conf) {
const children = []
if (conf.default) {
children.push(conf.default)
}
return children.join('\n')
}
// el-input innerHTML
function buildElInputChild(conf) {
const children = []
if (conf.prepend) {
children.push(`<template slot="prepend">${conf.prepend}</template>`)
}
if (conf.append) {
children.push(`<template slot="append">${conf.append}</template>`)
}
return children.join('\n')
}
function buildElSelectChild(conf) {
const children = []
if (conf.options && conf.options.length) {
children.push(`<el-option v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled"></el-option>`)
}
return children.join('\n')
}
function buildElRadioGroupChild(conf) {
const children = []
if (conf.options && conf.options.length) {
const tag = conf.optionType === 'button' ? 'el-radio-button' : 'el-radio'
const border = conf.border ? 'border' : ''
children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`)
}
return children.join('\n')
}
function buildElCheckboxGroupChild(conf) {
const children = []
if (conf.options && conf.options.length) {
const tag = conf.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox'
const border = conf.border ? 'border' : ''
children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`)
}
return children.join('\n')
}
function buildElUploadChild(conf) {
const list = []
if (conf['list-type'] === 'picture-card') list.push('<i class="el-icon-plus"></i>')
else list.push(`<el-button size="small" type="primary" icon="el-icon-upload">${conf.buttonText}</el-button>`)
if (conf.showTip) list.push(`<div slot="tip" class="el-upload__tip">只能上传不超过 ${conf.fileSize}${conf.sizeUnit}${conf.accept}文件</div>`)
return list.join('\n')
}
export function makeUpHtml(conf, type) {
const htmlList = []
confGlobal = conf
someSpanIsNot24 = conf.fields.some(item => item.span !== 24)
conf.fields.forEach(el => {
htmlList.push(layouts[el.layout](el))
})
const htmlStr = htmlList.join('\n')
let temp = buildFormTemplate(conf, htmlStr, type)
if (type === 'dialog') {
temp = dialogWrapper(temp)
}
confGlobal = null
return temp
}

View File

@ -1 +0,0 @@
["platform-eleme","eleme","delete-solid","delete","s-tools","setting","user-solid","user","phone","phone-outline","more","more-outline","star-on","star-off","s-goods","goods","warning","warning-outline","question","info","remove","circle-plus","success","error","zoom-in","zoom-out","remove-outline","circle-plus-outline","circle-check","circle-close","s-help","help","minus","plus","check","close","picture","picture-outline","picture-outline-round","upload","upload2","download","camera-solid","camera","video-camera-solid","video-camera","message-solid","bell","s-cooperation","s-order","s-platform","s-fold","s-unfold","s-operation","s-promotion","s-home","s-release","s-ticket","s-management","s-open","s-shop","s-marketing","s-flag","s-comment","s-finance","s-claim","s-custom","s-opportunity","s-data","s-check","s-grid","menu","share","d-caret","caret-left","caret-right","caret-bottom","caret-top","bottom-left","bottom-right","back","right","bottom","top","top-left","top-right","arrow-left","arrow-right","arrow-down","arrow-up","d-arrow-left","d-arrow-right","video-pause","video-play","refresh","refresh-right","refresh-left","finished","sort","sort-up","sort-down","rank","loading","view","c-scale-to-original","date","edit","edit-outline","folder","folder-opened","folder-add","folder-remove","folder-delete","folder-checked","tickets","document-remove","document-delete","document-copy","document-checked","document","document-add","printer","paperclip","takeaway-box","search","monitor","attract","mobile","scissors","umbrella","headset","brush","mouse","coordinate","magic-stick","reading","data-line","data-board","pie-chart","data-analysis","collection-tag","film","suitcase","suitcase-1","receiving","collection","files","notebook-1","notebook-2","toilet-paper","office-building","school","table-lamp","house","no-smoking","smoking","shopping-cart-full","shopping-cart-1","shopping-cart-2","shopping-bag-1","shopping-bag-2","sold-out","sell","present","box","bank-card","money","coin","wallet","discount","price-tag","news","guide","male","female","thumb","cpu","link","connection","open","turn-off","set-up","chat-round","chat-line-round","chat-square","chat-dot-round","chat-dot-square","chat-line-square","message","postcard","position","turn-off-microphone","microphone","close-notification","bangzhu","time","odometer","crop","aim","switch-button","full-screen","copy-document","mic","stopwatch","medal-1","medal","trophy","trophy-1","first-aid-kit","discover","place","location","location-outline","location-information","add-location","delete-location","map-location","alarm-clock","timer","watch-1","watch","lock","unlock","key","service","mobile-phone","bicycle","truck","ship","basketball","football","soccer","baseball","wind-power","light-rain","lightning","heavy-rain","sunrise","sunrise-1","sunset","sunny","cloudy","partly-cloudy","cloudy-and-sunny","moon","moon-night","dish","dish-1","food","chicken","fork-spoon","knife-fork","burger","tableware","sugar","dessert","ice-cream","hot-water","water-cup","coffee-cup","cold-drink","goblet","goblet-full","goblet-square","goblet-square-full","refrigerator","grape","watermelon","cherry","apple","pear","orange","coffee","ice-tea","ice-drink","milk-tea","potato-strips","lollipop","ice-cream-square","ice-cream-round"]

View File

@ -1,236 +0,0 @@
import { isArray } from 'util'
import { exportDefault, titleCase } from '@/utils/index'
import { trigger } from './config'
const units = {
KB: '1024',
MB: '1024 / 1024',
GB: '1024 / 1024 / 1024'
}
let confGlobal
const inheritAttrs = {
file: '',
dialog: 'inheritAttrs: false,'
}
export function makeUpJs(conf, type) {
confGlobal = conf = JSON.parse(JSON.stringify(conf))
const dataList = []
const ruleList = []
const optionsList = []
const propsList = []
const methodList = mixinMethod(type)
const uploadVarList = []
conf.fields.forEach(el => {
buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList)
})
const script = buildexport(
conf,
type,
dataList.join('\n'),
ruleList.join('\n'),
optionsList.join('\n'),
uploadVarList.join('\n'),
propsList.join('\n'),
methodList.join('\n')
)
confGlobal = null
return script
}
function buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) {
buildData(el, dataList)
buildRules(el, ruleList)
if (el.options && el.options.length) {
buildOptions(el, optionsList)
if (el.dataType === 'dynamic') {
const model = `${el.vModel}Options`
const options = titleCase(model)
buildOptionMethod(`get${options}`, model, methodList)
}
}
if (el.props && el.props.props) {
buildProps(el, propsList)
}
if (el.action && el.tag === 'el-upload') {
uploadVarList.push(
`${el.vModel}Action: '${el.action}',
${el.vModel}fileList: [],`
)
methodList.push(buildBeforeUpload(el))
if (!el['auto-upload']) {
methodList.push(buildSubmitUpload(el))
}
}
if (el.children) {
el.children.forEach(el2 => {
buildAttributes(el2, dataList, ruleList, optionsList, methodList, propsList, uploadVarList)
})
}
}
function mixinMethod(type) {
const list = []; const
minxins = {
file: confGlobal.formBtns ? {
submitForm: `submitForm() {
this.$refs['${confGlobal.formRef}'].validate(valid => {
if(!valid) return
// TODO 提交表单
})
},`,
resetForm: `resetForm() {
this.$refs['${confGlobal.formRef}'].resetFields()
},`
} : null,
dialog: {
onOpen: 'onOpen() {},',
onClose: `onClose() {
this.$refs['${confGlobal.formRef}'].resetFields()
},`,
close: `close() {
this.$emit('update:visible', false)
},`,
handelConfirm: `handelConfirm() {
this.$refs['${confGlobal.formRef}'].validate(valid => {
if(!valid) return
this.close()
})
},`
}
}
const methods = minxins[type]
if (methods) {
Object.keys(methods).forEach(key => {
list.push(methods[key])
})
}
return list
}
function buildData(conf, dataList) {
if (conf.vModel === undefined) return
let defaultValue
if (typeof (conf.defaultValue) === 'string' && !conf.multiple) {
defaultValue = `'${conf.defaultValue}'`
} else {
defaultValue = `${JSON.stringify(conf.defaultValue)}`
}
dataList.push(`${conf.vModel}: ${defaultValue},`)
}
function buildRules(conf, ruleList) {
if (conf.vModel === undefined) return
const rules = []
if (trigger[conf.tag]) {
if (conf.required) {
const type = isArray(conf.defaultValue) ? 'type: \'array\',' : ''
let message = isArray(conf.defaultValue) ? `请至少选择一个${conf.vModel}` : conf.placeholder
if (message === undefined) message = `${conf.label}不能为空`
rules.push(`{ required: true, ${type} message: '${message}', trigger: '${trigger[conf.tag]}' }`)
}
if (conf.regList && isArray(conf.regList)) {
conf.regList.forEach(item => {
if (item.pattern) {
rules.push(`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${trigger[conf.tag]}' }`)
}
})
}
ruleList.push(`${conf.vModel}: [${rules.join(',')}],`)
}
}
function buildOptions(conf, optionsList) {
if (conf.vModel === undefined) return
if (conf.dataType === 'dynamic') { conf.options = [] }
const str = `${conf.vModel}Options: ${JSON.stringify(conf.options)},`
optionsList.push(str)
}
function buildProps(conf, propsList) {
if (conf.dataType === 'dynamic') {
conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey)
conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey)
conf.childrenKey !== 'children' && (conf.props.props.children = conf.childrenKey)
}
const str = `${conf.vModel}Props: ${JSON.stringify(conf.props.props)},`
propsList.push(str)
}
function buildBeforeUpload(conf) {
const unitNum = units[conf.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const
returnList = []
if (conf.fileSize) {
rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize}
if(!isRightSize){
this.$message.error('文件大小超过 ${conf.fileSize}${conf.sizeUnit}')
}`
returnList.push('isRightSize')
}
if (conf.accept) {
acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type)
if(!isAccept){
this.$message.error('应该选择${conf.accept}类型的文件')
}`
returnList.push('isAccept')
}
const str = `${conf.vModel}BeforeUpload(file) {
${rightSizeCode}
${acceptCode}
return ${returnList.join('&&')}
},`
return returnList.length ? str : ''
}
function buildSubmitUpload(conf) {
const str = `submitUpload() {
this.$refs['${conf.vModel}'].submit()
},`
return str
}
function buildOptionMethod(methodName, model, methodList) {
const str = `${methodName}() {
// TODO 发起请求获取数据
this.${model}
},`
methodList.push(str)
}
function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods) {
const str = `${exportDefault}{
${inheritAttrs[type]}
components: {},
props: [],
data () {
return {
${conf.formModel}: {
${data}
},
${conf.formRules}: {
${rules}
},
${uploadVar}
${selectOptions}
${props}
}
},
computed: {},
watch: {},
created () {},
mounted () {},
methods: {
${methods}
}
}`
return str
}

View File

@ -1,126 +0,0 @@
import { makeMap } from '@/utils/index'
// 参考https://github.com/vuejs/vue/blob/v2.6.10/src/platforms/web/server/util.js
const isAttr = makeMap(
'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,'
+ 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,'
+ 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,'
+ 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,'
+ 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,'
+ 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,'
+ 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,'
+ 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,'
+ 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,'
+ 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,'
+ 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,'
+ 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,'
+ 'target,title,type,usemap,value,width,wrap'
)
function vModel(self, dataObject, defaultValue) {
dataObject.props.value = defaultValue
dataObject.on.input = val => {
self.$emit('input', val)
}
}
const componentChild = {
'el-button': {
default(h, conf, key) {
return conf[key]
},
},
'el-input': {
prepend(h, conf, key) {
return <template slot="prepend">{conf[key]}</template>
},
append(h, conf, key) {
return <template slot="append">{conf[key]}</template>
}
},
'el-select': {
options(h, conf, key) {
const list = []
conf.options.forEach(item => {
list.push(<el-option label={item.label} value={item.value} disabled={item.disabled}></el-option>)
})
return list
}
},
'el-radio-group': {
options(h, conf, key) {
const list = []
conf.options.forEach(item => {
if (conf.optionType === 'button') list.push(<el-radio-button label={item.value}>{item.label}</el-radio-button>)
else list.push(<el-radio label={item.value} border={conf.border}>{item.label}</el-radio>)
})
return list
}
},
'el-checkbox-group': {
options(h, conf, key) {
const list = []
conf.options.forEach(item => {
if (conf.optionType === 'button') {
list.push(<el-checkbox-button label={item.value}>{item.label}</el-checkbox-button>)
} else {
list.push(<el-checkbox label={item.value} border={conf.border}>{item.label}</el-checkbox>)
}
})
return list
}
},
'el-upload': {
'list-type': (h, conf, key) => {
const list = []
if (conf['list-type'] === 'picture-card') {
list.push(<i class="el-icon-plus"></i>)
} else {
list.push(<el-button size="small" type="primary" icon="el-icon-upload">{conf.buttonText}</el-button>)
}
if (conf.showTip) {
list.push(<div slot="tip" class="el-upload__tip">只能上传不超过 {conf.fileSize}{conf.sizeUnit} {conf.accept}文件</div>)
}
return list
}
}
}
export default {
render(h) {
const dataObject = {
attrs: {},
props: {},
on: {},
style: {}
}
const confClone = JSON.parse(JSON.stringify(this.conf))
const children = []
const childObjs = componentChild[confClone.tag]
if (childObjs) {
Object.keys(childObjs).forEach(key => {
const childFunc = childObjs[key]
if (confClone[key]) {
children.push(childFunc(h, confClone, key))
}
})
}
Object.keys(confClone).forEach(key => {
const val = confClone[key]
if (key === 'vModel') {
vModel(this, dataObject, confClone.defaultValue)
} else if (dataObject[key]) {
dataObject[key] = val
} else if (!isAttr(key)) {
dataObject.props[key] = val
} else {
dataObject.attrs[key] = val
}
})
return h(this.conf.tag, dataObject, children)
},
props: ['conf']
}

View File

@ -1,233 +0,0 @@
/**
* 通用js方法封装处理
* Copyright (c) 2019 hciot
*/
import { Loading } from 'element-ui';
const baseURL = process.env.VUE_APP_BASE_API
const targetURL = process.env.target
var loading = null;
// 日期格式化
export function parseTime(time, pattern) {
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/');
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
debugger
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
// 表单重置
export function resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields();
}
}
// 添加日期范围
export function addDateRange(params, dateRange) {
var search = params;
search.beginTime = "";
search.endTime = "";
if (null != dateRange && '' != dateRange) {
search.beginTime = this.dateRange[0];
search.endTime = this.dateRange[1];
}
return search;
}
// 回显数据字典
export function selectDictLabel(datas, value) {
var actions = [];
Object.keys(datas).map((key) => {
if (datas[key].dictValue == ('' + value)) {
actions.push(datas[key].dictLabel);
return false;
}
})
return actions.join('');
}
// 通用下载方法
export function download(fileName) {
window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
}
// 字符串格式化(%s )
export function sprintf(str) {
var args = arguments, flag = true, i = 1;
str = str.replace(/%s/g, function () {
var arg = args[i++];
if (typeof arg === 'undefined') {
flag = false;
return '';
}
return arg;
});
return flag ? str : '';
}
// 转换字符串undefined,null等转化为""
export function praseStrEmpty(str) {
if (!str || str == "undefined" || str == "null") {
return "";
}
return str;
}
/**
* 构造树型结构数据
* @param {*} data 数据源
* @param {*} id id字段 默认 'id'
* @param {*} parentId 父节点字段 默认 'parentId'
* @param {*} children 孩子节点字段 默认 'children'
* @param {*} rootId 根Id 默认 0
*/
export function handleTree(data, id, parentId, children, rootId) {
id = id || 'id'
parentId = parentId || 'parentId'
children = children || 'children'
rootId = rootId || 0
//对源数据深度克隆
const cloneData = JSON.parse(JSON.stringify(data))
//循环所有项
const treeData = cloneData.filter(father => {
let branchArr = cloneData.filter(child => {
//返回每一项的子级数组
return father[id] === child[parentId]
});
branchArr.length > 0 ? father.children = branchArr : '';
//返回第一层
return father[parentId] === rootId;
});
return treeData != '' ? treeData : data;
}
/**
* 参数处理
* @param {*} params 参数
*/
export function tansParams(params) {
let result = ''
Object.keys(params).forEach((key) => {
if (!Object.is(params[key], undefined) && !Object.is(params[key], null)) {
result += encodeURIComponent(key) + '=' + encodeURIComponent(params[key]) + '&'
}
})
return result
}
// 图片地址返回
export function getIotFileUrl(importUrl) {
if (!importUrl) {
return '/assets/logo/logo.png';
}
if (importUrl.indexOf('http') === 0 || importUrl.indexOf('https') === 0) {
return importUrl;
} else if (importUrl.indexOf('/profile/upload/') === 0 || importUrl.indexOf('/profile/avatar/') === 0) {
return baseURL + importUrl;
} else if (importUrl.indexOf('data:image/') === 0 || importUrl.indexOf('/static/') === 0) {
return importUrl;
}
return 'data:image/jpg;base64,' + importUrl;
}
// 字典值返回标题
export function dictValueToLabel(val, arr) {
for (const v in arr) {
if (arr[v].dictValue.toString() == val) {
return arr[v].dictLabel
}
}
return ''
}
// url 处理t
export const jsonSearchFu = (strSearch) => {
if (strSearch.indexOf('?') > -1) {
strSearch = strSearch.substring(strSearch.indexOf('?') + 1);
}
let jsonSearch = {};
let arrSearch = strSearch.split('&')
if (arrSearch == null) {
return;
}
arrSearch.forEach(element => {
if (element != '') {
let arrParam = element.split('=')
if (arrParam.length > 1) {
jsonSearch[arrParam[0]] = arrParam[1]
}
}
});
return jsonSearch
}
// 请求服务端防止重复请求机制
export const preventRepeatFu = (res) => {
if (res) {
loading = Loading.service({
lock: true,
text: '请求中。。。',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
}
}
// 关闭 防重复机制弹窗
export const preventCloseFu = () => {
if (loading) {
loading.close()
}
}
// 全局拷贝方法
export const pluginsCope = (value, _this) => {
_this.$copyText(value).then(
function () {
_this.$message({
message: "复制成功",
type: "success"
});
},
function () {
_this.$message.error("复制失败");
}
);
}

View File

@ -1,390 +0,0 @@
import { parseTime } from './smartpower'
/**
* 表格时间格式化
*/
export function formatDate(cellValue) {
if (cellValue == null || cellValue == "") return "";
var date = new Date(cellValue)
var year = date.getFullYear()
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
}
/**
* @param {number} time
* @param {string} option
* @returns {string}
*/
export function formatTime(time, option) {
if (('' + time).length === 10) {
time = parseInt(time) * 1000
} else {
time = +time
}
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return (
d.getMonth() +
1 +
'月' +
d.getDate() +
'日' +
d.getHours() +
'时' +
d.getMinutes() +
'分'
)
}
}
/**
* @param {string} url
* @returns {Object}
*/
export function getQueryObject(url) {
url = url == null ? window.location.href : url
const search = url.substring(url.lastIndexOf('?') + 1)
const obj = {}
const reg = /([^?&=]+)=([^?&=]*)/g
search.replace(reg, (rs, $1, $2) => {
const name = decodeURIComponent($1)
let val = decodeURIComponent($2)
val = String(val)
obj[name] = val
return rs
})
return obj
}
/**
* @param {string} input value
* @returns {number} output value
*/
export function byteLength(str) {
// returns the byte length of an utf8 string
let s = str.length
for (var i = str.length - 1; i >= 0; i--) {
const code = str.charCodeAt(i)
if (code > 0x7f && code <= 0x7ff) s++
else if (code > 0x7ff && code <= 0xffff) s += 2
if (code >= 0xDC00 && code <= 0xDFFF) i--
}
return s
}
/**
* @param {Array} actual
* @returns {Array}
*/
export function cleanArray(actual) {
const newArray = []
for (let i = 0; i < actual.length; i++) {
if (actual[i]) {
newArray.push(actual[i])
}
}
return newArray
}
/**
* @param {Object} json
* @returns {Array}
*/
export function param(json) {
if (!json) return ''
return cleanArray(
Object.keys(json).map(key => {
if (json[key] === undefined) return ''
return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
})
).join('&')
}
/**
* @param {string} url
* @returns {Object}
*/
export function param2Obj(url) {
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
if (!search) {
return {}
}
const obj = {}
const searchArr = search.split('&')
searchArr.forEach(v => {
const index = v.indexOf('=')
if (index !== -1) {
const name = v.substring(0, index)
const val = v.substring(index + 1, v.length)
obj[name] = val
}
})
return obj
}
/**
* @param {string} val
* @returns {string}
*/
export function html2Text(val) {
const div = document.createElement('div')
div.innerHTML = val
return div.textContent || div.innerText
}
/**
* Merges two objects, giving the last one precedence
* @param {Object} target
* @param {(Object|Array)} source
* @returns {Object}
*/
export function objectMerge(target, source) {
if (typeof target !== 'object') {
target = {}
}
if (Array.isArray(source)) {
return source.slice()
}
Object.keys(source).forEach(property => {
const sourceProperty = source[property]
if (typeof sourceProperty === 'object') {
target[property] = objectMerge(target[property], sourceProperty)
} else {
target[property] = sourceProperty
}
})
return target
}
/**
* @param {HTMLElement} element
* @param {string} className
*/
export function toggleClass(element, className) {
if (!element || !className) {
return
}
let classString = element.className
const nameIndex = classString.indexOf(className)
if (nameIndex === -1) {
classString += '' + className
} else {
classString =
classString.substr(0, nameIndex) +
classString.substr(nameIndex + className.length)
}
element.className = classString
}
/**
* @param {string} type
* @returns {Date}
*/
export function getTime(type) {
if (type === 'start') {
return new Date().getTime() - 3600 * 1000 * 24 * 90
} else {
return new Date(new Date().toDateString())
}
}
/**
* @param {Function} func
* @param {number} wait
* @param {boolean} immediate
* @return {*}
*/
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result
const later = function() {
// 据上一次触发时间间隔
const last = +new Date() - timestamp
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last)
} else {
timeout = null
// 如果设定为immediate===true因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
return function(...args) {
context = this
timestamp = +new Date()
const callNow = immediate && !timeout
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait)
if (callNow) {
result = func.apply(context, args)
context = args = null
}
return result
}
}
/**
* This is just a simple version of deep copy
* Has a lot of edge cases bug
* If you want to use a perfect deep copy, use lodash's _.cloneDeep
* @param {Object} source
* @returns {Object}
*/
export function deepClone(source) {
if (!source && typeof source !== 'object') {
throw new Error('error arguments', 'deepClone')
}
const targetObj = source.constructor === Array ? [] : {}
Object.keys(source).forEach(keys => {
if (source[keys] && typeof source[keys] === 'object') {
targetObj[keys] = deepClone(source[keys])
} else {
targetObj[keys] = source[keys]
}
})
return targetObj
}
/**
* @param {Array} arr
* @returns {Array}
*/
export function uniqueArr(arr) {
return Array.from(new Set(arr))
}
/**
* @returns {string}
*/
export function createUniqueString() {
const timestamp = +new Date() + ''
const randomNum = parseInt((1 + Math.random()) * 65536) + ''
return (+(randomNum + timestamp)).toString(32)
}
/**
* Check if an element has a class
* @param {HTMLElement} elm
* @param {string} cls
* @returns {boolean}
*/
export function hasClass(ele, cls) {
return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
}
/**
* Add class to element
* @param {HTMLElement} elm
* @param {string} cls
*/
export function addClass(ele, cls) {
if (!hasClass(ele, cls)) ele.className += ' ' + cls
}
/**
* Remove class from element
* @param {HTMLElement} elm
* @param {string} cls
*/
export function removeClass(ele, cls) {
if (hasClass(ele, cls)) {
const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
ele.className = ele.className.replace(reg, ' ')
}
}
export function makeMap(str, expectsLowerCase) {
const map = Object.create(null)
const list = str.split(',')
for (let i = 0; i < list.length; i++) {
map[list[i]] = true
}
return expectsLowerCase
? val => map[val.toLowerCase()]
: val => map[val]
}
export const exportDefault = 'export default '
export const beautifierConf = {
html: {
indent_size: '2',
indent_char: ' ',
max_preserve_newlines: '-1',
preserve_newlines: false,
keep_array_indentation: false,
break_chained_methods: false,
indent_scripts: 'separate',
brace_style: 'end-expand',
space_before_conditional: true,
unescape_strings: false,
jslint_happy: false,
end_with_newline: true,
wrap_line_length: '110',
indent_inner_html: true,
comma_first: false,
e4x: true,
indent_empty_lines: true
},
js: {
indent_size: '2',
indent_char: ' ',
max_preserve_newlines: '-1',
preserve_newlines: false,
keep_array_indentation: false,
break_chained_methods: false,
indent_scripts: 'normal',
brace_style: 'end-expand',
space_before_conditional: true,
unescape_strings: false,
jslint_happy: true,
end_with_newline: true,
wrap_line_length: '110',
indent_inner_html: true,
comma_first: false,
e4x: true,
indent_empty_lines: true
}
}
// 首字母大小
export function titleCase(str) {
return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
}
// 下划转驼峰
export function camelCase(str) {
return str.replace(/-[a-z]/g, str1 => str1.substr(-1).toUpperCase())
}
export function isNumberStr(str) {
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
}

View File

@ -1,30 +0,0 @@
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
// 密钥对生成 http://web.chacuo.net/netrsakeypair
const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
'7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
'UP8iWi1Qw0Y='
// 加密
export function encrypt(txt) {
const encryptor = new JSEncrypt()
encryptor.setPublicKey(publicKey) // 设置公钥
return encryptor.encrypt(txt) // 对数据进行加密
}
// 解密
export function decrypt(txt) {
const encryptor = new JSEncrypt()
encryptor.setPrivateKey(privateKey) // 设置私钥
return encryptor.decrypt(txt) // 对数据进行解密
}

View File

@ -1,73 +0,0 @@
import AMap from 'AMap'
var geocoder = null
var initMap = (address) => {
geocoder = new AMap.Geocoder({
city: address, //城市设为北京,默认:“全国”
radius: 1000 //范围默认500
});
}
// 关键字搜索获取经维度
var gjzCode = (address, _this, type) => {
// AMap.service(["AMap.PlaceSearch"], function() {
// //构造地点查询类
// var placeSearch = new AMap.PlaceSearch({
// pageSize: 1, // 单页显示结果条数
// pageIndex: 1, // 页码
// panel: "panel", // 结果列表将在此容器中进行展示。
// autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
// });
// //关键字查询
// placeSearch.search('address');
// });
AMap.plugin('AMap.PlaceSearch', function(){
var autoOptions = {
city: '0591'
}
var placeSearch = new AMap.PlaceSearch(autoOptions);
placeSearch.search(address, function(status, result) {
// 搜索成功时result即是对应的匹配数据
if (status === 'complete' && result['poiList']) {
var lnglat = result.poiList.pois[0]
_this[type.form][type.lat] = lnglat.location.lat
_this[type.form][type.lng] = lnglat.location.lng
_this.$forceUpdate()
}
})
})
}
// 根据地址返回高德地图经纬度
var geoCode = (address, _this, type) => {
geocoder.getLocation(address,(status, result) => {
if (status === 'complete'&& result.geocodes.length) {
var lnglat = result.geocodes[0].location
_this[type.form][type.lat] = lnglat.lat
_this[type.form][type.lng] = lnglat.lng
_this.$forceUpdate()
// return lnglat
}else{
result = ''
log.error('根据地址查询位置失败');
// return ''
}
});
}
// 根据经纬度返回高德地图地址
var regeoCode = (point, _this, type) => {
geocoder.getAddress(point, function(status, result) {
if (status === 'complete'&&result.regeocode) {
var address = result.regeocode.formattedAddress;
_this[type.form][type.address] = address
}else{
log.error('根据经纬度查询地址失败')
}
});
}
export {
initMap,
geoCode,
regeoCode,
gjzCode
}

View File

@ -1,51 +0,0 @@
import store from '@/store'
/**
* 字符权限校验
* @param {Array} value 校验值
* @returns {Boolean}
*/
export function checkPermi(value) {
if (value && value instanceof Array && value.length > 0) {
const permissions = store.getters && store.getters.permissions
const permissionDatas = value
const all_permission = "*:*:*";
const hasPermission = permissions.some(permission => {
return all_permission === permission || permissionDatas.includes(permission)
})
if (!hasPermission) {
return false
}
return true
} else {
console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`)
return false
}
}
/**
* 角色权限校验
* @param {Array} value 校验值
* @returns {Boolean}
*/
export function checkRole(value) {
if (value && value instanceof Array && value.length > 0) {
const roles = store.getters && store.getters.roles
const permissionRoles = value
const super_admin = "admin";
const hasRole = roles.some(role => {
return super_admin === role || permissionRoles.includes(role)
})
if (!hasRole) {
return false
}
return true
} else {
console.error(`need roles! Like checkRole="['admin','editor']"`)
return false
}
}

View File

@ -1,111 +0,0 @@
import axios from 'axios'
import { Notification, MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { preventCloseFu } from "@/utils/hciot";
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 10000
})
// request拦截器
service.interceptors.request.use(config => {
// 设置客户端类型
config.headers['ClientType'] = 1
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
if (config.url && config.url === '/login' && config.data.userType) {
config.headers['UserType'] = config.data.userType
config.data.userType = undefined
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?';
for (const propName of Object.keys(config.params)) {
const value = config.params[propName];
var part = encodeURIComponent(propName) + "=";
if (value !== null && typeof(value) !== "undefined") {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + "=";
url += subPart + encodeURIComponent(value[key]) + "&";
}
} else {
url += part + encodeURIComponent(value) + "&";
}
}
}
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
preventCloseFu();
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
if (code === 401) {
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
store.dispatch('LogOut').then(() => {
location.href = '/index';
})
})
} else if (code === 500) {
Message({
message: msg,
type: 'error'
})
return Promise.reject(new Error(msg))
} else if (code !== 200) {
Notification.error({
title: msg
})
return Promise.reject('error')
} else {
return res.data
}
},
error => {
console.log('err' + error)
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
}
else if (message.includes("timeout")) {
message = "系统接口请求超时";
}
else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
Message({
message: message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service

View File

@ -1,58 +0,0 @@
Math.easeInOutQuad = function(t, b, c, d) {
t /= d / 2
if (t < 1) {
return c / 2 * t * t + b
}
t--
return -c / 2 * (t * (t - 2) - 1) + b
}
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
var requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
})()
/**
* Because it's so fucking difficult to detect the scrolling element, just move them all
* @param {number} amount
*/
function move(amount) {
document.documentElement.scrollTop = amount
document.body.parentNode.scrollTop = amount
document.body.scrollTop = amount
}
function position() {
return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
}
/**
* @param {number} to
* @param {number} duration
* @param {Function} callback
*/
export function scrollTo(to, duration, callback) {
const start = position()
const change = to - start
const increment = 20
let currentTime = 0
duration = (typeof (duration) === 'undefined') ? 500 : duration
var animateScroll = function() {
// increment the time
currentTime += increment
// find the value with the quadratic in-out easing function
var val = Math.easeInOutQuad(currentTime, start, change, duration)
// move the document.body
move(val)
// do the animation unless its over
if (currentTime < duration) {
requestAnimFrame(animateScroll)
} else {
if (callback && typeof (callback) === 'function') {
// the animation is done so lets callback
callback()
}
}
}
animateScroll()
}

View File

@ -1,152 +0,0 @@
/**
* 通用js方法封装处理
* Copyright (c) 2019 smartpower
*/
const baseURL = process.env.VUE_APP_BASE_API
// 日期格式化
export function parseTime(time, pattern) {
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/');
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
// 表单重置
export function resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields();
}
}
// 添加日期范围
export function addDateRange(params, dateRange, propName) {
var search = params;
search.params = {};
if (null != dateRange && '' != dateRange) {
if (typeof(propName) === "undefined") {
search.params["beginTime"] = dateRange[0];
search.params["endTime"] = dateRange[1];
} else {
search.params["begin" + propName] = dateRange[0];
search.params["end" + propName] = dateRange[1];
}
}
return search;
}
// 回显数据字典
export function selectDictLabel(datas, value) {
var actions = [];
Object.keys(datas).some((key) => {
if (datas[key].dictValue == ('' + value)) {
actions.push(datas[key].dictLabel);
return true;
}
})
return actions.join('');
}
// 回显数据字典(字符串数组)
export function selectDictLabels(datas, value, separator) {
var actions = [];
var currentSeparator = undefined === separator ? "," : separator;
var temp = value.split(currentSeparator);
Object.keys(value.split(currentSeparator)).some((val) => {
Object.keys(datas).some((key) => {
if (datas[key].dictValue == ('' + temp[val])) {
actions.push(datas[key].dictLabel + currentSeparator);
}
})
})
return actions.join('').substring(0, actions.join('').length - 1);
}
// 通用下载方法
export function download(fileName) {
window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
}
// 字符串格式化(%s )
export function sprintf(str) {
var args = arguments, flag = true, i = 1;
str = str.replace(/%s/g, function () {
var arg = args[i++];
if (typeof arg === 'undefined') {
flag = false;
return '';
}
return arg;
});
return flag ? str : '';
}
// 转换字符串undefined,null等转化为""
export function praseStrEmpty(str) {
if (!str || str == "undefined" || str == "null") {
return "";
}
return str;
}
/**
* 构造树型结构数据
* @param {*} data 数据源
* @param {*} id id字段 默认 'id'
* @param {*} parentId 父节点字段 默认 'parentId'
* @param {*} children 孩子节点字段 默认 'children'
* @param {*} rootId 根Id 默认 0
*/
export function handleTree(data, id, parentId, children, rootId) {
id = id || 'id'
parentId = parentId || 'parentId'
children = children || 'children'
rootId = rootId || Math.min.apply(Math, data.map(item => { return item[parentId] })) || 0
//对源数据深度克隆
const cloneData = JSON.parse(JSON.stringify(data))
//循环所有项
const treeData = cloneData.filter(father => {
let branchArr = cloneData.filter(child => {
//返回每一项的子级数组
return father[id] === child[parentId]
});
branchArr.length > 0 ? father.children = branchArr : '';
//返回第一层
return father[parentId] === rootId;
});
return treeData != '' ? treeData : data;
}

View File

@ -1,83 +0,0 @@
/**
* @param {string} path
* @returns {Boolean}
*/
export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUsername(str) {
const valid_map = ['admin', 'editor']
return valid_map.indexOf(str.trim()) >= 0
}
/**
* @param {string} url
* @returns {Boolean}
*/
export function validURL(url) {
const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
return reg.test(url)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validLowerCase(str) {
const reg = /^[a-z]+$/
return reg.test(str)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUpperCase(str) {
const reg = /^[A-Z]+$/
return reg.test(str)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validAlphabets(str) {
const reg = /^[A-Za-z]+$/
return reg.test(str)
}
/**
* @param {string} email
* @returns {Boolean}
*/
export function validEmail(email) {
const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return reg.test(email)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function isString(str) {
if (typeof str === 'string' || str instanceof String) {
return true
}
return false
}
/**
* @param {Array} arg
* @returns {Boolean}
*/
export function isArray(arg) {
if (typeof Array.isArray === 'undefined') {
return Object.prototype.toString.call(arg) === '[object Array]'
}
return Array.isArray(arg)
}

View File

@ -1,40 +0,0 @@
import axios from 'axios'
import { getToken } from '@/utils/auth'
const mimeMap = {
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
zip: 'application/zip'
}
const baseUrl = process.env.VUE_APP_BASE_API
export function downLoadZip(str, filename) {
var url = baseUrl + str
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => {
resolveBlob(res, mimeMap.zip)
})
}
/**
* 解析blob响应内容并下载
* @param {*} res blob响应内容
* @param {String} mimeType MIME类型
*/
export function resolveBlob(res, mimeType) {
const aLink = document.createElement('a')
var blob = new Blob([res.data], { type: mimeType })
// //从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
var contentDisposition = decodeURI(res.headers['content-disposition'])
var result = patt.exec(contentDisposition)
var fileName = result[1]
fileName = fileName.replace(/\"/g, '')
aLink.href = URL.createObjectURL(blob)
aLink.setAttribute('download', fileName) // 设置下载文件名称
document.body.appendChild(aLink)
aLink.click()
document.body.appendChild(aLink)
}

View File

@ -1,190 +0,0 @@
<template>
<!-- 告警记录功能 -->
<div class="app-container alarm-record">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="报警时间" prop="alarmTime">
<el-date-picker
clearable
size="small"
v-model="queryParams.alarmTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择报警时间"
></el-date-picker>
</el-form-item>
<el-form-item label="告警类型" prop="typeName">
<el-input
v-model="queryParams.typeName"
placeholder="请输入告警类型"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:record:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="recordList">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="设备名称" align="left" width="200px" prop="deviceName" />
<el-table-column label="设备当前值" align="left" width="200px" prop="currentValue" />
<el-table-column label="推送内容" align="left" prop="alarmContent" />
<el-table-column label="报警时间" align="center" prop="alarmTime" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.alarmTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="处理状态" width="100px" align="center" prop="processState" :formatter="stateFormatter"/>
<el-table-column label="处理结果" align="left" width="150px" prop="processResult" />
<el-table-column label="处理时间" align="center" prop="processTime" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.processTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="告警类型" align="left" width="150px" prop="typeName" />
<el-table-column label="类型编码" align="left" width="150px" prop="typeCode" />
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import {
listRecord,
getRecord,
exportRecord
} from "@/api/alarm/record";
import Editor from "@/components/Editor";
export default {
name: "Record",
components: {
Editor
},
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
recordList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
typeName: null,
typeCode: null,
alarmDivide: 'ALARM'
},
//
form: {},
//
rules: {}
};
},
created() {
this.getList();
},
methods: {
stateFormatter(val) {
return val === '2' ? '已处理' : '未处理'
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
/** 查询报警记录列表 */
getList() {
this.loading = true;
listRecord(this.queryParams).then(response => {
this.recordList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
// id
getRecordInfo(id) {
getRecord(id).then(res => {
this.form = res.data;
this.open = true;
this.title = `告警记录详情`;
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有报警记录数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportRecord(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>

View File

@ -1,412 +0,0 @@
<template>
<div class="app-container alarm-type">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
<!-- <el-form-item label="编码" prop="typeCode">
<el-input
v-model="queryParams.typeCode"
placeholder="请输入报警类型编码"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>-->
<el-form-item label="标签">
<el-input
v-model="queryParams.tag"
placeholder="请输入报警标签"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="名称" prop="typeName">
<el-input
v-model="queryParams.typeName"
placeholder="请输入报警类型名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:type:add']"
>新增</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['iot:type:edit']"
>修改</el-button>
</el-col> -->
<el-col :span="1.5">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['iot:type:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:type:export']"
>导出</el-button>
</el-col>
</el-row>
<el-table
v-loading="loading"
@sort-change="sortChange"
:data="alarmTypeList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="编码" align="center" sortable="custom" prop="typeCode" />
<el-table-column label="名称" align="center" sortable="custom" prop="typeName" />
<el-table-column label="设备类型" align="center" prop="deviceTypeName" />
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<span v-if="scope.row.status === 1">启用</span>
<span v-else>关闭</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
v-if="scope.row.tenantId === tenantId"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:type:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-if="scope.row.tenantId === tenantId"
v-hasPermi="['iot:type:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改告警类型对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" width="500px" >
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="名称" prop="typeName">
<el-input v-model="form.typeName" placeholder="请输入报警类型名称" />
</el-form-item>
<el-form-item label="编码" prop="typeCode">
<el-input v-model="form.typeCode" placeholder="请输入编码" />
</el-form-item>
<el-form-item label="标签" prop="tag">
<el-input v-model="form.tag" placeholder="请输入标签" />
</el-form-item>
<el-form-item label="设备类型" prop="deviceType">
<el-select
v-model="form.deviceType"
style="width: 100%;"
clearable
placeholder="请输入报警设备类型"
>
<el-option
v-for="(keys, vals) in deviceTypeList"
:label="keys"
:value="vals"
:key="vals"
/>
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-switch
v-model="form.status"
active-color="#13ce66"
inactive-color="#dad5d5"
active-value="1"
inactive-value="0"
></el-switch>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listAlarmType,
getAlarmType,
delAlarmType,
addAlarmType,
updateAlarmType
} from "@/api/alarm/alarmType";
import { listDeviceTypeList } from "@/api/iot/device";
// import { selectedProdmodel } from "@/api/device/prodmodel";
export default {
name: "AlarmType",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
total: 0,
//
alarmTypeList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
typeCode: undefined,
typeName: undefined,
tag: undefined,
orderByColumn: "",
isAsc: "desc"
},
//
form: {},
//
rules: {
typeName: [
{ required: true, message: "类型名称不能为空", trigger: "blur" }
],
tag: [{ required: true, message: "告警标签不能为空", trigger: "blur" }]
},
tenantId: "",
deviceTypeList: []
};
},
created() {
this.tenantId = this.$store.getters.tenantId;
this.getList();
},
methods: {
//
getDeviceTypeList() {
listDeviceTypeList().then(response => {
this.deviceTypeList = response.data;
});
},
sortChange(column) {
const sort = {
isAsc: column.order === "descending" ? "desc" : "asc",
orderByColumn: column.prop
};
this.queryParams = Object.assign(this.queryParams, sort);
this.handleQuery();
},
//
getModelList() {
// selectedProdmodel().then(res => {
// this.deviceTypeList = res.data;
// });
},
/** 查询告警类型列表 */
getList() {
this.loading = true;
listAlarmType(this.queryParams).then(response => {
this.alarmTypeList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
deviceType: undefined,
typeCode: undefined,
typeName: undefined,
status: "1",
tag: ""
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.typeId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.getDeviceTypeList();
this.open = true;
this.title = "添加告警类型";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.getDeviceTypeList();
const typeId = row.typeId || this.ids;
getAlarmType(typeId).then(response => {
this.form = response.data;
this.open = true;
this.form.status = response.data.status.toString();
this.title = "修改告警类型";
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.typeId != undefined) {
updateAlarmType(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
}
});
} else {
addAlarmType(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
}
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const typeIds = row.typeId || this.ids;
this.$confirm(
// '"' + typeIds + '"?',
"是否删除该选项",
"警告",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
)
.then(function() {
return delAlarmType(typeIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
})
.catch(function() {});
},
/** 导出按钮操作 */
handleExport() {
this.download(
"iot/alarmType/export",
{
...this.queryParams
},
`iot_alarmType.xlsx`
);
}
}
};
</script>
<style lang="scss">
.alarm-type {
.eldialog-wrap {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-dialog__body {
padding: 0px;
}
.el-form {
padding: 20px;
padding-right: 40px;
}
.el-dialog__footer {
height: 60px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding: 0px;
padding-top: 15px;
.el-button + .el-button {
margin-right: 10px;
}
.el-button {
padding-top: 8px;
}
}
.form-params-wrap {
height: 100%;
width: calc(100% + 110px);
position: relative;
top: 35px;
left: -90px;
max-height: 250px;
overflow: auto;
padding: 10px;
border: 1px solid #009688;
border-radius: 5px;
}
}
}
</style>

View File

@ -1,188 +0,0 @@
<template>
<!-- 告警记录功能 -->
<div class="app-container alarm-record">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="报警时间" prop="alarmTime">
<el-date-picker
clearable
size="small"
v-model="queryParams.alarmTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择报警时间"
></el-date-picker>
</el-form-item>
<el-form-item label="告警类型" prop="typeName">
<el-input
v-model="queryParams.typeName"
placeholder="请输入告警类型"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:record:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="recordList">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="设备名称" align="left" width="200px" prop="deviceName" />
<el-table-column label="设备当前值" align="left" width="200px" prop="currentValue" />
<el-table-column label="推送内容" align="left" prop="alarmContent" />
<el-table-column label="报警时间" align="center" prop="alarmTime" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.alarmTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column
label="处理状态"
width="100px"
align="center"
prop="processState"
:formatter="stateFormatter"
/>
<el-table-column label="处理结果" align="left" width="150px" prop="processResult" />
<el-table-column label="处理时间" align="center" prop="processTime" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.processTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="告警类型" align="left" width="150px" prop="typeName" />
<el-table-column label="类型编码" align="left" width="150px" prop="typeCode" />
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listRecord, getRecord, exportRecord } from "@/api/alarm/record";
export default {
name: "WarningRecord",
components: {},
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
recordList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
typeName: null,
typeCode: null,
alarmDivide: "WARNING"
},
//
form: {},
//
rules: {}
};
},
created() {
this.getList();
},
methods: {
stateFormatter(val) {
return val === "2" ? "已处理" : "未处理";
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
/** 查询报警记录列表 */
getList() {
this.loading = true;
listRecord(this.queryParams).then(response => {
this.recordList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
// id
getRecordInfo(id) {
getRecord(id).then(res => {
this.form = res.data;
this.open = true;
this.title = `告警记录详情`;
});
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有报警记录数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportRecord(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>

View File

@ -1,62 +0,0 @@
<template>
<div>
<div class="tigs">
<div class="tigs-title">
{{title}}
</div>
<div class="tigs-div" v-for="(item, index) in option" :key="index">
<img :src="item.img"/>
<p style="text-align: center;">{{item.lable}}</p>
<p style="text-align: center;">{{item.describe}}</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'indexTips',
data() {
return {}
},
props: {
title: String,
option: Array,
}
}
</script>
<style scoped>
img {
width: 70%;
height: 70%;
}
.tigs {
background-color: #ffffff;
border-radius: 5px;
box-shadow: 0px 0.5px 2px 0.5px;
margin-bottom: 25px;
color: #666666;
height: 373px;
}
.tigs-title {
height: 34px;
border-radius: 5px 5px 0px 0px;
/* color: #c4c4c4; */
border-bottom: 1px solid #c4c4c4;
font-size: 16px;
padding: 20px 0px 5px 20px;
height: 50px;
}
.tigs-div {
text-align: center;
margin: auto;
padding: 10px 10px 10px 10px;
}
.tigs-div>p {
text-align: left;
line-height: 1.8;
margin-bottom: 8px;
font-size: 14px;
text-align: center;
}
</style>

View File

@ -1,112 +0,0 @@
<template>
<div class="new-destail">
<h3
style="width: 100%;
text-align: center;
line-height: 1.5;
font-size: 18px;
font-weight: 600;
margin: 15px 0;
"
>{{info.noticeTitle}}</h3>
<span
style="
width: 100%;
text-align: center;
color: #808080;
line-height: 1.5;
font: 13px/1.6 Arial,sans-serif,Tahoma,Roboto,'Source Code Pro';
"
>发布时间{{info.updateTime}}</span>
<span @click="toNowsTable(info.noticeId)" class="gd-news">更多新闻</span>
<el-divider></el-divider>
<div v-html="info.noticeContent" style="padding: 20px;"></div>
<div style="
position: fixed;
bottom: 10px;
right: 10px;
">
<!-- <el-tooltip class="item" effect="dark" content="前往首页" placement="top">
<el-button
type="primary"
style="
width: 50px;
height: 50px;
font-size: 25px;
z-index: 100;
"
icon="el-icon-back"
@click="toTableClick"
circle
></el-button>
</el-tooltip> -->
</div>
</div>
</template>
<script>
import { getNotice } from "@/api/system/notice";
export default {
name: "NewDestail",
data() {
return {
info: {}
};
},
created() {
this.init();
},
methods: {
init() {
let noticeId = this.$router.currentRoute.query.newId;
this.getNewsList(noticeId);
},
getNewsList(id) {
getNotice(id)
.then(response => {
this.info = response.data;
})
.catch(err => {
console.log(err);
});
},
toNowsTable(id) {
console.log(id);
this.$router.push({ path: "/news", query: { newId: id } });
},
toTableClick() {
this.$router.push({ path: "/" });
}
},
watch: {
$route: {
handler() {
let noticeId = this.$route.query.newId;
if (noticeId || noticeId === 0) {
this.getNewsList(noticeId);
}
},
deep: true
}
}
};
</script>
<style lang="scss">
.new-destail {
padding: 20px;
display: flex;
justify-content: center;
flex-wrap: wrap;
height: auto;
.el-divider--horizontal {
margin: 15px 0;
}
.gd-news {
margin-top: 5px;
}
.gd-news:hover {
color: #1890ff;
cursor: default;
}
}
</style>

View File

@ -1,111 +0,0 @@
<template>
<div
class="new-destail"
v-loading="loading"
element-loading-text="加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
>
<h3
style="width: 100%;
text-align: center;
line-height: 1.5;
font-size: 18px;
font-weight: 600;
margin: 15px 0;
"
>{{info.noticeTitle}}</h3>
<span
style="
width: 100%;
text-align: center;
color: #808080;
line-height: 1.5;
font: 13px/1.6 Arial,sans-serif,Tahoma,Roboto,'Source Code Pro';
"
>发布时间{{info.updateTime}}</span>
<el-divider></el-divider>
<div v-html="info.noticeContent" style="padding: 20px;"></div>
<div style="
position: fixed;
bottom: 10px;
right: 10px;
">
<!-- <el-tooltip class="item" effect="dark" content="前往首页" placement="top">
<el-button
type="primary"
style="
width: 50px;
height: 50px;
font-size: 25px;
z-index: 100;
"
icon="el-icon-back"
@click="toTableClick"
circle
></el-button>
</el-tooltip> -->
</div>
</div>
</template>
<script>
import { getNotice } from "@/api/system/notice";
export default {
name: "NewsTableDetails",
props: {
newId: {
type: [Number, String]
}
},
data() {
return {
info: {},
loading: false
};
},
created() {
this.loading = true;
},
methods: {
getNewsList(id) {
getNotice(id)
.then(response => {
this.loading = false;
this.info = response.data;
})
.catch(err => {
this.loading = false;
console.log(err);
});
},
toTableClick() {
this.$router.push({ path: "/" });
}
},
watch: {
newId: {
handler() {
this.loading = true;
let noticeId = this.newId;
if (noticeId || noticeId === 0) {
this.getNewsList(noticeId);
}
},
deep: true
}
}
};
</script>
<style lang="scss">
.new-destail {
padding: 20px;
display: flex;
justify-content: center;
flex-wrap: wrap;
height: auto;
.el-divider--horizontal {
margin: 15px 0;
}
}
</style>

View File

@ -1,230 +0,0 @@
<template>
<div class="news-table">
<div class="news-details-block">
<news-table-details :newId="newId" />
</div>
<div class="news-scroll-block">
<span class="titel-block">新闻列表</span>
<ul class="infinite-list" style="overflow:auto; height: auto; width: 94%;">
<li v-for="(item,index) in list" :key="item.noticeId" class="infinite-list-item item-block" ref="noticeRef">
<span class="news-item-span1"></span>
<span class="news-info-span" @click="toNewDestail(item.noticeId, index)">{{item.noticeTitle}}</span>
</li>
</ul>
<p
v-loading="loading"
element-loading-spinner="el-icon-loading"
class="more-bottom"
v-if="noMore === false && list.length < total" @click="moreNews">查看更多</p>
<p style="margin: 10px auto;
font-size: 12px;
color: rgb(174, 174, 174);
height: 15px;"
v-else>已加载全部~</p>
</div>
</div>
</template>
<script>
import { listNotice } from "@/api/system/notice"
import NewsTableDetails from './newTD'
export default {
name: 'NewsTable',
components: {
NewsTableDetails
},
data() {
return {
newId: null,
list: [],
count: 0,
loading: false,
params: {
pageNum: 1,
pageSize: 10
},
resList: [],
noMore: false,
classIndex: 0,
total: 0
}
},
created() {
this.init()
},
methods: {
moreNews() {
this.params.pageNum += 1
this.loading = true
this.getList()
},
init() {
let noticeId = this.$router.currentRoute.query.newId // id
this.getList()
},
toNewDestail(id, index) {
this.newId = id
this.classIndex = index
},
getList() {
var _this = this
var noticeId = this.$router.currentRoute.query.newId
listNotice(this.params).then(response => {
this.loading = false
if (response.code === 200 && response.rows) {
this.total = response.total;
if (response.rows.length > 0) {
_this.resList = response.rows
_this.list = _this.list.concat(response.rows)
if (noticeId) {
this.newId = noticeId
setTimeout(() => {
for(let v in _this.list) {
if (_this.list[v].noticeId === Number(noticeId)) {
_this.classIndex = v
break;
}
}
}, 100)
} else {
this.newId = this.list[0].noticeId
setTimeout(() => {
this.classIndex = '0'
}, 100)
}
} else {
this.noMore = true
}
}
}).catch(err => {
console.log(err)
})
}
},
watch: {
classIndex(val, old) {
if (old || old === 0) {
this.$refs.noticeRef[old].className = "infinite-list-item item-block"
this.$refs.noticeRef[val].className = "infinite-list-item item-block reader-info-span"
}
},
$route: {
handler() {
let noticeId = this.$route.query.newId;
if (noticeId || noticeId === 0) {
this.newId = noticeId
for(let v in this.list) {
if (this.list[v].noticeId === Number(noticeId)) {
this.classIndex = v
break;
}
}
}
},
deep: true,
}
}
}
</script>
<style lang="scss">
.news-table {
padding: 20px;
display: flex;
background: #f3f5f7;
padding: 20px;
display: -webkit-box;
display: flex;
background: #f3f5f7;
// height: calc(100vh - 85px);
// overflow: auto;
.news-details-block {
width: calc(100% - 340px);
box-shadow: 0px 0px 2px -1px;
background-color: #fff;
}
.news-scroll-block {
width: 320px;
display: flex;
justify-content: flex-start;
font-size: 14px;
color: #777;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
cursor: default;
border-radius: 3px;
box-shadow: 0px 0px 3px -1px;
margin-left: 20px;
flex-wrap: wrap;
// max-height: calc(100vh - 130px);
height: 100%;
background-color: #fff;
.more-bottom {
margin: 10px auto;
font-size: 12px;
color: rgb(174, 174, 174);
height: 15px;
}
.more-bottom:hover {
color: #174cfe;
}
.titel-block {
display: block;
width: 100%;
background: #fac9362b;
font-size: 18px;
padding-left: 20px;
line-height: 2.5;
height: 45px;
box-shadow: 1px 0px 3px 0px;
}
.infinite-list {
padding-left: 25px;
margin-bottom: 5px;
margin-top: 10px;
}
.item-block {
line-height: 1.5;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
display: flex;
justify-content: flex-start;
align-items: center;
border-bottom: 1px dashed;
margin-bottom: 5px;
}
.news-item-span1 {
display: block;
width: 7px;
height: 7px;
background-color: #6f6b6b;
margin-right: 10px;
border-radius: 50%;
}
.news-info-span {
font-size: 13px;
line-height: 24px;
color: #777777;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
cursor: default;
}
.news-info-span:hover {
color: #174cfe;
}
}
.reader-info-span {
background: #fff;
color: red;
}
}
</style>

View File

@ -1,99 +0,0 @@
<template>
<div class="bigscreen-echarts">
<div :id="id" :style="styles" ></div>
</div>
</template>
<script>
// import echarts from 'echarts'
import * as echarts from "echarts";
export default {
name: 'pancake_echarts',
props: {
id: {
type: String
},
option: {
type: Object
},
styles: {
type: String
},
config: {
type: Object
}
},
data() {
return {
chart: null
}
},
created() {
this.chart = null
},
mounted() {
this.drawLine()
},
methods: {
drawLine(){
if(!this.chart){
this.chart = echarts.init(document.getElementById(this.id))
}
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: this.config.tooltip.formatter
},
series: [{
name: this.option.title,
type:'pie',
radius: this.config.series.radius,
avoidLabelOverlap: false,
label: {
normal: {
show: false,
position: 'center'
},
emphasis: {
show: false,
textStyle: {
fontSize: '20',
fontWeight: 'bold'
}
}
},
labelLine: {
normal: {
show: false
},
show: function(value) {
return value !== 0
}
},
data: this.option.data,
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
},
normal: this.config.itemStyle.normal
}
}]
});
}
},
watch: {
option(val, oldVal) {
this.chart = null
console.log(val)
this.drawLine()
}
}
}
</script>
<style lang="scss" >
.bigscreen-echarts {
position: relative;
top: -62px;
}
</style>

View File

@ -1,222 +0,0 @@
<template>
<div
class="big-v1-wrap"
id="big-v1-wrap-id"
:style="{
'transformOrigin':'center top',
'transform':`scale(${scalseNum},${scalseNum})`,
'-webkit-transform':`scale(${scalseNum},${scalseNum})`,
'-moz-transform':`scale(${scalseNum},${scalseNum})`,
'-o-transform':`scale(${scalseNum},${scalseNum})`,
'-ms-transform':`scale(${scalseNum},${scalseNum})`
}"
>
<div class="main-block">
<head-wrap
ref="mainHead"
:handelTile="title"
:projectList="projectList"
@eventFullscreen="eventFullscreen"
@eventProjectId="eventProjectId"
@eventRegionalismId="eventRegionalismId"
></head-wrap>
<div class="count-wrap">
<div class="count-left">
<div class="left-block-1">
<device-proportion-wrap :projectId="projectId"></device-proportion-wrap>
<wraring-info-wrap :result="alarmInfoResult"></wraring-info-wrap>
</div>
<div class="map-block-1">
<map-wrap :fullscreen="fullscreen" :countResult="alarmInfoResult" @eventFullscreen="eventFullscreenMap" :projectList="projectList"></map-wrap>
</div>
<div class="bottom-block-1">
<alarm-table-list-wrap :projectId="projectId"></alarm-table-list-wrap>
</div>
</div>
<div class="right-block-1">
<today-ratio-wrap :result="resultInfo.warningAnalysisStatisticsVo || []"></today-ratio-wrap>
<type-distribution-wrap :result="resultInfo.alarmCategoriesList || []"></type-distribution-wrap>
<trend-wrap :result="resultInfo.alarmChartDataVo || []"></trend-wrap>
</div>
</div>
</div>
</div>
</template>
<script>
import HeadWrap from "./profile/head";
import DeviceProportionWrap from "./profile/deviceProportion";
import WraringInfoWrap from "./profile/wraringInfo";
import AlarmTableListWrap from "./profile/alarmTableList";
import TodayRatioWrap from "./profile/todayRatio";
import TypeDistributionWrap from "./profile/typeDistribution";
import trendWrap from "./profile/trend";
import MapWrap from "./profile/mapWrap";
import { getWarningAnalysis, homeCount, appProjectList } from "@/api/app";
export default {
name: "BigScreenWraps",
components: {
HeadWrap,
DeviceProportionWrap,
WraringInfoWrap,
AlarmTableListWrap,
TodayRatioWrap,
TypeDistributionWrap,
trendWrap,
MapWrap
},
data() {
return {
title: "智慧能源综合管理系统",
scalseNum: 1,
resultInfo: {},
alarmInfoResult: {},
projectList: [],
projectId: null,
regionalismId: null,
fullscreen: false
};
},
mounted() {
//
this.resize_window();
window.addEventListener("resize", () => {
this.resize_window();
});
},
created() {
document.getElementById("app").style.background = "#021c80";
document.getElementById("con_lf_top_div").style.background = "#021c80";
document.getElementById("con_lf_top_div").style.height =
"calc(100vh - 84px)";
document.getElementById("con_lf_top_div").style.overflow = "hidden";
document.getElementById("con_lf_top_div").scrollTop = 0;
this.getProjectList();
this.warningAnalysisList();
this.homeCount();
},
methods: {
//
eventFullscreenMap(data) {
this.fullscreen = data.value
this.$refs.mainHead["fullscreen"] = data.value
},
//
eventFullscreen(data) {
this.fullscreen = data.value
},
eventProjectId(data) {
this.projectId = data;
this.homeCount();
this.warningAnalysisList();
},
eventRegionalismId(data) {
this.regionalismId = data;
this.getProjectList();
},
resize_window() {
var w_height = 0;
if (this.fullscreen) {
w_height = Number(document.documentElement.clientHeight / 1080);
} else {
w_height = Number(document.documentElement.clientHeight / 1186);
}
this.scalseNum = w_height;
},
//
getProjectList() {
appProjectList({
regionalismId: this.regionalismId
}).then(response => {
this.projectList = response.rows;
});
},
//
homeCount() {
homeCount({
alarmDivide: "ALARM",
projectId: this.projectId
}).then(res => {
this.alarmInfoResult = res.data;
});
},
//
warningAnalysisList() {
getWarningAnalysis({
projectId: this.projectId
}).then(res => {
this.resultInfo = res.data;
});
}
},
destroyed() {
document.getElementById("app").style.background = "#fff";
document.getElementById("con_lf_top_div").style.background = "#fff0";
document.getElementById("con_lf_top_div").style.overflow = "auto";
}
};
</script>
<style lang="scss">
.big-v1-wrap {
width: 100%;
height: calc(100vh - 85px);
display: flex;
justify-content: center;
background-image: url("../../../assets/images/big/bigpg_v1.jpg");
cursor: default;
.main-block {
width: 100%;
height: 100%;
display: flex;
flex-wrap: wrap;
.count-wrap {
width: 100%;
height: calc(100% - 65px);
display: flex;
flex-wrap: wrap;
color: #fff;
background: #1531f508;
.count-left {
display: flex;
flex-wrap: wrap;
width: calc(100% - 400px);
height: calc(100%);
.left-block-1 {
width: 400px;
height: calc(100% - 270px);
}
.map-block-1 {
width: calc(100% - 400px);
height: calc(100% - 270px);
border: 1px solid #0790b9;
}
.bottom-block-1 {
width: 100%;
height: 270px;
}
}
.right-block-1 {
width: 400px;
height: calc(100%);
}
}
}
}
.app-main {
width: 100%;
height: calc(100vh - 100px);
// background: #021c80;
}
.big-v1-wrap {
width: 1920px;
height: 1080px;
transform-origin: center top 0px;
position: relative;
left: 50%;
margin-left: -960px;
}
</style>

View File

@ -1,161 +0,0 @@
<template>
<div class="big-alarm-table-list-wrap">
<div class="title-t">{{title}}</div>
<div class="query-right-div">
<el-checkbox-group v-model="queryCheckbox">
<el-checkbox label="warning">包含预警</el-checkbox>
<el-checkbox label="off">只显示离线报警</el-checkbox>
</el-checkbox-group>
</div>
<el-table :data="list" class="alarm-table" height="212" :highlight-pageNum-row="true">
<el-table-column prop="projectName" label="项目" align="center" width="250">
<template slot-scope="scope">
<div>
<i class="iconfont iconbaojing" v-if="scope.row.processStatus === 'UNPROCESS'" style="color: #FF2F60;"></i>
<i class="iconfont iconbaojing" v-if="scope.row.processStatus === 'PROCESSED'" style="color: #25F094;"></i>
<i class="iconfont iconbaojing" v-if="scope.row.processStatus === 'IGNORE'" style="color: #25F094;"></i>
<span style="margin-left: 10px;" v-text="scope.row.projectName"></span>
</div>
</template>
</el-table-column>
<el-table-column prop="projectAddress" label="地址" align="left"></el-table-column>
<el-table-column prop="deviceName" label="线路" align="center" width="150"></el-table-column>
<el-table-column
prop="alarmDivide"
label="报警类型"
align="center"
width="150"
:formatter="alarmTypeFormatter"
></el-table-column>
<el-table-column prop="alarmTime" label="报警时间" align="center" width="160"></el-table-column>
<el-table-column prop="t6" label="耗时" align="center" width="150"></el-table-column>
<el-table-column prop="processStatus" label="状态" align="center" width="150">
<template slot-scope="scope">
<span v-if="scope.row.processStatus === 'UNPROCESS'" :style="'color: #FF2F60;'">未处理</span>
<span v-if="scope.row.processStatus === 'PROCESSED'" :style="'color: #25F094;'">已处理</span>
<span v-if="scope.row.processStatus === 'IGNORE'" :style="'color: #c0c4cc;'">忽略</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { appAlarmRecordList } from "@/api/app";
export default {
name: "alarmTableList",
props: ["projectId"],
data() {
return {
title: "实时报警列表",
queryCheckbox: [],
list: []
};
},
created() {
this.getAlarmRecrdList();
},
watch: {
projectId(val, oldval) {
this.getAlarmRecrdList();
},
queryCheckbox(val,oldVal) {
this.getAlarmRecrdList();
}
},
methods: {
alarmTypeFormatter(row) {
if (row.alarmDivide === "ALARM") {
return "报警";
} else if (row.alarmDivide === "WARNING") {
return "预警";
}
},
getAlarmRecrdList() {
appAlarmRecordList({
alarmDivide:
this.queryCheckbox.indexOf("warning") < 0 ? "ALARM" : undefined,
deviceState:
this.queryCheckbox.indexOf("off") >= 0 ? "OFFLINE" : undefined,
projectId: this.projectId || undefined,
pageNum: 1,
pageSize: 5
}).then(res => {
this.list = res.rows;
});
}
}
};
</script>
<style lang="scss">
.big-alarm-table-list-wrap {
width: 100%;
height: calc(100%);
display: flex;
flex-wrap: wrap;
.title-t {
font-size: 16px;
letter-spacing: 1px;
height: 60px;
width: 400px;
background-size: cover;
display: flex;
justify-content: left;
padding-left: 45px;
align-items: center;
padding-bottom: 10px;
background-image: url("../../../../assets/images/big/b.png");
}
.query-right-div {
width: calc(100% - 400px);
display: flex;
justify-content: flex-end;
align-items: center;
padding-right: 60px;
.el-checkbox__label {
color: #fff;
}
}
.alarm-table {
width: calc(100% - 20px);
margin-left: 20px;
.el-table__header-wrapper th,
.el-table .el-table__fixed-header-wrapper th {
background-color: #0124a9;
background-color: #002cd27d;
color: #fff;
height: 50px;
border: 0 !important;
font-size: 15px;
letter-spacing: 2px;
}
.el-table__empty-block {
background: #0124a600;
}
tr {
background: #0124a600;
color: #fff;
}
.el-table__body-wrapper {
background: #0124a600;
}
.el-table__body tr:hover > td {
background-color: #0124a600 !important;
}
.el-table__body tr.current-row > td {
background-color: #0124a9 !important;
}
.el-table__body-wrapper::-webkit-scrollbar {
width: 6px;
height: 6px;
}
/*滚动条滑块*/
.el-table__body-wrapper::-webkit-scrollbar-thumb {
background-color: #114f9d;
}
}
.el-table {
background-color: #ffffff00;
}
}
</style>

View File

@ -1,87 +0,0 @@
<template>
<div class="big-device-proportion-wrap">
<div class="title-t">{{title}}</div>
<echarts-radar-wrap :styles="'width: 100%; height: 230px;'" eId="echartsGaugeDP" :option="radarOption"></echarts-radar-wrap>
</div>
</template>
<script>
import titleImg from "@/assets/images/big/b.png";
import EchartsRadarWrap from "./echartsRadar";
import { appDeviceStatistics } from '@/api/app'
export default {
name: "DeviceProportionWrap",
components: {
EchartsRadarWrap
},
props: ['projectId'],
data() {
return {
list: [],
titleImg,
title: "所有设备占比分析",
radarOption: {
indicator: [
{ name: "物联网断路器", max: 100 },
{ name: "智能摄像机", max: 100 },
{ name: "智能电表", max: 100 },
{ name: "烟雾传感器", max: 100 },
{ name: "智能气表", max: 100 },
{ name: "智能电表", max: 100 },
{ name: "智能电表", max: 100 },
{ name: "智能水表", max: 100 }
],
seriesList: [
{
value: [],
name: "预算分配Allocated Budget"
}
]
}
};
},
watch: {
projectId(val) {
this.getDeviceProportionList()
}
},
created() {
this.getDeviceProportionList()
},
methods: {
getDeviceProportionList() {
appDeviceStatistics({ projectId: this.projectId }).then(res => {
const list = res.data;
this.radarOption.indicator = [];
this.radarOption.seriesList = [];
var _this = this;
for (var i = 0; i < list.length; i++) {
_this.radarOption.indicator.push({
name: list[i].deviceTypeName,
max: list[i].total <= 0 ? 1 : list[i].total
});
_this.radarOption.seriesList.push(list[i].thisTotal);
}
});
}
}
};
</script>
<style lang="scss">
.big-device-proportion-wrap {
width: 100%;
height: 300px;
.title-t {
font-size: 16px;
letter-spacing: 1px;
height: 60px;
width: 100%;
background-size: cover;
display: flex;
justify-content: left;
padding-left: 45px;
align-items: center;
padding-bottom: 10px;
background-image: url("../../../../assets/images/big/b.png");
}
}
</style>

View File

@ -1,148 +0,0 @@
<template>
<div class="bigscreen-echarts-bar">
<div id="chartBar" :style="styles"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "echartsBar",
props: {
styles: {
type: String
},
colorList: {
type: [Array, String],
default: ""
},
option: {
stype: Array,
default: []
}
},
data() {
return {
chart: null
};
},
created() {
this.chart = null;
},
mounted() {
this.drawLine();
},
methods: {
drawLine() {
if (!this.chart) {
this.chart = echarts.init(document.getElementById("chartBar"));
}
const option = {
color: ["#3398DB"],
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
grid: {
left: "20",
right: "20",
bottom: "25",
top: 15,
containLabel: true
},
toolbox: {
show: false,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ["line", "bar"] },
restore: { show: true },
saveAsImage: { show: true }
}
},
xAxis: [
{
type: "category",
data: ["报警总数", "未处理", "已处理"],
axisTick: {
alignWithLabel: false
},
axisLine: {
show: false,
lineStyle: {
color: "#fff"
}
},
axisLabel: {
interval: 0,
margin: 10,
textStyle: {
color: "#fff"
}
}
}
],
yAxis: [
{
type: "value",
axisLine: {
lineStyle: {
color: "#fff"
}
},
axisLabel: {
interval: 0,
margin: 10,
textStyle: {
color: "#fff"
}
}
}
],
series: [
{
name: "数量:",
type: "bar",
barWidth: "40%",
data: this.option,
itemStyle: {
//
normal: {
//colorListcolorList使
color: function(params) {
var colorList = [
"#00FCFF",
"#FF2F60",
"#25F094"
];
return colorList[params.dataIndex];
}
},
//
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)"
}
}
}
]
};
this.chart.setOption(option);
}
},
watch: {
option(val, oldVal) {
this.chart = null;
this.drawLine();
}
}
};
</script>
<style lang="scss">
.bigscreen-echarts-bar {
height: 100%;
}
</style>

View File

@ -1,117 +0,0 @@
<template>
<div class="bigscreen-echarts-gauge">
<div :id="eId" :style="styles"></div>
</div>
</template>
<script>
import * as echarts from "echarts/core";
import { GaugeChart } from "echarts/charts";
import { CanvasRenderer } from "echarts/renderers";
export default {
name: "echartsRadarWrap",
props: {
eId: {
type: String
},
styles: {
type: String
},
colorList: {
type: [Array, String],
default: ["#27d0ec"]
},
option: {
stype: Number,
default: 0
}
},
data() {
return {
chart: null
};
},
created() {
this.chart = null;
echarts.use([GaugeChart, CanvasRenderer]);
},
mounted() {
this.drawLine();
},
methods: {
drawLine() {
if (!this.chart) {
this.chart = echarts.init(document.getElementById(this.eId));
}
const options = {
series: [
{
type: "gauge",
color: this.colorList,
progress: {
show: true,
width: 15
},
axisLine: {
lineStyle: {
width: 15
}
},
axisTick: {
show: false
},
splitLine: {
length: 15,
show: false,
lineStyle: {
width: 2,
color: "#004299a3"
}
},
axisLabel: {
distance: 25,
show: false,
color: "#999",
fontSize: 10
},
anchor: {
show: false,
showAbove: true,
size: 5,
itemStyle: {
borderWidth: 2
}
},
title: {
text: "今日报警"
},
detail: {
valueAnimation: true,
fontSize: 15,
color: this.colorList[0] || "#27d0ec",
offsetCenter: [0, "80%"]
},
data: [
{
value: this.option
}
]
}
]
};
this.chart.setOption(options);
}
},
watch: {
option(val, oldVal) {
this.chart = null;
this.drawLine();
}
}
};
</script>
<style lang="scss">
.bigscreen-echarts-gauge {
height: calc(100% - 30px);
width: 100%;
}
</style>

View File

@ -1,66 +0,0 @@
<template>
<div class="bigscreen-echarts-pie">
<div :id="eId" :style="styles"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "echartsRadarWrap",
props: {
eId: {
type: String
},
styles: {
type: String
},
colorList: {
type: [Array, String],
default: ""
},
option: {
stype: Object,
default: {}
}
},
data() {
return {
chart: null
};
},
created() {
this.chart = null;
},
mounted() {
this.drawLine();
},
methods: {
updateEchart() {
if (this.chart) {
this.chart = null;
}
this.drawLine();
},
drawLine() {
if (!this.chart) {
this.chart = echarts.init(document.getElementById(this.eId));
}
this.chart.setOption(this.option);
}
},
watch: {
option(val, oldVal) {
this.chart = null;
this.drawLine();
}
}
};
</script>
<style lang="scss">
.bigscreen-echarts-pie {
position: relative;
height: 100%;
top: 0px;
width: 80%;
}
</style>

View File

@ -1,114 +0,0 @@
<template>
<div class="bigscreen-echarts-pie">
<div :id="eId" :style="styles" ></div>
<!-- <div v-else>暂无数据</div> -->
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "echartsRadarWrap",
props: {
eId: {
type: String
},
styles: {
type: String
},
colorList: {
type: [Array, String],
default: ""
},
option: {
stype: Object,
default: []
}
},
data() {
return {
chart: null
};
},
created() {
this.chart = null;
},
mounted() {
this.drawLine();
},
methods: {
updateEchart() {
if (this.chart) {
this.chart = null;
}
this.drawLine();
},
drawLine() {
if (!this.chart) {
this.chart = echarts.init(document.getElementById(this.eId));
}
const option = {
legend: {
top: "5",
right: "60",
type: "scroll",
orient: "vertical",
pageIconColor: "#6495ed", //
pageIconInactiveColor: "#aaa", //
pageIconSize: 10, //
pageButtonItemGap: 1, //
textStyle: {
color: "#fff",
fontSize: 16
},
},
toolbox: {
show: false,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
restore: { show: true },
saveAsImage: { show: true }
}
},
series: [
{
name: "",
type: "pie",
radius: [30, 70],
center: ["25%", "50%"],
roseType: "area",
emphasis: {
label: {
show: false
}
},
label: {
show: false
},
itemStyle: {
borderRadius: 1
},
data: this.option
}
]
};
this.chart.setOption(option);
}
},
watch: {
option(val, oldVal) {
this.chart = null;
this.drawLine();
}
}
};
</script>
<style lang="scss">
.bigscreen-echarts-pie {
position: relative;
height: 100%;
top: 0px;
width: 80%;
}
</style>

View File

@ -1,129 +0,0 @@
<template>
<div class="bigscreen-echarts-radar">
<div :id="eId" :style="styles"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "echartsRadarWrap",
props: {
eId: {
type: String
},
styles: {
type: String
},
colorList: {
type: [Array, String],
default: ""
},
option: {
stype: Object,
default: {}
}
},
data() {
return {
chart: null
};
},
created() {
this.chart = null;
},
mounted() {
this.drawLine();
},
methods: {
drawLine() {
if (!this.chart) {
this.chart = echarts.init(document.getElementById(this.eId));
}
const option = {
title: {
text: ""
},
color: this.colorList,
tooltip: {},
legend: {
data: []
},
radar: {
nameGap: 5,
name: {
textStyle: {
color: "#fff",
backgroundColor: "#99999900",
borderRadius: 2,
padding: [1, 1]
}
},
splitArea: {
show: true,
areaStyle: {
color: ["#515a6e00"] //
}
},
axisLabel: {
// axis.axisLabel
show: false,
textStyle: {
color: "#247bd7" //
}
},
splitLine: {
show: true,
lineStyle: {
width: 1,
color: "#0865da" // 线
}
},
indicator: this.option.indicator
},
series: [
{
name: "预算 vs 开销Budget vs spending",
type: "radar",
symbol: "none",
itemStyle: {
normal: {
color: "rgba(46, 255, 233, 1)", // 线
lineStyle: {
color: "rgba(30, 238, 255, 1)" // 线
},
areaStyle: {
type: "default"
}
}
},
data: [
{
value: this.option.seriesList,
name: ""
}
]
}
]
};
console.log('radar',this.option, this.chart)
this.chart.setOption(option);
}
},
watch: {
option: {
handler: function (val, oldVal) {
this.chart = null;
this.drawLine();
},
deep: true
}
}
};
</script>
<style lang="scss">
.bigscreen-echarts-radar {
position: relative;
height: 100%;
top: 0px;
}
</style>

View File

@ -1,206 +0,0 @@
<template>
<div class="big-head-wrap">
<div class="left-wrap">
<!-- <i class="el-icon-map-location"></i>
<span class="span-info">全国</span>-->
<!-- <el-cascader :options="treeList" :props="{ checkStrictly: true }" clearable></el-cascader> -->
<treeselect
class="tree-select-wrap"
v-model="treeValue"
:options="treeList"
placeholder="全国"
v-show="tempUserType !== 'PERSONAL'"
/>
<el-select
v-show="tempUserType !== 'PERSONAL'"
v-model="inputValue"
size="small"
filterable
placeholder="项目名称"
clearable
>
<el-option
v-for="item in projectList"
:key="item.projectId"
:label="item.projectName"
:value="item.projectId"
></el-option>
</el-select>
</div>
<div class="title-wrap">{{handelTile}}</div>
<div class="right-wrap">
<span>{{days}}</span>
<span>{{weeks}}</span>
<span>{{time}}</span>
<!-- <el-button type="text" @click="signOut" title="退出大屏" plain icon="iconfont icontuichu"></el-button> -->
<el-button type="text" @click="fullScreen" title="全屏" plain icon="iconfont iconquanping1"></el-button>
</div>
</div>
</template>
<script>
import { treeListRegionalism } from "@/api/system/regionalism";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
name: "bigHeadWrap",
props: ["handelTile", "projectList"],
components: {
Treeselect
},
data() {
return {
inputValue: "",
days: "",
weeks: "",
time: "",
treeList: [],
treeValue: null,
tempUserType: null,
fullscreen: false
};
},
mounted() {
setInterval(this.getDate, 1000);
},
created() {
this.tempUserType = this.$store.getters.userType;
this.treeListRegionalism();
this.getDate();
},
watch: {
inputValue(val) {
this.$emit("eventProjectId", val);
},
treeValue(val) {
this.$emit("eventRegionalismId", val);
}
},
methods: {
// 退
signOut() {
this.$router.push("/");
},
fullScreen() {
// let element = document.getElementsByClassName("big-head-wrap"); // id==con_lf_top_div
let element = document.getElementById("con_lf_top_div"); // id==con_lf_top_div
if (this.fullscreen) {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
} else {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.webkitRequestFullScreen) {
element.webkitRequestFullScreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.msRequestFullscreen) {
// IE11
element.msRequestFullscreen();
}
}
this.fullscreen = !this.fullscreen;
this.$emit('eventFullscreen', { value: this.fullscreen })
},
treeListRegionalism() {
treeListRegionalism({}).then(res => {
this.treeList = res.data;
});
},
getDate() {
this.weeks = this.parseTime(new Date(), "星期{a}");
this.days = this.parseTime(new Date(), "{y}-{m}-{d}");
this.time = this.parseTime(new Date(), "{h}:{i}:{s}");
}
}
};
</script>
<style lang="scss">
.big-head-wrap {
height: 65px;
width: 100%;
display: flex;
background-image: url("../../../../assets/images/big/head_v1.png");
background-size: cover;
.left-wrap {
width: 20%;
height: 100%;
display: flex;
// color: #fff;
font-size: 14px;
align-items: flex-end;
justify-content: left;
padding-left: 30px;
> i {
line-height: 1.5;
}
.span-info {
display: block;
width: 70px;
margin-left: 5px;
}
.el-input {
min-width: 150px;
}
.el-input--small .el-input__inner {
// line-height: 36px;
background: #ff000000;
border-color: #007598;
color: #fff;
margin-left: 10px;
}
.el-input__prefix {
top: -4px;
}
.tree-select-wrap {
height: 32px;
.vue-treeselect__control {
background: #fff0;
border-color: #007598;
height: 32px;
}
.vue-treeselect__single-value {
color: #fff;
}
}
}
.title-wrap {
color: #fff;
width: calc(100% - 40%);
display: flex;
font-size: 36px;
font-family: "Source Han Sans CN";
font-weight: 500;
letter-spacing: 2px;
justify-content: center;
}
.right-wrap {
width: 20%;
display: flex;
color: #fff;
font-size: 14px;
justify-content: space-around;
align-items: flex-end;
.el-button--text {
border: 1px solid;
width: 30px;
height: 30px;
border-radius: 5px 0;
padding-top: 6px;
font-size: 16px;
.el-icon-setting {
font-weight: 600;
}
}
.el-button--texthover {
background: transparent;
}
}
}
</style>

View File

@ -1,242 +0,0 @@
<template>
<div class="big-map-wrap">
<amap-wrap
:mapCenter="{
lng: 116.397428,
lat: 39.90923,
address: ''
}"
ref="bigscLocationMap"
:projectList="projectList"
></amap-wrap>
<div class="top-wrap-1">
<div
v-for="item in labelList"
:key="item.valueKeys"
v-show="!(tempUserType === 'PERSONAL' && item.valueKeys === 'projectTotal')"
>
<div class="item-value">{{countResult[item.valueKeys]}}</div>
<img :src="item.image" style="pointer-events: none;" />
<div class="item-label" @click="routerTokeys(item.valueKeys)">{{item.label}}</div>
</div>
</div>
<div class="bottom-wrap-1">
<div>
<!-- <el-button class="mapButton" icon="iconfont iconquanping1"></el-button> -->
</div>
<div>
<el-button class="mapButton" icon="iconfont iconsheji" @click="overview"></el-button>全局总览
</div>
</div>
</div>
</template>
<script>
import amapWrap from "@/components/Amap/components/bigscLocation/index";
import imgs from "@/assets/images/big/maptp_v1.png";
import { appProjectDeviceList } from "@/api/app";
export default {
name: "mapWrap",
components: {
amapWrap
},
props: ["countResult", "projectList", "fullscreen"],
data() {
return {
imgs,
labelList: [
{
guid: "1",
label: "项目总数",
valueKeys: "projectTotal",
image: imgs,
routerKeys: 'project'
},
{
guid: "2",
label: "设备总数",
valueKeys: "deviceTotal",
image: imgs,
routerKeys: 'device'
},
{
guid: "3",
label: "在线设备",
valueKeys: "onlineDeviceTotal",
image: imgs,
routerKeys: 'device'
},
{
guid: "4",
label: "今日报警",
valueKeys: "todayAlarmTotal",
image: imgs,
routerKeys: 'alarm'
},
{
guid: "2",
label: "报警总数",
valueKeys: "alarmTotal",
image: imgs,
routerKeys: 'alarm'
}
],
deviceList: [],
tempUserType: null
};
},
created() {
this.tempUserType = this.$store.getters.userType;
},
methods: {
closeFullScreen() {
let element = document.getElementById("con_lf_top_div");
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
this.$emit('eventFullscreen', { value: false })
},
routerTokeys(keys) {
if (this.fullscreen) {
this.closeFullScreen()
}
var routerPath = ''
switch (keys) {
case 'projectTotal':
routerPath = '/project/project'
if (this.$store.getters.userType === 'TENANT') {
routerPath = '/project_tenant/project_tenant'
}
case 'deviceTotal':
routerPath = '/device/device'
if (this.$store.getters.userType === 'TENANT') {
routerPath = '/device_tenant/device_tenant'
} else if (this.$store.getters.userType === 'PERSONAL') {
routerPath = '/device_oneself/device_oneself'
}
case 'onlineDeviceTotal':
routerPath = '/device/device'
if (this.$store.getters.userType === 'TENANT') {
routerPath = '/device_tenant/device_tenant'
} else if (this.$store.getters.userType === 'PERSONAL') {
routerPath = '/device_oneself/device_oneself'
}
case 'todayAlarmTotal':
routerPath = '/alarm/record'
if (this.$store.getters.userType === 'TENANT') {
routerPath = '/alarm_tenant/alarm_tenant'
} else if (this.$store.getters.userType === 'PERSONAL') {
routerPath = '/alarm_oneself/alarm_oneself'
}
case 'alarmTotal':
routerPath = '/alarm/record'
if (this.$store.getters.userType === 'TENANT') {
routerPath = '/alarm_tenant/alarm_tenant'
} else if (this.$store.getters.userType === 'PERSONAL') {
routerPath = '/alarm_oneself/alarm_oneself'
}
}
this.$router.push({ 'path': routerPath })
},
overview() {
this.$refs.bigscLocationMap.overview();
},
},
watch: {
}
};
</script>
<style lang="scss">
.big-map-wrap {
height: 100%;
width: 100%;
.top-wrap-1 {
width: 100%;
height: 200px;
position: relative;
top: -743px;
display: flex;
align-items: center;
justify-content: space-around;
// pointer-events: none;
> div {
width: 150px;
height: 150px;
display: -webkit-box;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
align-items: center;
justify-content: center;
.item-value {
width: 100%;
display: flex;
justify-content: center;
height: 35px;
font-size: 28px;
font-family: "Source Han Sans CN";
font-weight: 500;
color: #f7f2ea;
background: linear-gradient(180deg, #fbcf34 0%, #ff9b58 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
pointer-events: none;
}
.item-label {
width: 100%;
height: 16px;
font-size: 16px;
font-family: "Microsoft YaHei";
font-weight: 400;
color: #ffffff;
line-height: 8px;
text-align: center;
}
.item-label:hover {
color: #fbcf34;
}
}
}
.bottom-wrap-1 {
position: relative;
top: -280px;
left: 90%;
> div {
margin-bottom: 5px;
font-size: 14px;
font-family: "Source Han Sans CN";
font-weight: 400;
color: #07beff;
line-height: 20px;
}
.mapButton {
padding: 5px;
width: 26px;
height: 26px;
background: #00629866;
border: 1px solid #008ee3;
border-radius: 2px;
color: #05bcff;
margin-right: 5px;
}
}
.amap-logo {
display: none;
opacity: 0 !important;
}
.amap-copyright {
opacity: 0;
}
}
</style>

View File

@ -1,167 +0,0 @@
<template>
<div class="big-today-ratio-wrap">
<div class="title-t">{{title}}</div>
<div class="echarts-list-wrap">
<div v-for="item in rchartsList" :key="item.valueKeys">
<div class="title">{{item.title}}</div>
<echarts-gauge-wrap
:styles="item.styles"
:colorList="item.colorList"
:eId="item.valueKeys"
:option="tempResult[item.valueKeys]"
></echarts-gauge-wrap>
</div>
</div>
<div class="info-tb-block">
<div>
<div>{{alarmTB}}%</div>
<div>同比</div>
</div>
<div>
<div>{{warningTB}}%</div>
<div>同比</div>
</div>
</div>
</div>
</template>
<script>
import EchartsGaugeWrap from "./echartsGauge";
export default {
name: "todayRatio",
components: {
EchartsGaugeWrap
},
props: ["result"],
data() {
return {
tempResult: {
q1: 0,
q2: 0,
q3: 0,
q4: 0
},
alarmTB: 0,
warningTB: 0,
rchartsList: [
{
styles: "width: 100%; height: 100%;",
colorList: ["#27d0ec"],
valueKeys: "q1",
title: "今日报警"
},
{
styles: "width: 100%; height: 100%;",
colorList: ["#fdc46e"],
valueKeys: "q2",
title: "昨日报警 "
},
{
styles: "width: 100%; height: 100%;",
colorList: ["#27d0ec"],
valueKeys: "q3",
title: "今日预警"
},
{
styles: "width: 100%; height: 100%;",
colorList: ["#fdc46e"],
valueKeys: "q4",
title: "昨日预警"
}
],
title: "最近2天警情同比"
};
},
watch: {
result: {
handler: function(val, oldVal) {
if (val) {
this.tempResult = {};
for (var i = 0; i < val.length; i++) {
if (val[i]["alarmDivide"] === "ALARM") {
this.tempResult["q1"] = val[i]["todayAlarm"];
this.tempResult["q2"] = val[i]["yesterdayAlarm"];
this.alarmTB = val[i]["dayOnDay"];
} else if (val[i]["alarmDivide"] === "WARNING") {
this.tempResult["q3"] = val[i]["todayAlarm"];
this.tempResult["q4"] = val[i]["yesterdayAlarm"];
this.warningTB = val[i]["dayOnDay"];
}
}
}
},
deep: true
}
}
};
</script>
<style lang="scss">
.big-today-ratio-wrap {
width: 100%;
height: 420px;
display: flex;
flex-wrap: wrap;
.title-t {
font-size: 16px;
letter-spacing: 1px;
height: 60px;
width: 100%;
background-size: cover;
display: flex;
justify-content: left;
padding-left: 45px;
align-items: center;
padding-bottom: 10px;
background-image: url("../../../../assets/images/big/b.png");
}
.echarts-list-wrap {
width: 80%;
height: 200px;
height: calc(100% - 70px);
display: flex;
flex-wrap: wrap;
> div {
width: 50%;
height: calc(100% / 2);
display: flex;
flex-wrap: wrap;
justify-content: center;
font-size: 14px;
font-family: "Source Han Sans CN";
font-weight: 400;
> .title {
position: relative;
top: 10px;
width: 100%;
display: flex;
justify-content: center;
height: 30px;
}
}
}
.info-tb-block {
height: 200px;
height: calc(100% - 70px);
display: flex;
width: 20%;
flex-wrap: wrap;
align-items: center;
font-size: 16px;
cursor: default;
> div {
width: 100%;
// height: 50%;
display: flex;
flex-wrap: wrap;
align-items: inherit;
justify-content: center;
> div {
width: 100%;
height: 20px;
display: flex;
justify-content: center;
}
}
}
}
</style>

View File

@ -1,191 +0,0 @@
<template>
<div class="big-trend-wrap">
<div class="title-t">{{title}}</div>
<div class="count-echarts-wrap">
<echarts-line-wrap
ref="echartsLineTrend"
:styles="echartsOption.styles"
:colorList="echartsOption.colorList"
:eId="echartsOption.eId"
:option="resultOption"
></echarts-line-wrap>
</div>
</div>
</template>
<script>
import echartsLineWrap from "./echartsLineT";
import * as echarts from "echarts";
export default {
name: "typeDistribution",
components: {
echartsLineWrap
},
props: ['result'],
data() {
return {
echartsOption: {
styles: "width: 100%; height: 100%;",
colorList: [],
eId: "trendEchartsLine"
},
title: "报警预警趋势",
typeName: "alarm",
resultOption: {
title: {
text: "",
show: false
},
tooltip: {
trigger: "axis"
},
legend: {
top: 5,
right: 5,
data: ["报警", "预警"],
icon: "circle",
textStyle: {
color: "#fff",
fontSize: 16
}
},
grid: {
left: "20",
right: "20",
bottom: "5",
top: 30,
containLabel: true
},
xAxis: {
type: "category",
boundaryGap: false,
show: true,
data: [],
splitLine: {
show: false
},
axisLabel: {
show: true,
textStyle: {
color: "#fff"
}
}
},
yAxis: {
type: "value",
splitLine: {
show: false
},
axisLabel: {
show: true,
textStyle: {
color: "#fff"
}
}
},
series: [
{
name: "报警",
type: "line",
smooth: true,
symbolSize: 12,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(58,77,233,0.8)"
},
{
offset: 1,
color: "rgba(58,77,233,0.1)"
}
])
},
label: {
show: false,
formatter: function(params) {
return echarts.format.formatTime("yyyy-MM-dd", params.value);
},
backgroundColor: "#7581BD"
},
data: []
},
{
name: "预警",
type: "line",
smooth: false,
symbolSize: 12,
data: []
}
]
}
};
},
watch: {
result: {
handler: function(val, oldVal) {
this.resultOption.xAxis.data = val['name']
this.resultOption.series[0].data = val['alarm']
this.resultOption.series[1].data = val['warning']
this.updateEcharts()
},
deep: true
}
},
methods: {
//
updateEcharts() {
this.$refs.echartsLineTrend.updateEchart()
}
}
};
</script>
<style lang="scss">
.big-trend-wrap {
width: 100%;
height: 220px;
display: flex;
flex-wrap: wrap;
margin-top: 20px;
.title-t {
font-size: 16px;
letter-spacing: 1px;
height: 60px;
width: 100%;
background-size: cover;
display: flex;
justify-content: left;
padding-left: 45px;
align-items: center;
padding-bottom: 10px;
background-image: url("../../../../assets/images/big/b.png");
}
.count-echarts-wrap {
width: 100%;
height: calc(100% - 60px);
display: flex;
flex-wrap: wrap;
justify-content: center;
padding-top: 10px;
.tabs-block {
width: 305px;
height: 38px;
background: #bfbfbf94;
display: flex;
color: #fff;
> div {
width: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 18px;
letter-spacing: 7px;
cursor: default;
}
.div-select {
background: #0010ff;
}
}
}
}
</style>

View File

@ -1,132 +0,0 @@
<template>
<div class="big-type-distribution-wrap">
<div class="title-t">{{title}}</div>
<div class="count-echarts-wrap">
<div class="tabs-block">
<div @click="typeName = 'alarm'" :class="typeName === 'alarm' ? 'div-select' : ''">报警</div>
<div @click="typeName = 'waraing'" :class="typeName === 'waraing' ? 'div-select' : ''">预警</div>
</div>
<echarts-pie-wrap
ref="echartsPieType"
:styles="echartsOption.styles"
:colorList="echartsOption.colorList"
:eId="echartsOption.eId"
:option="templist[typeName]"
></echarts-pie-wrap>
</div>
</div>
</template>
<script>
import EchartsPieWrap from "./echartsPie";
export default {
name: "typeDistribution",
components: {
EchartsPieWrap
},
props: ['result'],
data() {
return {
resultList: [
{ value: 40, name: "rose 1" },
{ value: 38, name: "rose 2" },
{ value: 32, name: "rose 3" },
{ value: 30, name: "rose 4" }
],
templist: {
alarm: [],
waraing: []
},
echartsOption: {
styles: "width: 100%; height: 100%;",
colorList: [],
eId: "typeEchartsPie"
},
title: "最近2天警情同比",
typeName: 'alarm'
};
},
watch: {
typeName(val, old) {
if (val) {
this.updateEcharts()
}
},
result: {
handler: function(list, oldVal) {
this.templist = {
alarm: [],
waraing: []
}
if (list) {
for(var i = 0; i < list.length; i++) {
console.log(list[i]['typeCode'].indexOf('a'))
if (list[i]['typeCode'].indexOf('a') === 0) {
this.templist['alarm'].push({ value: list[i].alarmTotal, name: list[i].typeName })
} else if (list[i]['typeCode'].indexOf('w') === 0) {
this.templist['waraing'].push({ value: list[i].alarmTotal, name: list[i].typeName })
}
}
}
console.log(this.templist)
this.updateEcharts()
},
deep: true
}
},
methods: {
//
updateEcharts() {
this.$refs.echartsPieType.updateEchart()
}
}
};
</script>
<style lang="scss">
.big-type-distribution-wrap {
width: 100%;
height: 350px;
display: flex;
flex-wrap: wrap;
.title-t {
font-size: 16px;
letter-spacing: 1px;
height: 60px;
width: 100%;
background-size: cover;
display: flex;
justify-content: left;
padding-left: 45px;
align-items: center;
padding-bottom: 10px;
background-image: url("../../../../assets/images/big/b.png");
}
.count-echarts-wrap {
width: 100%;
height: calc(100% - 60px);
display: flex;
flex-wrap: wrap;
justify-content: center;
padding-top: 10px;
.tabs-block {
width: 305px;
height: 38px;
background: #bfbfbf94;
display: flex;
color: #fff;
>div {
width: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 18px;
letter-spacing: 7px;
cursor: default;
}
.div-select {
background: #0010FF;
}
}
}
}
</style>

View File

@ -1,134 +0,0 @@
<template>
<div class="big-wraring-info-wrap">
<div class="title-t">{{title}}</div>
<div class="count-block">
<div class="info-block-div">
<div>报警总数</div>
<div>{{result.alarmTotal}}</div>
</div>
<div class="info-block-div">
<div>已处理率</div>
<div>{{result.processedRate}}%</div>
</div>
<div class="info-block-div">
<div>未处理</div>
<div style="color: rgba(255, 47, 96, 1);">{{result.unProcessed}}</div>
</div>
<div class="info-block-div">
<div>已处理</div>
<div style="color: rgba(40, 255, 155, 1);">{{result.processed}}</div>
</div>
<div class="alarm-icon-block">
<i class="iconfont iconbaojing"></i>
</div>
</div>
<echarts-bar-wrap :styles="'width: 100%; height: 220px;'" :option="radarOption"></echarts-bar-wrap>
</div>
</template>
<script>
import EchartsBarWrap from "./echartsBar";
export default {
name: "wraringInfoWrap",
components: {
EchartsBarWrap
},
props: ["result"],
data() {
return {
title: "警情信息处理情况",
radarOption: []
};
},
created() {
this.radarOption = [0,0,0];
},
watch: {
result: {
handler: function (obj, oldVal) {
this.radarOption = [];
if (obj) {
this.radarOption.push(obj.alarmTotal)
this.radarOption.push(obj.unProcessed)
this.radarOption.push(obj.processed)
} else {
this.radarOption = [0,0,0];
}
},
deep: true
}
}
};
</script>
<style lang="scss">
.big-wraring-info-wrap {
width: 100%;
height: calc(100% - 300px);
.title-t {
font-size: 16px;
letter-spacing: 1px;
height: 60px;
width: 100%;
background-size: cover;
display: flex;
justify-content: left;
padding-left: 45px;
align-items: center;
padding-bottom: 10px;
background-image: url("../../../../assets/images/big/b.png");
width: 410px;
}
.count-block {
width: calc(100% - 40px);
height: 180px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: flex-start;
margin: 5px 20px;
.info-block-div {
height: calc((180px - 20px) / 2);
width: calc((100% - 10px) / 2);
border: 1px solid #03a9f4;
display: flex;
flex-wrap: wrap;
padding: 8px 0;
justify-content: center;
align-items: center;
margin-bottom: 10px;
> div {
width: 100%;
display: flex;
justify-content: center;
font-family: "Source Han Sans CN";
font-weight: 500;
}
> div:nth-child(1) {
font-size: 14px;
color: #ffffff;
}
> div:nth-child(2) {
font-size: 16px;
color: #ffffff;
}
}
.alarm-icon-block {
position: relative;
width: 49px;
height: 49px;
z-index: 1;
border: 2px solid #21ffff;
border-radius: 50%;
display: flex;
justify-content: center;
top: -120px;
left: 155px;
background: #042fb4;
box-shadow: 0px 0px 60px 15px #012c9e;
> i {
color: #21ffff;
font-size: 30px;
}
}
}
}
</style>

View File

@ -1,3 +0,0 @@
const elementIcons = ['platform-eleme', 'eleme', 'delete-solid', 'delete', 's-tools', 'setting', 'user-solid', 'user', 'phone', 'phone-outline', 'more', 'more-outline', 'star-on', 'star-off', 's-goods', 'goods', 'warning', 'warning-outline', 'question', 'info', 'remove', 'circle-plus', 'success', 'error', 'zoom-in', 'zoom-out', 'remove-outline', 'circle-plus-outline', 'circle-check', 'circle-close', 's-help', 'help', 'minus', 'plus', 'check', 'close', 'picture', 'picture-outline', 'picture-outline-round', 'upload', 'upload2', 'download', 'camera-solid', 'camera', 'video-camera-solid', 'video-camera', 'message-solid', 'bell', 's-cooperation', 's-order', 's-platform', 's-fold', 's-unfold', 's-operation', 's-promotion', 's-home', 's-release', 's-ticket', 's-management', 's-open', 's-shop', 's-marketing', 's-flag', 's-comment', 's-finance', 's-claim', 's-custom', 's-opportunity', 's-data', 's-check', 's-grid', 'menu', 'share', 'd-caret', 'caret-left', 'caret-right', 'caret-bottom', 'caret-top', 'bottom-left', 'bottom-right', 'back', 'right', 'bottom', 'top', 'top-left', 'top-right', 'arrow-left', 'arrow-right', 'arrow-down', 'arrow-up', 'd-arrow-left', 'd-arrow-right', 'video-pause', 'video-play', 'refresh', 'refresh-right', 'refresh-left', 'finished', 'sort', 'sort-up', 'sort-down', 'rank', 'loading', 'view', 'c-scale-to-original', 'date', 'edit', 'edit-outline', 'folder', 'folder-opened', 'folder-add', 'folder-remove', 'folder-delete', 'folder-checked', 'tickets', 'document-remove', 'document-delete', 'document-copy', 'document-checked', 'document', 'document-add', 'printer', 'paperclip', 'takeaway-box', 'search', 'monitor', 'attract', 'mobile', 'scissors', 'umbrella', 'headset', 'brush', 'mouse', 'coordinate', 'magic-stick', 'reading', 'data-line', 'data-board', 'pie-chart', 'data-analysis', 'collection-tag', 'film', 'suitcase', 'suitcase-1', 'receiving', 'collection', 'files', 'notebook-1', 'notebook-2', 'toilet-paper', 'office-building', 'school', 'table-lamp', 'house', 'no-smoking', 'smoking', 'shopping-cart-full', 'shopping-cart-1', 'shopping-cart-2', 'shopping-bag-1', 'shopping-bag-2', 'sold-out', 'sell', 'present', 'box', 'bank-card', 'money', 'coin', 'wallet', 'discount', 'price-tag', 'news', 'guide', 'male', 'female', 'thumb', 'cpu', 'link', 'connection', 'open', 'turn-off', 'set-up', 'chat-round', 'chat-line-round', 'chat-square', 'chat-dot-round', 'chat-dot-square', 'chat-line-square', 'message', 'postcard', 'position', 'turn-off-microphone', 'microphone', 'close-notification', 'bangzhu', 'time', 'odometer', 'crop', 'aim', 'switch-button', 'full-screen', 'copy-document', 'mic', 'stopwatch', 'medal-1', 'medal', 'trophy', 'trophy-1', 'first-aid-kit', 'discover', 'place', 'location', 'location-outline', 'location-information', 'add-location', 'delete-location', 'map-location', 'alarm-clock', 'timer', 'watch-1', 'watch', 'lock', 'unlock', 'key', 'service', 'mobile-phone', 'bicycle', 'truck', 'ship', 'basketball', 'football', 'soccer', 'baseball', 'wind-power', 'light-rain', 'lightning', 'heavy-rain', 'sunrise', 'sunrise-1', 'sunset', 'sunny', 'cloudy', 'partly-cloudy', 'cloudy-and-sunny', 'moon', 'moon-night', 'dish', 'dish-1', 'food', 'chicken', 'fork-spoon', 'knife-fork', 'burger', 'tableware', 'sugar', 'dessert', 'ice-cream', 'hot-water', 'water-cup', 'coffee-cup', 'cold-drink', 'goblet', 'goblet-full', 'goblet-square', 'goblet-square-full', 'refrigerator', 'grape', 'watermelon', 'cherry', 'apple', 'pear', 'orange', 'coffee', 'ice-tea', 'ice-drink', 'milk-tea', 'potato-strips', 'lollipop', 'ice-cream-square', 'ice-cream-round']
export default elementIcons

View File

@ -1,87 +0,0 @@
<template>
<div class="icons-container">
<aside>
<a href="#" target="_blank">Add and use
</a>
</aside>
<el-tabs type="border-card">
<el-tab-pane label="Icons">
<div v-for="item of svgIcons" :key="item">
<el-tooltip placement="top">
<div slot="content">
{{ generateIconCode(item) }}
</div>
<div class="icon-item">
<svg-icon :icon-class="item" class-name="disabled" />
<span>{{ item }}</span>
</div>
</el-tooltip>
</div>
</el-tab-pane>
<el-tab-pane label="Element-UI Icons">
<div v-for="item of elementIcons" :key="item">
<el-tooltip placement="top">
<div slot="content">
{{ generateElementIconCode(item) }}
</div>
<div class="icon-item">
<i :class="'el-icon-' + item" />
<span>{{ item }}</span>
</div>
</el-tooltip>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import svgIcons from './svg-icons'
import elementIcons from './element-icons'
export default {
name: 'Icons',
data() {
return {
svgIcons,
elementIcons
}
},
methods: {
generateIconCode(symbol) {
return `<svg-icon icon-class="${symbol}" />`
},
generateElementIconCode(symbol) {
return `<i class="el-icon-${symbol}" />`
}
}
}
</script>
<style lang="scss" scoped>
.icons-container {
margin: 10px 20px 0;
overflow: hidden;
.icon-item {
margin: 20px;
height: 85px;
text-align: center;
width: 100px;
float: left;
font-size: 30px;
color: #24292e;
cursor: pointer;
}
span {
display: block;
font-size: 16px;
margin-top: 10px;
}
.disabled {
pointer-events: none;
}
}
</style>

View File

@ -1,10 +0,0 @@
const req = require.context('../../../assets/icons/svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys()
const re = /\.\/(.*)\.svg/
const svgIcons = requireAll(req).map(i => {
return i.match(re)[1]
})
export default svgIcons

View File

@ -1,102 +0,0 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
const animationDuration = 6000
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { //
type: 'shadow' // 线'line' | 'shadow'
}
},
grid: {
top: 10,
left: '2%',
right: '2%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisTick: {
alignWithLabel: true
}
}],
yAxis: [{
type: 'value',
axisTick: {
show: false
}
}],
series: [{
name: 'pageA',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [79, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageB',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [80, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageC',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [30, 52, 200, 334, 390, 330, 220],
animationDuration
}]
})
}
}
}
</script>

View File

@ -1,135 +0,0 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '350px'
},
autoResize: {
type: Boolean,
default: true
},
chartData: {
type: Object,
required: true
}
},
data() {
return {
chart: null
}
},
watch: {
chartData: {
deep: true,
handler(val) {
this.setOptions(val)
}
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.setOptions(this.chartData)
},
setOptions({ expectedData, actualData } = {}) {
this.chart.setOption({
xAxis: {
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
boundaryGap: false,
axisTick: {
show: false
}
},
grid: {
left: 10,
right: 10,
bottom: 20,
top: 30,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: {
axisTick: {
show: false
}
},
legend: {
data: ['expected', 'actual']
},
series: [{
name: 'expected', itemStyle: {
normal: {
color: '#FF005A',
lineStyle: {
color: '#FF005A',
width: 2
}
}
},
smooth: true,
type: 'line',
data: expectedData,
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
{
name: 'actual',
smooth: true,
type: 'line',
itemStyle: {
normal: {
color: '#3888fa',
lineStyle: {
color: '#3888fa',
width: 2
},
areaStyle: {
color: '#f3f8ff'
}
}
},
data: actualData,
animationDuration: 2800,
animationEasing: 'quadraticOut'
}]
})
}
}
}
</script>

View File

@ -1,181 +0,0 @@
<template>
<el-row :gutter="40" class="panel-group">
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('newVisitis')">
<div class="card-panel-icon-wrapper icon-people">
<svg-icon icon-class="peoples" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
访客
</div>
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('messages')">
<div class="card-panel-icon-wrapper icon-message">
<svg-icon icon-class="message" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
消息
</div>
<count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('purchases')">
<div class="card-panel-icon-wrapper icon-money">
<svg-icon icon-class="money" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
金额
</div>
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
订单
</div>
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" />
</div>
</div>
</el-col>
</el-row>
</template>
<script>
import CountTo from 'vue-count-to'
export default {
components: {
CountTo
},
methods: {
handleSetLineChartData(type) {
this.$emit('handleSetLineChartData', type)
}
}
}
</script>
<style lang="scss" scoped>
.panel-group {
margin-top: 18px;
.card-panel-col {
margin-bottom: 32px;
}
.card-panel {
height: 108px;
cursor: pointer;
font-size: 12px;
position: relative;
overflow: hidden;
color: #666;
background: #fff;
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
border-color: rgba(0, 0, 0, .05);
&:hover {
.card-panel-icon-wrapper {
color: #fff;
}
.icon-people {
background: #40c9c6;
}
.icon-message {
background: #36a3f7;
}
.icon-money {
background: #f4516c;
}
.icon-shopping {
background: #34bfa3
}
}
.icon-people {
color: #40c9c6;
}
.icon-message {
color: #36a3f7;
}
.icon-money {
color: #f4516c;
}
.icon-shopping {
color: #34bfa3
}
.card-panel-icon-wrapper {
float: left;
margin: 14px 0 0 14px;
padding: 16px;
transition: all 0.38s ease-out;
border-radius: 6px;
}
.card-panel-icon {
float: left;
font-size: 48px;
}
.card-panel-description {
float: right;
font-weight: bold;
margin: 26px;
margin-left: 0px;
.card-panel-text {
line-height: 18px;
color: rgba(0, 0, 0, 0.45);
font-size: 16px;
margin-bottom: 12px;
}
.card-panel-num {
font-size: 20px;
}
}
}
}
@media (max-width:550px) {
.card-panel-description {
display: none;
}
.card-panel-icon-wrapper {
float: none !important;
width: 100%;
height: 100%;
margin: 0 !important;
.svg-icon {
display: block;
margin: 14px auto !important;
float: none !important;
}
}
}
</style>

View File

@ -1,79 +0,0 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
bottom: '10',
data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts']
},
series: [
{
name: 'WEEKLY WRITE ARTICLES',
type: 'pie',
roseType: 'radius',
radius: [15, 95],
center: ['50%', '38%'],
data: [
{ value: 320, name: 'Industries' },
{ value: 240, name: 'Technology' },
{ value: 149, name: 'Forex' },
{ value: 100, name: 'Gold' },
{ value: 59, name: 'Forecasts' }
],
animationEasing: 'cubicInOut',
animationDuration: 2600
}
]
})
}
}
}
</script>

View File

@ -1,116 +0,0 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
const animationDuration = 3000
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { //
type: 'shadow' // 线'line' | 'shadow'
}
},
radar: {
radius: '66%',
center: ['50%', '42%'],
splitNumber: 8,
splitArea: {
areaStyle: {
color: 'rgba(127,95,132,.3)',
opacity: 1,
shadowBlur: 45,
shadowColor: 'rgba(0,0,0,.5)',
shadowOffsetX: 0,
shadowOffsetY: 15
}
},
indicator: [
{ name: 'Sales', max: 10000 },
{ name: 'Administration', max: 20000 },
{ name: 'Information Techology', max: 20000 },
{ name: 'Customer Support', max: 20000 },
{ name: 'Development', max: 20000 },
{ name: 'Marketing', max: 20000 }
]
},
legend: {
left: 'center',
bottom: '10',
data: ['Allocated Budget', 'Expected Spending', 'Actual Spending']
},
series: [{
type: 'radar',
symbolSize: 0,
areaStyle: {
normal: {
shadowBlur: 13,
shadowColor: 'rgba(0,0,0,.2)',
shadowOffsetX: 0,
shadowOffsetY: 10,
opacity: 1
}
},
data: [
{
value: [5000, 7000, 12000, 11000, 15000, 14000],
name: 'Allocated Budget'
},
{
value: [4000, 9000, 15000, 15000, 13000, 11000],
name: 'Expected Spending'
},
{
value: [5500, 11000, 12000, 15000, 12000, 12000],
name: 'Actual Spending'
}
],
animationDuration: animationDuration
}]
})
}
}
}
</script>

View File

@ -1,56 +0,0 @@
import { debounce } from '@/utils'
export default {
data() {
return {
$_sidebarElm: null,
$_resizeHandler: null
}
},
mounted() {
this.initListener()
},
activated() {
if (!this.$_resizeHandler) {
// avoid duplication init
this.initListener()
}
// when keep-alive chart activated, auto resize
this.resize()
},
beforeDestroy() {
this.destroyListener()
},
deactivated() {
this.destroyListener()
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.$_resizeHandler()
}
},
initListener() {
this.$_resizeHandler = debounce(() => {
this.resize()
}, 100)
window.addEventListener('resize', this.$_resizeHandler)
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
},
destroyListener() {
window.removeEventListener('resize', this.$_resizeHandler)
this.$_resizeHandler = null
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
},
resize() {
const { chart } = this
chart && chart.resize()
}
}
}

View File

@ -1,88 +0,0 @@
<template>
<div class="errPage-container">
<el-button icon="arrow-left" class="pan-back-btn" @click="back">
返回
</el-button>
<el-row>
<el-col :span="12">
<h1 class="text-jumbo text-ginormous">
401错误!
</h1>
<h2>您没有访问权限</h2>
<h6>对不起您没有访问权限请不要进行非法操作您可以返回主页面</h6>
<ul class="list-unstyled">
<li class="link-type">
<router-link to="/">
回首页
</router-link>
</li>
</ul>
</el-col>
<el-col :span="12">
<img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream.">
</el-col>
</el-row>
</div>
</template>
<script>
import errGif from '@/assets/401_images/401.gif'
export default {
name: 'Page401',
data() {
return {
errGif: errGif + '?' + +new Date()
}
},
methods: {
back() {
if (this.$route.query.noGoBack) {
this.$router.push({ path: '/' })
} else {
this.$router.go(-1)
}
}
}
}
</script>
<style lang="scss" scoped>
.errPage-container {
width: 800px;
max-width: 100%;
margin: 100px auto;
.pan-back-btn {
background: #008489;
color: #fff;
border: none!important;
}
.pan-gif {
margin: 0 auto;
display: block;
}
.pan-img {
display: block;
margin: 0 auto;
width: 100%;
}
.text-jumbo {
font-size: 60px;
font-weight: 700;
color: #484848;
}
.list-unstyled {
font-size: 14px;
li {
padding-bottom: 5px;
}
a {
color: #008489;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
}
</style>

View File

@ -1,233 +0,0 @@
<template>
<div class="wscn-http404-container">
<div class="wscn-http404">
<div class="pic-404">
<img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404">
<img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404">
<img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404">
<img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
</div>
<div class="bullshit">
<div class="bullshit__oops">
404错误!
</div>
<div class="bullshit__headline">
{{ message }}
</div>
<div class="bullshit__info">
对不起您正在寻找的页面不存在尝试检查URL的错误然后按浏览器上的刷新按钮或尝试在我们的应用程序中找到其他内容
</div>
<router-link to="/" class="bullshit__return-home">
返回首页
</router-link>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Page404',
computed: {
message() {
return '找不到网页!'
}
}
}
</script>
<style lang="scss" scoped>
.wscn-http404-container{
transform: translate(-50%,-50%);
position: absolute;
top: 40%;
left: 50%;
}
.wscn-http404 {
position: relative;
width: 1200px;
padding: 0 50px;
overflow: hidden;
.pic-404 {
position: relative;
float: left;
width: 600px;
overflow: hidden;
&__parent {
width: 100%;
}
&__child {
position: absolute;
&.left {
width: 80px;
top: 17px;
left: 220px;
opacity: 0;
animation-name: cloudLeft;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
&.mid {
width: 46px;
top: 10px;
left: 420px;
opacity: 0;
animation-name: cloudMid;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1.2s;
}
&.right {
width: 62px;
top: 100px;
left: 500px;
opacity: 0;
animation-name: cloudRight;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
@keyframes cloudLeft {
0% {
top: 17px;
left: 220px;
opacity: 0;
}
20% {
top: 33px;
left: 188px;
opacity: 1;
}
80% {
top: 81px;
left: 92px;
opacity: 1;
}
100% {
top: 97px;
left: 60px;
opacity: 0;
}
}
@keyframes cloudMid {
0% {
top: 10px;
left: 420px;
opacity: 0;
}
20% {
top: 40px;
left: 360px;
opacity: 1;
}
70% {
top: 130px;
left: 180px;
opacity: 1;
}
100% {
top: 160px;
left: 120px;
opacity: 0;
}
}
@keyframes cloudRight {
0% {
top: 100px;
left: 500px;
opacity: 0;
}
20% {
top: 120px;
left: 460px;
opacity: 1;
}
80% {
top: 180px;
left: 340px;
opacity: 1;
}
100% {
top: 200px;
left: 300px;
opacity: 0;
}
}
}
}
.bullshit {
position: relative;
float: left;
width: 300px;
padding: 30px 0;
overflow: hidden;
&__oops {
font-size: 32px;
font-weight: bold;
line-height: 40px;
color: #1482f0;
opacity: 0;
margin-bottom: 20px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
&__headline {
font-size: 20px;
line-height: 24px;
color: #222;
font-weight: bold;
opacity: 0;
margin-bottom: 10px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.1s;
animation-fill-mode: forwards;
}
&__info {
font-size: 13px;
line-height: 21px;
color: grey;
opacity: 0;
margin-bottom: 30px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.2s;
animation-fill-mode: forwards;
}
&__return-home {
display: block;
float: left;
width: 110px;
height: 36px;
background: #1482f0;
border-radius: 100px;
text-align: center;
color: #ffffff;
opacity: 0;
font-size: 14px;
line-height: 36px;
cursor: pointer;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.3s;
animation-fill-mode: forwards;
}
@keyframes slideUp {
0% {
transform: translateY(60px);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
}
}
</style>

View File

@ -1,609 +0,0 @@
<template>
<div class="page-cloud">
<div class="public-nav-div">
<div :style="'width: calc(100% - 280px); float: left;'">
<div class="genert-div button-div">
<div class="title" >云端数据概况</div>
<div class="content-div buttom-div" v-if="userType === 'SYSTEM'">
<i class="iconfont icon-chanpinC fontsize"></i>
<p class="buttom-div-p">{{tempObject.modelCount}}</p>
<p>全部型号数量</p>
<el-button type="text" :disabled="true" @click="toProdFu">管理型号</el-button>
</div>
<div class="content-div buttom-div" v-else-if="userType === 'TENANT'">
<i class="iconfont icon-chanpinC fontsize"></i>
<p class="buttom-div-p">{{tempObject.modelCount}}</p>
<p>全部项目数量</p>
<el-button type="text" :disabled="true" @click="toProdFu">管理项目</el-button>
</div>
<div class="content-div buttom-div" v-else>
<i class="iconfont icon-chanpinC fontsize"></i>
<p class="buttom-div-p">0</p>
<p>全部项目数量</p>
<el-button type="text" :disabled="true" @click="toProdFu">管理项目</el-button>
</div>
<div class="content-div buttom-div">
<i class="iconfont icon-shebeishuliang fontsize"></i>
<p class="buttom-div-p">{{tempObject.deviceCount}}</p>
<p>全部设备数量</p>
<el-button type="text" :disabled="true" @click="toDeviceFu">管理设备</el-button>
</div>
<div class="content-div buttom-div">
<i class="iconfont icon-chufaqi fontsize"></i>
<p class="buttom-div-p">{{tempObject.onlineCount}}</p>
<p>在线设备数量</p>
<el-button type="text" :disabled="true" @click="toDeviceFu">管理设备</el-button>
</div>
<div class="content-div buttom-div">
<div style=" width: 100%; height: 160px; position: relative; top: 32px;">
<span
style="font-size: 14px; font-family: 'Microsoft YaHei'; font-weight: bold; position: relative;top: 35px;left: 20px;"
>在线率</span>
<span
style="font-size: 17px; font-family: 'Microsoft YaHei'; font-weight: bold; color: #30ff00; position: relative;top: 20px;left: -20px;"
>{{deviceRate( tempObject.deviceCount, tempObject.onlineCount)}}</span>
<pancake
styles="width: 100%; height: 160px; width: 158px; border-radius: 50%; border: 1px solid; height: 158px;"
id="pancake026"
:config="deviceConfig"
:option="{ data: [{value: tempObject.onlineCount, name:'在线'}, {value: tempObject.offlineCount, name:'离线'}], title: '设备状态' }"
></pancake>
</div>
</div>
<div class="content-div buttom-div">
<i class="iconfont icon-baojing fontsize"></i>
<p class="buttom-div-p">{{alarmCount.alarmCount}}</p>
<p>报警总数</p>
<el-button type="text" :disabled="true" @click="toAlarmFu">管理报警</el-button>
</div>
<div class="content-div buttom-div">
<i class="iconfont icon-gaojingyichuli fontsize"></i>
<p class="buttom-div-p">{{alarmCount.processCount}}</p>
<p>已处理</p>
<el-button type="text" :disabled="true" @click="toAlarmFu">管理报警</el-button>
</div>
<div class="content-div buttom-div">
<i class="iconfont icon-weichuligaojing fontsize"></i>
<p class="buttom-div-p">{{alarmCount.unProcessCount}}</p>
<p>未处理</p>
<el-button type="text" :disabled="true" @click="toAlarmFu">管理报警</el-button>
</div>
<div class="content-div buttom-div">
<div style=" width: 100%; height: 160px; position: relative; top: 32px;">
<span
style="font-size: 14px; font-family: 'Microsoft YaHei'; font-weight: bold; position: relative;top: 35px;left: 18px;"
>处理率</span>
<span
style="font-size: 17px; font-family: 'Microsoft YaHei'; font-weight: bold; color: #30ff00; position: relative;top: 20px;left: -20px;"
>{{alarmRate(alarmCount.alarmCount, alarmCount.processCount)}}</span>
<pancake
styles="width: 100%; height: 160px; height: 160px; width: 158px; border-radius: 50%; border: 1px solid; height: 158px;"
:config="alarmConfig"
id="pancake157"
:option="{ data: [{value: alarmCount.processCount, name:'已处理'}, {value: alarmCount.unProcessCount, name:'未处理'}], title: '报警处理' }"
></pancake>
</div>
</div>
</div>
<div class="genert-div" v-if="index_m_tzgg">
<div class="title">云端设备组态流程</div>
<div class="content">
<div class="content-div" @click="toProdFu">
<i class="iconfont icon-chanpinC fontsize"></i>
<p>添加产品</p>
<p>定义产品属性</p>
</div>
<div class="right-icon">
<i class="iconfont icon-right-fill youjiantou"></i>
</div>
<div class="content-div" @click="toDeviceFu">
<i class="iconfont icon-tianjiashebei fontsize"></i>
<p>添加设备</p>
<p>创建设备与实物对应</p>
</div>
<div class="right-icon">
<i class="iconfont icon-right-fill youjiantou"></i>
</div>
<div class="content-div">
<i class="iconfont icon-icon_xinyong_xianxing_jijin- fontsize"></i>
<p>数据上报</p>
<p>设备实时数据上传云端</p>
</div>
<div class="right-icon">
<i class="iconfont icon-right-fill youjiantou"></i>
</div>
<div class="content-div">
<i class="iconfont icon-lishijilu fontsize"></i>
<p>云端查看</p>
<p>云端查看设备历史数据</p>
</div>
</div>
</div>
<div
class="genert-div button-div"
style="width: calc((100% - 30px) / 2); margin-right: 30px;"
>
<div class="title">
更新日志
<div class="see-more" @click="versionSeeMoreClick()">查看更多</div>
</div>
<div class="new-div-wrap">
<div
style="font-size: 20px; line-height: 24px; margin-bottom: 3px;"
>更新内容 ( {{versionObj.version}} )</div>
<div
style="font-size: 16px; line-height: 25px; padding-left: 0px; height: 140px; overflow: auto;"
class="new-info-wrap"
v-html="versionObj.content"
>
<!-- <el-input v-model="versionObj.content" :readonly="true" type="textarea" class="version-input" :rows="6"></el-input> -->
</div>
</div>
</div>
<div class="genert-div button-div" style="width: calc((100% - 30px) / 2)">
<div class="title">
通知公告
<div class="see-more" @click="noticeSeeMoreClick()">查看更多</div>
</div>
<div style="padding: 20px 5px; " class="new-div-wrap">
<div v-for="(item, index) in newsList" :key="index" class="news-item">
<span class="ontice-span"></span>
<span @click="noticeClick(item)">{{item.noticeTitle}}</span>
</div>
</div>
</div>
</div>
<div class="dashboard-tips">
<indexTips title="微信小程序" :option="option1"></indexTips>
<indexTips title="微信公众号" :option="option2"></indexTips>
</div>
</div>
</div>
</template>
<script>
import indexTips from "./bashboardcom/indexTips";
import pancake from "./bashboardcom/pancake_echarts";
import { homeCount } from "@/api/system/home";
import { newUplog } from '@/api/system/uplog'
import { listNotice } from "@/api/system/notice";
import gzhqr from "@/assets/images/gzhqr.jpg"
import ydxcx from "@/assets/images/ydxcx.jpg"
export default {
name: "cloud",
data() {
return {
activeNames: ["1", "2", "3", "4"],
DATA: [],
text: "",
actor: "",
count: 0,
isText: false,
currentRole: "adminDashboard",
headerObj: "",
versionObj: {},
newsList: [],
tempObject: {
onlineCount: "0",
activeCount: "0",
deviceCount: "0",
modelCount: "0",
offlineCount: "0",
userId: "",
userName: ""
},
alarmCount: {
processCount: "0",
unProcessCount: "0",
alarmCount: "0"
},
deviceConfig: {
tooltip: {
formatter: "{a} <br/>{b}: {c} ({d}%)"
},
series: {
radius: ["50%", "75%"]
},
itemStyle: {
normal: {
color: function(params) {
var colorList = ["#00cefc", "rgb(211, 251, 253)"];
return colorList[params.dataIndex];
}
}
}
},
alarmConfig: {
tooltip: {
formatter: "{a} <br/>{b}: {c} ({d}%)"
},
series: {
radius: ["50%", "75%"]
},
itemStyle: {
normal: {
color: function(params) {
var colorList = ["rgb(255, 158, 98)", "rgb(255, 233, 213)"];
return colorList[params.dataIndex];
}
}
}
},
option1: [
{
img: ydxcx,
lable: "微信小程序",
describe: "企业用户和个人用户通过微信小程序,可以查看设备,控制设备,查看设备实时数据和历史数据;查看报警信息,处理报警信息,查看项目信息等。"
}
],
option2: [
{
img: gzhqr,
lable: "微信公众号",
describe: "通过关注微信公众号,可以实时接收到系统通知,触发器消息等。"
}
],
index_m_tzgg: false,
head_btn_gjjk: false,
head_btn_sbjk: false,
index_m_ydxcx: false,
userType: null
};
},
components: {
indexTips,
pancake
},
created() {
this.init();
},
methods: {
init() {
this.userType = this.$store.getters.userType;
this.getCount();
this.getVersionList();
this.getNoticeList();
},
versionSeeMoreClick() {
this.$router.push({
path: "/uplog/list"
});
},
noticeSeeMoreClick() {
this.$router.push({ path: "/news" });
// this.$router.push({
// path: "/admin/notices/list"
// });
},
getNoticeList() {
listNotice({
pageNum: 1,
pageSize: 5
}).then(response => {
this.newsList = response.rows
}).catch(err => {})
},
getVersionList() {
newUplog().then(response => {
this.versionObj = response.data
}).catch(err => {})
},
noticeClick(row) {
this.$router.push({ path: "/news", query: { newId: row.noticeId } });
},
contentToString(val) {
let str = "";
if (val) {
let list = new Array();
list = val.split(";");
list.forEach((v, index) => {
// if (index !== list.length -1) {
str += v + " <br>";
// }
});
}
return str;
},
deviceRate(count, zk) {
let num = ((parseInt(zk) / parseInt(count)) * 100).toFixed(0);
if (num !== "NaN") {
return num + " %";
} else {
return "0 %";
}
},
alarmRate(count, zk) {
let num = ((parseInt(zk) / parseInt(count)) * 100).toFixed(0);
if (num !== "NaN") {
return num + " %";
} else {
return "0 %";
}
},
getAlarmCount() {
},
getCount() {
homeCount().then(response => {
this.tempObject = {
onlineCount: response.data.onlineDeviceTotal,
activeCount: response.data.activeCount,
deviceCount: response.data.deviceTotal,
modelCount: response.data.projectTotal,
offlineCount: (response.data.deviceTotal - response.data.onlineDeviceTotal) || 0
}
this.alarmCount = {
processCount: response.data.processed,
unProcessCount: response.data.unProcessed,
alarmCount: response.data.alarmTotal
};
}).catch(err => {
console.log(err)
})
},
toDeviceFu() {
this.$router.push({
path: "/iot/devices"
});
},
toProdFu() {
this.$router.push({
path: "/iot/prod"
});
},
toAlarmFu() {
this.$router.push({
path: "/trigger/trigger/log"
});
},
getData() {
if (this.count < this.DATA.length - 1) {
this.count++;
} else {
this.count = 0;
}
this.isText = true;
this.actor = this.DATA[this.count];
},
setData() {
let num = 0;
let count = 0;
let active = false;
let timeoutstart = 5000;
let timeoutend = 1000;
let timespeed = 10;
setInterval(() => {
if (this.isText) {
if (count == this.actor.length) {
active = true;
} else {
active = false;
}
if (active) {
num--;
this.text = this.actor.substr(0, num);
if (num == 0) {
this.isText = false;
setTimeout(() => {
count = 0;
this.getData();
}, timeoutend);
}
} else {
num++;
this.text = this.actor.substr(0, num);
if (num == this.actor.length) {
this.isText = false;
setTimeout(() => {
this.isText = true;
count = this.actor.length;
}, timeoutstart);
}
}
}
}, timespeed);
}
}
};
</script>
<style lang="scss">
.page-cloud {
padding: 20px;
height: calc(100vh - 84px);
width: 100%;
padding: 20px;
background: #f0f2f5;
overflow: auto;
.public-nav-div {
//
width: 100%;
min-width: 1100px;
}
.genert-div {
border: 0px;
border-radius: 5px;
box-shadow: 0px 1px 3px 1px;
background-color: white;
font: 14px/16px "Roboto", sans-serif;
color: #666666;
width: 100%;
float: left;
margin-bottom: 20px;
cursor: default;
}
.new-div-wrap {
height: 200px;
width: calc(100% - 35px);
overflow: auto;
padding: 20px 5px 10px 30px;
padding-left: 30px;
}
.title {
height: 50px;
border-bottom: 1px solid #c4c4c4;
padding: 21px 10px 10px 30px;
font-size: 18px;
}
.content {
height: 160px;
padding: 30px 20px 30px 30px;
color: #999;
}
.content-div {
float: left;
width: 160px;
min-height: 150px;
font-size: 16px;
text-align: center;
padding-top: 25px;
border-radius: 5px;
p {
margin-top: 10px;
}
}
.content-div:hover {
box-shadow: 0 0 10px #09c;
color: #09c;
}
.buttom-div {
margin: 20px 20px 20px 20px;
margin-left: calc((100% - (170px * 4)) / 8);
margin-right: calc((100% - (170px * 4)) / 8);
}
.fontsize {
font-size: 64px;
line-height: 1;
}
.dashboard-tips {
width: 260px;
float: left;
margin-left: 20px;
}
.youjiantou {
font-size: 18px;
}
.right-icon {
width: calc((100% - (170px * 4)) / 3);
float: left;
padding-top: 65px;
margin-right: 10px;
text-align: center;
}
}
.wel-contailer {
position: relative;
}
.banner-text {
position: relative;
padding: 0 20px;
font-size: 20px;
text-align: center;
color: #333;
}
.buttom-div-p {
font-size: 22px;
}
.news-item {
position: relative;
left: 20px;
line-height: 30px;
font-size: 16px;
width: calc(100% - 20px);
overflow: hidden;
}
.news-item:hover {
color: #1890ff;
}
.ontice-span {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 6px;
background: #1890ff;
margin-right: 20px;
position: relative;
top: -1px;
}
.see-more {
position: relative;
// left: 10px;
float: right;
font-size: 12px;
// top: 10px;
}
.see-more:hover {
color: #1890ff;
}
.new-div-wrap .new-info-wrap::-webkit-scrollbar {
/*滚动条整体样式*/
width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
height: 3px;
}
.new-div-wrap .new-info-wrap::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
box-shadow: inset 0 0 5px #9e9d9d;
background: #ffffff;
}
.new-div-wrap .new-info-wrap::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px #f6f6f6;
border-radius: 10px;
background: #ffffff;
}
.page-cloud::-webkit-scrollbar {
/*滚动条整体样式*/
width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
height: 3px;
}
.page-cloud::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
box-shadow: inset 0 0 5px #9e9d9d;
background: #ffffff;
}
.page-cloud::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px #f6f6f6;
border-radius: 10px;
background: #ffffff;
}
</style>
<style>
.version-input .el-textarea__inner {
border: 0px;
cursor: default;
}
</style>

View File

@ -1,98 +0,0 @@
<template>
<div class="dashboard-editor-container">
<panel-group @handleSetLineChartData="handleSetLineChartData" />
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
<line-chart :chart-data="lineChartData" />
</el-row>
<el-row :gutter="32">
<el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper">
<raddar-chart />
</div>
</el-col>
<el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper">
<pie-chart />
</div>
</el-col>
<el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper">
<bar-chart />
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import PanelGroup from './dashboard/PanelGroup'
import LineChart from './dashboard/LineChart'
import RaddarChart from './dashboard/RaddarChart'
import PieChart from './dashboard/PieChart'
import BarChart from './dashboard/BarChart'
const lineChartData = {
newVisitis: {
expectedData: [100, 120, 161, 134, 105, 160, 165],
actualData: [120, 82, 91, 154, 162, 140, 145]
},
messages: {
expectedData: [200, 192, 120, 144, 160, 130, 140],
actualData: [180, 160, 151, 106, 145, 150, 130]
},
purchases: {
expectedData: [80, 100, 121, 104, 105, 90, 100],
actualData: [120, 90, 100, 138, 142, 130, 130]
},
shoppings: {
expectedData: [130, 140, 141, 142, 145, 150, 160],
actualData: [120, 82, 91, 154, 162, 140, 130]
}
}
export default {
name: 'Index',
components: {
PanelGroup,
LineChart,
RaddarChart,
PieChart,
BarChart
},
data() {
return {
lineChartData: lineChartData.newVisitis
}
},
methods: {
handleSetLineChartData(type) {
this.lineChartData = lineChartData[type]
}
}
}
</script>
<style lang="scss" scoped>
.dashboard-editor-container {
padding: 32px;
background-color: rgb(240, 242, 245);
position: relative;
.chart-wrapper {
background: #fff;
padding: 16px 16px 0;
margin-bottom: 32px;
}
}
@media (max-width:1024px) {
.chart-wrapper {
padding: 8px;
}
}
</style>

View File

@ -1,169 +0,0 @@
<template>
<div class="app-container tenant-home">
主页暂未开发
<!-- <div class="top-wrap">
<div v-for="(doctTop, index) in topOption" :Key="index">
<div class="icon-wrap">
<img :src="doctTop.leftImg" class="top-img" alt="dark" />
<span :class="'jg-span ' + doctTop.spanClass"></span>
</div>
<div class="info-block">
<span>{{doctTop.title}}</span>
<div class="info-wrap" :style="{'color': doctTop.valueColor}">{{topValue[doctTop.value]}}</div>
</div>
</div>
</div>
<div class="beas-wrap">
<div>
</div>
</div> -->
</div>
</template>
<script>
// import './rhea.js'
// var container = require('./rhea.js');
// var container = require('rhea');
export default {
name: "tenantHome",
data() {
return {
topValue: {
farstValue: 158,
twoValue: 5,
threeValue: 159,
lastVlaue: 1158
},
topOption: [
{
leftImg: "/images/quickStart_icon_subuserCounts.992898a.png",
spanClass: "span-bg1",
valueColor: "#b176e9",
value: "farstValue",
title: "注册用户"
},
{
leftImg: "/images/quickStart_icon_subuserCounts.992898a.png",
spanClass: "span-bg1",
valueColor: "#b176e9",
value: "twoValue",
title: "项目总数"
},
{
leftImg: "/images/quickStart_icon_subuserCounts.992898a.png",
spanClass: "span-bg1",
valueColor: "#b176e9",
value: "threeValue",
title: "设备总数"
},
{
leftImg: "/images/quickStart_icon_subuserCounts.992898a.png",
spanClass: "span-bg1",
valueColor: "#b176e9",
value: "lastVlaue",
title: "告警总数"
}
// {
// leftImg: "/images/quickStart_icon_subuserCounts.992898a.png",
// spanClass: "span-bg1",
// valueColor: "#b176e9",
// value: "lastVlaue",
// title: " (: )"
// }
]
};
},
created(){
// console.log(container)
// var connection = container['__proto__'].websocket_connect({'host':'192.168.18.134','port':5672,'username':'admin','password':'fd2018'});
// console.log(connection)
}
};
</script>
<style lang="scss">
.tenant-home {
.top-wrap {
width: calc(100%);
display: flex;
justify-content: space-between;
> div {
width: calc((100% - 60px) / 4);
height: 120px;
display: flex;
padding: 10px 10px;
color: #f7f7f7;
align-items: center;
justify-content: space-around;
box-shadow: 0px 0px 5px #a5a4a4;
.icon-wrap {
width: 35%;
display: flex;
justify-content: space-around;
align-items: center;
.top-img {
width: 55%;
height: 60%;
}
.jg-span {
display: block;
width: 3px;
background: #c7c3c3;
height: 70px;
margin: 0 10px;
background: -webkit-linear-gradient(
bottom,
#2196f36e,
#b176e9 50%,
#2196f36e
);
}
.span-bg1 {
background: -webkit-linear-gradient(
bottom,
#2196f36e,
#b176e9 50%,
#2196f36e
);
}
}
.info-block {
width: calc(100% - 35%);
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
height: 75%;
align-items: center;
justify-content: left;
.info-wrap {
color: #b176e9;
font-size: 1.5vw;
width: 100%;
height: 70%;
align-items: center;
display: flex;
}
> span {
color: #9c9c9c;
font-size: 14px;
display: block;
height: 20px;
text-align: left;
padding-right: 10px;
position: relative;
top: 0px;
left: -6px;
}
}
}
> div:hover{
box-shadow: 0px 0px 5px #4db8f7;
}
}
.beas-wrap {
height: calc((100vh - 260px));
width: 100%;
border: 1px solid red;
margin-top: 10px;
}
}
</style>

View File

@ -1,211 +0,0 @@
<template>
<!-- 告警记录功能 -->
<div class="app-container alarm-record">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="报警时间" prop="alarmTime">
<el-date-picker
v-model="time"
size="small"
@change="queryTimeChange"
clearable
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item label="告警类型" prop="typeName">
<el-input
v-model="queryParams.typeName"
placeholder="请输入告警类型"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:record:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="recordList">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="设备名称" align="left" width="200px" prop="deviceName" />
<!-- <el-table-column label="设备当前值" align="left" prop="currentValue" >
<template slot-scope="scope">
<span style="text-overflow: ellipsis; overflow: hidden; white-space: nowrap;">{{scope.row.currentValue}}</span>
</template>
</el-table-column> -->
<el-table-column label="推送内容" align="left" prop="alarmContent" />
<el-table-column label="报警时间" align="center" prop="alarmTime" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.alarmTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="处理状态" width="100px" align="center" prop="processState" :formatter="stateFormatter"/>
<el-table-column label="处理结果" align="left" width="150px" prop="processResult" />
<el-table-column label="处理时间" align="center" prop="processTime" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.processTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="告警类型" align="left" width="150px" prop="typeName" />
<el-table-column label="类型编码" align="left" width="150px" prop="typeCode" />
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import {
listRecord,
getRecord,
exportRecord
} from "@/api/alarm/record";
import Editor from "@/components/Editor";
export default {
name: "Record",
components: {
Editor
},
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
recordList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
typeName: null,
typeCode: null,
beginTime: null,
endTime: null,
alarmDivide: 'ALARM'
},
//
form: {},
//
rules: {},
time: []
};
},
created() {
this.getList();
},
methods: {
queryTimeChange(val) {
if (val) {
this.queryParams.beginTime = this.parseTime(val[0], '{y}-{m}-{d} {h}:{i}:{s}')
this.queryParams.endTime = this.parseTime(val[1], '{y}-{m}-{d} {h}:{i}:{s}')
} else {
this.queryParams.beginTime = null;
this.queryParams.endTime = null;
}
},
stateFormatter(val) {
return val === '2' ? '已处理' : '未处理'
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
/** 查询报警记录列表 */
getList() {
this.loading = true;
listRecord(this.queryParams).then(response => {
this.recordList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
// id
getRecordInfo(id) {
getRecord(id).then(res => {
this.form = res.data;
this.open = true;
this.title = `告警记录详情`;
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.time = [];
this.queryParams.beginTime = null;
this.queryParams.endTime = null;
this.handleQuery();
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有报警记录数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportRecord(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>

View File

@ -1,434 +0,0 @@
<template>
<div class="app-container alarm-type">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
<!-- <el-form-item label="编码" prop="typeCode">
<el-input
v-model="queryParams.typeCode"
placeholder="请输入报警类型编码"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>-->
<!-- <el-form-item label="标签">
<el-input
v-model="queryParams.tag"
placeholder="请输入报警标签"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item> -->
<el-form-item label="类型名称" prop="typeName">
<el-input
v-model="queryParams.typeName"
placeholder="请输入报警类型名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:type:add']"
>新增</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['iot:type:edit']"
>修改</el-button>
</el-col> -->
<el-col :span="1.5">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['iot:type:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:type:export']"
>导出</el-button>
</el-col>
</el-row>
<el-table
v-loading="loading"
@sort-change="sortChange"
:data="alarmTypeList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="编码" align="left" sortable="custom" prop="typeCode" /> -->
<el-table-column label="名称" align="left" sortable="custom" prop="typeName" />
<el-table-column label="设备类型" align="center" prop="deviceTypeName" />
<el-table-column label="报警划分" align="center" width="100px" prop="alarmDivide" :formatter="alarmDivideForm" />
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<span v-if="scope.row.status === 0">启用</span>
<span v-else>关闭</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
v-if="scope.row.tenantId === tenantId"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:type:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-if="scope.row.tenantId === tenantId"
v-hasPermi="['iot:type:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改告警类型对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" width="500px" >
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="名称" prop="typeName">
<el-input v-model="form.typeName" placeholder="请输入报警类型名称" />
</el-form-item>
<el-form-item label="编码" prop="typeCode">
<el-input v-model="form.typeCode" placeholder="请输入编码" />
</el-form-item>
<el-form-item label="标签" prop="tag">
<el-input v-model="form.tag" placeholder="请输入标签" />
</el-form-item>
<el-form-item label="设备类型" prop="deviceType">
<el-select
v-model="form.deviceType"
style="width: 100%;"
clearable
placeholder="请输入报警设备类型"
>
<el-option
v-for="(keys, vals) in deviceTypeList"
:label="keys"
:value="vals"
:key="vals"
/>
</el-select>
</el-form-item>
<el-form-item label="报警划分" prop="alarmDivide">
<el-radio-group v-model="form.alarmDivide">
<el-radio :label="vals" v-for="(keys, vals) in alarmDivideType">{{keys}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="状态">
<el-switch
v-model="form.status"
active-color="#13ce66"
inactive-color="#dad5d5"
active-value="1"
inactive-value="0"
></el-switch>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listAlarmType,
getAlarmType,
delAlarmType,
addAlarmType,
updateAlarmType
} from "@/api/alarm/alarmType";
import { listDeviceTypeList } from "@/api/iot/device";
// import { selectedProdmodel } from "@/api/device/prodmodel";
const alarmDivideType = {
ALARM: '报警',
WARNING: '预警'
}
export default {
name: "AlarmType",
data() {
return {
alarmDivideType,
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
total: 0,
//
alarmTypeList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
typeCode: undefined,
typeName: undefined,
tag: undefined,
orderByColumn: "",
isAsc: "desc"
},
//
form: {},
//
rules: {
typeName: [
{ required: true, message: "类型名称不能为空", trigger: "blur" }
],
tag: [{ required: true, message: "告警标签不能为空", trigger: "blur" }]
},
tenantId: "",
deviceTypeList: []
};
},
created() {
this.tenantId = this.$store.getters.tenantId;
this.getList();
},
methods: {
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
alarmDivideForm(row) {
return this.alarmDivideType[row.alarmDivide]
},
//
getDeviceTypeList() {
listDeviceTypeList().then(response => {
this.deviceTypeList = response.data;
});
},
sortChange(column) {
const sort = {
isAsc: column.order === "descending" ? "desc" : "asc",
orderByColumn: column.prop
};
this.queryParams = Object.assign(this.queryParams, sort);
this.handleQuery();
},
//
getModelList() {
// selectedProdmodel().then(res => {
// this.deviceTypeList = res.data;
// });
},
/** 查询告警类型列表 */
getList() {
this.loading = true;
listAlarmType(this.queryParams).then(response => {
this.alarmTypeList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
deviceType: undefined,
typeCode: undefined,
typeName: undefined,
alarmDivide: 'ALARM',
status: "1",
tag: ""
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.typeId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.getDeviceTypeList();
this.open = true;
this.title = "添加告警类型";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.getDeviceTypeList();
const typeId = row.typeId || this.ids;
getAlarmType(typeId).then(response => {
this.form = response.data;
this.open = true;
this.form.status = response.data.status.toString();
this.title = "修改告警类型";
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.typeId != undefined) {
updateAlarmType(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
}
});
} else {
addAlarmType(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
}
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const typeIds = row.typeId || this.ids;
this.$confirm(
// '"' + typeIds + '"?',
"是否删除该选项",
"警告",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
)
.then(function() {
return delAlarmType(typeIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
})
.catch(function() {});
},
/** 导出按钮操作 */
handleExport() {
this.download(
"iot/alarmType/export",
{
...this.queryParams
},
`iot_alarmType.xlsx`
);
}
}
};
</script>
<style lang="scss">
.alarm-type {
.eldialog-wrap {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-dialog__body {
padding: 0px;
}
.el-form {
padding: 20px;
padding-right: 40px;
}
.el-dialog__footer {
height: 60px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding: 0px;
padding-top: 15px;
.el-button + .el-button {
margin-right: 10px;
}
.el-button {
padding-top: 8px;
}
}
.form-params-wrap {
height: 100%;
width: calc(100% + 110px);
position: relative;
top: 35px;
left: -90px;
max-height: 250px;
overflow: auto;
padding: 10px;
border: 1px solid #009688;
border-radius: 5px;
}
}
}
</style>

View File

@ -1,209 +0,0 @@
<template>
<!-- 告警记录功能 -->
<div class="app-container alarm-record">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="预警时间" prop="alarmTime">
<el-date-picker
v-model="time"
size="small"
@change="queryTimeChange"
clearable
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item label="告警类型" prop="typeName">
<el-input
v-model="queryParams.typeName"
placeholder="请输入告警类型"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:record:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="recordList">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="设备名称" align="left" width="200px" prop="deviceName" />
<!-- <el-table-column label="设备当前值" align="left" width="200px" prop="currentValue" >
<template slot-scope="scope">
<span style="text-overflow: ellipsis; overflow: hidden; white-space: nowrap;">{{scope.row.currentValue}}</span>
</template>
</el-table-column> -->
<el-table-column label="推送内容" align="left" prop="alarmContent" />
<el-table-column label="预警时间" align="center" prop="alarmTime" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.alarmTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column
label="处理状态"
width="100px"
align="center"
prop="processState"
:formatter="stateFormatter"
/>
<el-table-column label="处理结果" align="left" width="150px" prop="processResult" />
<el-table-column label="处理时间" align="center" prop="processTime" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.processTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="告警类型" align="left" width="150px" prop="typeName" />
<el-table-column label="类型编码" align="left" width="150px" prop="typeCode" />
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { listRecord, getRecord, exportRecord } from "@/api/alarm/record";
export default {
name: "WarningRecord",
components: {},
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
recordList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
typeName: null,
typeCode: null,
beginTime: null,
endTime: null,
alarmDivide: "WARNING"
},
//
form: {},
//
rules: {},
time: []
};
},
created() {
this.getList();
},
methods: {
queryTimeChange(val) {
if (val) {
this.queryParams.beginTime = this.parseTime(val[0], '{y}-{m}-{d} {h}:{i}:{s}')
this.queryParams.endTime = this.parseTime(val[1], '{y}-{m}-{d} {h}:{i}:{s}')
} else {
this.queryParams.beginTime = null;
this.queryParams.endTime = null;
}
},
stateFormatter(val) {
return val === "2" ? "已处理" : "未处理";
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
/** 查询预警记录列表 */
getList() {
this.loading = true;
listRecord(this.queryParams).then(response => {
this.recordList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
// id
getRecordInfo(id) {
getRecord(id).then(res => {
this.form = res.data;
this.open = true;
this.title = `告警记录详情`;
});
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.time = [];
this.queryParams.beginTime = null;
this.queryParams.endTime = null;
this.handleQuery();
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有预警记录数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportRecord(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>

View File

@ -1,522 +0,0 @@
<template>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="任务名称" prop="jobName">
<el-input
v-model="queryParams.jobName"
placeholder="请输入任务名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="任务组名" prop="jobGroup">
<el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable size="small">
<el-option
v-for="dict in jobGroupOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="任务状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable size="small">
<el-option
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['monitor:job:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['monitor:job:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-s-operation"
size="mini"
@click="handleJobLog"
v-hasPermi="['monitor:job:query']"
>日志</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="jobList">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column
label="任务名称"
align="left"
prop="jobName"
:show-overflow-tooltip="true"
/>
<el-table-column
label="任务组名"
align="center"
prop="jobGroup"
:formatter="jobGroupFormat"
/>
<!-- <el-table-column
label="调用目标字符串"
align="left"
prop="invokeTarget"
:show-overflow-tooltip="true"
/> -->
<!-- <el-table-column
label="cron执行表达式"
align="left"
prop="cronExpression"
width="250px"
:show-overflow-tooltip="true"
/> -->
<el-table-column label="状态" align="center">
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
active-value="0"
inactive-value="1"
@change="handleStatusChange(scope.row)"
></el-switch>
</template>
</el-table-column>
<el-table-column
label="操作"
width="200px"
align="center"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-caret-right"
@click="handleRun(scope.row)"
v-hasPermi="['monitor:job:changeStatus']"
>执行一次</el-button>
<!-- <el-button
size="mini"
type="text"
@click="handleUpdate(scope.row)"
v-hasPermi="['monitor:job:update']"
>修改</el-button> -->
<el-button
size="mini"
type="text"
@click="handleDetails(scope.row)"
v-hasPermi="['monitor:job:update']"
>详情</el-button>
<el-button
size="mini"
type="text"
@click="handleDelete(scope.row)"
v-hasPermi="['monitor:job:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改定时任务对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" @close="detailsShow = false" width="50%">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :span="24">
<el-form-item label="任务名称:" prop="jobName">
<el-input :disabled="detailsShow" v-model="form.jobName" placeholder="请输入任务名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<div>
<easy-cron :disabled="detailsShow" style="width: 100%;" v-model="form.cronExpression" :exeStartTime="exeStartTime"></easy-cron>
</div>
</el-col>
<el-col :span="24">
<div style="margin-top: 20px;">
<el-button size="mini" v-show="detailsShow === false" type="primary" @click="addDeviceInfo">添加设备</el-button>
<device-param-wrap
ref="paramsWrap"
:disabled="detailsShow"
v-for="(item,index) in relationList"
:tempIndex="item.guid"
:deleteButtonD="relationList.length < 2"
:key="item.guid"
:appInfo="appInfo"
:paramsDevcie="item"
@delInfo="delInfo"
@resultEvent="resultEvent"
></device-param-wrap>
</div>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" v-show="detailsShow" @click="detailsShow = false">编辑</el-button>
<el-button size="mini" type="primary" v-show="detailsShow === false" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listJob,
getJob,
delJob,
addJob,
updateJob,
exportJob,
runJob,
changeJobStatus
} from "@/api/iot/deviceJob";
import EasyCron from "@/components/EasyCron";
import CronValidator from '@/components/EasyCron/validator'
import DeviceParamWrap from "./profile/deviceParam";
import md5 from 'js-md5';
export default {
name: "DeviceJob",
components: {
EasyCron,
DeviceParamWrap
},
data() {
return {
exeStartTime: '',
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
jobList: [],
//
title: "",
//
open: false,
//
openView: false,
//
jobGroupOptions: [],
//
statusOptions: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
jobName: undefined,
jobGroup: undefined,
status: undefined
},
detailsShow: false,
//
form: {},
appInfo: {
appkey: "",
sign: "",
timestamp: ""
},
intervalInfo: null,
//
rules: {
jobName: [
{ required: true, message: "任务名称不能为空", trigger: "blur" }
],
invokeTarget: [
{ required: true, message: "调用目标字符串不能为空", trigger: "blur" }
],
cronExpression: [
{ required: true, message: "cron执行表达式不能为空", trigger: "blur" },
{ validator: CronValidator }
]
},
relationList: [], //
updateMD5List: ''
};
},
created() {
this.getList();
// this.intervalInfofu();
this.getDicts("sys_job_group").then(response => {
this.jobGroupOptions = response.data;
});
this.getDicts("sys_job_status").then(response => {
this.statusOptions = response.data;
});
},
methods: {
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
getGuid() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(
c
) {
var r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
},
delInfo(index) {
var arr = [];
this.relationList.forEach(v => {
if (v.guid !== index) {
arr.push(v);
}
});
this.relationList = [];
this.relationList = arr;
this.$forceUpdate();
},
resultEvent(data) {
for (var i = 0; i < this.form.list.length; i++) {
if (this.form.list[i].guid === data.index) {
this.form.list[i] = data.result;
break;
}
}
},
addDeviceInfo() {
this.relationList.push({
cmdKey: "",
deviceId: "",
prodId: "",
property: "",
guid: this.getGuid()
});
},
/** 查询定时任务列表 */
getList() {
this.loading = true;
listJob(this.queryParams).then(response => {
this.jobList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
jobGroupFormat(row, column) {
return this.selectDictLabel(this.jobGroupOptions, row.jobGroup);
},
//
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, row.status);
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
jobName: undefined,
invokeTarget: undefined,
cronExpression: '* * * ? * * *',
misfirePolicy: 1,
concurrent: 1,
list: []
};
this.exeStartTime = this.parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}');
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.jobId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
//
handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用";
this.$confirm(
'确认要"' + text + '""' + row.jobName + '"任务吗?',
"警告",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
)
.then(function() {
return changeJobStatus(row.jobId, row.status);
})
.then(() => {
this.msgSuccess(text + "成功");
})
.catch(function() {
row.status = row.status === "0" ? "1" : "0";
});
},
/* 立即执行一次 */
handleRun(row) {
this.$confirm('确认要立即执行一次"' + row.jobName + '"任务吗?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return runJob(row.jobId, row.jobGroup);
})
.then(() => {
this.msgSuccess("执行成功");
});
},
/** 任务详细信息 */
handleView(row) {
getJob(row.jobId).then(response => {
this.form = response.data;
this.openView = true;
});
},
/** 任务日志列表查询 */
handleJobLog() {
this.$router.push("/job/system/log");
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.relationList = [];
this.open = true;
this.title = "添加任务";
},
//
handleDetails(row) {
this.detailsShow = true;
this.handleUpdate(row)
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.updateMD5List = ''
getJob(row.jobId).then(response => {
this.form = response.data;
this.relationList = this.form.list
this.relationList.forEach(v => {
v.guid = this.getGuid();
});
this.updateMD5List = md5(JSON.stringify(this.relationList));
this.open = true;
this.title = "修改任务";
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.jobId != undefined) {
const listA = [...this.relationList]
this.form.list = this.updateMD5List === md5(JSON.stringify(this.relationList)) ? [] : this.relationList
updateJob(this.form).then(response => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
})
} else {
if (this.relationList.length < 1) {
this.msgError("至少需要一条设备数据!");
} else {
this.form.list = this.relationList
addJob(this.form).then(response => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const jobIds = row.jobId;
this.$confirm("是否删除该选项", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return delJob(jobIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有定时任务数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportJob(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>

View File

@ -1,416 +0,0 @@
<template>
<div class="autocontrol-job-params">
<el-row :gutter="15">
<el-col :span="11">
<span>设备</span>
<el-input
style="width: 80%;"
:disabled="disabled"
v-model="form.deviceName"
placeholder="请输入内容"
@focus="deviceFocus"
></el-input>
</el-col>
<el-col :span="11">
<span>分组</span>
<el-select v-model="form.cmdKey" :disabled="disabled" style="width: 85%;" @change="cmdChange" placeholder="请选择">
<el-option
v-for="item in cmdListOption"
:key="item.cmdKey"
:label="item.cmdName"
:value="item.cmdKey"
></el-option>
</el-select>
</el-col>
<el-col :span="2">
<el-button
@click="delThisInfo()"
v-show="disabled === false"
:disabled="deleteButtonD"
type="text"
icon="el-icon-delete-solid"
style="
font-size: 20px;
margin-top: 0px;
padding-bottom: 1px;
color: #f36464;
"
></el-button>
</el-col>
<el-col :span="24" v-show="comdlistOption && comdlistOption.length > 0">
<div class="param-wrap">
<el-form
:model="property"
v-if="comdlistOption && comdlistOption.length > 0"
ref="loginForm"
label-width="120px"
width="100%"
>
<el-col
:span="comdlistOption.length === 1 ? 24:12"
v-for="paramsItem in comdlistOption"
:key="paramsItem.funId"
>
<el-form-item :label="paramsItem.funName + ''" :prop="paramsItem.funKey">
<el-select
:disabled="disabled"
style="width: 100%;"
v-model="property[paramsItem.funKey]"
v-if="paramsItem.funValidType === 'ENUM'"
clearable
>
<el-option
v-for="(keys, valus) in strtoJson(paramsItem.funObj)"
:key="valus"
:label="keys"
:value="valus"
></el-option>
</el-select>
<el-input-number
style="width: 100%;"
:disabled="disabled"
v-model="property[paramsItem.funKey]"
v-else-if="paramsItem.funValidType === 'RANGE' && (paramsItem.funDataType === 'FLOAT' || paramsItem.funDataType === 'INT32')"
:max="paramsItem.funValMax || 0"
:min="paramsItem.funValMin || 0"
clearable
></el-input-number>
<el-input-number
style="width: 100%;"
clearable
:disabled="disabled"
v-model="property[paramsItem.funKey]"
v-else-if="paramsItem.funValidType === 'NOT' && (paramsItem.funDataType === 'FLOAT' || paramsItem.funDataType === 'INT32')"
></el-input-number>
<el-input
clearable
style="width: 100%;"
:disabled="disabled"
v-else-if="paramsItem.funDataType === 'TEXT'"
v-model="property[paramsItem.funKey]"
/>
</el-form-item>
</el-col>
</el-form>
</div>
</el-col>
</el-row>
<el-dialog
title="选择"
:visible.sync="selectTableShow"
width="75%"
top="10vh"
class="select-table-dialog"
:close-on-click-modal="false"
append-to-body
>
<select-table-wrap
v-if="selectTableShow"
:tableOption="tableSelectOption.tableOpt"
:queryOption="tableSelectOption.queryOpt"
:tableList="tableSelectOption.tableList"
@parentGetList="childGetList($event)"
:otherOption="tableSelectOption.otherOption"
@returnEvent="returnEvent($event)"
/>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="resuleClick"> </el-button>
<el-button size="mini" @click="() =>{selectTableShow = false}"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listDevice } from "@/api/iot/device";
import SelectTableWrap from "@/components/SelectTable/index";
import axios from "axios";
import { getToken } from "@/utils/auth";
import { basePlatformUrl } from '@/config/env'
import { getDeviceFunList, getDeviceCmdList } from "@/api/iot/device";
export default {
name: "DeviceParamWrap",
components: {
SelectTableWrap
},
props: ["paramsDevcie", "tempIndex", "deleteButtonD", "disabled"],
data() {
return {
tableSelectOption: {},
selectResult: {},
selectTableShow: false,
cmdListOption: [],
comdlistOption: [],
cmdId: "",
property: {},
farstInput: true,
form: {
deviceName: "",
deviceId: "",
prodId: "",
guid: "",
cmdKey: "",
property: ""
}
};
},
watch: {
property: {
handler(val, oldVal) {
if (this.property) {
this.form.property = JSON.stringify(this.property);
} else {
this.form.property = "";
}
this.reultEventFu();
},
deep: true
},
form: {
handler(val, oldVal) {
this.reultEventFu();
},
deep: true
}
},
created() {
this.form = this.paramsDevcie;
if (this.form.prodId) {
this.farstInput = false;
this.getCmdList();
}
},
methods: {
reultEventFu() {
this.form.guid = this.tempIndex;
this.$emit("resultEvent", { result: this.form, index: this.tempIndex });
},
delThisInfo() {
if (this.deleteButtonD === true) {
this.msgError("至少需要一条设备数据!");
} else {
this.form.guid = this.tempIndex;
this.$emit("delInfo", this.tempIndex);
}
},
strtoJson(str) {
return str ? JSON.parse(str.replace(/\\\"/g, '"')) : {};
},
cmdChange(val) {
for (var i = 0; i < this.cmdListOption.length; i++) {
if (val === this.cmdListOption[i]["cmdKey"]) {
this.cmdId = this.cmdListOption[i]["cmdId"];
this.getcomdlistOption();
break;
}
}
},
getcomdlistOption() {
this.comdlistOption = [];
const params = {
deviceId: this.form.deviceId,
cmdId: this.cmdId,
cmdType: "2"
}
getDeviceFunList(params).then(res => {
var result = {};
this.comdlistOption = res.data;
if (this.farstInput) {
this.property = {};
this.comdlistOption.forEach(v => {
if (!result[v.funKey]) {
result[v.funKey] = "";
}
});
this.property = result;
} else {
this.property = JSON.parse(this.form.property);
this.farstInput = true;
}
});
},
// id
getCmdList() {
const params = {
deviceId: this.form.deviceId,
cmdId: this.cmdId,
cmdType: "2"
}
getDeviceCmdList(params).then(res => {
this.cmdListOption = res.data;
if (this.form.cmdKey) {
this.cmdChange(this.form.cmdKey);
}
});
},
deviceFocus() {
this.openTableSelectDialog();
},
//
openTableSelectDialog() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "device"
},
queryOpt: {
disable: false,
labelWidth: "68px",
property: {
deviceName: "",
modelId: "",
parentId: 0,
deviceType: "GATEWAY_CONTROLLER"
},
page: {
pageSize: 10,
pageNum: 1,
total: 0
},
inline: true,
queryChilds: [
// {
// style: "",
// placeholder: "",
// clearable: true,
// label: "",
// type: "input",
// key: "deviceName",
// size: "small",
// value: ""
// }
]
},
tableOpt: {
loading: false,
rowKey: "deviceId",
selection: false,
maxHeight: "45vh",
childs: [
{
style: "",
label: "所属型号",
type: "",
prop: "modelName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "设备名称",
type: "",
prop: "deviceName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "设备Key",
type: "",
prop: "deviceKey",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "创建时间",
type: "time",
prop: "createTime",
align: "center",
width: "160",
"show-overflow-tooltip": false,
tempType: "span"
}
],
tableList: {
type: Array
}
},
tableList: []
};
this.selectTableShow = true;
},
//
returnEvent(data) {
if (data.type === "dblclick") {
this.form.deviceName = data.value.deviceName;
this.form.deviceId = data.value.deviceId;
this.form.prodId = data.value.prodKey;
this.form.deviceKey = data.value.deviceKey
this.selectTableShow = false;
this.form.cmdKey = "";
this.property = {};
this.comdlistOption = [];
this.getCmdList();
} else if (data.type === "click") {
this.selectResult = {};
this.selectResult.deviceId = data.value.deviceId;
this.selectResult.deviceName = data.value.deviceName;
this.selectResult.prodId = data.value.prodKey;
this.selectResult.deviceKey = data.value.deviceKey
}
},
//
resuleClick() {
this.form.deviceName = this.selectResult.deviceName;
this.form.deviceId = this.selectResult.deviceId;
this.form.prodId = this.selectResult.prodKey;
this.form.deviceKey = this.selectResult.deviceKey
this.selectTableShow = false;
this.form.cmdKey = "";
this.property = {};
this.comdlistOption = [];
this.getCmdList();
},
//
childGetList(data) {
this.deviceChildList(data);
},
deviceChildList(data) {
listDevice(Object.assign(data.page, data.param, { selected: 1 })).then(
response => {
this.tableSelectOption.tableList = response.rows;
this.tableSelectOption.queryOpt.page.total = Number(response.total);
}
);
}
}
};
</script>
<style lang="scss">
.autocontrol-job-params {
padding: 10px 5px;
background-color: #e4e3e3;
margin-top: 5px;
.param-wrap {
height: 100%;
width: 100%;
max-height: 200px;
overflow: auto;
/* border: 1px solid red; */
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
padding: 10px;
margin-top: 10px;
background: #99e4f59e;
box-shadow: 0px 0px 4px #6a6c6d9e;
}
}
</style>

View File

@ -1,298 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="任务名称" prop="jobName">
<el-input
v-model="queryParams.jobName"
placeholder="请输入任务名称"
clearable
size="small"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="任务组名" prop="jobGroup">
<el-select
v-model="queryParams.jobGroup"
placeholder="请任务组名"
clearable
size="small"
style="width: 240px"
>
<el-option
v-for="dict in jobGroupOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="执行状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择执行状态"
clearable
size="small"
style="width: 240px"
>
<el-option
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="执行时间">
<el-date-picker
v-model="dateRange"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['monitor:job:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
@click="handleClean"
v-hasPermi="['monitor:job:remove']"
>清空</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['monitor:job:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="jobLogList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="任务名称" align="left" prop="jobName" :show-overflow-tooltip="true" />
<el-table-column label="任务组名" align="center" prop="jobGroup" width="160" :formatter="jobGroupFormat" :show-overflow-tooltip="true" />
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
<el-table-column label="日志信息" align="center" prop="jobMessage" :show-overflow-tooltip="true" />
<el-table-column label="执行状态" align="center" prop="status" width="160" :formatter="statusFormat" />
<el-table-column label="执行时间" align="center" prop="createTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="150" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleView(scope.row)"
v-hasPermi="['monitor:job:query']"
>详细</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 调度日志详细 -->
<el-dialog title="调度日志详细" :visible.sync="open" width="700px" append-to-body>
<el-form ref="form" :model="form" label-width="100px" size="mini">
<el-row>
<el-col :span="12">
<el-form-item label="日志序号:">{{ form.jobLogId }}</el-form-item>
<el-form-item label="任务名称:">{{ form.jobName }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务分组:">{{ form.jobGroup }}</el-form-item>
<el-form-item label="执行时间:">{{ form.createTime }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="调用方法:">{{ form.invokeTarget }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="日志信息:">{{ form.jobMessage }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="执行状态:">
<div v-if="form.status == 0">正常</div>
<div v-else-if="form.status == 1">失败</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="异常信息:" v-if="form.status == 1">{{ form.exceptionInfo }}</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listJobLog, delJobLog, exportJobLog, cleanJobLog } from "@/api/iot/deviceJobLog";
export default {
name: "JobLog",
data() {
return {
//
loading: true,
//
ids: [],
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
jobLogList: [],
//
open: false,
//
dateRange: [],
//
form: {},
//
statusOptions: [],
//
jobGroupOptions: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
jobName: undefined,
jobGroup: undefined,
status: undefined
}
};
},
created() {
this.getList();
this.getDicts("sys_job_status").then(response => {
this.statusOptions = response.data;
});
this.getDicts("sys_job_group").then(response => {
this.jobGroupOptions = response.data;
});
},
methods: {
/** 查询调度日志列表 */
getList() {
this.loading = true;
listJobLog(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.jobLogList = response.rows;
this.total = response.total;
this.loading = false;
}
);
},
//
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, row.status);
},
//
jobGroupFormat(row, column) {
return this.selectDictLabel(this.jobGroupOptions, row.jobGroup);
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.jobLogId);
this.multiple = !selection.length;
},
/** 详细按钮操作 */
handleView(row) {
this.open = true;
this.form = row;
},
/** 删除按钮操作 */
handleDelete(row) {
const jobLogIds = this.ids;
this.$confirm('是否删除该选项', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return delJobLog(jobLogIds);
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
})
},
/** 清空按钮操作 */
handleClean() {
this.$confirm("是否确认清空所有调度日志数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return cleanJobLog();
}).then(() => {
this.getList();
this.msgSuccess("清空成功");
})
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有调度日志数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return exportJobLog(queryParams);
}).then(response => {
this.download(response.msg);
})
}
}
};
</script>

View File

@ -1,441 +0,0 @@
<template>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="手机号码" prop="phone">
<el-input
v-model="queryParams.phone"
placeholder="请输入手机号码"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="微信昵称" prop="mpNickName">
<el-input
v-model="queryParams.mpNickName"
placeholder="请输入微信昵称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:contacts:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:contacts:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="contactsList">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="姓名" align="left" prop="name" />
<el-table-column label="手机号码" align="left" prop="phone" />
<el-table-column label="微信昵称" align="left" prop="mpNickName" />
<el-table-column label="头像" align="center" width="50px" prop="mpAvatar">
<template slot-scope="scope">
<div class="demo-image__preview">
<el-image
v-if="scope.row.mpAvatar"
style="width: 35px; height: 35px"
:src="getIotFileUrl(scope.row.mpAvatar)"
:preview-src-list="[getIotFileUrl(scope.row.mpAvatar)]"
></el-image>
<span v-else>暂无</span>
</div>
</template>
</el-table-column>
<el-table-column
label="状态"
align="center"
width="120px"
prop="status"
:formatter="statusFormatter"
/>
<el-table-column
label="操作"
align="center"
width="300px"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:contacts:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-connection"
@click="handelBinding(scope.row)"
v-hasPermi="['iot:contacts:edit']"
>绑定微信</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-c-scale-to-original"
@click="handleUbind(scope.row)"
v-hasPermi="['iot:contacts:edit']"
>解绑微信</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:contacts:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改联系人对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="姓名:" prop="name">
<el-input v-model="form.name" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="手机号码:" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号码" />
</el-form-item>
<el-form-item label="状态:" >
<el-switch
v-model="form.status"
active-value='0'
inactive-value='1'
active-color="#13ce66"
inactive-color="#ff4949">
</el-switch>
</el-form-item>
<el-form-item label="描述:" >
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入描述" />
</el-form-item>
<!-- <el-form-item label="邮箱地址:" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱地址" />
</el-form-item>-->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 添加或修改联系人对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" title="授权扫二维码" :visible.sync="qrCodeDialogOpen" width="650px">
<div class="qrcode-wrap" v-if="qrCodeDialogOpen">
<div class="qr-wrap">
<img src="@/assets/images/gzhqr.jpg"/>
<span>第一步扫码关注公众号</span>
</div>
<el-button type="text" style="font-size: 20px;" icon="el-icon-d-arrow-right"></el-button>
<div class="qr-wrap">
<div id="qrcode"></div>
<span style="margin-top: 10px;">第二步扫码绑定微信</span>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" style="margin-right: 10px;" @click="qrCodeSubmit"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listContacts,
getContacts,
delContacts,
addContacts,
updateContacts,
exportContacts,
getqrcodeUrl,
contactsUbind
} from "@/api/iot/contacts";
import { getIotFileUrl } from "@/utils/hciot";
import QRCode from "qrcodejs2";
import gzhqr from "@/assets/images/gzhqr.jpg"
export default {
name: "Contacts",
components: {},
data() {
return {
gzhqr,
qrCodeDialogOpen: false,
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
contactsList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
name: null,
phone: null,
mpNickName: null
},
//
form: {},
//
rules: {
name: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
phone: [
{ required: true, message: "手机号码不能为空", trigger: "blur" },
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码",
trigger: "blur"
}
],
email: [
{
type: "email",
message: "'请输入正确的邮箱地址",
trigger: ["blur", "change"]
}
]
}
};
},
created() {
this.getList();
},
methods: {
getIotFileUrl,
statusFormatter(row) {
return row.status === '0' ? '正常' : '停用';
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
/** 查询联系人列表 */
getList() {
this.loading = true;
listContacts(this.queryParams).then(response => {
this.contactsList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
name: null,
phone: null,
email: null,
remark: null,
status: '0'
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加联系人";
},
//
handelBinding(row) {
getqrcodeUrl({
id: row.id
}).then(res => {
this.qrCodeDialogOpen = true;
setTimeout(() => {
this.qrcode(res.data);
}, 50);
});
},
qrcode(url) {
if (!document.querySelector("#qrcode")) {
return;
}
// document.querySelector('#qrcode').innerHtml = ""
let qrcode = new QRCode("qrcode", {
width: 250,
height: 250,
text: url
});
},
qrCodeSubmit() {
this.qrCodeDialogOpen = false;
this.getList();
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
getContacts(id).then(response => {
this.form = response.data;
this.form.status = this.form.status.toString();
this.open = true;
this.title = "修改联系人";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateContacts(this.form).then(response => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addContacts(this.form).then(response => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
//
handleUbind(row) {
const ids = row.id
this.$confirm("是否解除此微信号绑定?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return contactsUbind(ids);
})
.then(() => {
this.getList();
this.msgSuccess("解绑成功");
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return delContacts(ids);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有联系人数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportContacts(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>
<style lang="scss">
.qrcode-wrap {
width: 100%;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
.qr-wrap {
height: 100%;
display: flex;
width: 45%;
-webkit-box-align: self-start;
-ms-flex-align: self-start;
align-items: self-start;
flex-wrap: wrap;
justify-content: center;
padding-top: 10px;
}
}
#qrcode {
}
</style>

View File

@ -1,935 +0,0 @@
<template>
<div class="app-container iot-device">
<component :is="componectVal" :sourceId="sourceId"></component>
<div v-show="componectVal === ''">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<!-- <el-form-item label="所属型号" prop="modelId">
<el-select v-model="queryParams.modelId" placeholder="所属型号" clearable size="small" @change="handleQuery">
<el-option
:label="doct.modelName"
v-for="doct in queryModelOpt"
:key="doct.modelId"
:value="doct.modelId"
/>
</el-select>
</el-form-item>-->
<el-form-item label="型号名称" prop="modelName">
<el-input
v-model="queryParams.modelName"
placeholder="请输入型号名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="设备名称" prop="deviceName">
<el-input
v-model="queryParams.deviceName"
placeholder="请输入设备名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="设备状态" prop="deviceState">
<el-select
v-model="queryParams.deviceState"
placeholder="请选择设备状态"
@change="handleQuery"
clearable
size="small"
>
<el-option
:label="keys"
v-for="(keys, vals) in deviceStatusOpt"
:key="vals"
:value="vals"
/>
</el-select>
</el-form-item>
<el-form-item label="设备类型" prop="deviceType">
<el-select
v-model="queryParams.deviceType"
placeholder="请选择设备类型"
@change="handleQuery"
clearable
size="small"
>
<el-option
:label="keys"
:value="vals"
v-for="(keys, vals) in deviceTypeList"
:key="vals"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:device:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="deviceList"
:default-sort="{prop: 'createTime', order: 'descending'}"
@sort-change="sortChange"
>
<el-table-column
type="index"
label="序号"
align="center"
:index="indexFormatter"
width="80px"
></el-table-column>
<el-table-column label="设备名称" align="left" prop="deviceName" />
<el-table-column label="所属型号" align="left" prop="modelName" />
<el-table-column label="设备key" align="left" prop="deviceKey" />
<el-table-column label="设备类型" align="left" width="120px" prop="deviceTypeName" />
<!-- <el-table-column label="父设备" align="left" prop="parentName" /> -->
<el-table-column label="设备状态" align="center" width="120" prop="deviceState">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.deviceState === 'ONLINE'">在线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OFFLINE'">离线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OUTLINE'">脱线</el-tag>
<el-tag type="info" v-else-if="scope.row.deviceState === 'UNACTIVE'">未激活</el-tag>
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
sortable="custom"
width="160px"
prop="createTime"
/>
<el-table-column
label="操作"
align="center"
width="200px"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-search"
@click="handleDetails(scope.row)"
>详情</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:device:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:device:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 添加或修改设备对话框 -->
<el-dialog
class="eldialog-wrap"
:close-on-click-modal="false"
:title="title"
:visible.sync="open"
width="500px"
>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="所属型号:" prop="modelId">
<el-input
v-model="form.modelName"
placeholder="点击选择型号"
@focus="openModelTableSelectDialog()"
/>
</el-form-item>
<el-form-item label="设备类型:" prop="deviceType">
<el-select
disabled
v-model="form.deviceType"
style="width: 100%;"
placeholder="请选择设备类型"
clearable
>
<el-option
:label="keys"
:value="vals"
v-for="(keys, vals) in deviceTypeList"
:key="vals"
/>
</el-select>
</el-form-item>
<el-form-item label="父设备:" prop="parentId" v-if="form.deviceType === 'MINIATURE_BREAKER'">
<el-input
v-model="form.parentName"
placeholder="点击选择父设备"
@focus="openTableSelectDialog()"
/>
</el-form-item>
<el-form-item label="线路类型:" prop="lineType" v-if="form.deviceType === 'MINIATURE_BREAKER'">
<el-select v-model="form.lineType" style="width: 100%;" placeholder="请选择线路类型" clearable>
<el-option :label="keys" :value="vals" v-for="(keys, vals) in lineTypeOpt" :key="vals" />
</el-select>
</el-form-item>
<el-form-item label="设备名称:" prop="deviceName">
<el-input v-model="form.deviceName" placeholder="请输入设备名称" />
</el-form-item>
<el-form-item label="设备KEY" prop="deviceKey">
<el-input v-model="form.deviceKey" placeholder="请输入设备KEY" />
</el-form-item>
<el-form-item label="参数设置:">
<span style="color: red; font-size: 12px;">*注意锁定即参数不可修改未锁则可以修改</span>
<div class="form-params-wrap">
<param-wrap ref="paramWrap" typeKeys v-if="open"></param-wrap>
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
<el-dialog
title="选择"
:visible.sync="selectTableShow"
width="75%"
top="10vh"
class="select-table-dialog"
:close-on-click-modal="false"
>
<select-table-wrap
v-if="selectTableShow"
:tableOption="tableSelectOption.tableOpt"
:queryOption="tableSelectOption.queryOpt"
:tableList="tableSelectOption.tableList"
@parentGetList="childGetList($event)"
:otherOption="tableSelectOption.otherOption"
@returnEvent="returnEvent($event)"
/>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="resuleClick"> </el-button>
<el-button size="mini" @click="() =>{selectTableShow = false}"> </el-button>
</div>
</el-dialog>
<div class="to-home-wrap2" @click="toTableClick" v-show="componectVal !== ''">
<el-button icon="el-icon-d-arrow-left" title="返回列表" circle>返回列表</el-button>
</div>
</div>
</template>
<script>
import {
listDevice,
getDevice,
delDevice,
addDevice,
updateDevice,
exportDevice,
listDeviceTypeList
} from "@/api/iot/device";
import { listModel, getModel } from "@/api/iot/model";
import SelectTableWrap from "@/components/SelectTable/index";
import DetailsWrap from "./profile/details";
import ParamWrap from "@/components/ParamWrap/deviceParam";
import axios from "axios";
const deviceStatusOpt = {
ONLINE: "在线",
OFFLINE: "离线",
OUTLINE: "脱线",
UNACTIVE: "未激活"
};
const lineTypeOpt = {
MAIN: "总路",
BRANCH: "支路"
};
export default {
name: "Device",
components: {
SelectTableWrap,
DetailsWrap,
ParamWrap
},
data() {
return {
deviceStatusOpt,
lineTypeOpt,
sourceId: "",
componectVal: "",
selectTableShow: false,
tableSelectOption: {},
selectResult: {},
queryModelOpt: [],
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
deviceList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
modelId: null,
parentId: null,
deviceName: null,
deviceState: null,
deviceType: null,
modelName: null,
orderByColumn: "createTime",
isAsc: "desc"
},
//
form: {},
//
rules: {
modelId: [
{ required: true, message: "所属型号不能为空", trigger: "blur" }
],
deviceType: [
{ required: true, message: "设备类型不能为空", trigger: "blur" }
],
parentId: [
{ required: true, message: "父设备不能为空", trigger: "blur" }
],
deviceName: [
{ required: true, message: "设备名称不能为空", trigger: "blur" }
],
lineType: [
{ required: true, message: "线路类型不能为空", trigger: "blur" }
],
deviceKey: [
{
required: true,
validator: this.chenking_deviceKey,
trigger: "blur"
}
]
},
deviceTypeList: {}
};
},
created() {
this.getDeviceTypeList();
this.initGetModelList();
this.getList();
},
methods: {
sortChange(column) {
const sort = {
isAsc: column.order === "descending" ? "desc" : "asc",
orderByColumn: column.prop
};
this.queryParams = Object.assign(this.queryParams, sort);
this.handleQuery();
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
handleDetails(row) {
this.sourceId = row.deviceId;
this.componectVal = "DetailsWrap";
},
//
toTableClick() {
this.componectVal = "";
},
//
openModelTableSelectDialog() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "model"
},
queryOpt: {
disable: false,
labelWidth: "68px",
params: {
protocolType: "",
modelName: ""
},
page: {
pageSize: 10,
pageNum: 1,
total: 0
},
inline: true,
queryChilds: [
{
style: "",
placeholder: "型号名称",
clearable: true,
label: "型号名称",
type: "input",
key: "modelName",
size: "small",
value: ""
},
{
style: "",
placeholder: "协议类型",
clearable: true,
label: "协议类型",
type: "select",
key: "protocolType",
size: "small",
value: "",
options: [
{
key: "IOTOS",
label: "iot平台",
value: "IOTOS"
},
{
key: "ONENET",
label: "ONENET",
value: "ONENET"
}
],
optionKey: {
key: "key",
label: "label",
value: "value"
}
}
]
},
tableOpt: {
loading: false,
rowKey: "deviceId",
selection: false,
maxHeight: "45vh",
childs: [
{
style: "",
label: "厂商名称",
type: "",
prop: "vendorName",
align: "left",
width: "200",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "型号名称",
type: "",
prop: "modelName",
align: "left",
width: "200",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "设备类型",
type: "",
prop: "deviceTypeName",
align: "left",
width: "120",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "产品PK",
type: "",
prop: "prodKey",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "产品密钥",
type: "",
prop: "prodSecret",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
}
],
tableList: {
type: Array
}
},
tableList: []
};
this.selectTableShow = true;
},
//
openTableSelectDialog() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "device"
},
queryOpt: {
disable: false,
labelWidth: "68px",
params: {
deviceName: "",
modelId: "",
parentId: 0,
deviceType: "GATEWAY_CONTROLLER"
},
page: {
pageSize: 10,
pageNum: 1,
total: 0
},
inline: true,
queryChilds: [
{
style: "",
placeholder: "设备名称",
clearable: true,
label: "设备名称",
type: "input",
key: "deviceName",
size: "small",
value: ""
}
]
},
tableOpt: {
loading: false,
rowKey: "deviceId",
selection: false,
maxHeight: "45vh",
childs: [
{
style: "",
label: "所属型号",
type: "",
prop: "modelName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "设备名称",
type: "",
prop: "deviceName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "设备Key",
type: "",
prop: "deviceKey",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "创建时间",
type: "time",
prop: "createTime",
align: "center",
width: "160",
"show-overflow-tooltip": false,
tempType: "span"
}
],
tableList: {
type: Array
}
},
tableList: []
};
this.selectTableShow = true;
},
//
childGetList(data) {
if (data.otherOption.tableType === "device") {
this.deviceChildList(data);
} else if (data.otherOption.tableType === "model") {
this.modelChildList(data);
}
},
initGetModelList() {
listModel({
pageNum: 1,
pageSize: 99999
}).then(response => {
this.queryModelOpt = response.rows;
});
},
modelChildList(data) {
listModel(Object.assign(data.page, data.param, { selected: 1 })).then(
response => {
this.tableSelectOption.tableList = response.rows;
this.tableSelectOption.queryOpt.page.total = Number(response.total);
}
);
},
deviceChildList(data) {
listDevice(Object.assign(data.page, data.param, { selected: 1 })).then(
response => {
this.tableSelectOption.tableList = response.rows;
this.tableSelectOption.queryOpt.page.total = Number(response.total);
}
);
},
// id
getModelInfoById(modelId) {
getModel(modelId).then(res => {
this.$refs.paramWrap.setList(res.data.paramList || []);
});
},
//
returnEvent(data) {
if (data.type === "dblclick") {
if (data.otherOption.tableType === "device") {
this.form.parentId = data.value.deviceId;
this.form.parentName = data.value.deviceName;
} else if (data.otherOption.tableType === "model") {
this.getModelInfoById(data.value.modelId);
this.form.modelId = data.value.modelId;
this.form.modelName = data.value.modelName;
this.form.deviceType = data.value.deviceType;
this.form.prodKey = data.value.prodKey;
this.deviceTypeChange(this.form.deviceType);
}
this.selectTableShow = false;
} else if (data.type === "click") {
this.selectResult = {};
if (data.otherOption.tableType === "device") {
this.selectResult.parentId = data.value.deviceId;
this.selectResult.parentName = data.value.deviceName;
} else if (data.otherOption.tableType === "model") {
this.selectResult.modelId = data.value.modelId;
this.selectResult.modelName = data.value.modelName;
this.selectResult.deviceType = data.value.deviceType;
// this.selectResult.paramList = data.value.paramList;
this.selectResult.prodKey = data.value.prodKey;
}
this.selectResult.tableType = data.otherOption.tableType;
}
},
//
resuleClick() {
if (this.selectResult.tableType === "device") {
this.form.parentId = this.selectResult.parentId;
this.form.parentName = this.selectResult.parentName;
} else if (this.selectResult.tableType === "model") {
this.form.modelId = this.selectResult.modelId;
this.form.prodKey = this.selectResult.prodKey;
this.form.modelName = this.selectResult.modelName;
this.form.deviceType = this.selectResult.deviceType;
this.deviceTypeChange(this.form.deviceType);
this.getModelInfoById(this.selectResult.modelId);
// this.$refs.paramWrap.setList(this.selectResult.paramList || []);
}
this.selectTableShow = false;
},
deviceTypeChange(val) {
if (val !== "MINIATURE_BREAKER") {
this.form.parentId = 0;
this.form.parentName = "";
} else if (!val) {
this.form.parentId = "";
this.form.parentName = "";
}
},
//
getDeviceTypeList() {
listDeviceTypeList().then(response => {
this.deviceTypeList = response.data;
});
},
/** 查询设备列表 */
getList() {
this.loading = true;
listDevice(this.queryParams).then(response => {
this.deviceList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
modelId: null,
modelName: "",
parentName: "",
parentId: null,
deviceName: null,
deviceType: null,
paramList: [],
deviceKey: "",
lineType: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加设备";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const deviceId = row.deviceId || this.ids;
const _this = this;
getDevice(deviceId).then(response => {
_this.form = response.data;
_this.open = true;
_this.title = "修改设备";
setTimeout(() => {
_this.$refs.paramWrap.setList(response.data.paramList || []);
}, 100);
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.form.paramList = this.$refs.paramWrap.getResult();
this.form.lineType =
this.form.deviceType === "MINIATURE_BREAKER"
? this.form.lineType
: undefined;
if (this.form.deviceId != null) {
updateDevice(this.form).then(response => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addDevice(this.form).then(response => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const deviceIds = row.deviceId || this.ids;
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return delDevice(deviceIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有设备数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportDevice(queryParams);
})
.then(response => {
this.download(response.msg);
});
},
chenking_deviceKey(rule, value, callback) {
const isExp = /^[A-Z a-z 0-9 _ - $]{0,36}$/;
if (this.form.deviceKey && !isExp.test(this.form.deviceKey)) {
callback(new Error("格式不正确(数字英文字母大小写36个字符)"));
} else {
callback();
}
}
}
};
</script>
<style lang="scss">
.iot-device {
.eldialog-wrap {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-dialog__body {
padding: 0px;
}
.el-form {
padding: 20px;
padding-right: 40px;
}
.el-dialog__footer {
height: 60px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding: 0px;
padding-top: 15px;
.el-button + .el-button {
margin-right: 10px;
}
.el-button {
padding-top: 8px;
}
}
.form-params-wrap {
height: 100%;
width: calc(100% + 110px);
position: relative;
top: 15px;
left: -90px;
max-height: 250px;
overflow: auto;
padding: 10px;
border: 1px solid #009688;
border-radius: 5px;
}
}
.to-home-wrap2 {
width: 100px;
height: 30px;
position: absolute;
right: 30px;
top: 30px;
display: flex;
justify-content: center;
align-items: center;
z-index: 100;
color: #656363;
font-size: 20px;
cursor: default;
.el-button--medium.is-circle {
width: 25px;
height: 20px;
padding: 0;
background: #f26a6a;
color: #fff;
font-size: 16px;
border-radius: 5px;
height: 30px;
width: 100%;
font-size: 14px;
}
}
.to-home-wrap2:hover {
color: #1890ff;
font-size: 30px;
}
}
.form-params-wrap::-webkit-scrollbar {
/*滚动条整体样式*/
width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
height: 5px;
}
.form-params-wrap::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
box-shadow: inset 0 0 5px #c4c4c4;
background: #dededea6;
}
.form-params-wrap::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px #f6f6f6;
border-radius: 10px;
background: #ffffff;
}
</style>

View File

@ -1,562 +0,0 @@
<template>
<div class="iot-child-device">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="设备名称" prop="deviceName">
<el-input
v-model="queryParams.deviceName"
placeholder="请输入设备名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="deviceList">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="设备名称" align="left" prop="deviceName" />
<el-table-column label="所属型号" align="left" prop="modelName" />
<el-table-column label="设备key" align="left" prop="deviceKey" />
<el-table-column label="设备类型" align="left" width="120px" prop="deviceTypeName" />
<el-table-column label="设备状态" align="center" width="120" prop="deviceStatus">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.deviceState === 'ONLINE'">在线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OFFLINE'">离线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OUTLINE'">脱线</el-tag>
<el-tag type="info" v-else-if="scope.row.deviceState === 'UNACTIVE'">未激活</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" width="160px" prop="createTime" />
<el-table-column
label="操作"
align="center"
width="200px"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-search"
@click="handleDetails(scope.row)"
>详情</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:device:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改设备对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="所属型号:" prop="modelId">
<el-input
v-model="form.modelName"
placeholder="点击选择型号"
@focus="openModelTableSelectDialog()"
/>
</el-form-item>
<el-form-item label="设备类型:" prop="deviceType">
<el-select
disabled
v-model="form.deviceType"
style="width: 100%;"
placeholder="请选择设备类型"
clearable
>
<el-option
:label="keys"
:value="vals"
v-for="(keys, vals) in deviceTypeList"
:key="vals"
/>
</el-select>
</el-form-item>
<!-- <el-form-item label="父设备:" prop="parentId" >
<el-input
v-model="form.parentName"
placeholder="点击选择父设备"
disabled
/>
</el-form-item> -->
<el-form-item label="设备名称:" prop="deviceName">
<el-input v-model="form.deviceName" placeholder="请输入设备名称" />
</el-form-item>
<el-form-item label="设备KEY" prop="deviceKey">
<el-input :disabled="title === '修改子设备'" v-model="form.deviceKey" placeholder="请输入设备KEY" />
</el-form-item>
<el-form-item label="线路类型:" prop="lineType">
<el-select
v-model="form.lineType"
style="width: 100%;"
placeholder="请选择线路类型"
clearable
>
<el-option
:label="keys"
:value="vals"
v-for="(keys, vals) in lineTypeOpt"
:key="vals"
/>
</el-select>
</el-form-item>
<el-form-item label="参数设置:">
<span style="color: red; font-size: 12px;">*注意锁定即参数不可修改未锁则可以修改</span>
<div class="form-params-wrap">
<param-wrap ref="paramWrap" typeKeys="" v-if="open"></param-wrap>
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="open = false"> </el-button>
</div>
</el-dialog>
<el-dialog
title="选择"
:visible.sync="selectTableShow"
width="75%"
top="10vh"
class="select-table-dialog"
:close-on-click-modal="false"
>
<select-table-wrap
v-if="selectTableShow"
:tableOption="tableSelectOption.tableOpt"
:queryOption="tableSelectOption.queryOpt"
:tableList="tableSelectOption.tableList"
@parentGetList="childGetList($event)"
:otherOption="tableSelectOption.otherOption"
@returnEvent="returnEvent($event)"
/>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="resuleClick"> </el-button>
<el-button size="mini" @click="() =>{selectTableShow = false}"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listDevice,
delDevice,
addDevice,
updateDevice,
listDeviceTypeList,
getDevice
} from "@/api/iot/device";
import { listModel, getModel } from "@/api/iot/model";
import SelectTableWrap from "@/components/SelectTable/index";
import ParamWrap from "@/components/ParamWrap/deviceParam";
const lineTypeOpt = {
MAIN:'总路',
BRANCH: '支路'
}
export default {
name: '',
props: ['sourceId', 'pDevcieInfo'],
components: {
SelectTableWrap,
ParamWrap
},
data() {
return {
lineTypeOpt,
selectTableShow: false,
tableSelectOption: {},
selectResult: {},
//
queryParams: {
pageNum: 1,
pageSize: 10,
modelId: null,
parentId: null,
deviceCode: null,
deviceName: null,
deviceStatus: null,
deviceKey: null,
deviceType: null,
parentId: ''
},
open: false,
title: '',
showSearch: true,
//
deviceList: [],
total: 0,
form: {},
//
rules: {
modelId: [
{ required: true, message: "所属型号不能为空", trigger: "blur" }
],
deviceType: [
{ required: true, message: "设备类型不能为空", trigger: "blur" }
],
parentId: [
{ required: true, message: "父设备不能为空", trigger: "blur" }
],
deviceName: [
{ required: true, message: "设备名称不能为空", trigger: "blur" }
],
lineType: [
{ required: true, message: "线路类型不能为空", trigger: "blur" }
],
deviceKey: [
{
required: true,
validator: this.chenking_deviceKey,
trigger: "blur"
}
]
},
deviceTypeList: []
}
},
created() {
this.getDeviceTypeList();
this.getList()
},
methods: {
chenking_deviceKey(rule, value, callback) {
const isExp = /^[A-Z a-z 0-9 _ - $]{0,36}$/;
if (this.form.deviceKey && !isExp.test(this.form.deviceKey)) {
callback(new Error("格式不正确(数字英文字母大小写36个字符)"));
} else {
callback();
}
},
//
childGetList(data) {
this.modelChildList(data);
},
//
returnEvent(data) {
if (data.type === "dblclick") {
this.getModelInfoById(data.value.modelId);
this.form.modelId = data.value.modelId;
this.form.modelName = data.value.modelName;
this.form.deviceType = data.value.deviceType;
this.form.prodKey = data.value.prodKey;
// this.deviceTypeChange(this.form.deviceType);
this.selectTableShow = false;
} else if (data.type === "click") {
this.selectResult = {};
this.selectResult.modelId = data.value.modelId;
this.selectResult.modelName = data.value.modelName;
this.selectResult.deviceType = data.value.deviceType;
this.selectResult.prodKey = data.value.prodKey;
}
},
// id
getModelInfoById(modelId) {
getModel(modelId).then(res => {
this.$refs.paramWrap.setList(res.data.paramList || []);
});
},
modelChildList(data) {
listModel(Object.assign(data.page, data.param, { selected: 1 })).then(
response => {
this.tableSelectOption.tableList = response.rows;
this.tableSelectOption.queryOpt.page.total = Number(response.total);
}
);
},
//
resuleClick() {
this.form.modelId = this.selectResult.modelId;
this.form.prodKey = this.selectResult.prodKey;
this.form.modelName = this.selectResult.modelName;
this.form.deviceType = this.selectResult.deviceType;
// this.deviceTypeChange(this.form.deviceType);
this.getModelInfoById(this.selectResult.modelId);
this.selectTableShow = false;
},
//
openModelTableSelectDialog() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "model"
},
queryOpt: {
disable: false,
labelWidth: "68px",
params: {
modelName: "",
modelCode: "",
deviceType: 'MINIATURE_BREAKER',
protocolType: ''
},
page: {
pageSize: 10,
pageNum: 1,
total: 0
},
inline: true,
queryChilds: [
{
style: "",
placeholder: "型号名称",
clearable: true,
label: "型号名称",
type: "input",
key: "modelName",
size: "small",
value: ""
},
{
style: "",
placeholder: "协议类型",
clearable: true,
label: "协议类型",
type: "select",
key: "protocolType",
size: "small",
value: "",
options: [
{
key: 'IOTOS',
label: "iot平台",
value: 'IOTOS'
},
{
key: 'ONENET',
label: "ONENET",
value: 'ONENET'
}
],
optionKey: {
key: 'key',
label: "label",
value: 'value'
}
}
]
},
tableOpt: {
loading: false,
rowKey: "deviceId",
selection: false,
maxHeight: "45vh",
childs: [
{
style: "",
label: "厂商名称",
type: "",
prop: "vendorName",
align: "left",
width: "200",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "型号名称",
type: "",
prop: "modelName",
align: "left",
width: "200",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "设备类型",
type: "",
prop: "deviceTypeName",
align: "left",
width: "120",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "产品PK",
type: "",
prop: "prodKey",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "产品密钥",
type: "",
prop: "prodSecret",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
}
],
tableList: {
type: Array
}
},
tableList: []
};
this.selectTableShow = true;
},
//
getDeviceTypeList() {
listDeviceTypeList().then(response => {
this.deviceTypeList = response.data;
});
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加子设备";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const _this = this;
getDevice(row.deviceId).then(response => {
_this.form = response.data;
_this.open = true;
_this.title = "修改子设备";
setTimeout(() => {
_this.$refs.paramWrap.setList(response.data.paramList || []);
}, 100);
});
},
indexFormatter(val) {
return val + 1 + ((this.queryParams.pageNum - 1) * this.queryParams.pageSize);
},
/** 查询设备列表 */
getList() {
this.loading = true;
this.queryParams.parentId = this.sourceId
listDevice(this.queryParams).then(response => {
this.deviceList = response.rows;
this.total = response.total;
this.loading = false;
});
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
handleDetails(row) {
if (row.deviceId) {
this.$emit('toChildEvent', { deviceId: row.deviceId })
}
},
/** 删除按钮操作 */
handleDelete(row) {
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return delDevice(row.deviceId);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.form.paramList = this.$refs.paramWrap.getResult();
this.form.lineType = this.form.deviceType === 'MINIATURE_BREAKER' ? this.form.lineType : undefined;
if (this.form.deviceId != null) {
updateDevice(this.form).then(response => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addDevice(this.form).then(response => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
//
reset() {
this.form = {
modelId: null,
modelName: "",
parentName: this.pDevcieInfo.deviceName,
parentId: this.pDevcieInfo.deviceId,
deviceName: '',
deviceType: 'MINIATURE_BREAKER',
paramList: [],
deviceKey: "",
lineType: ''
};
this.resetForm("form");
},
},
}
</script>

View File

@ -1,893 +0,0 @@
<template>
<div class="iot-project-details-warp">
<div class="info-tabs">
<div class="breadcrumb-wrap" v-show="breadcrumbList.length > 1">
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item v-for="(item, index) in breadcrumbList" :key="index">
<span @click="deviceClick(item, index)" :class="item.deviceId === deviceId ? 'breadcrumb-span show-wrap' : 'breadcrumb-span'">{{item.deviceName}}</span>
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<el-tabs
v-model="activeName"
:class="breadcrumbList.length > 1 ? 'children-wrap' : ''"
type="border-card"
>
<el-tab-pane label="运行状态" name="runingState">
<div class="tabs-body protocol-wrap">
<device-run-starts-wrap
v-if="devudeRunState"
:sourceId="deviceId"
:deviceInfo="infoData"
:prodId="infoData.prodKey"
></device-run-starts-wrap>
</div>
</el-tab-pane>
<el-tab-pane label="设备信息" name="info">
<div class="tabs-body">
<info-wrap :infoData="infoData" @updateInfo="updateInfo($event)" />
</div>
</el-tab-pane>
<el-tab-pane label="子设备" name="child" v-if="infoData.deviceType === 'GATEWAY_CONTROLLER'">
<div class="tabs-body">
<child-device
v-if="activeName === 'child'"
:pDevcieInfo="infoData"
:sourceId="infoData.deviceId"
@toChildEvent="toNewDevice"
></child-device>
</div>
</el-tab-pane>
<el-tab-pane label="触发器" name="trigger">
<div class="tabs-body protocol-wrap">
<trigger-wrap :sourceId="infoData.deviceId" :deviceInfo="infoData"></trigger-wrap>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script>
import { getDevice } from "@/api/iot/device";
import InfoWrap from "./info";
import ChildDevice from "./childDevice";
import DeviceRunStartsWrap from "@/views/profile/DeviceRunStarts/index";
import TriggerWrap from "@/views/profile/DeviceTrigger/index";
export default {
name: "DetailsWrap",
props: ["sourceId"],
components: {
InfoWrap,
ChildDevice,
DeviceRunStartsWrap,
TriggerWrap
},
data() {
return {
infoData: {},
activeName: "runingState",
breadcrumbList: [],
tempType: "bs",
deviceId: "",
devudeRunState: false
};
},
created() {
this.deviceId = this.sourceId;
this.deviceInfo();
},
methods: {
//
deviceClick(row, index) {
if (row.deviceId === this.deviceId) {
return;
}
const leng = this.breadcrumbList.length - 1;
this.breadcrumbList.splice(index + 1, leng);
this.activeName = "runingState";
this.deviceId = row.deviceId;
this.devudeRunState = false;
this.deviceInfo();
},
//
deviceInfo() {
getDevice(this.deviceId).then(response => {
this.infoData = response.data;
if (this.breadcrumbList.length <= 0) {
this.breadcrumbList.push(this.infoData);
}
for (var i = 0; i < this.breadcrumbList.length; i++) {
if (
this.breadcrumbList[i]["deviceId"] === this.infoData["deviceId"]
) {
this.breadcrumbList[i] = this.infoData;
} else if (i === this.breadcrumbList.length - 1) {
this.breadcrumbList.push(this.infoData);
}
}
this.devudeRunState = true;
});
},
toNewDevice(data) {
this.tempType = "children";
this.deviceId = data.deviceId;
this.devudeRunState = false;
this.deviceInfo();
this.activeName = "runingState";
},
updateInfo(...data) {
this.deviceInfo();
}
}
};
</script>
<style lang="scss">
.iot-project-details-warp {
.breadcrumb-wrap {
position: absolute;
top: 15px;
z-index: 10;
left: 20px;
width: 90%;
overflow: hidden;
.breadcrumb-span:hover {
color: #1890ff;
cursor: default;
}
.show-wrap {
color: #1890ff;
}
}
.product-release-dialog {
.title-i {
font-size: 20px;
color: #9c9a9a;
line-height: 18px;
}
.i-color {
color: rgb(0, 193, 222);
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.top-tigs {
background: #fbfbfc;
border: 1px solid #ecedee;
padding: 20px;
margin-bottom: 25px;
color: #999;
}
.form-bottom-prod-details {
margin-top: 40px;
height: 10px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.bottom-div {
height: 70px;
font-size: 12px;
border: 1px solid #ecedee;
margin: -1px;
}
.one-div {
width: 15%;
float: left;
border-right: 1px solid #ecedee;
height: 30px;
line-height: 30px;
/* padding-left: 10px; */
text-align: center;
font-size: 18px;
height: 70px;
line-height: 76px;
text-align: center;
font-size: 18px;
}
.two-div {
width: calc(100% - 36%);
float: left;
padding: 22px 10px 10px 10px;
font-size: 12px;
}
.there-div {
width: 10%;
float: left;
padding-top: 28px;
}
.four-div {
width: 5%;
float: left;
padding-top: 28px;
}
}
.heard {
padding: 20px 40px 0;
background-color: #fff;
height: 112px;
padding: 0px;
}
.info-title {
margin-top: 0px;
margin-bottom: 16px;
line-height: 29px;
overflow: hidden;
height: 30px;
.title {
float: left;
font-size: 20px;
margin: 0 8px 0 0;
line-height: 28px;
}
.el-button--small,
.el-button--small.is-round {
padding: 8px 15px;
float: right;
}
}
.info-icon {
margin-top: -70px;
float: left;
width: 101px;
border: 1px dotted rgb(205, 203, 203);
height: 101px;
.image {
width: 100px;
height: 100px;
}
}
.info-des {
font-size: 14px;
width: 100%;
float: left;
.info-row {
overflow: hidden;
display: block;
text-overflow: ellipsis;
line-height: 20px;
white-space: nowrap;
.label {
color: #aaa;
}
.centent {
color: #999;
margin-right: 8px;
}
}
}
.info-tabs {
position: relative;
box-sizing: border-box;
.el-tabs__content {
height: calc(100vh - 191px);
overflow: auto;
}
.el-tabs__header {
background-color: #fff;
position: relative;
// top: -10px;
.el-tabs__nav-wrap {
margin-left: 0px;
.el-tabs__item {
font-size: 16px;
}
}
}
.el-tabs__nav-scroll {
height: 65px;
padding-top: 25px;
padding-left: 15px;
background: #e4eaf3;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
background: #fff;
color: #333;
border: 0;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item {
// border-color: red;
color: #909399;
background: #d3deec;
border-radius: 8px 8px 0 0;
border-bottom: 0;
margin-left: 15px;
}
.tabs-body {
margin-left: 0px;
margin-right: 0px;
padding: 0px;
overflow: hidden;
background-color: #fff;
margin-bottom: 0px;
}
.protocol-wrap {
.el-tabs__nav-scroll {
height: auto;
padding-top: 0;
padding-left: 0;
background: #fff;
}
}
}
.children-wrap {
.el-tabs__header {
.el-tabs__nav-scroll {
height: 85px;
.el-tabs__nav {
margin-top: 20px;
}
}
}
}
.child-table {
margin-top: 25px;
// margin-left: 20px;
margin-right: 0px;
padding: 0px;
overflow: hidden;
background-color: #fff;
}
}
.product-release-dialog {
.title-i {
font-size: 20px;
color: #9c9a9a;
line-height: 18px;
}
.i-color {
color: rgb(0, 193, 222);
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.top-tigs {
background: #fbfbfc;
border: 1px solid #ecedee;
padding: 20px;
margin-bottom: 25px;
color: #999;
}
.form-bottom-prod-details {
margin-top: 15px;
height: 30px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.bottom-div {
height: 70px;
font-size: 12px;
border: 1px solid #ecedee;
margin: 0px;
}
.one-div {
width: 15%;
float: left;
border-right: 1px solid #ecedee;
height: 30px;
line-height: 30px;
/* padding-left: 10px; */
text-align: center;
font-size: 18px;
height: 70px;
line-height: 76px;
text-align: center;
font-size: 18px;
}
.two-div {
width: calc(100% - 36%);
float: left;
padding: 22px 10px 10px 10px;
font-size: 12px;
}
.there-div {
width: 10%;
float: left;
padding-top: 28px;
}
.four-div {
width: 5%;
float: left;
padding-top: 28px;
}
}
.product-detail-info {
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.form-buttons-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.el-form-item--mini.el-form-item,
.el-form-item--small.el-form-item {
margin-bottom: 10px;
margin-left: 60px;
}
.el-form--label-top .el-form-item__label {
padding: 0 0 9px;
margin-top: 10px;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
line-height: 17px;
}
.avue-input-number,
.el-cascader,
.el-date-editor.el-input,
.el-date-editor.el-input__inner,
.el-select {
width: 100%;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.form-buttons-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
}
}
.product-topic-dialog {
.top-tips {
height: 150px;
margin: 20px;
margin-top: 30px;
margin-right: 0px;
border: 1px solid #00c1df;
padding: 10px 10px 0;
background: #e6f9fc;
display: flex;
border-radius: 3px;
padding-left: 20px;
padding-top: 20px;
margin-bottom: 0px;
}
.el-form-item__error {
left: 80px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 90%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.el-select {
width: 100%;
}
.form-buttonx-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.product-fun-dialog {
.insert-div {
width: 100%;
margin-bottom: 10px;
padding-top: 10px;
padding-left: 30px;
}
.el-transfer-panel {
// margin-left: 10px;
width: 225px;
}
.el-transfer__buttons {
padding: 0px 10px;
}
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.fw {
.el-input--mini {
width: 155px;
}
}
.el-form-item__error {
left: 120px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 92%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.form-buttonb-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.product-custom-fun {
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.fw {
.el-input--mini {
width: 155px;
}
}
.el-form-item__error {
left: 120px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 92%;
}
.el-select {
width: 100%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.form-buttona-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.product-prop-standard-dialog {
.insert-div {
width: 100%;
margin-bottom: 10px;
padding-top: 10px;
padding-left: 30px;
}
.el-transfer-panel {
// margin-left: 10px;
width: 225px;
}
.el-transfer__buttons {
padding: 0px 10px;
}
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.fw {
.el-input--mini {
width: 155px;
}
}
.el-form-item__error {
left: 120px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 92%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.form-buttonb-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.product-prop-custom-dialog {
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.fw {
.el-input--mini {
width: 155px;
}
}
.el-form-item__error {
left: 120px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 92%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.form-buttona-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.model-function-dialog {
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.fw {
.el-input--mini {
width: 155px;
}
}
.el-form-item__error {
left: 120px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 92%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.el-select {
width: 100%;
}
.form-bottom-prod-details {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.sr {
.el-form-item {
margin-bottom: -17px;
width: 100%;
}
}
.iot-project-details-warp .info-tabs .el-tabs__content::-webkit-scrollbar {
/*滚动条整体样式*/
width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
height: 3px;
}
.iot-project-details-warp
.info-tabs
.el-tabs__content::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
box-shadow: inset 0 0 5px #9e9d9d;
background: #ffffff;
}
.iot-project-details-warp
.info-tabs
.el-tabs__content::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px #f6f6f6;
border-radius: 10px;
background: #ffffff;
}
</style>

View File

@ -1,402 +0,0 @@
<template>
<div class="product-details-info">
<div class="group-list-info">
<div class="top">
<div class="top-label">
<svg-icon icon-class="A_product1" style="margin-right: 2px; height: 20px; width: 20px;" />设备信息
<span
v-if="updateState === false"
style="margin: 0px 15px 0 10px; font-weight: 200; font-size: 14px;"
>设备名称{{infoData.deviceName}}</span>
<span
v-if="updateState === true"
style="margin: 0px 5px 0 10px; font-weight: 200; font-size: 14px;"
>设备名称</span>
<el-input v-if="updateState === true" v-model="temp.deviceName" />
<el-button
v-if="updateState === false"
type="text"
@click.stop="handleUpdate(infoData)"
>编辑</el-button>
<el-button v-if="updateState === true" type="text" @click.stop="submit">确定</el-button>
</div>
<!-- <div class="top-button">
<el-button type="primary" @click="download" size="small">下载本地模拟器</el-button>
</div> -->
</div>
</div>
<div class="group-list-table">
<div class="table-row">
<div class="table-row-col">
<div class="title">设备ID</div>
<div class="content">
<span class="name">{{infoData.deviceKey}}</span>
<el-button type="text" size="small" @click.stop="copyTexts(infoData.deviceKey)">复制</el-button>
</div>
</div>
<div class="table-row-col">
<div class="title">型号</div>
<div class="content">
<span class="group-id">{{infoData.modelName}}</span>
</div>
</div>
<div class="table-row-col">
<div class="title">设备密码</div>
<div class="content">
<span v-show="!showDevicePassword" class="centent">********</span>
<span
v-show="showDevicePassword"
class="centent secret"
:title="infoData.devicePassword"
>{{infoData.devicePassword}}</span>
<el-button
v-show="!showDevicePassword"
type="text"
size="small"
@click.stop="showDevicePassword = true"
>显示</el-button>
<el-button
v-show="showDevicePassword"
type="text"
size="small"
@click.stop="copyTexts(infoData.devicePassword)"
>复制</el-button>
<el-button
v-show="showDevicePassword"
type="text"
size="small"
@click.stop="showDevicePassword = false"
>隐藏</el-button>
</div>
</div>
</div>
<div class="table-row">
<div class="table-row-col">
<div class="title">产品PK</div>
<div class="content">
<span class="name">{{infoData.prodKey}}</span>
<el-button type="text" size="small" @click.stop="copyTexts(infoData.prodKey)">复制</el-button>
</div>
</div>
<div class="table-row-col">
<div class="title">设备KEY</div>
<div class="content">{{infoData.deviceKey }}</div>
</div>
<div class="table-row-col">
<div class="title">devSecret</div>
<div class="content">
<span v-show="!showProdSecret" class="centent">********</span>
<span
v-show="showProdSecret"
class="centent secret"
:title="infoData.deviceSecret"
>{{infoData.deviceSecret}}</span>
<el-button
v-show="!showProdSecret"
type="text"
size="small"
@click.stop="showProdSecret = true"
>显示</el-button>
<el-button
v-show="showProdSecret"
type="text"
size="small"
@click.stop="copyTexts(infoData.deviceSecret)"
>复制</el-button>
<el-button
v-show="showProdSecret"
type="text"
size="small"
@click.stop="showProdSecret = false"
>隐藏</el-button>
</div>
</div>
</div>
<div class="table-row">
<div class="table-row-col">
<div class="title">设备类型</div>
<div class="content">{{infoData.deviceTypeName}}</div>
</div>
<div class="table-row-col">
<div class="title">当前状态</div>
<div class="content" v-if="infoData.deviceState === 'ONLINE'">在线</div>
<div class="content" v-else-if="infoData.deviceState === 'OFFLINE'">离线</div>
<div class="content" v-else-if="infoData.deviceState === 'OUTLINE'">脱线</div>
<div class="content" v-else-if="infoData.deviceState === 'UNACTIVE'">未激活</div>
</div>
<div class="table-row-col">
<div class="title">创建时间</div>
<div class="content">{{infoData.createTime || '--'}}</div>
</div>
</div>
<div class="table-row">
<div class="table-row-col" style="flex: 3 1 0%;">
<div class="title">设备图片</div>
<div class="content">--</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { updateDevice } from "@/api/iot/device";
export default {
name: "DeviceInfo",
props: ["infoData"],
data() {
const validatorNull = (rule, value, callback) => {
callback();
};
return {
updateState: false,
prodtreeOptions: [],
modelList: [],
showProdSecret: false,
showDevicePassword: false,
temp: {
deviceName: "",
deviceId: undefined
},
rules: {}
};
},
methods: {
copyTexts(val) {
this.copeFu(val, this);
},
//
handleUpdate(row) {
this.newTemp();
this.temp = Object.assign({}, row);
this.updateState = true;
},
newTemp() {
this.temp = {
deviceName: "",
deviceId: undefined
};
},
// --
download() {},
submit() {
if (this.temp.deviceName && this.temp.deviceId) {
updateDevice(this.temp).then(response => {
this.updateState = false;
if (response.code === 200) {
this.msgSuccess("修改成功");
}
this.$emit("updateInfo", {
deviceId: this.infoData.deviceId,
deviceName: this.infoData.deviceName
});
});
} else {
this.msgError("设备名称不能为空!");
}
}
}
};
</script>
<style lang="scss">
.product-details-info {
.group-list-info {
.top {
text-align: left;
width: 100%;
float: left;
height: 40px;
.top-label {
float: left;
width: calc(100% - 200px);
font-size: 16px;
font-weight: 700;
color: #373d41;
display: flex;
align-items: center;
justify-content: flex-start;
.el-input--medium {
width: 150px;
}
.el-button--text {
padding: 8px 12px;
color: #333;
}
.el-button--text:hover {
background-color: #d1dbe6;
border-radius: 0;
color: #1890ff;
}
}
.top-button {
float: left;
text-align: right;
width: 200px;
}
}
display: flex;
justify-content: space-between;
margin-bottom: 6px;
flex: 1;
.title {
line-height: 30px;
font-size: 16px;
font-weight: 700;
color: #373d41;
display: flex;
align-items: center;
flex: 1;
}
}
.group-list-table {
border-top: 1px solid #d4d4d4;
border-left: 1px solid #d4d4d4;
.table-row {
display: flex;
width: 100%;
.table-row-col {
display: flex;
flex: 1 1 0%;
overflow: hidden;
font-size: 14px;
.title {
width: 180px;
height: 48px;
color: rgb(116, 119, 122);
display: flex;
align-items: center;
background: rgb(250, 250, 252);
border-bottom: 1px solid #d4d4d4;
border-right: 1px solid #d4d4d4;
padding: 0px 12px;
margin-bottom: 0px;
font-size: 15px;
font-weight: 100;
}
.content {
display: flex;
justify-content: flex-start;
align-items: center;
flex: 1 1 0%;
overflow: hidden;
color: #666;
border-bottom: 1px solid #d4d4d4;
border-right: 1px solid #d4d4d4;
padding: 0px 12px;
.name {
display: inline-block;
max-width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
cursor: pointer;
overflow: hidden;
}
.group-id {
margin-right: 8px;
}
.notice-item {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 6px;
background: #d3d5d5;
margin-right: 3px;
}
.n {
background: #0fc18a;
}
.secret {
display: block;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
}
.eldaialog-wrap {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-radio {
width: 90px;
}
.el-dialog__body {
padding: 0px;
}
.cus-itme.el-form-item--mini .el-form-item__content {
margin-left: 0px !important;
}
.select {
// width: 92%;
display: inline-block;
width: calc(92% - 50px);
display: inline-block;
float: left;
margin-right: 4px;
.el-input {
width: 100%;
}
}
.el-textarea {
width: 92%;
width: calc(92% - 50px);
width: 100%;
}
.el-input {
width: 92%;
width: calc(92% - 50px);
width: 100%;
}
.info {
width: 100%;
float: left;
margin-bottom: 15px;
/* margin-top: 13px; */
margin-left: -10px;
font-size: 16px;
font-weight: 600;
}
.span {
width: calc(100% - 91px);
display: block;
content: "";
height: 1px;
/* width: 100%; */
border-top: 1px dashed #ecedee;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
margin-left: 80px;
margin-top: -10px;
}
.form-buttons-div {
height: 45px;
display: flex;
justify-content: flex-end;
align-items: center;
padding-right: 10px;
border-top: 1px solid #747373;
}
}
.group-dialog {
.el-dialog__header {
border-bottom: 1px solid #ccc;
}
.el-dialog__body {
padding: 28px;
.el-form-item {
margin-bottom: 0;
.el-form-item__label {
line-height: 30px;
}
}
}
}
}
</style>

View File

@ -1,757 +0,0 @@
<template>
<div class="app-container iot-model">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="型号名称" prop="modelName">
<el-input
v-model="queryParams.modelName"
placeholder="型号名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="产品PK" prop="prodKey">
<el-input
v-model="queryParams.prodKey"
placeholder="产品PK"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="协议类型" prop="protocolType">
<el-select v-model="queryParams.protocolType" @change="handleQuery" placeholder="请选择协议类型" clearable size="small">
<el-option
:label="keys"
:value="vals"
v-for="(keys, vals) in protocolTypeOpt"
:key="keys"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:model:add']"
>新增</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="modelList"
:default-sort="{prop: 'createTime', order: 'descending'}"
@sort-change="sortChange"
>
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="型号名称" align="left" width="200px" prop="modelName" />
<el-table-column label="厂商名称" align="left" width="200px" prop="vendorName" />
<el-table-column label="产品PK" align="left" width="200px" prop="prodKey" />
<el-table-column label="产品密钥" align="left" prop="prodSecret" />
<el-table-column label="设备类型" align="center" prop="deviceType" width="120px">
<template slot-scope="scope">
<span v-text="deviceTypeList[scope.row.deviceType]"></span>
</template>
</el-table-column>
<el-table-column label="协议类型" align="center" prop="protocolType" width="120px">
<template slot-scope="scope">
<span v-text="protocolTypeOpt[scope.row.protocolType]"></span>
</template>
</el-table-column>
<el-table-column label="设备状态" align="center" prop="modelStatus" width="100px">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.modelStatus === '0'">启用</el-tag>
<el-tag type="danger" v-else>禁用</el-tag>
</template>
</el-table-column>
<el-table-column
label=" 创建时间"
align="center"
sortable="custom"
prop="createTime"
width="150px"
/>
<el-table-column
width="160px"
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:model:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:model:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改型号对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="厂商:" prop="vendorId">
<el-input
v-model="form.vendorName"
placeholder="点击选择厂商"
@focus="openTableSelectDialog()"
/>
</el-form-item>
<el-form-item label="协议类型:" prop="protocolType">
<el-select
v-model="form.protocolType"
style="width: 100%;"
placeholder="请选择协议类型"
size="small"
>
<el-option
:label="keys"
:value="vals"
v-for="(keys, vals) in protocolTypeOpt"
:key="vals"
/>
</el-select>
</el-form-item>
<el-form-item label="产品PK" prop="prodKey">
<el-input
v-model="form.prodKey"
placeholder="点击选择产品"
@focus="openProductTableSelectDialog()"
/>
</el-form-item>
<el-form-item label="型号名称:" prop="modelName">
<el-input v-model="form.modelName" placeholder="请输入型号名称" />
</el-form-item>
<el-form-item label="设备类型:" prop="deviceType">
<el-select
v-model="form.deviceType"
style="width: 100%;"
placeholder="请选择设备类型"
clearable
size="small"
>
<el-option
:label="keys"
:value="vals"
v-for="(keys, vals) in deviceTypeList"
:key="vals"
/>
</el-select>
</el-form-item>
<el-form-item label="参数设置:" v-show="form.deviceType">
<span style="color: red; font-size: 12px;">*注意锁定即参数不可修改未锁则可以修改</span>
<div class="form-params-wrap">
<param-wrap ref="paramWrap" :typeKeys="form.deviceType"></param-wrap>
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" @click="submitForm"> </el-button>
<el-button @click="cancel" size="mini"> </el-button>
</div>
</el-dialog>
<el-dialog
title="选择"
:visible.sync="selectTableShow"
width="75%"
top="10vh"
class="select-table-dialog"
:close-on-click-modal="false"
>
<select-table-wrap
v-if="selectTableShow"
:tableOption="tableSelectOption.tableOpt"
:queryOption="tableSelectOption.queryOpt"
:tableList="tableSelectOption.tableList"
@parentGetList="childGetList($event)"
:otherOption="tableSelectOption.otherOption"
@returnEvent="returnEvent($event)"
/>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="resuleClick"> </el-button>
<el-button size="mini" @click="() =>{selectTableShow = false}"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listModel,
getModel,
delModel,
addModel,
updateModel,
exportModel,
listProductList
} from "@/api/iot/model";
import { listVendor } from "@/api/iot/vendor";
import { listDeviceTypeList } from "@/api/iot/device";
import SelectTableWrap from "@/components/SelectTable/index";
import ParamWrap from "@/components/ParamWrap/deviceParam";
const deviceStartsOpt = {
0: "禁用",
1: "启用"
};
const protocolTypeOpt = {
IOTOS: "iot平台",
ONENET: "ONENET"
};
export default {
name: "Model",
components: {
SelectTableWrap,
ParamWrap
},
data() {
return {
protocolTypeOpt,
selectTableShow: false,
tableSelectOption: {},
selectResult: {},
deviceStartsOpt,
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
modelList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
vendorId: null,
modelName: null,
modelCode: null,
prodKey: null,
prodSecret: null,
protocolType: null,
orderByColumn: "createTime",
isAsc: "desc"
},
//
form: {},
//
rules: {
vendorId: [
{ required: true, message: "厂商不能为空", trigger: "blur" }
],
prodKey: [
{ required: true, message: "产品PK不能为空", trigger: "blur" }
],
modelName: [
{ required: true, message: "型号名称不能为空", trigger: "blur" }
],
deviceType: [
{ required: true, message: "设备类型不能为空", trigger: "blur" }
]
},
deviceTypeList: {}
};
},
created() {
this.getDeviceTypeList();
this.getList();
},
methods: {
sortChange(column) {
const sort = {
isAsc: column.order === "descending" ? "desc" : "asc",
orderByColumn: column.prop
};
this.queryParams = Object.assign(this.queryParams, sort);
this.handleQuery();
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
//
getDeviceTypeList() {
listDeviceTypeList().then(response => {
this.deviceTypeList = response.data;
});
},
openProductTableSelectDialog() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "product"
},
queryOpt: {
disable: false,
labelWidth: "68px",
params: {
protocolType: this.form.protocolType
},
page: {
pageSize: 10,
pageNum: 1,
total: 0
},
inline: true,
queryChilds: [
// {
// style: "",
// placeholder: "",
// clearable: true,
// label: "",
// type: "input",
// key: "prodName",
// size: "small",
// value: ""
// }
]
},
tableOpt: {
loading: false,
rowKey: "prodId",
selection: false,
maxHeight: "45vh",
childs: [
{
style: "",
label: "产品名称",
type: "",
prop: "prodName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "产品PK",
type: "",
prop: "prodId",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
// {
// style: "",
// label: "ProdSecret",
// type: "",
// prop: "prodSecret",
// align: "left",
// width: "",
// "show-overflow-tooltip": false,
// tempType: "span"
// },
// {
// style: "",
// label: "",
// type: "",
// prop: "prodNodeTypeName",
// align: "left",
// width: "",
// "show-overflow-tooltip": false,
// tempType: "span"
// }
],
tableList: {
type: Array
}
},
tableList: []
};
this.selectTableShow = true;
},
//
openTableSelectDialog() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "vendor"
},
queryOpt: {
disable: false,
labelWidth: "68px",
params: {
vendorName: "",
vendorAddress: "",
vendorContact: ""
},
page: {
pageSize: 10,
pageNum: 1,
total: 0
},
inline: true,
queryChilds: [
{
style: "",
placeholder: "厂商名称",
clearable: true,
label: "厂商名称",
type: "input",
key: "vendorName",
size: "small",
value: ""
},
{
style: "",
placeholder: "厂商地址",
clearable: true,
label: "厂商地址",
type: "input",
key: "vendorAddress",
size: "small",
value: ""
},
{
style: "",
placeholder: "联系方式",
clearable: true,
label: "联系方式",
type: "input",
key: "vendorContact",
size: "small",
value: ""
}
]
},
tableOpt: {
loading: false,
rowKey: "deviceId",
selection: false,
maxHeight: "45vh",
childs: [
{
style: "",
label: "厂商名称",
type: "",
prop: "vendorName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: " 联系方式",
type: "",
prop: "vendorContact",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "厂商地址",
type: "",
prop: "vendorAddress",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
}
],
tableList: {
type: Array
}
},
tableList: []
};
this.selectTableShow = true;
},
//
childGetList(data) {
if (data.otherOption.tableType === "vendor") {
this.vendorChildList(data);
} else if (data.otherOption.tableType === "product") {
this.productChildList(data);
}
},
productChildList(data) {
listProductList(
Object.assign(data.page, data.param, { selected: 1 })
).then(response => {
this.tableSelectOption.tableList = response.data;
// this.tableSelectOption.queryOpt.page.total = Number(response.total);
});
},
vendorChildList(data) {
listVendor(Object.assign(data.page, data.param, { selected: 1 })).then(
response => {
this.tableSelectOption.tableList = response.rows;
this.tableSelectOption.queryOpt.page.total = Number(response.total);
}
);
},
//
returnEvent(data) {
this.selectResult = {};
if (data.type === "dblclick") {
if (data.otherOption.tableType === "vendor") {
this.form.vendorId = data.value.vendorId;
this.form.vendorName = data.value.vendorName;
} else if (data.otherOption.tableType === "product") {
this.form.prodKey = data.value.prodId;
this.form.prodSecret = data.value.prodSecret;
}
this.selectTableShow = false;
} else if (data.type === "click") {
if (data.otherOption.tableType === "vendor") {
this.selectResult.vendorId = data.value.vendorId;
this.selectResult.vendorName = data.value.vendorName;
} else if (data.otherOption.tableType === "product") {
this.selectResult.prodKey = data.value.prodId;
this.selectResult.prodSecret = data.value.prodSecret;
}
this.selectResult.tableType = data.otherOption.tableType;
}
},
//
resuleClick() {
if (this.selectResult.tableType === "vendor") {
this.form.vendorId = this.selectResult.vendorId;
this.form.vendorName = this.selectResult.vendorName;
} else if (this.selectResult.tableType === "product") {
this.form.prodKey = this.selectResult.prodKey;
this.form.prodSecret = this.selectResult.prodSecret;
}
this.selectTableShow = false;
},
/** 查询型号列表 */
getList() {
this.loading = true;
listModel(this.queryParams).then(response => {
this.modelList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
vendorId: null,
modelName: null,
vendorName: "",
prodKey: "",
deviceType: "",
paramList: [],
protocolType: 'IOTOS'
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.modelId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加型号";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const modelId = row.modelId || this.ids;
const _this = this;
getModel(modelId).then(response => {
_this.form = response.data;
_this.open = true;
_this.title = "修改型号";
setTimeout(() => {
_this.$refs.paramWrap.setList(response.data.paramList || []);
}, 100);
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.form.paramList = this.$refs.paramWrap.getResult();
if (this.form.modelId != null) {
updateModel(this.form).then(response => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addModel(this.form).then(response => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const modelIds = row.modelId || this.ids;
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return delModel(modelIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有型号数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportModel(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>
<style lang="scss">
.iot-model {
.eldialog-wrap {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-dialog__body {
padding: 0px;
}
.el-form {
padding: 20px;
padding-right: 40px;
}
.el-dialog__footer {
height: 60px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding: 0px;
padding-top: 15px;
.el-button + .el-button {
margin-right: 10px;
}
.el-button {
padding-top: 8px;
}
}
.form-params-wrap {
height: 100%;
width: calc(100% + 110px);
position: relative;
top: 15px;
left: -90px;
max-height: 250px;
overflow: auto;
padding: 10px;
border: 1px solid #009688;
border-radius: 5px;
}
}
}
.form-params-wrap::-webkit-scrollbar {
/*滚动条整体样式*/
width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
height: 5px;
}
.form-params-wrap::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
box-shadow: inset 0 0 5px #c4c4c4;
background: #dededea6;
}
.form-params-wrap::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px #f6f6f6;
border-radius: 10px;
background: #ffffff;
}
</style>

View File

@ -1,447 +0,0 @@
<template>
<div class="app-container iot-param">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="功率限额" prop="powerLimit">
<el-input
v-model="queryParams.powerLimit"
placeholder="请输入功率限额"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="电压下限" prop="voltageMin">
<el-input
v-model="queryParams.voltageMin"
placeholder="请输入电压下限"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="电压上限" prop="voltageMax">
<el-input
v-model="queryParams.voltageMax"
placeholder="请输入电压上限"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="电流限额" prop="currentLimit">
<el-input
v-model="queryParams.currentLimit"
placeholder="请输入电流限额"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="漏电流限" prop="leakageCurrentLimit">
<el-input
v-model="queryParams.leakageCurrentLimit"
placeholder="请输入漏电流限额"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="温度限额" prop="temperatureLimit">
<el-input
v-model="queryParams.temperatureLimit"
placeholder="请输入温度限额"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item> -->
<el-form-item>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:param:add']"
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['iot:param:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['iot:param:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:param:export']"
>导出</el-button
>
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="paramList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="序号" align="center" prop="index" width="50" />
<el-table-column label="来源ID" align="center" prop="sourceId" />
<el-table-column
label="功率限额(单位:W)"
align="center"
prop="powerLimit"
/>
<el-table-column
label="电压下限(单位:V)"
align="center"
prop="voltageMin"
/>
<el-table-column
label="电压上限(单位:V)"
align="center"
prop="voltageMax"
/>
<el-table-column
label="电流限额(单位:A)"
align="center"
prop="currentLimit"
/>
<el-table-column
label="漏电流限额(单位:mA)"
align="center"
prop="leakageCurrentLimit"
/>
<el-table-column
label="温度限额(单位:℃)"
align="center"
prop="temperatureLimit"
/>
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:param:edit']"
>修改</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:param:remove']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改设备参数对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="功率限额(单位:W)" prop="powerLimit">
<el-input
v-model="form.powerLimit"
placeholder="请输入功率限额(单位:W)"
/>
</el-form-item>
<el-form-item label="电压下限(单位:V)" prop="voltageMin">
<el-input
v-model="form.voltageMin"
placeholder="请输入电压下限(单位:V)"
/>
</el-form-item>
<el-form-item label="电压上限(单位:V)" prop="voltageMax">
<el-input
v-model="form.voltageMax"
placeholder="请输入电压上限(单位:V)"
/>
</el-form-item>
<el-form-item label="电流限额(单位:A)" prop="currentLimit">
<el-input
v-model="form.currentLimit"
placeholder="请输入电流限额(单位:A)"
/>
</el-form-item>
<el-form-item label="漏电流限额(单位:mA)" prop="leakageCurrentLimit">
<el-input
v-model="form.leakageCurrentLimit"
placeholder="请输入漏电流限额(单位:mA)"
/>
</el-form-item>
<el-form-item label="温度限额(单位:℃)" prop="temperatureLimit">
<el-input
v-model="form.temperatureLimit"
placeholder="请输入温度限额(单位:℃)"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listParam,
getParam,
delParam,
addParam,
updateParam,
exportParam
} from "@/api/iot/param";
export default {
name: "Param",
components: {},
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
paramList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
powerLimit: null,
voltageMin: null,
voltageMax: null,
currentLimit: null,
leakageCurrentLimit: null,
temperatureLimit: null
},
//
form: {},
//
rules: {}
};
},
created() {
this.getList();
},
methods: {
/** 查询设备参数列表 */
getList() {
this.loading = true;
listParam(this.queryParams).then(response => {
this.paramList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
sourceId: null,
powerLimit: null,
voltageMin: null,
voltageMax: null,
currentLimit: null,
leakageCurrentLimit: null,
temperatureLimit: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.sourceId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加设备参数";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const sourceId = row.sourceId || this.ids;
getParam(sourceId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改设备参数";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.sourceId != null) {
updateParam(this.form).then(response => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addParam(this.form).then(response => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const sourceIds = row.sourceId || this.ids;
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return delParam(sourceIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有设备参数数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportParam(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>
<style lang="scss">
.iot-model {
.eldialog-wrap {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-dialog__body {
padding: 0px;
}
.el-form {
padding: 20px;
padding-right: 40px;
}
.el-dialog__footer {
height: 60px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding: 0px;
padding-top: 15px;
.el-button + .el-button {
margin-right: 10px;
}
.el-button {
padding-top: 8px;
}
}
}
}
</style>

View File

@ -1,779 +0,0 @@
<template>
<div class="app-container iot-project">
<component :is="componectVal" :sourceId="sourceId"></component>
<div v-show="componectVal === ''">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="项目名称" prop="projectName">
<el-input
v-model="queryParams.projectName"
placeholder="请输入项目名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="项目类型" prop="industry">
<el-select v-model="queryParams.industry" placeholder="请选择项目类型" clearable size="small">
<el-option
v-for="dict in projectTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:project:add']"
>新增</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="projectList"
:default-sort="{prop: 'createTime', order: 'descending'}"
@sort-change="sortChange"
>
<el-table-column
type="index"
label="序号"
align="center"
:index="indexFormatter"
width="80px"
></el-table-column>
<el-table-column label="项目名称" width="200px" align="left" prop="projectName" />
<el-table-column
label="项目类型"
align="center"
width="150"
:formatter="statusFormat"
prop="industry"
/>
<el-table-column label="行政区划" align="left" width="250" prop="regionalismFullName" />
<el-table-column label="项目地址" align="left" prop="projectAddress" />
<el-table-column
label="创建时间"
sortable="custom"
align="center"
width="160"
prop="createTime"
/>
<el-table-column
label="操作"
align="center"
width="200"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-search"
@click="handleDetails(scope.row)"
>详情</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:project:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:project:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改项目对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" width="720px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="项目名称:" prop="projectName">
<el-input v-model="form.projectName" placeholder="请输入项目名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目类型:" prop="industry">
<el-select v-model="form.industry" style="width: 100%;" placeholder="请选择项目类型">
<el-option
v-for="dict in projectTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="电价合同:" >
<el-input v-model="form.contractName" suffix-icon="el-icon-caret-bottom" @focus="inputFocusContract()" placeholder="请输入电价合同" />
</el-form-item>
<el-form-item label="行政区划" prop="regionalismId">
<!-- <el-input v-model="form.regionalismId" placeholder="请输入行政区划代码" /> -->
<treeselect
@select="regionalismChange"
:disable-branch-nodes="true"
v-model="form.regionalismId"
:options="regionalismOption"
:normalizer="normalizer"
placeholder="请选择上级行政区划"
/>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="项目经度" prop="projectLng">
<el-input v-model="form.projectLng" disabled placeholder="请输入项目经度" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目纬度" prop="projectLat">
<el-input v-model="form.projectLat" disabled placeholder="请输入项目纬度" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="项目地址" prop="projectAddress">
<el-input
v-model="form.projectAddress"
@blur="mapAddressFromPoint"
placeholder="请输入项目地址"
>
<el-popover
slot="suffix"
placement="left-start"
title="地图选择坐标"
width="730"
trigger="manual"
v-model="visible"
>
<i slot="reference" class="el-icon-map-location" @click="mapClick"></i>
<!-- 地图模块选择和设置 -->
<slot>
<el-row>
<el-col :span="7">
<span>经度{{mapForm.lng}}</span>
</el-col>
<el-col :span="7">
<span>纬度{{mapForm.lat}}</span>
</el-col>
<el-col :span="10">
<span>地址{{mapForm.address}}</span>
</el-col>
</el-row>
<shop-location
v-if="visible === true"
style="height: 300px;"
:mapCenter="mapCenter"
:draggable="true"
@mapEvent="mapEvent"
:zoom="zoom"
/>
<div
style="
width: 100%;
height: 50px;
display: flex;
align-items: center;
justify-content: flex-end;
margin-top: 5px;
"
>
<el-button type="primary" @click="mapSureClick"> </el-button>
<el-button @click="visible = false"> </el-button>
</div>
</slot>
</el-popover>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
<el-dialog
title="选择"
:visible.sync="selectTableShow"
width="75%"
top="10vh"
class="select-table-dialog"
:close-on-click-modal="false"
>
<select-table-wrap
v-if="selectTableShow"
:tableOption="tableSelectOption.tableOpt"
:queryOption="tableSelectOption.queryOpt"
:tableList="tableSelectOption.tableList"
@parentGetList="childGetList($event)"
:otherOption="tableSelectOption.otherOption"
@returnEvent="returnEvent($event)"
/>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="resuleClick"> </el-button>
<el-button size="mini" @click="() =>{selectTableShow = false}"> </el-button>
</div>
</el-dialog>
<div class="to-home-wrap2" @click="toTableClick" v-show="componectVal !== ''">
<el-button icon="el-icon-d-arrow-left" title="返回列表" circle>返回列表</el-button>
</div>
</div>
</template>
<script>
import {
listProject,
getProject,
delProject,
addProject,
updateProject,
exportProject
} from "@/api/iot/project";
import {
listContract
} from "@/api/iot/contract";
import { listRegionalism } from "@/api/system/regionalism";
import { initMap, gjzCode } from "@/utils/latlngFromAddress.js";
import ShopLocation from "@/components/Amap/components/shopLocation/index";
import DetailsWrap from "./profile/details";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import SelectTableWrap from "@/components/SelectTable/index";
export default {
name: "Project",
components: {
ShopLocation,
Treeselect,
DetailsWrap,
SelectTableWrap
},
data() {
return {
selectTableShow: false,
tableSelectOption: {},
selectResult: {},
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
projectList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
projectName: null,
industry: null,
regionalismId: null,
projectAddress: null,
projectStatus: null,
orderByColumn: "createTime",
isAsc: "desc"
},
//
form: {},
//
rules: {
projectName: [
{ required: true, message: "项目名称不能为空", trigger: "blur" }
],
industry: [
{ required: true, message: "项目类型不能为空", trigger: "blur" }
],
regionalismId: [
{ required: true, message: "行政区划不能为空", trigger: "blur" }
],
projectAddress: [
{ required: true, message: "项目地址不能为空", trigger: "blur" }
],
projectLng: [
{ required: true, message: "经度不能为空", trigger: "blur" }
],
projectLat: [
{ required: true, message: "纬度不能为空", trigger: "blur" }
]
},
projectTypeOptions: [],
mapCenter: {
lng: 119.459889,
lat: 25.98974
},
baiduMapKey: "N05AG95Umzs3fouk6WpFqtGxcDlw0fRn",
zoom: 15,
BMap: null,
map: null,
visible: false,
mapForm: {},
//
regionalismOption: [],
componectVal: "",
sourceId: ""
};
},
created() {
this.getDicts("project_industry").then(response => {
this.projectTypeOptions = response.data;
});
this.getList();
this.getTreeselect();
},
methods: {
//
inputFocusContract() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "model"
},
queryOpt: {
disable: false,
labelWidth: "68px",
params: {
contractName: "",
modelCode: ""
},
page: {
pageSize: 10,
pageNum: 1,
total: 0
},
inline: true,
queryChilds: [
{
style: "",
placeholder: "合同名称",
clearable: true,
label: "合同名称",
type: "input",
key: "contractName",
size: "small",
value: ""
}
]
},
tableOpt: {
loading: false,
rowKey: "deviceId",
selection: false,
maxHeight: "45vh",
childs: [
{
style: "",
label: "合同名称",
type: "",
prop: "contractName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "计价类型",
type: "",
prop: "contractType",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "strType",
option: {
PEAK_VALLEY: "峰谷时段计价",
LADDER: "阶梯计价"
}
},
{
style: "",
label: "状态",
type: "",
prop: "status",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "text1"
}
],
tableList: {
type: Array
}
},
tableList: []
};
this.selectTableShow = true;
},
//
childGetList(data) {
listContract(Object.assign(data.page, data.param, { selected: 1 })).then(
response => {
this.tableSelectOption.tableList = response.rows;
this.tableSelectOption.queryOpt.page.total = Number(response.total);
}
);
},
//
returnEvent(data) {
if (data.type === "dblclick") {
this.form.contractId = data.value.contractId;
this.form.contractName = data.value.contractName;
this.selectTableShow = false;
} else if (data.type === "click") {
this.selectResult = {};
this.selectResult.contractId = data.value.contractId;
this.selectResult.contractName = data.value.contractName;
}
},
//
resuleClick() {
this.form.contractId = this.selectResult.contractId;
this.form.contractName = this.selectResult.contractName;
this.selectTableShow = false;
},
sortChange(column) {
const sort = {
isAsc: column.order === "descending" ? "desc" : "asc",
orderByColumn: column.prop
};
this.queryParams = Object.assign(this.queryParams, sort);
this.handleQuery();
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
handleDetails(row) {
this.sourceId = row.projectId;
this.componectVal = "DetailsWrap";
},
//
toTableClick() {
this.componectVal = "";
},
//
statusFormat(row, column) {
return this.selectDictLabel(this.projectTypeOptions, row.industry);
},
/** 查询行政区划下拉树结构 */
getTreeselect() {
listRegionalism().then(response => {
this.regionalismOption = [];
const data = {
regionalismId: 0,
regionalismName: "中国",
children: []
};
data.children = this.handleTree(
response.data,
"regionalismId",
"parentId"
);
this.regionalismOption.push(data);
});
},
/** 转换行政划分数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.regionalismId,
label: node.regionalismName,
children: node.children
};
},
regionalismChange(val) {
this.mapCenter = {
lng: val.stationLng,
lat: val.stationLat
};
this.form.projectLng = val.stationLng;
this.form.projectLat = val.stationLat;
},
//
handler({ BMap, map }) {
//
this.BMap = BMap;
this.map = map;
this.mapLoading = false;
// this.getPointByIp()
},
mapEvent(data) {
this.mapForm.lng = data.lng;
this.mapForm.lat = data.lat;
this.mapForm.address = data.address;
this.$forceUpdate();
},
// 使
mapClick() {
if (this.form.projectLng && this.form.projectLat) {
this.mapCenter.lng = this.form.projectLng;
this.mapCenter.lat = this.form.projectLat;
this.mapForm.lng = this.form.projectLng;
this.mapForm.lat = this.form.projectLat;
this.mapForm.address = this.form.projectAddress;
} else {
this.mapCenter = {
lng: 119.459889,
lat: 25.98974
};
this.mapForm.lng = 119.459889;
this.mapForm.lat = 25.98974;
this.mapForm.address = "";
}
this.visible = !this.visible;
},
mapSureClick() {
// form
this.form.projectAddress = this.mapForm.address
? this.mapForm.address
: this.form.projectAddress;
this.form.projectLng = this.mapForm.lng;
this.form.projectLat = this.mapForm.lat;
this.visible = false;
},
mapAddressFromPoint() {
if (this.form.projectAddress) {
// geoCode(this.form.projectAddress, this, { form: 'form', lat: 'shopLat', lng: 'shopLng' })
gjzCode(this.form.projectAddress, this, {
form: "form",
lat: "shopLat",
lng: "shopLng"
});
}
},
/** 查询项目列表 */
getList() {
this.loading = true;
listProject(this.queryParams).then(response => {
this.projectList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
projectName: null,
industry: null,
regionalismId: null,
projectAddress: null,
projectLng: null,
projectLat: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.projectId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加项目";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const projectId = row.projectId || this.ids;
getProject(projectId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改项目";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.projectId != null) {
updateProject(this.form).then(response => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addProject(this.form).then(response => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const projectIds = row.projectId || this.ids;
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return delProject(projectIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有项目数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportProject(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>
<style lang="scss">
.iot-project {
.eldialog-wrap {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-dialog__body {
padding: 0px;
}
.el-form {
padding: 20px;
padding-right: 40px;
}
.el-dialog__footer {
height: 60px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding: 0px;
padding-top: 15px;
.el-button + .el-button {
margin-right: 10px;
}
.el-button {
padding-top: 8px;
}
}
}
.to-home-wrap2 {
width: 20px;
height: 20px;
position: absolute;
right: 30px;
top: 30px;
display: flex;
justify-content: center;
align-items: center;
z-index: 100;
color: #656363;
font-size: 20px;
cursor: default;
width: 100px;
.el-button--medium.is-circle {
width: 25px;
height: 20px;
padding: 0;
background: #f26a6a;
color: #fff;
font-size: 16px;
border-radius: 5px;
height: 30px;
width: 100%;
font-size: 14px;
}
}
.to-home-wrap2:hover {
color: #1890ff;
font-size: 30px;
}
}
</style>

View File

@ -1,69 +0,0 @@
<template>
<div class="iot-project-details-warp">
<div class="info-tabs">
<el-tabs v-model="activeName" type="border-card">
<el-tab-pane label="项目信息" name="info">
<div class="tabs-body">
<info-wrap v-if="activeName === 'info'" :infoData="infoData" />
</div>
</el-tab-pane>
<el-tab-pane label="项目租户" name="tenant">
<div class="tabs-body">
<tenant-wrap v-if="activeName === 'tenant'" :infoData="infoData" />
</div>
</el-tab-pane>
<el-tab-pane label="项目空间" name="space">
<div class="tabs-body">
<space-wrap v-if="activeName === 'space'" :infoData="infoData" />
</div>
</el-tab-pane>
<el-tab-pane label="设备列表" name="allDevice">
<div class="tabs-body">
<device-list-wrap v-if="activeName === 'allDevice'" :sourceId="infoData.projectId" />
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script>
import {
getProject
} from "@/api/iot/project";
import InfoWrap from './info'
import TenantWrap from './tenant'
import SpaceWrap from './space'
import DeviceListWrap from './deviceList'
export default {
name: 'DetailsWrap',
props: ['sourceId'],
components: {
InfoWrap,
TenantWrap,
SpaceWrap,
DeviceListWrap
},
data() {
return {
infoData: {},
activeName: ''
}
},
created() {
this.getInfoByProjectId()
this.activeName = 'info'
},
methods: {
getInfoByProjectId() {
getProject(this.sourceId).then(response => {
this.infoData = response.data;
});
}
}
}
</script>
<style less="scss">
.iot-project-details-warp {
}
</style>

View File

@ -1,51 +0,0 @@
<template>
<div class="app-container iot-project-detail-all-device">
<el-table v-loading="loading" :data="list" :default-sort="{prop: 'createTime', order: 'descending'}">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="设备名称" align="left" prop="deviceName" />
<el-table-column label="所属型号" align="left" prop="modelName" />
<el-table-column label="设备key" align="left" prop="deviceKey" />
<el-table-column label="设备类型" align="left" width="150" prop="deviceTypeName" />
<el-table-column label="设备状态" align="center" width="150" prop="deviceState">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.deviceState === 'ONLINE'">在线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OFFLINE'">离线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OUTLINE'">脱线</el-tag>
<el-tag type="info" v-else-if="scope.row.deviceState === 'UNACTIVE'">未激活</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" sortable align="center" width="200" prop="createTime" />
</el-table>
</div>
</template>
<script>
import { listDeviceByProjectId } from "@/api/iot/project";
export default {
name: "ProjectDeviceList",
props: ["sourceId"],
data() {
return {
list: [],
loading: false,
queryParams: {
}
};
},
created() {
this.getList();
},
methods: {
indexFormatter(val) {
return val + 1;
},
/** 查询空间设备列表 */
getList() {
this.loading = true;
listDeviceByProjectId(this.sourceId).then(response => {
this.list = response.data;
this.loading = false;
});
}
}
};
</script>

View File

@ -1,482 +0,0 @@
<template>
<div class="project-details-info">
<div class="group-list-info">
<div class="top">
<div class="top-label">
<svg-icon icon-class="A_product1" style="margin-right: 2px; height: 20px; width: 20px;" />项目信息
<span
v-if="updateState === false"
style="margin: 0px 15px 0 10px; font-weight: 200; font-size: 14px;"
>项目名称{{infoData.projectName}}</span>
</div>
</div>
</div>
<div class="group-list-table">
<div class="table-row">
<div class="table-row-col">
<div class="title">项目ID</div>
<div class="content">
<span class="name">{{infoData.projectId}}</span>
<el-button type="text" size="small" @click.stop="copyText(infoData.projectId)">复制</el-button>
</div>
</div>
<div class="table-row-col">
<div class="title">项目编号</div>
<div class="content">
<span class="group-id">{{infoData.projectCode}}</span>
</div>
</div>
<div class="table-row-col">
<div class="title">项目类型</div>
<div class="content">
<span class="group-id">{{statusFormat(infoData)}}</span>
</div>
</div>
</div>
<div class="table-row">
<div class="table-row-col">
<div class="title">项目纬度</div>
<div class="content">{{infoData.projectLat}}</div>
</div>
<div class="table-row-col">
<div class="title">项目经度</div>
<div class="content">{{infoData.projectLng}}</div>
</div>
<div class="table-row-col">
<div class="title">项目状态</div>
<div class="content">{{infoData.projectStatus === '0' ? '启用' : '禁用' }}</div>
</div>
</div>
<div class="table-row">
<div class="table-row-col">
<div class="title">项目地址</div>
<div class="content">
<span class="centent">{{infoData.projectAddress}}</span>
</div>
</div>
</div>
<div class="table-row">
<div class="table-row-col">
<div class="title">创建时间</div>
<div class="content">{{infoData.createTime || '--'}}</div>
</div>
<div class="table-row-col" style="flex: 2 0 0%;">
<div class="title">行政区划</div>
<div class="content">{{infoData.regionalismFullName}}</div>
</div>
</div>
</div>
<div class="group-list-info" style="margin-top: 20px;">
<div class="top">
<div class="top-label">
<svg-icon icon-class="A_product1" style="margin-right: 2px; height: 20px; width: 20px;" />电价合同
<span
v-if="updateState === false"
style="margin: 0px 15px 0 10px; font-weight: 200; font-size: 14px;"
>{{contrctInfo.contractName}}</span>
</div>
</div>
</div>
<div class="group-list-table">
<div class="table-row">
<div class="table-row-col">
<div class="title">合同ID</div>
<div class="content">
<span class="name">{{contrctInfo.contractId}}</span>
<el-button type="text" size="small" @click.stop="copyText(contrctInfo.contractId)">复制</el-button>
</div>
</div>
<div class="table-row-col">
<div class="title">合同类型</div>
<div class="content">
<span class="group-id">{{contrctInfo.contractTypeName}}</span>
</div>
</div>
<div class="table-row-col">
<div class="title">合同状态</div>
<div class="content">
<span class="group-id">{{contrctInfo.status === '0' ? '启用' : '禁用' }}</span>
</div>
</div>
</div>
<div class="table-row" >
<div class="table-row-col">
<div class="title" style="height: 160px;">合同规则</div>
<div class="content" style="overflow: auto;">
<div
class="crat-warp"
v-for="item in contrctInfo.priceContractRuleList"
:key="item.ruleNum"
>
<div class="title-span">{{item.ruleName}}</div>
<div class="time-wrap" v-if="contrctInfo.contractType === 'PEAK_VALLEY'">
<span class="time-title">时间:</span>
<div class="time-val">
<span style="color: #3300ff;">{{item.minTime}}</span>
<span>~</span>
<span style="color: #3300ff;">{{item.maxTime}}</span>
</div>
</div>
<div class="time-wrap" v-else>
<div class="vlue-warp">
<span>最小值:</span>
<span >{{item.minVal}}</span>
</div>
<div class="vlue-warp">
<span>最大值:</span>
<span >{{item.maxVal}}</span>
</div>
</div>
<div class="dj-wrap">
<span class="dj-title">单价:</span>
<span class="dj-value">{{item.unitPrice}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { getContract } from "@/api/iot/contract";
export default {
name: "ProjectInfo",
props: ["infoData"],
data() {
const validatorNull = (rule, value, callback) => {
callback();
};
return {
updateState: false,
prodtreeOptions: [],
modelList: [],
showProdSecret: false,
temp: {
deviceName: "",
deviceId: undefined
},
rules: {},
projectTypeOptions: {},
contrctInfo: {}
};
},
created() {
this.getDicts("project_industry").then(response => {
this.projectTypeOptions = response.data;
});
this.getContractById();
},
watch: {
infoData(val) {
if (val) {
this.getContractById();
}
}
},
methods: {
getContractById() {
if (!this.infoData.contractId && this.infoData.contractId !== 0) {
return;
}
getContract(this.infoData.contractId).then(response => {
this.contrctInfo = response.data;
// this.contrctInfo.priceContractRuleList = arr || [];
});
},
//
statusFormat(row) {
return this.selectDictLabel(this.projectTypeOptions, row.industry);
},
copyText(val) {
this.copeFu(val, this);
},
//
handleUpdate(row) {
this.newTemp();
this.temp = Object.assign({}, row);
this.updateState = true;
},
newTemp() {
this.temp = {
deviceName: "",
deviceId: undefined
};
}
}
};
</script>
<style lang="scss">
.project-details-info {
.group-list-info {
.top {
text-align: left;
width: 100%;
float: left;
height: 40px;
.top-label {
float: left;
width: calc(100% - 200px);
font-size: 16px;
font-weight: 700;
color: #373d41;
display: flex;
align-items: center;
justify-content: flex-start;
.el-input--medium {
width: 150px;
}
.el-button--text {
padding: 8px 12px;
color: #333;
}
.el-button--text:hover {
background-color: #d1dbe6;
border-radius: 0;
color: #1890ff;
}
}
.top-button {
float: left;
text-align: right;
width: 200px;
}
}
display: flex;
justify-content: space-between;
margin-bottom: 6px;
flex: 1;
.title {
line-height: 30px;
font-size: 16px;
font-weight: 700;
color: #373d41;
display: flex;
align-items: center;
flex: 1;
}
}
.group-list-table {
border-top: 1px solid #d4d4d4;
border-left: 1px solid #d4d4d4;
.table-row {
display: flex;
width: 100%;
.table-row-col {
display: flex;
flex: 1 1 0%;
overflow: hidden;
font-size: 14px;
.title {
width: 180px;
height: 48px;
color: rgb(116, 119, 122);
display: flex;
align-items: center;
background: rgb(250, 250, 252);
border-bottom: 1px solid #d4d4d4;
border-right: 1px solid #d4d4d4;
padding: 0px 12px;
margin-bottom: 0px;
font-size: 15px;
font-weight: 100;
}
.content {
display: flex;
justify-content: flex-start;
align-items: center;
flex: 1 1 0%;
overflow: hidden;
color: #666;
border-bottom: 1px solid #d4d4d4;
border-right: 1px solid #d4d4d4;
padding: 0px 12px;
.name {
display: inline-block;
max-width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
cursor: pointer;
overflow: hidden;
}
.group-id {
margin-right: 8px;
}
.notice-item {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 6px;
background: #d3d5d5;
margin-right: 3px;
}
.n {
background: #0fc18a;
}
.secret {
display: block;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
}
.eldaialog-wrap {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-radio {
width: 90px;
}
.el-dialog__body {
padding: 0px;
}
.cus-itme.el-form-item--mini .el-form-item__content {
margin-left: 0px !important;
}
.select {
// width: 92%;
display: inline-block;
width: calc(92% - 50px);
display: inline-block;
float: left;
margin-right: 4px;
.el-input {
width: 100%;
}
}
.el-textarea {
width: 92%;
width: calc(92% - 50px);
width: 100%;
}
.el-input {
width: 92%;
width: calc(92% - 50px);
width: 100%;
}
.info {
width: 100%;
float: left;
margin-bottom: 15px;
/* margin-top: 13px; */
margin-left: -10px;
font-size: 16px;
font-weight: 600;
}
.span {
width: calc(100% - 91px);
display: block;
content: "";
height: 1px;
/* width: 100%; */
border-top: 1px dashed #ecedee;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
margin-left: 80px;
margin-top: -10px;
}
.form-buttons-div {
height: 45px;
display: flex;
justify-content: flex-end;
align-items: center;
padding-right: 10px;
border-top: 1px solid #747373;
}
}
.group-dialog {
.el-dialog__header {
border-bottom: 1px solid #ccc;
}
.el-dialog__body {
padding: 28px;
.el-form-item {
margin-bottom: 0;
.el-form-item__label {
line-height: 30px;
}
}
}
}
.crat-warp {
height: 100px;
width: 200px;
border: 1px solid #333;
padding: 5px;
height: 120px;
width: 250px;
margin: 5px;
.title-span {
height: 30px;
font-size: 18px;
border-bottom: 1px dotted #333;
padding-left: 5px;
}
.time-wrap {
height: 50px;
display: flex;
width: 100%;
align-items: center;
font-size: 16px;
.time-title {
display: block;
width: 40px;
text-align: end;
margin-right: 5px;
}
.time-val {
display: flex;
font-size: 16px;
width: calc(100% - 45px);
justify-content: space-around;
}
.vlue-warp {
width: 50%;
display: flex;
justify-content: center;
>span:nth-child(1) {
display: block;
text-align: left;
margin-right: 5px;
width: 55px;
}
>span:nth-child(2) {
display: block;
width: calc(100% - 55px);
text-align: center;
color: #3300ff;
}
}
}
.dj-wrap {
height: 35px;
display: flex;
align-items: center;
font-size: 16px;
.dj-title {
display: block;
width: 40px;
text-align: end;
}
.dj-value {
display: block;
width: calc(100% - 45px);
text-align: center;
color: red;
}
}
}
}
</style>

View File

@ -1,371 +0,0 @@
<template>
<div class="app-container iot-detail-space">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="上级空间" prop="parentId">
<treeselect
style="width: 200px;"
v-model="queryParams.parentId"
:options="querySpaceOptions"
:normalizer="normalizer"
placeholder="请选择上级空间"
/>
</el-form-item>
<el-form-item label="空间名称" prop="spaceName">
<el-input
v-model="queryParams.spaceName"
placeholder="空间名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="空间类型" prop="spaceType">
<el-select v-model="queryParams.spaceType" placeholder="空间类型" clearable>
<el-option
v-for="dict in spaceTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="spaceList"
row-key="spaceId"
default-expand-all
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="空间名称" align="left" prop="spaceName" />
<!-- <el-table-column label="空间ID" align="left" prop="spaceId" />
<el-table-column label="空间编码" align="left" prop="spaceCode" />-->
<el-table-column label="空间类型" align="center" prop="spaceType" :formatter="statusFormat" />
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-search"
@click="handleDetails(scope.row)"
>空间设备</el-button>
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改项目空间对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="上级空间:" prop="parentId">
<treeselect v-model="form.parentId" :options="spaceOptions" placeholder="请选择上级空间" />
</el-form-item>
<el-form-item label="空间名称:" prop="spaceName">
<el-input v-model="form.spaceName" placeholder="请输入空间名称" />
</el-form-item>
<el-form-item label="类型:" prop="spaceType">
<el-select v-model="form.spaceType" style="width: 100%;" placeholder="请选择空间类型">
<el-option
v-for="dict in spaceTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
<el-dialog
class="eldialog-wrap"
:title="spaceDeviceTitle"
:visible.sync="selectTableShow"
width="75%"
top="10vh"
:close-on-click-modal="false"
>
<space-device-wrap
v-if="selectTableShow"
:sourceId="sourceId"
:projectId="infoData.projectId"
></space-device-wrap>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="() =>{selectTableShow = false}"> </el-button>
<el-button size="mini" @click="() =>{selectTableShow = false}"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listSpace,
getSpace,
delSpace,
addSpace,
updateSpace,
exportSpace,
listSpaceDevice,
listSpaceTree
} from "@/api/iot/space";
import SpaceDeviceWrap from "./spaceDevice";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
name: "Space",
components: {
Treeselect,
SpaceDeviceWrap
},
props: ["infoData"],
data() {
return {
selectTableShow: false,
//
loading: true,
//
showSearch: true,
//
spaceList: [],
//
spaceOptions: [],
//
title: "",
//
open: false,
//
queryParams: {
parentId: null,
projectId: null,
spaceName: null,
spaceCode: null,
spaceType: null
},
//
form: {},
//
rules: {},
spaceTypeOptions: [],
querySpaceOptions: [],
sourceId: "",
spaceDeviceTitle: ""
};
},
created() {
this.getDicts("space_type").then(response => {
this.spaceTypeOptions = response.data;
});
this.getQueryTreeselect();
this.getList();
},
methods: {
indexFormatter(val) {
return val + 1;
},
//
handleDetails(row) {
this.sourceId = row.spaceId;
this.spaceDeviceTitle = `[ ${row.spaceName} ] 空间--设备管理`;
this.selectTableShow = true;
},
//
statusFormat(row, column) {
return this.selectDictLabel(this.spaceTypeOptions, row.spaceType);
},
/** 查询项目空间列表 */
getList() {
this.loading = true;
this.queryParams.projectId = this.infoData.projectId;
listSpace(this.queryParams).then(response => {
this.spaceList = this.handleTree(response.data, "spaceId", "parentId");
this.loading = false;
});
},
/** 转换项目空间数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.spaceId,
label: node.spaceName,
children: node.children
};
},
/** 查询部门下拉树结构 */
getTreeselect(param) {
listSpaceTree(param).then(response => {
this.spaceOptions = [];
const data = { id: 0, label: "顶级节点", children: [] };
// data.children = this.handleTree(response.data, "spaceId", "parentId");
data.children = response.data;
this.spaceOptions.push(data);
});
},
/** 查询部门下拉树结构 */
getQueryTreeselect() {
let param = {
projectId: this.infoData.projectId
};
listSpace(param).then(response => {
this.querySpaceOptions = [];
const data = { spaceId: 0, spaceName: "顶级节点", children: [] };
data.children = this.handleTree(response.data, "spaceId", "parentId");
this.querySpaceOptions.push(data);
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
parentId: null,
projectId: this.infoData.projectId,
spaceName: null,
spaceType: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
let param = {
projectId: this.infoData.projectId
};
this.getTreeselect(param);
this.open = true;
this.title = "添加项目空间";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
let param = {
projectId: this.infoData.projectId,
spaceId: row.spaceId
};
this.getTreeselect(param);
if (row != null) {
this.form.parentId = row.spaceId;
}
getSpace(row.spaceId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改项目空间";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.spaceId != null) {
updateSpace(this.form).then(response => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addSpace(this.form).then(response => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
this.$confirm(
'是否确认删除项目空间编号为"' + row.spaceId + '"的数据项?',
"警告",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
)
.then(function() {
return delSpace(row.spaceId);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
}
}
};
</script>
<style lang="scss">
.iot-detail-space {
.eldialog-wrap {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-dialog__body {
padding: 0px;
height: calc(100vh - 200px);
overflow: auto;
}
.el-form {
padding: 20px;
padding-right: 40px;
}
.el-dialog__footer {
height: 60px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding: 0px;
padding-top: 15px;
.el-button + .el-button {
margin-right: 10px;
}
.el-button {
padding-top: 8px;
}
}
}
}
</style>

View File

@ -1,352 +0,0 @@
<template>
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="space_deviceList"
:default-sort="{prop: 'createTime', order: 'descending'}"
@sort-change="sortChange"
>
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="设备名称" align="left" width="200px" prop="deviceName" />
<el-table-column label="所属型号" align="left" prop="modelName" />
<el-table-column label="设备key" align="left" prop="deviceKey" />
<el-table-column label="设备类型" align="left" width="120px" prop="deviceTypeName" />
<el-table-column label="创建时间" sortable="custom" align="center" width="200" prop="createTime" />
<el-table-column label="操作" width="150" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-delete"
v-if="scope.row.deviceType !== 'MINIATURE_BREAKER'"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改空间设备对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px"></el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
<el-dialog
title="选择设备"
:visible.sync="selectTableShow"
width="75%"
top="10vh"
class="select-table-dialog"
:close-on-click-modal="false"
append-to-body
>
<select-table-wrap
v-if="selectTableShow"
:tableOption="tableSelectOption.tableOpt"
:queryOption="tableSelectOption.queryOpt"
:tableList="tableSelectOption.tableList"
@parentGetList="childGetList($event)"
:otherOption="tableSelectOption.otherOption"
@returnEvent="returnEvent($event)"
/>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="() =>{selectTableShow = false}"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listSpace_device,
getSpace_device,
delSpace_device,
addSpace_device,
updateSpace_device,
exportSpace_device,
listProjectDevice
} from "@/api/iot/spaceDevice";
import { listSpaceDevice } from "@/api/iot/space";
import SelectTableWrap from "@/components/SelectTable/index";
export default {
name: "SpaceDeviceWrap",
props: ["sourceId", "projectId"],
components: {
SelectTableWrap
},
data() {
return {
selectTableShow: false,
tableSelectOption: {},
selectResult: {},
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
space_deviceList: [],
//
title: "",
//
open: false,
//
queryParams: {
spaceId: "",
pageNum: 1,
pageSize: 10,
orderByColumn: "createTime",
isAsc: "desc"
},
//
form: {},
//
rules: {}
};
},
created() {
this.getList();
},
methods: {
sortChange(column) {
const sort = {
isAsc: column.order === "descending" ? "desc" : "asc",
orderByColumn: column.prop
};
this.queryParams = Object.assign(this.queryParams, sort);
this.handleQuery();
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
//
handleDetails() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "device"
},
queryOpt: {
disable: false,
labelWidth: "68px",
params: {
deviceName: "",
modelId: "",
parentId: 0,
deviceType: "GATEWAY_CONTROLLER"
},
page: {
pageSize: 10,
pageNum: 1,
total: 0
},
inline: true,
queryChilds: [
{
style: "",
placeholder: "设备名称",
clearable: true,
label: "设备名称",
type: "input",
key: "deviceName",
size: "small",
value: ""
}
]
},
tableOpt: {
loading: false,
rowKey: "deviceId",
selection: false,
maxHeight: "45vh",
childs: [
{
style: "",
label: "所属型号",
type: "",
prop: "modelName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "设备名称",
type: "",
prop: "deviceName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "设备Key",
type: "",
prop: "deviceKey",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "设备类型",
type: "",
prop: "deviceTypeName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "创建时间",
type: "time",
prop: "createTime",
align: "center",
width: "180",
"show-overflow-tooltip": false,
tempType: "span"
}
],
tableList: {
type: Array
}
},
tableList: []
};
this.selectTableShow = true;
},
childGetList(data) {
listProjectDevice().then(response => {
this.tableSelectOption.tableList = response.data;
// this.tableSelectOption.queryOpt.page.total = Number(response.total);
});
},
returnEvent(data) {
if (data.type === "dblclick") {
this.form.deviceId = data.value.deviceId;
this.submitForm();
} else if (data.type === "click") {
this.form.deviceId = data.value.deviceId;
}
},
/** 查询空间设备列表 */
getList() {
this.loading = true;
this.queryParams.spaceId = this.sourceId;
listSpace_device(this.queryParams).then(response => {
this.space_deviceList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
spaceId: this.sourceId,
deviceId: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.spaceId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.handleDetails();
},
/** 提交按钮 */
submitForm() {
addSpace_device(this.form).then(response => {
this.msgSuccess("新增成功");
this.selectTableShow = false;
this.getList();
});
},
/** 删除按钮操作 */
handleDelete(row) {
const spaceIds = row.deviceId;
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return delSpace_device(spaceIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有空间设备数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportSpace_device(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>

View File

@ -1,386 +0,0 @@
<template>
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="project_tenantList" :default-sort="{prop: 'expirationTime', order: 'descending'}"
@sort-change="sortChange">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="企业名称" align="center" prop="tenantName" />
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<span v-text="scope.row.status === '0' ? '正常' : '停用'"></span>
</template>
</el-table-column>
<el-table-column label="有效期" align="center" sortable="custom" prop="expirationTime" width="160" />
<el-table-column
label="操作"
align="center"
width="200px"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>解除租户</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改项目租户关系对话框 -->
<!-- <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px"></el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog> -->
<el-dialog
title="选择租户"
:visible.sync="selectTableShow"
width="50%"
top="10vh"
class="select-table-dialog"
:close-on-click-modal="false"
append-to-body
>
<select-table-wrap
v-if="selectTableShow"
:tableOption="tableSelectOption.tableOpt"
:queryOption="tableSelectOption.queryOpt"
:tableList="tableSelectOption.tableList"
@parentGetList="childGetList($event)"
:otherOption="tableSelectOption.otherOption"
@returnEvent="returnEvent($event)"
/>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="() =>{selectTableShow = false}"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listProject_tenant,
getProject_tenant,
delProject_tenant,
addProject_tenant,
updateProject_tenant,
exportProject_tenant,
listUserdByProjectId
} from "@/api/iot/projectTenant";
import SelectTableWrap from "@/components/SelectTable/index";
export default {
name: "ProjectTenant",
components: {
SelectTableWrap
},
props: ["infoData"],
data() {
return {
selectTableShow: false,
tableSelectOption: {},
selectResult: {},
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
project_tenantList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
orderByColumn: "expirationTime",
isAsc: "desc"
},
//
form: {},
//
rules: {},
//
statusOptions: [],
tenantTypeOptions: []
};
},
created() {
this.getDicts("sys_tenant_type").then(response => {
this.tenantTypeOptions = response.data;
});
this.getDicts("sys_normal_disable").then(response => {
this.statusOptions = response.data;
});
this.getList();
},
methods: {
sortChange(column) {
const sort = {
isAsc: column.order === "descending" ? "desc" : "asc",
orderByColumn: column.prop
};
this.queryParams = Object.assign(this.queryParams, sort);
this.handleQuery();
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
//
handleDetails() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "device"
},
queryOpt: {
disable: false,
labelWidth: "68px",
params: {
projectId: this.infoData.projectId,
tenantName: ""
},
page: {
pageSize: 10,
pageNum: 1,
total: 0
},
inline: true,
queryChilds: [
{
style: "",
placeholder: "企业名称",
clearable: true,
label: "企业名称",
type: "input",
key: "tenantName",
size: "small",
value: ""
}
]
},
tableOpt: {
loading: false,
rowKey: "deviceId",
selection: false,
maxHeight: "45vh",
childs: [
{
style: "",
label: "企业名称",
type: "",
prop: "tenantName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "企业法人",
type: "",
prop: "corporation",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "状态",
type: "",
prop: "status",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "text1"
},
{
style: "",
label: "有效期",
type: "time",
prop: "expirationTime",
align: "center",
width: "180",
"show-overflow-tooltip": false,
tempType: "span"
}
],
tableList: {
type: Array
}
},
tableList: []
};
this.selectTableShow = true;
},
childGetList(data) {
listUserdByProjectId(Object.assign(data.page, data.param)).then(
response => {
this.tableSelectOption.tableList = response.rows;
this.tableSelectOption.queryOpt.page.total = Number(response.total);
}
);
},
returnEvent(data) {
if (data.type === "dblclick") {
this.form.tenantId = data.value.tenantId;
this.submitForm();
} else if (data.type === "click") {
this.form.tenantId = data.value.tenantId;
}
},
//
statusFormat(row, column) {
var rulesStr = "";
this.statusOptions.forEach(v => {
if (v.dictValue === row.status) {
rulesStr = v.dictLabel;
}
});
return rulesStr;
},
tenantTypeFormat(row, column) {
var rulesStr = "";
this.tenantTypeOptions.forEach(v => {
if (v.dictValue === row.status) {
rulesStr = v.dictLabel;
}
});
return rulesStr;
},
/** 查询项目租户关系列表 */
getList() {
this.loading = true;
this.queryParams.projectId = this.infoData.projectId;
listProject_tenant(this.queryParams).then(response => {
this.project_tenantList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
projectId: this.infoData.projectId,
tenantId: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.projectId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.handleDetails();
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const projectId = row.projectId || this.ids;
getProject_tenant(projectId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改项目租户关系";
});
},
/** 提交按钮 */
submitForm() {
addProject_tenant(this.form).then(response => {
this.msgSuccess("新增成功");
this.selectTableShow = false;
this.getList();
});
},
/** 删除按钮操作 */
handleDelete(row) {
const projectIds = row.projectId;
const tenantId = row.tenantId;
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return delProject_tenant(projectIds, tenantId);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有项目租户关系数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportProject_tenant(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>

View File

@ -1,329 +0,0 @@
<template>
<div class="trigger-list">
<div>
<el-form :model="queryParams" ref="queryForm" :inline="true">
<el-form-item label="关键字" prop="searchValue">
<el-input
v-model="queryParams.searchValue"
placeholder="关键字"
clearable
size="small"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:trigger:add']"
>新增</el-button>
</el-col>
</el-row>
<el-table
v-loading="listLoading"
:default-sort="{prop: 'updateTime', order: 'descending'}"
@sort-change="sortChange"
:data="tableList"
>
<el-table-column
type="index"
label="序号"
align="center"
:index="indexFormatter"
width="80px"
></el-table-column>
<el-table-column label="触发器名称" sortable="custom" width="250" align="left" prop="triggerName" />
<el-table-column label="推送内容" align="left" :aria-hidden="true" prop="templateContent" />
<el-table-column label="状态" align="center" width="80">
<template slot-scope="scope">
<el-tag v-if="scope.row.status === '0'">启用</el-tag>
<el-tag type="danger" v-else>禁用</el-tag>
</template>
</el-table-column>
<el-table-column
label="创建时间"
sortable="custom"
align="center"
prop="createTime"
width="160"
></el-table-column>
<el-table-column label="操作" width="200" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-document-add"
@click="handleCopperIn(scope.row, 'copper')"
v-hasPermi="['iot:trigger:add']"
>复制新增</el-button>
<!-- <el-button
size="mini"
type="text"
icon="el-icon-search"
@click="details(scope.row)"
v-hasPermi="['iot:trigger:edit']"
>查看</el-button> -->
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleCopperIn(scope.row, 'update')"
v-hasPermi="['iot:trigger:edit']"
>编辑</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDeletes(scope.row)"
v-hasPermi="['iot:trigger:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<div class="trigger-dialog">
<el-dialog
:close-on-press-escape="false"
:close-on-click-modal="false"
title="触发器详情"
width="40%"
:visible.sync="triggerDetailsDialog"
top="5vh"
>
<!-- <triggerDetails v-if="triggerDetailsDialog === true" :triggerId="tempModel.triggerId"></triggerDetails> -->
</el-dialog>
<!-- 新增触发器dialog -->
<el-dialog
class="trigger-d-dialog"
:close-on-click-modal="false"
title="新增触发器"
width="900px"
:visible.sync="outerVisible"
append-to-body
>
<component
v-if="outerVisible"
:is="componectVal"
:type="childOpt.type"
:triggerId="childOpt.triggerId"
@recover="dialogRecover"
></component>
</el-dialog>
</div>
<div
style="
position: fixed;
bottom: 10px;
right: 10px;
"
v-show="componectVal !== ''"
>
<el-tooltip class="item" effect="dark" content="前往列表" placement="top">
<el-button
type="primary"
style="
width: 50px;
height: 50px;
font-size: 25px;
z-index: 100;
"
icon="el-icon-back"
@click="toTableClick"
circle
></el-button>
</el-tooltip>
</div>
</div>
</template>
<script>
// import TriggerDetails from "./triggerDetails";
// import { fetchList } from '@/api/admin/dict'
import { listTrigger, delTrigger } from "@/api/iot/trigger";
// // import { openDetailsPage } from '@/util/util'
import InsertTriggerDialog from "./profile/insertTriggerDialog";
import { listAlarmType } from "@/api/alarm/alarmType";
export default {
name: "Rule",
components: {
// TriggerDetails,
InsertTriggerDialog
},
data() {
return {
listLoading: false,
triggerDetailsDialog: false,
outerVisible: false,
tempModel: {},
total: 0,
queryParams: {
searchValue: undefined,
pageNum: 1,
pageSize: 10,
orderByColumn: "createTime",
isAsc: "desc"
},
page: {
total: 0, //
currentPage: 1, //
pageSize: 20, // ,
isAsc: false //
},
tableList: [],
alarmTypeList: [],
//
componectVal: "",
childOpt: {
type: "create", // create, copper, update
triggerId: 0 // id
}
};
},
watch: {
$route() {
console.log('routeUpdate')
}
},
created() {
this.handleQuery();
this.getAlaramTypeList()
},
methods: {
sortChange(column) {
const sort = {
isAsc: column.order === "descending" ? "desc" : "asc",
orderByColumn: column.prop
};
this.queryParams = Object.assign(this.queryParams, sort);
this.handleQuery();
},
toTableClick() {
this.outerVisible = false;
this.componectVal = "";
},
//
statusFormat(row, column) {
for(var i = 0; i<this.alarmTypeList.length; i++) {
if (this.alarmTypeList[i].typeCode === row.alarmTypeCode) {
return this.alarmTypeList[i].typeName;
}
}
return '';
},
// dialog .
dialogRecover() {
this.componectVal = "";
this.outerVisible = false;
this.handleQuery();
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
getList() {
this.listLoading = true;
listTrigger(this.queryParams).then(response => {
this.tableList = response.rows;
this.total = parseInt(response.total);
this.listLoading = false;
});
},
details(row) {
this.tempModel = row;
this.triggerDetailsDialog = true;
},
//
handleAdd() {
this.childOpt.type = "create";
this.childOpt.triggerId = "";
this.outerVisible = true;
this.componectVal = "InsertTriggerDialog";
},
handleCopperIn(row, type) {
this.childOpt.type = type;
this.childOpt.triggerId = row.triggerId;
this.outerVisible = true;
this.componectVal = "InsertTriggerDialog";
},
handleDeletes(row, index) {
this.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
delTrigger(row.triggerId)
.then(response => {
this.msgSuccess("删除成功");
this.getList();
})
.catch(err => {
console.log(err);
});
});
},
/** 查询告警类型列表 */
getAlaramTypeList() {
listAlarmType({pageNum: 1, pageSize: 9999}).then(response => {
this.alarmTypeList = response.rows;
});
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
}
};
</script>
<style lang="scss">
.trigger-list {
padding: 20px;
.title {
box-sizing: inherit;
background: #fff;
padding: 20px 40px;
font-size: 20px;
font-weight: 700;
color: #373d41;
height: 68px;
}
}
.trigger-d-dialog {
.el-dialog__body {
padding: 0px;
}
.el-dialog__header {
border-bottom: 1px solid #929191;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -1,340 +0,0 @@
<template>
<div class="app-container iot-vendor">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="厂商名称" prop="vendorName">
<el-input
v-model="queryParams.vendorName"
placeholder="厂商名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="厂商地址" prop="vendorAddress">
<el-input
v-model="queryParams.vendorAddress"
placeholder="厂商地址"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="联系方式" prop="vendorContact">
<el-input
v-model="queryParams.vendorContact"
placeholder="联系方式"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:vendor:add']"
>新增</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="vendorList"
@selection-change="handleSelectionChange"
:default-sort="{prop: 'createTime', order: 'descending'}"
@sort-change="sortChange"
>
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="厂商名称" align="left" width="250" prop="vendorName" />
<el-table-column label="联系方式" align="left" width="250" prop="vendorContact" />
<el-table-column label="厂商地址" align="left" prop="vendorAddress" />
<el-table-column label="备注" align="left" prop="remark" />
<el-table-column label="创建时间" align="center" sortable="custom" width="160" prop="createTime" />
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:vendor:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:vendor:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改厂商对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="厂商名称:" prop="vendorName">
<el-input v-model="form.vendorName" placeholder="请输入厂商名称" />
</el-form-item>
<el-form-item label="联系方式:" prop="vendorContact">
<el-input v-model="form.vendorContact" placeholder="请输入厂商联系方式" />
</el-form-item>
<el-form-item label="厂商地址:" prop="vendorAddress">
<el-input v-model="form.vendorAddress" placeholder="请输入厂商地址" />
</el-form-item>
<el-form-item label="备注:" prop="remark">
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="form-button-div">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listVendor,
getVendor,
delVendor,
addVendor,
updateVendor,
exportVendor
} from "@/api/iot/vendor";
export default {
name: "Vendor",
components: {},
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
vendorList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
vendorName: null,
vendorAddress: null,
vendorContact: null,
orderByColumn: "createTime",
isAsc: "desc"
},
//
form: {},
//
rules: {
vendorName: [
{ required: true, message: "厂商名称不能为空", trigger: "blur" }
],
vendorContact: [
{ required: true, message: "联系方式不能为空", trigger: "blur" }
]
}
};
},
created() {
this.getList();
},
methods: {
sortChange(column) {
const sort = {
isAsc: column.order === "descending" ? "desc" : "asc",
orderByColumn: column.prop
};
this.queryParams = Object.assign(this.queryParams, sort);
this.handleQuery();
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
/** 查询厂商列表 */
getList() {
this.loading = true;
listVendor(this.queryParams).then(response => {
this.vendorList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
vendorId: null,
vendorName: null,
vendorAddress: null,
vendorContact: null,
delFlag: null,
createId: null,
createTime: null,
updateId: null,
updateTime: null,
remark: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.vendorId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加厂商";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const vendorId = row.vendorId || this.ids;
getVendor(vendorId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改厂商";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.vendorId != null) {
updateVendor(this.form).then(response => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addVendor(this.form).then(response => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const vendorIds = row.vendorId || this.ids;
this.$confirm("是否删除该选项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return delVendor(vendorIds);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有厂商数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportVendor(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>
<style lang="scss">
.iot-vendor {
.eldialog-wrap {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-dialog__body {
padding: 0px;
}
.el-form {
padding: 20px;
padding-right: 40px;
}
.el-dialog__footer {
height: 60px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding: 0px;
padding-top: 15px;
.el-button + .el-button {
margin-right: 10px;
}
.el-button {
padding-top: 8px;
}
}
}
}
</style>

View File

@ -1,333 +0,0 @@
<template>
<div class="login">
<div class="form-wrap">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
<div class="title-tags-wrap">
<div
@click="userTypeClick('system')"
:class="formTitleType === 'system' ? 'tags-div tags-checked' : 'tags-div'"
>
<h3>运营登录</h3>
<span></span>
</div>
<div
@click="userTypeClick('enter')"
:class="formTitleType === 'enter' ? 'tags-div tags-checked' : 'tags-div'"
>
<h3>企业登录</h3>
<span></span>
</div>
<div
@click="userTypeClick('personal')"
:class="formTitleType === 'personal' ? 'tags-div tags-checked' : 'tags-div'"
>
<h3>个人登录</h3>
<span></span>
</div>
</div>
<el-form-item prop="username">
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
<svg-icon slot="prefix" icon-class="A_loginUser" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="A_loginPassword" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="code">
<el-input
v-model="loginForm.code"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="A_loginCode" class="el-input__icon input-icon" />
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img" />
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px; margin-left: 25px;">记住密码</el-checkbox>
<el-form-item style="width:100%;">
<el-button
:loading="loading"
size="medium"
type="primary"
style="width:100%; height: 42px;"
@click.native.prevent="handleLogin"
>
<span v-if="!loading"> </span>
<span v-else> 中...</span>
</el-button>
</el-form-item>
</el-form>
</div>
<!-- 底部 -->
<!-- <div class="el-login-footer">
<span>Copyright © 2018-2021 smartpower.vip All Rights Reserved.</span>
</div> -->
</div>
</template>
<script>
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt";
export default {
name: "Login",
data() {
return {
formTitle: {
enter: "企业登录",
personal: "个人登录"
},
formTitleType: "enter",
codeUrl: "",
cookiePassword: "",
loginForm: {
username: "",
password: "",
rememberMe: false,
code: "",
uuid: ""
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "用户名不能为空" }
],
password: [
{ required: true, trigger: "blur", message: "密码不能为空" }
],
code: [{ required: true, trigger: "change", message: "验证码不能为空" }]
},
loading: false,
redirect: undefined
};
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect;
},
immediate: true
}
},
created() {
this.getCode();
this.getCookie();
},
methods: {
userTypeClick(val) {
this.formTitleType = val;
},
getCode() {
getCodeImg().then(res => {
this.codeUrl = "data:image/gif;base64," + res.img;
this.loginForm.uuid = res.uuid;
});
},
getCookie() {
const username = Cookies.get("username");
const password = Cookies.get("password");
const rememberMe = Cookies.get("rememberMe");
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password:
password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
};
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 });
Cookies.set("password", encrypt(this.loginForm.password), {
expires: 30
});
Cookies.set("rememberMe", this.loginForm.rememberMe, {
expires: 30
});
} else {
Cookies.remove("username");
Cookies.remove("password");
Cookies.remove("rememberMe");
}
switch(this.formTitleType) {
case 'enter':
this.loginForm["userType"] = 'TENANT'
break;
case 'system':
this.loginForm["userType"] = 'SYSTEM'
break;
case 'personal':
this.loginForm["userType"] = 'PERSONAL'
break;
};
// this.loginForm["userType"] =
// this.formTitleType === "enter" ? undefined : "PERSONAL";
this.$store
.dispatch("Login", this.loginForm)
.then(() => {
this.$router.push({ path: this.redirect || "/" }).catch(() => {});
})
.catch(() => {
this.loading = false;
this.getCode();
});
}
});
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss">
.login {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
background-image: url("../assets/images/login-background.jpg");
background-size: cover;
.title {
margin: 0px auto 30px auto;
text-align: center;
color: #707070;
}
.login-form {
border-radius: 6px;
background: #ffffff00;
width: 400px;
padding: 25px 25px 5px 25px;
.el-checkbox__input.is-checked + .el-checkbox__label {
margin-left: 3px;
}
.el-input {
input {
height: 45px;
border: 2px solid #fff;
border-radius: 30px;
padding-left: 50px;
font-size: 14px;
color: #e4e2e2;
}
input:-webkit-autofill,
textarea:-webkit-autofill,
select:-webkit-autofill {
-webkit-text-fill-color: #ededed !important;
-webkit-box-shadow: 0 0 0px 1000px #06060600 inset !important;
background-color: #06060657;
background-image: none;
transition: background-color 50000s ease-in-out 0s; //
}
input {
background-color: #06060657;
}
}
.input-icon {
height: 42px;
width: 26px;
margin-left: 15px;
}
}
.login-tip {
font-size: 13px;
text-align: center;
color: #bfbfbf;
}
.login-code {
width: 122px;
height: 45px;
float: right;
img {
cursor: pointer;
vertical-align: middle;
border-radius: 40px;
height: 45px;
}
}
.el-login-footer {
height: 40px;
line-height: 40px;
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
font-family: Arial;
font-size: 12px;
letter-spacing: 1px;
}
.login-code-img {
height: 38px;
}
.form-wrap {
background: #0009;
width: 100%;
height: 420px;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border: 0;
.el-form-item__error {
left: 25px;
}
}
.title-tags-wrap {
display: flex;
width: 100%;
height: 70px;
justify-content: center;
align-items: baseline;
margin-bottom: 20px;
cursor: default;
.tags-div {
display: flex;
width: 50%;
align-items: center;
height: 100%;
color: #ffffff80;
font-family: "Source Han Sans CN";
font-weight: 400;
font-size: 20px;
flex-wrap: wrap;
justify-content: center;
padding-bottom: 20px;
> h3 {
width: 100%;
margin: 0px;
text-align: center;
font-weight: 400;
}
> span {
display: none;
width: 20px;
border-radius: 10px;
height: 5px;
background: #fff;
}
}
.tags-checked {
color: #fff;
> span {
display: block;
}
}
}
}
</style>

View File

@ -1,153 +0,0 @@
<template>
<div class="app-container">
<el-row>
<el-col :span="24" class="card-box">
<el-card>
<div slot="header"><span>基本信息</span></div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%">
<tbody>
<tr>
<td><div class="cell">Redis版本</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.redis_version }}</div></td>
<td><div class="cell">运行模式</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }}</div></td>
<td><div class="cell">端口</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.tcp_port }}</div></td>
<td><div class="cell">客户端数</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.connected_clients }}</div></td>
</tr>
<tr>
<td><div class="cell">运行时间()</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.uptime_in_days }}</div></td>
<td><div class="cell">使用内存</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.used_memory_human }}</div></td>
<td><div class="cell">使用CPU</div></td>
<td><div class="cell" v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</div></td>
<td><div class="cell">内存配置</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.maxmemory_human }}</div></td>
</tr>
<tr>
<td><div class="cell">AOF是否开启</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.aof_enabled == "0" ? "" : "" }}</div></td>
<td><div class="cell">RDB是否成功</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</div></td>
<td><div class="cell">Key数量</div></td>
<td><div class="cell" v-if="cache.dbSize">{{ cache.dbSize }} </div></td>
<td><div class="cell">网络入口/出口</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps</div></td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
<el-col :span="12" class="card-box">
<el-card>
<div slot="header"><span>命令统计</span></div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<div ref="commandstats" style="height: 420px" />
</div>
</el-card>
</el-col>
<el-col :span="12" class="card-box">
<el-card>
<div slot="header">
<span>内存信息</span>
</div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<div ref="usedmemory" style="height: 420px" />
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import { getCache } from "@/api/monitor/cache";
import * as echarts from 'echarts/core';
export default {
name: "Server",
data() {
return {
//
loading: [],
//
commandstats: null,
// 使
usedmemory: null,
// cache
cache: [],
};
},
created() {
this.getList();
this.openLoading();
},
methods: {
/** 查缓存询信息 */
getList() {
getCache().then((response) => {
this.cache = response.data;
this.loading.close();
this.commandstats = echarts.init(this.$refs.commandstats, "macarons");
this.commandstats.setOption({
tooltip: {
trigger: "item",
formatter: "{a} <br/>{b} : {c} ({d}%)",
},
series: [
{
name: "命令",
type: "pie",
roseType: "radius",
radius: [15, 95],
center: ["50%", "38%"],
data: response.data.commandStats,
animationEasing: "cubicInOut",
animationDuration: 1000,
},
],
});
this.usedmemory = echarts.init(this.$refs.usedmemory, "macarons");
this.usedmemory.setOption({
tooltip: {
formatter: "{b} <br/>{a} : " + this.cache.info.used_memory_human,
},
series: [
{
name: "峰值",
type: "gauge",
min: 0,
max: 1000,
detail: {
formatter: this.cache.info.used_memory_human,
},
data: [
{
value: parseFloat(this.cache.info.used_memory_human),
name: "内存消耗",
},
],
},
],
});
});
},
//
openLoading() {
this.loading = this.$loading({
lock: true,
text: "拼命读取中",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
},
},
};
</script>

View File

@ -1,26 +0,0 @@
<template>
<div v-loading="loading" :style="'height:'+ height">
<iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" />
</div>
</template>
<script>
export default {
name: "Druid",
data() {
return {
src: process.env.VUE_APP_BASE_API + "/druid/index.html",
height: document.documentElement.clientHeight - 94.5 + "px;",
loading: true
};
},
mounted: function() {
setTimeout(() => {
this.loading = false;
}, 230);
const that = this;
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 94.5 + "px;";
};
}
};
</script>

View File

@ -1,488 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="任务名称" prop="jobName">
<el-input
v-model="queryParams.jobName"
placeholder="请输入任务名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="任务组名" prop="jobGroup">
<el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable size="small">
<el-option
v-for="dict in jobGroupOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="任务状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable size="small">
<el-option
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['monitor:job:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['monitor:job:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['monitor:job:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['monitor:job:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-s-operation"
size="mini"
@click="handleJobLog"
v-hasPermi="['monitor:job:query']"
>日志</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="任务编号" align="center" prop="jobId" />
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
<el-table-column label="任务组名" align="center" prop="jobGroup" :formatter="jobGroupFormat" />
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
<el-table-column label="cron执行表达式" align="center" prop="cronExpression" :show-overflow-tooltip="true" />
<el-table-column label="状态" align="center">
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
active-value="0"
inactive-value="1"
@change="handleStatusChange(scope.row)"
></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-caret-right"
@click="handleRun(scope.row)"
v-hasPermi="['monitor:job:changeStatus']"
>执行一次</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleView(scope.row)"
v-hasPermi="['monitor:job:query']"
>详细</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改定时任务对话框 -->
<el-dialog :title="title" :visible.sync="open" width="700px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-row>
<el-col :span="12">
<el-form-item label="任务名称" prop="jobName">
<el-input v-model="form.jobName" placeholder="请输入任务名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务分组" prop="jobGroup">
<el-select v-model="form.jobGroup" placeholder="请选择">
<el-option
v-for="dict in jobGroupOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item prop="invokeTarget">
<span slot="label">
调用方法
<el-tooltip placement="top">
<div slot="content">
Bean调用示例spTask.spParams('sp')
<br />Class类调用示例com.smartpower.quartz.task.SpTask.spParams('sp')
<br />参数说明支持字符串布尔类型长整型浮点型整型
</div>
<i class="el-icon-question"></i>
</el-tooltip>
</span>
<el-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="cron表达式" prop="cronExpression">
<el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否并发" prop="concurrent">
<el-radio-group v-model="form.concurrent" size="small">
<el-radio-button label="0">允许</el-radio-button>
<el-radio-button label="1">禁止</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="错误策略" prop="misfirePolicy">
<el-radio-group v-model="form.misfirePolicy" size="small">
<el-radio-button label="1">立即执行</el-radio-button>
<el-radio-button label="2">执行一次</el-radio-button>
<el-radio-button label="3">放弃执行</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="dict.dictValue"
>{{dict.dictLabel}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 任务日志详细 -->
<el-dialog title="任务详细" :visible.sync="openView" width="700px" append-to-body>
<el-form ref="form" :model="form" label-width="120px" size="mini">
<el-row>
<el-col :span="12">
<el-form-item label="任务编号:">{{ form.jobId }}</el-form-item>
<el-form-item label="任务名称:">{{ form.jobName }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务分组:">{{ jobGroupFormat(form) }}</el-form-item>
<el-form-item label="创建时间:">{{ form.createTime }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="cron表达式">{{ form.cronExpression }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下次执行时间:">{{ parseTime(form.nextValidTime) }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="调用目标方法:">{{ form.invokeTarget }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务状态:">
<div v-if="form.status == 0">正常</div>
<div v-else-if="form.status == 1">失败</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否并发:">
<div v-if="form.concurrent == 0">允许</div>
<div v-else-if="form.concurrent == 1">禁止</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="执行策略:">
<div v-if="form.misfirePolicy == 0">默认策略</div>
<div v-else-if="form.misfirePolicy == 1">立即执行</div>
<div v-else-if="form.misfirePolicy == 2">执行一次</div>
<div v-else-if="form.misfirePolicy == 3">放弃执行</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="openView = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listJob, getJob, delJob, addJob, updateJob, exportJob, runJob, changeJobStatus } from "@/api/monitor/job";
export default {
name: "Job",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
jobList: [],
//
title: "",
//
open: false,
//
openView: false,
//
jobGroupOptions: [],
//
statusOptions: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
jobName: undefined,
jobGroup: undefined,
status: undefined
},
//
form: {},
//
rules: {
jobName: [
{ required: true, message: "任务名称不能为空", trigger: "blur" }
],
invokeTarget: [
{ required: true, message: "调用目标字符串不能为空", trigger: "blur" }
],
cronExpression: [
{ required: true, message: "cron执行表达式不能为空", trigger: "blur" }
]
}
};
},
created() {
this.getList();
this.getDicts("sys_job_group").then(response => {
this.jobGroupOptions = response.data;
});
this.getDicts("sys_job_status").then(response => {
this.statusOptions = response.data;
});
},
methods: {
/** 查询定时任务列表 */
getList() {
this.loading = true;
listJob(this.queryParams).then(response => {
this.jobList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
jobGroupFormat(row, column) {
return this.selectDictLabel(this.jobGroupOptions, row.jobGroup);
},
//
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, row.status);
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
jobId: undefined,
jobName: undefined,
jobGroup: undefined,
invokeTarget: undefined,
cronExpression: undefined,
misfirePolicy: 1,
concurrent: 1,
status: "0"
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.jobId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
//
handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用";
this.$confirm('确认要"' + text + '""' + row.jobName + '"任务吗?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return changeJobStatus(row.jobId, row.status);
}).then(() => {
this.msgSuccess(text + "成功");
}).catch(function() {
row.status = row.status === "0" ? "1" : "0";
});
},
/* 立即执行一次 */
handleRun(row) {
this.$confirm('确认要立即执行一次"' + row.jobName + '"任务吗?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return runJob(row.jobId, row.jobGroup);
}).then(() => {
this.msgSuccess("执行成功");
})
},
/** 任务详细信息 */
handleView(row) {
getJob(row.jobId).then(response => {
this.form = response.data;
this.openView = true;
});
},
/** 任务日志列表查询 */
handleJobLog() {
this.$router.push("/job/log");
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加任务";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const jobId = row.jobId || this.ids;
getJob(jobId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改任务";
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.jobId != undefined) {
updateJob(this.form).then(response => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addJob(this.form).then(response => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const jobIds = row.jobId || this.ids;
this.$confirm('是否删除该选项', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return delJob(jobIds);
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
})
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有定时任务数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return exportJob(queryParams);
}).then(response => {
this.download(response.msg);
})
}
}
};
</script>

View File

@ -1,299 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="任务名称" prop="jobName">
<el-input
v-model="queryParams.jobName"
placeholder="请输入任务名称"
clearable
size="small"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="任务组名" prop="jobGroup">
<el-select
v-model="queryParams.jobGroup"
placeholder="请任务组名"
clearable
size="small"
style="width: 240px"
>
<el-option
v-for="dict in jobGroupOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="执行状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择执行状态"
clearable
size="small"
style="width: 240px"
>
<el-option
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="执行时间">
<el-date-picker
v-model="dateRange"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['monitor:job:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
@click="handleClean"
v-hasPermi="['monitor:job:remove']"
>清空</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['monitor:job:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="jobLogList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="日志编号" width="80" align="center" prop="jobLogId" />
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
<el-table-column label="任务组名" align="center" prop="jobGroup" :formatter="jobGroupFormat" :show-overflow-tooltip="true" />
<el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
<el-table-column label="日志信息" align="center" prop="jobMessage" :show-overflow-tooltip="true" />
<el-table-column label="执行状态" align="center" prop="status" :formatter="statusFormat" />
<el-table-column label="执行时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleView(scope.row)"
v-hasPermi="['monitor:job:query']"
>详细</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 调度日志详细 -->
<el-dialog title="调度日志详细" :visible.sync="open" width="700px" append-to-body>
<el-form ref="form" :model="form" label-width="100px" size="mini">
<el-row>
<el-col :span="12">
<el-form-item label="日志序号:">{{ form.jobLogId }}</el-form-item>
<el-form-item label="任务名称:">{{ form.jobName }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务分组:">{{ form.jobGroup }}</el-form-item>
<el-form-item label="执行时间:">{{ form.createTime }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="调用方法:">{{ form.invokeTarget }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="日志信息:">{{ form.jobMessage }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="执行状态:">
<div v-if="form.status == 0">正常</div>
<div v-else-if="form.status == 1">失败</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="异常信息:" v-if="form.status == 1">{{ form.exceptionInfo }}</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listJobLog, delJobLog, exportJobLog, cleanJobLog } from "@/api/monitor/jobLog";
export default {
name: "JobLog",
data() {
return {
//
loading: true,
//
ids: [],
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
jobLogList: [],
//
open: false,
//
dateRange: [],
//
form: {},
//
statusOptions: [],
//
jobGroupOptions: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
jobName: undefined,
jobGroup: undefined,
status: undefined
}
};
},
created() {
this.getList();
this.getDicts("sys_job_status").then(response => {
this.statusOptions = response.data;
});
this.getDicts("sys_job_group").then(response => {
this.jobGroupOptions = response.data;
});
},
methods: {
/** 查询调度日志列表 */
getList() {
this.loading = true;
listJobLog(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.jobLogList = response.rows;
this.total = response.total;
this.loading = false;
}
);
},
//
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, row.status);
},
//
jobGroupFormat(row, column) {
return this.selectDictLabel(this.jobGroupOptions, row.jobGroup);
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.jobLogId);
this.multiple = !selection.length;
},
/** 详细按钮操作 */
handleView(row) {
this.open = true;
this.form = row;
},
/** 删除按钮操作 */
handleDelete(row) {
const jobLogIds = this.ids;
this.$confirm('是否删除该选项', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return delJobLog(jobLogIds);
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
})
},
/** 清空按钮操作 */
handleClean() {
this.$confirm("是否确认清空所有调度日志数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return cleanJobLog();
}).then(() => {
this.getList();
this.msgSuccess("清空成功");
})
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有调度日志数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return exportJobLog(queryParams);
}).then(response => {
this.download(response.msg);
})
}
}
};
</script>

View File

@ -1,233 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="登录地址" prop="ipaddr">
<el-input
v-model="queryParams.ipaddr"
placeholder="请输入登录地址"
clearable
style="width: 240px;"
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户名称" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入用户名称"
clearable
style="width: 240px;"
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="登录状态"
clearable
size="small"
style="width: 240px"
>
<el-option
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="登录时间">
<el-date-picker
v-model="dateRange"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['monitor:logininfor:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
@click="handleClean"
v-hasPermi="['monitor:logininfor:remove']"
>清空</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:logininfor:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="访问编号" align="center" prop="infoId" />
<el-table-column label="用户名称" align="center" prop="userName" />
<el-table-column label="登录地址" align="center" prop="ipaddr" width="130" :show-overflow-tooltip="true" />
<el-table-column label="登录地点" align="center" prop="loginLocation" :show-overflow-tooltip="true" />
<el-table-column label="浏览器" align="center" prop="browser" />
<el-table-column label="操作系统" align="center" prop="os" />
<el-table-column label="登录状态" align="center" prop="status" :formatter="statusFormat" />
<el-table-column label="操作信息" align="center" prop="msg" />
<el-table-column label="登录日期" align="center" prop="loginTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.loginTime) }}</span>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import { list, delLogininfor, cleanLogininfor, exportLogininfor } from "@/api/monitor/logininfor";
export default {
name: "Logininfor",
data() {
return {
//
loading: true,
//
ids: [],
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
list: [],
//
statusOptions: [],
//
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
ipaddr: undefined,
userName: undefined,
status: undefined
}
};
},
created() {
this.getList();
this.getDicts("sys_common_status").then(response => {
this.statusOptions = response.data;
});
},
methods: {
/** 查询登录日志列表 */
getList() {
this.loading = true;
list(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.list = response.rows;
this.total = response.total;
this.loading = false;
}
);
},
//
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, row.status);
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.infoId)
this.multiple = !selection.length
},
/** 删除按钮操作 */
handleDelete(row) {
const infoIds = row.infoId || this.ids;
this.$confirm('是否删除该选项', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return delLogininfor(infoIds);
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
})
},
/** 清空按钮操作 */
handleClean() {
this.$confirm('是否确认清空所有登录日志数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return cleanLogininfor();
}).then(() => {
this.getList();
this.msgSuccess("清空成功");
})
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm('是否确认导出所有操作日志数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return exportLogininfor(queryParams);
}).then(response => {
this.download(response.msg);
})
}
}
};
</script>

View File

@ -1,128 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
<el-form-item label="登录地址" prop="ipaddr">
<el-input
v-model="queryParams.ipaddr"
placeholder="请输入登录地址"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户名称" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入用户名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="loading"
:data="list.slice((pageNum-1)*pageSize,pageNum*pageSize)"
style="width: 100%;"
>
<el-table-column label="序号" type="index" align="center">
<template slot-scope="scope">
<span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span>
</template>
</el-table-column>
<el-table-column label="会话编号" align="center" prop="tokenId" :show-overflow-tooltip="true" />
<el-table-column label="登录名称" align="center" prop="userName" :show-overflow-tooltip="true" />
<el-table-column label="部门名称" align="center" prop="deptName" />
<el-table-column label="主机" align="center" prop="ipaddr" :show-overflow-tooltip="true" />
<el-table-column label="登录地点" align="center" prop="loginLocation" :show-overflow-tooltip="true" />
<el-table-column label="浏览器" align="center" prop="browser" />
<el-table-column label="操作系统" align="center" prop="os" />
<el-table-column label="登录时间" align="center" prop="loginTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.loginTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleForceLogout(scope.row)"
v-hasPermi="['monitor:online:forceLogout']"
>强退</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" />
</div>
</template>
<script>
import { list, forceLogout } from "@/api/monitor/online";
export default {
name: "Online",
data() {
return {
//
loading: true,
//
total: 0,
//
list: [],
pageNum: 1,
pageSize: 10,
//
queryParams: {
ipaddr: undefined,
userName: undefined
}
};
},
created() {
this.getList();
},
methods: {
/** 查询登录日志列表 */
getList() {
this.loading = true;
list(this.queryParams).then(response => {
this.list = response.rows;
this.total = response.total;
this.loading = false;
});
},
/** 搜索按钮操作 */
handleQuery() {
this.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 强退按钮操作 */
handleForceLogout(row) {
this.$confirm('是否确认强退名称为"' + row.userName + '"的数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return forceLogout(row.tokenId);
}).then(() => {
this.getList();
this.msgSuccess("强退成功");
})
}
}
};
</script>

View File

@ -1,321 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="系统模块" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入系统模块"
clearable
style="width: 240px;"
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="操作人员" prop="operName">
<el-input
v-model="queryParams.operName"
placeholder="请输入操作人员"
clearable
style="width: 240px;"
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="类型" prop="businessType">
<el-select
v-model="queryParams.businessType"
placeholder="操作类型"
clearable
size="small"
style="width: 240px"
>
<el-option
v-for="dict in typeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="操作状态"
clearable
size="small"
style="width: 240px"
>
<el-option
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="操作时间">
<el-date-picker
v-model="dateRange"
size="small"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['monitor:operlog:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
@click="handleClean"
v-hasPermi="['monitor:operlog:remove']"
>清空</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:config:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="日志编号" align="center" prop="operId" />
<el-table-column label="系统模块" align="center" prop="title" />
<el-table-column label="操作类型" align="center" prop="businessType" :formatter="typeFormat" />
<el-table-column label="请求方式" align="center" prop="requestMethod" />
<el-table-column label="操作人员" align="center" prop="operName" />
<el-table-column label="主机" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" />
<el-table-column label="操作地点" align="center" prop="operLocation" :show-overflow-tooltip="true" />
<el-table-column label="操作状态" align="center" prop="status" :formatter="statusFormat" />
<el-table-column label="操作日期" align="center" prop="operTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.operTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleView(scope.row,scope.index)"
v-hasPermi="['monitor:operlog:query']"
>详细</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 操作日志详细 -->
<el-dialog title="操作日志详细" :visible.sync="open" width="700px" append-to-body>
<el-form ref="form" :model="form" label-width="100px" size="mini">
<el-row>
<el-col :span="12">
<el-form-item label="操作模块:">{{ form.title }} / {{ typeFormat(form) }}</el-form-item>
<el-form-item
label="登录信息:"
>{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="请求地址:">{{ form.operUrl }}</el-form-item>
<el-form-item label="请求方式:">{{ form.requestMethod }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="操作方法:">{{ form.method }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="请求参数:">{{ form.operParam }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="返回参数:">{{ form.jsonResult }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="操作状态:">
<div v-if="form.status === 0">正常</div>
<div v-else-if="form.status === 1">失败</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="操作时间:">{{ parseTime(form.operTime) }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="异常信息:" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { list, delOperlog, cleanOperlog, exportOperlog } from "@/api/monitor/operlog";
export default {
name: "Operlog",
data() {
return {
//
loading: true,
//
ids: [],
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
list: [],
//
open: false,
//
typeOptions: [],
//
statusOptions: [],
//
dateRange: [],
//
form: {},
//
queryParams: {
pageNum: 1,
pageSize: 10,
title: undefined,
operName: undefined,
businessType: undefined,
status: undefined
}
};
},
created() {
this.getList();
this.getDicts("sys_oper_type").then(response => {
this.typeOptions = response.data;
});
this.getDicts("sys_common_status").then(response => {
this.statusOptions = response.data;
});
},
methods: {
/** 查询登录日志 */
getList() {
this.loading = true;
list(this.addDateRange(this.queryParams, this.dateRange)).then( response => {
this.list = response.rows;
this.total = response.total;
this.loading = false;
}
);
},
//
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, row.status);
},
//
typeFormat(row, column) {
return this.selectDictLabel(this.typeOptions, row.businessType);
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.operId)
this.multiple = !selection.length
},
/** 详细按钮操作 */
handleView(row) {
this.open = true;
this.form = row;
},
/** 删除按钮操作 */
handleDelete(row) {
const operIds = row.operId || this.ids;
this.$confirm('是否删除该选项', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return delOperlog(operIds);
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
})
},
/** 清空按钮操作 */
handleClean() {
this.$confirm('是否确认清空所有操作日志数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return cleanOperlog();
}).then(() => {
this.getList();
this.msgSuccess("清空成功");
})
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm('是否确认导出所有操作日志数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return exportOperlog(queryParams);
}).then(response => {
this.download(response.msg);
})
}
}
};
</script>

View File

@ -1,210 +0,0 @@
<template>
<div class="app-container">
<el-row>
<el-col :span="12" class="card-box">
<el-card>
<div slot="header"><span>CPU</span></div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;">
<thead>
<tr>
<th class="is-leaf"><div class="cell">属性</div></th>
<th class="is-leaf"><div class="cell"></div></th>
</tr>
</thead>
<tbody>
<tr>
<td><div class="cell">核心数</div></td>
<td><div class="cell" v-if="server.cpu">{{ server.cpu.cpuNum }}</div></td>
</tr>
<tr>
<td><div class="cell">用户使用率</div></td>
<td><div class="cell" v-if="server.cpu">{{ server.cpu.used }}%</div></td>
</tr>
<tr>
<td><div class="cell">系统使用率</div></td>
<td><div class="cell" v-if="server.cpu">{{ server.cpu.sys }}%</div></td>
</tr>
<tr>
<td><div class="cell">当前空闲率</div></td>
<td><div class="cell" v-if="server.cpu">{{ server.cpu.free }}%</div></td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
<el-col :span="12" class="card-box">
<el-card>
<div slot="header"><span>内存</span></div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;">
<thead>
<tr>
<th class="is-leaf"><div class="cell">属性</div></th>
<th class="is-leaf"><div class="cell">内存</div></th>
<th class="is-leaf"><div class="cell">JVM</div></th>
</tr>
</thead>
<tbody>
<tr>
<td><div class="cell">总内存</div></td>
<td><div class="cell" v-if="server.mem">{{ server.mem.total }}G</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.total }}M</div></td>
</tr>
<tr>
<td><div class="cell">已用内存</div></td>
<td><div class="cell" v-if="server.mem">{{ server.mem.used}}G</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.used}}M</div></td>
</tr>
<tr>
<td><div class="cell">剩余内存</div></td>
<td><div class="cell" v-if="server.mem">{{ server.mem.free }}G</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.free }}M</div></td>
</tr>
<tr>
<td><div class="cell">使用率</div></td>
<td><div class="cell" v-if="server.mem" :class="{'text-danger': server.mem.usage > 80}">{{ server.mem.usage }}%</div></td>
<td><div class="cell" v-if="server.jvm" :class="{'text-danger': server.jvm.usage > 80}">{{ server.jvm.usage }}%</div></td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
<el-col :span="24" class="card-box">
<el-card>
<div slot="header">
<span>服务器信息</span>
</div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;">
<tbody>
<tr>
<td><div class="cell">服务器名称</div></td>
<td><div class="cell" v-if="server.sys">{{ server.sys.computerName }}</div></td>
<td><div class="cell">操作系统</div></td>
<td><div class="cell" v-if="server.sys">{{ server.sys.osName }}</div></td>
</tr>
<tr>
<td><div class="cell">服务器IP</div></td>
<td><div class="cell" v-if="server.sys">{{ server.sys.computerIp }}</div></td>
<td><div class="cell">系统架构</div></td>
<td><div class="cell" v-if="server.sys">{{ server.sys.osArch }}</div></td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
<el-col :span="24" class="card-box">
<el-card>
<div slot="header">
<span>Java虚拟机信息</span>
</div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;">
<tbody>
<tr>
<td><div class="cell">Java名称</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.name }}</div></td>
<td><div class="cell">Java版本</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.version }}</div></td>
</tr>
<tr>
<td><div class="cell">启动时间</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.startTime }}</div></td>
<td><div class="cell">运行时长</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.runTime }}</div></td>
</tr>
<tr>
<td colspan="1"><div class="cell">安装路径</div></td>
<td colspan="3"><div class="cell" v-if="server.jvm">{{ server.jvm.home }}</div></td>
</tr>
<tr>
<td colspan="1"><div class="cell">项目路径</div></td>
<td colspan="3"><div class="cell" v-if="server.sys">{{ server.sys.userDir }}</div></td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
<el-col :span="24" class="card-box">
<el-card>
<div slot="header">
<span>磁盘状态</span>
</div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;">
<thead>
<tr>
<th class="is-leaf"><div class="cell">盘符路径</div></th>
<th class="is-leaf"><div class="cell">文件系统</div></th>
<th class="is-leaf"><div class="cell">盘符类型</div></th>
<th class="is-leaf"><div class="cell">总大小</div></th>
<th class="is-leaf"><div class="cell">可用大小</div></th>
<th class="is-leaf"><div class="cell">已用大小</div></th>
<th class="is-leaf"><div class="cell">已用百分比</div></th>
</tr>
</thead>
<tbody v-if="server.sysFiles">
<tr v-for="sysFile in server.sysFiles">
<td><div class="cell">{{ sysFile.dirName }}</div></td>
<td><div class="cell">{{ sysFile.sysTypeName }}</div></td>
<td><div class="cell">{{ sysFile.typeName }}</div></td>
<td><div class="cell">{{ sysFile.total }}</div></td>
<td><div class="cell">{{ sysFile.free }}</div></td>
<td><div class="cell">{{ sysFile.used }}</div></td>
<td><div class="cell" :class="{'text-danger': sysFile.usage > 80}">{{ sysFile.usage }}%</div></td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import { getServer } from "@/api/monitor/server";
export default {
name: "Server",
data() {
return {
//
loading: [],
//
server: []
};
},
created() {
this.getList();
this.openLoading();
},
methods: {
/** 查询服务器信息 */
getList() {
getServer().then(response => {
this.server = response.data;
this.loading.close();
});
},
//
openLoading() {
this.loading = this.$loading({
lock: true,
text: "拼命读取中",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)"
});
}
}
};
</script>

View File

@ -1,202 +0,0 @@
<template>
<!-- 告警记录功能 -->
<div class="app-container alarm-record">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="报警时间" prop="alarmTime">
<el-date-picker
v-model="time"
size="small"
@change="queryTimeChange"
clearable
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item label="告警类型" prop="typeName">
<el-input
v-model="queryParams.typeName"
placeholder="请输入告警类型"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:record:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="recordList">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="设备名称" align="left" width="200px" prop="deviceName" />
<!-- <el-table-column label="设备当前值" align="left" width="200px" prop="currentValue" >
<template slot-scope="scope">
<span style="text-overflow: ellipsis; overflow: hidden; white-space: nowrap;">{{scope.row.currentValue}}</span>
</template>
</el-table-column> -->
<el-table-column label="推送内容" align="left" prop="alarmContent" />
<el-table-column label="报警时间" align="center" prop="alarmTime" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.alarmTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="处理状态" width="100px" align="center" prop="processState" :formatter="stateFormatter"/>
<el-table-column label="处理结果" align="left" width="150px" prop="processResult" />
<el-table-column label="处理时间" align="center" prop="processTime" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.processTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="告警类型" align="left" width="150px" prop="typeName" />
<el-table-column label="类型编码" align="left" width="150px" prop="typeCode" />
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import {
listRecord,
exportRecord
} from "@/api/personal/alarm";
import Editor from "@/components/Editor";
export default {
name: "Record",
components: {
Editor
},
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
recordList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
typeName: null,
typeCode: null,
beginTime: null,
endTime: null,
alarmDivide: 'ALARM'
},
//
form: {},
//
rules: {},
time: []
};
},
created() {
this.getList();
},
methods: {
queryTimeChange(val) {
if (val) {
this.queryParams.beginTime = this.parseTime(val[0], '{y}-{m}-{d} {h}:{i}:{s}')
this.queryParams.endTime = this.parseTime(val[1], '{y}-{m}-{d} {h}:{i}:{s}')
} else {
this.queryParams.beginTime = null;
this.queryParams.endTime = null;
}
},
stateFormatter(val) {
return val === '2' ? '已处理' : '未处理'
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
/** 查询报警记录列表 */
getList() {
this.loading = true;
listRecord(this.queryParams).then(response => {
this.recordList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.time = [];
this.queryParams.beginTime = null;
this.queryParams.endTime = null;
this.handleQuery();
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有报警记录数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportRecord(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>

View File

@ -1,352 +0,0 @@
<template>
<div class="app-container iot-device">
<component :is="componectVal" :sourceId="sourceId"></component>
<div v-show="componectVal === ''">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="设备名称" prop="deviceName">
<el-input
v-model="queryParams.deviceName"
placeholder="请输入设备名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="设备状态" prop="deviceState">
<el-select v-model="queryParams.deviceState" placeholder="请选择设备状态" clearable size="small">
<el-option
:label="keys"
v-for="(keys, vals) in deviceStatusOpt"
:key="vals"
:value="vals"
/>
</el-select>
</el-form-item>
<el-form-item label="设备类型" prop="deviceType">
<el-select v-model="queryParams.deviceType" placeholder="请选择设备类型" clearable size="small">
<el-option
:label="keys"
:value="vals"
v-for="(keys, vals) in deviceTypeList"
:key="vals"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="deviceList"
:default-sort="{prop: 'createTime', order: 'descending'}"
@sort-change="sortChange"
>
<el-table-column
type="index"
label="序号"
align="center"
:index="indexFormatter"
width="80px"
></el-table-column>
<el-table-column label="设备名称" align="left" prop="deviceName" />
<el-table-column label="所属型号" align="left" prop="modelName" />
<el-table-column label="设备key" align="left" prop="deviceKey" />
<el-table-column label="设备类型" align="left" width="120px" prop="deviceTypeName" />
<el-table-column label="设备状态" align="center" width="120" prop="deviceState">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.deviceState === 'ONLINE'">在线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OFFLINE'">离线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OUTLINE'">脱线</el-tag>
<el-tag type="info" v-else-if="scope.row.deviceState === 'UNACTIVE'">未激活</el-tag>
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
sortable="custom"
width="160px"
prop="createTime"
/>
<el-table-column
label="操作"
align="center"
width="200px"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-search"
@click="handleDetails(scope.row)"
>详情</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<div class="to-home-wrap2" @click="toTableClick" v-show="componectVal !== ''">
<el-button icon="el-icon-d-arrow-left" title="返回列表" circle>返回列表</el-button>
</div>
</div>
</template>
<script>
import { listDevice, exportDevice, listDeviceTypeList } from "@/api/personal/device";
// import { listDeviceTypeList } from "@/api/tenant/device";
import DetailsWrap from "./profile/details";
const deviceStatusOpt = {
ONLINE: "在线",
OFFLINE: "离线",
OUTLINE: "脱线",
UNACTIVE: "未激活"
};
const lineTypeOpt = {
MAIN: "总路",
BRANCH: "支路"
};
export default {
name: "Device",
components: {
DetailsWrap
},
data() {
return {
deviceStatusOpt,
lineTypeOpt,
sourceId: "",
componectVal: "",
selectTableShow: false,
tableSelectOption: {},
selectResult: {},
queryModelOpt: [],
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
deviceList: [],
//
//
queryParams: {
pageNum: 1,
pageSize: 10,
modelId: null,
parentId: null,
deviceName: null,
deviceState: null,
deviceType: null,
orderByColumn: "createTime",
isAsc: "desc"
},
//
deviceTypeList: {}
};
},
created() {
this.getDeviceTypeList();
this.getList();
},
methods: {
sortChange(column) {
const sort = {
isAsc: column.order === "descending" ? "desc" : "asc",
orderByColumn: column.prop
};
this.queryParams = Object.assign(this.queryParams, sort);
this.handleQuery();
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
handleDetails(row) {
this.sourceId = row.deviceId;
this.componectVal = "DetailsWrap";
},
//
toTableClick() {
this.componectVal = "";
},
deviceTypeChange(val) {
if (val !== "MINIATURE_BREAKER") {
this.form.parentId = 0;
this.form.parentName = "";
} else if (!val) {
this.form.parentId = "";
this.form.parentName = "";
}
},
//
getDeviceTypeList() {
listDeviceTypeList().then(response => {
this.deviceTypeList = response.data;
});
},
/** 查询设备列表 */
getList() {
this.loading = true;
listDevice(this.queryParams).then(response => {
this.deviceList = response.rows;
this.total = response.total;
this.loading = false;
});
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm("是否确认导出所有设备数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(function() {
return exportDevice(queryParams);
})
.then(response => {
this.download(response.msg);
});
}
}
};
</script>
<style lang="scss">
.iot-device {
.eldialog-wrap {
.el-dialog__header {
border-bottom: 1px solid #747373;
}
.el-dialog__body {
padding: 0px;
}
.el-form {
padding: 20px;
padding-right: 40px;
}
.el-dialog__footer {
height: 60px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding: 0px;
padding-top: 15px;
.el-button + .el-button {
margin-right: 10px;
}
.el-button {
padding-top: 8px;
}
}
.form-params-wrap {
height: 100%;
width: calc(100% + 110px);
position: relative;
top: 35px;
left: -90px;
max-height: 250px;
overflow: auto;
padding: 10px;
border: 1px solid #009688;
border-radius: 5px;
}
}
.to-home-wrap2 {
width: 100px;
height: 20px;
position: absolute;
right: 30px;
top: 30px;
display: flex;
justify-content: center;
align-items: center;
z-index: 100;
color: #656363;
font-size: 20px;
cursor: default;
.el-button--medium.is-circle {
width: 25px;
height: 20px;
padding: 0;
background: #f26a6a;
color: #fff;
font-size: 16px;
border-radius: 5px;
height: 30px;
width: 100%;
font-size: 14px;
}
}
.to-home-wrap2:hover {
color: #1890ff;
font-size: 30px;
}
}
.form-params-wrap::-webkit-scrollbar {
/*滚动条整体样式*/
width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
height: 5px;
}
.form-params-wrap::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
box-shadow: inset 0 0 5px #c4c4c4;
background: #dededea6;
}
.form-params-wrap::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px #f6f6f6;
border-radius: 10px;
background: #ffffff;
}
</style>

View File

@ -1,154 +0,0 @@
<template>
<div class="iot-child-device">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="设备名称" prop="deviceName">
<el-input
v-model="queryParams.deviceName"
placeholder="请输入设备名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="deviceList">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column label="设备名称" align="left" prop="deviceName" />
<el-table-column label="所属型号" align="left" prop="modelName" />
<el-table-column label="设备key" align="left" prop="deviceKey" />
<el-table-column label="设备类型" align="left" width="120px" prop="deviceTypeName" />
<el-table-column label="设备状态" align="center" width="120" prop="deviceStatus">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.deviceState === 'ONLINE'">在线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OFFLINE'">离线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OUTLINE'">脱线</el-tag>
<el-tag type="info" v-else-if="scope.row.deviceState === 'UNACTIVE'">未激活</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" width="160px" prop="createTime" />
<el-table-column
label="操作"
align="center"
width="200px"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-search"
@click="handleDetails(scope.row)"
>详情</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
import {
listOneselfDevide
} from "@/api/personal/device";
import { listDeviceTypeList } from "@/api/tenant/device";
const lineTypeOpt = {
MAIN: "总路",
BRANCH: "支路"
};
export default {
name: "",
props: ["sourceId", "pDevcieInfo"],
components: {
},
data() {
return {
lineTypeOpt,
selectTableShow: false,
tableSelectOption: {},
selectResult: {},
//
queryParams: {
pageNum: 1,
pageSize: 10,
modelId: null,
parentId: null,
deviceCode: null,
deviceName: null,
deviceStatus: null,
deviceKey: null,
deviceType: null,
parentId: ""
},
open: false,
title: "",
showSearch: true,
//
deviceList: [],
total: 0,
form: {},
deviceTypeList: []
};
},
created() {
this.getDeviceTypeList();
this.getList();
},
methods: {
//
getDeviceTypeList() {
listDeviceTypeList().then(response => {
this.deviceTypeList = response.data;
});
},
indexFormatter(val) {
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
/** 查询设备列表 */
getList() {
this.loading = true;
this.queryParams.parentId = this.sourceId;
listOneselfDevide(this.queryParams).then(response => {
this.deviceList = response.rows;
this.total = response.total;
this.loading = false;
});
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
handleDetails(row) {
if (row.deviceId) {
this.$emit("toChildEvent", { deviceId: row.deviceId });
}
},
}
};
</script>

View File

@ -1,886 +0,0 @@
<template>
<div class="iot-project-details-warp">
<div class="info-tabs">
<div class="breadcrumb-wrap" v-show="breadcrumbList.length > 1">
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item v-for="(item, index) in breadcrumbList" :key="index">
<span @click="deviceClick(item, index)" :class="item.deviceId === deviceId ? 'breadcrumb-span show-wrap' : 'breadcrumb-span'">{{item.deviceName}}</span>
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<el-tabs
v-model="activeName"
:class="breadcrumbList.length > 1 ? 'children-wrap' : ''"
type="border-card"
>
<el-tab-pane label="运行状态" name="runingState">
<div class="tabs-body protocol-wrap">
<device-run-starts-wrap
v-if="devudeRunState"
:sourceId="deviceId"
:deviceInfo="infoData"
:prodId="infoData.prodKey"
></device-run-starts-wrap>
</div>
</el-tab-pane>
<el-tab-pane label="设备信息" name="info">
<div class="tabs-body">
<info-wrap :infoData="infoData" @updateInfo="updateInfo($event)" />
</div>
</el-tab-pane>
<el-tab-pane label="子设备" name="child" v-if="infoData.deviceType === 'GATEWAY_CONTROLLER'">
<div class="tabs-body">
<child-device
v-if="activeName === 'child'"
:pDevcieInfo="infoData"
:sourceId="infoData.deviceId"
@toChildEvent="toNewDevice"
></child-device>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script>
import { getDevice } from "@/api/personal/device";
import InfoWrap from "./info";
import ChildDevice from "./childDevice";
import DeviceRunStartsWrap from "@/views/profile/DeviceRunStarts/index";
export default {
name: "DetailsWrap",
props: ["sourceId"],
components: {
InfoWrap,
ChildDevice,
DeviceRunStartsWrap
},
data() {
return {
infoData: {},
activeName: "runingState",
breadcrumbList: [],
tempType: "bs",
deviceId: "",
devudeRunState: false
};
},
created() {
this.deviceId = this.sourceId;
this.deviceInfo();
},
methods: {
//
deviceClick(row, index) {
if (row.deviceId === this.deviceId) {
return;
}
const leng = this.breadcrumbList.length - 1;
this.breadcrumbList.splice(index + 1, leng);
this.activeName = "runingState";
this.deviceId = row.deviceId;
this.devudeRunState = false;
this.deviceInfo();
},
//
deviceInfo() {
getDevice(this.deviceId).then(response => {
this.infoData = response.data;
if (this.breadcrumbList.length <= 0) {
this.breadcrumbList.push(this.infoData);
}
for (var i = 0; i < this.breadcrumbList.length; i++) {
if (
this.breadcrumbList[i]["deviceId"] === this.infoData["deviceId"]
) {
this.breadcrumbList[i] = this.infoData;
} else if (i === this.breadcrumbList.length - 1) {
this.breadcrumbList.push(this.infoData);
}
}
this.devudeRunState = true;
});
},
toNewDevice(data) {
this.tempType = "children";
this.deviceId = data.deviceId;
this.devudeRunState = false;
this.deviceInfo();
this.activeName = "runingState";
},
updateInfo(...data) {
this.deviceInfo();
}
}
};
</script>
<style lang="scss">
.iot-project-details-warp {
.breadcrumb-wrap {
position: absolute;
top: 15px;
z-index: 10;
left: 20px;
width: 90%;
overflow: hidden;
.breadcrumb-span:hover {
color: #1890ff;
cursor: default;
}
.show-wrap {
color: #1890ff;
}
}
.product-release-dialog {
.title-i {
font-size: 20px;
color: #9c9a9a;
line-height: 18px;
}
.i-color {
color: rgb(0, 193, 222);
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.top-tigs {
background: #fbfbfc;
border: 1px solid #ecedee;
padding: 20px;
margin-bottom: 25px;
color: #999;
}
.form-bottom-prod-details {
margin-top: 40px;
height: 10px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.bottom-div {
height: 70px;
font-size: 12px;
border: 1px solid #ecedee;
margin: -1px;
}
.one-div {
width: 15%;
float: left;
border-right: 1px solid #ecedee;
height: 30px;
line-height: 30px;
/* padding-left: 10px; */
text-align: center;
font-size: 18px;
height: 70px;
line-height: 76px;
text-align: center;
font-size: 18px;
}
.two-div {
width: calc(100% - 36%);
float: left;
padding: 22px 10px 10px 10px;
font-size: 12px;
}
.there-div {
width: 10%;
float: left;
padding-top: 28px;
}
.four-div {
width: 5%;
float: left;
padding-top: 28px;
}
}
.heard {
padding: 20px 40px 0;
background-color: #fff;
height: 112px;
padding: 0px;
}
.info-title {
margin-top: 0px;
margin-bottom: 16px;
line-height: 29px;
overflow: hidden;
height: 30px;
.title {
float: left;
font-size: 20px;
margin: 0 8px 0 0;
line-height: 28px;
}
.el-button--small,
.el-button--small.is-round {
padding: 8px 15px;
float: right;
}
}
.info-icon {
margin-top: -70px;
float: left;
width: 101px;
border: 1px dotted rgb(205, 203, 203);
height: 101px;
.image {
width: 100px;
height: 100px;
}
}
.info-des {
font-size: 14px;
width: 100%;
float: left;
.info-row {
overflow: hidden;
display: block;
text-overflow: ellipsis;
line-height: 20px;
white-space: nowrap;
.label {
color: #aaa;
}
.centent {
color: #999;
margin-right: 8px;
}
}
}
.info-tabs {
position: relative;
box-sizing: border-box;
.el-tabs__content {
height: calc(100vh - 191px);
overflow: auto;
}
.el-tabs__header {
background-color: #fff;
position: relative;
// top: -10px;
.el-tabs__nav-wrap {
margin-left: 0px;
.el-tabs__item {
font-size: 16px;
}
}
}
.el-tabs__nav-scroll {
height: 65px;
padding-top: 25px;
padding-left: 15px;
background: #e4eaf3;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
background: #fff;
color: #333;
border: 0;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item {
// border-color: red;
color: #909399;
background: #d3deec;
border-radius: 8px 8px 0 0;
border-bottom: 0;
margin-left: 15px;
}
.tabs-body {
margin-left: 0px;
margin-right: 0px;
padding: 0px;
overflow: hidden;
background-color: #fff;
margin-bottom: 0px;
}
.protocol-wrap {
.el-tabs__nav-scroll {
height: auto;
padding-top: 0;
padding-left: 0;
background: #fff;
}
}
}
.children-wrap {
.el-tabs__header {
.el-tabs__nav-scroll {
height: 85px;
.el-tabs__nav {
margin-top: 20px;
}
}
}
}
.child-table {
margin-top: 25px;
// margin-left: 20px;
margin-right: 0px;
padding: 0px;
overflow: hidden;
background-color: #fff;
}
}
.product-release-dialog {
.title-i {
font-size: 20px;
color: #9c9a9a;
line-height: 18px;
}
.i-color {
color: rgb(0, 193, 222);
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.top-tigs {
background: #fbfbfc;
border: 1px solid #ecedee;
padding: 20px;
margin-bottom: 25px;
color: #999;
}
.form-bottom-prod-details {
margin-top: 15px;
height: 30px;
border-top: 1px solid #747373;
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.bottom-div {
height: 70px;
font-size: 12px;
border: 1px solid #ecedee;
margin: 0px;
}
.one-div {
width: 15%;
float: left;
border-right: 1px solid #ecedee;
height: 30px;
line-height: 30px;
/* padding-left: 10px; */
text-align: center;
font-size: 18px;
height: 70px;
line-height: 76px;
text-align: center;
font-size: 18px;
}
.two-div {
width: calc(100% - 36%);
float: left;
padding: 22px 10px 10px 10px;
font-size: 12px;
}
.there-div {
width: 10%;
float: left;
padding-top: 28px;
}
.four-div {
width: 5%;
float: left;
padding-top: 28px;
}
}
.product-detail-info {
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.form-buttons-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.el-form-item--mini.el-form-item,
.el-form-item--small.el-form-item {
margin-bottom: 10px;
margin-left: 60px;
}
.el-form--label-top .el-form-item__label {
padding: 0 0 9px;
margin-top: 10px;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
line-height: 17px;
}
.avue-input-number,
.el-cascader,
.el-date-editor.el-input,
.el-date-editor.el-input__inner,
.el-select {
width: 100%;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.form-buttons-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
}
}
.product-topic-dialog {
.top-tips {
height: 150px;
margin: 20px;
margin-top: 30px;
margin-right: 0px;
border: 1px solid #00c1df;
padding: 10px 10px 0;
background: #e6f9fc;
display: flex;
border-radius: 3px;
padding-left: 20px;
padding-top: 20px;
margin-bottom: 0px;
}
.el-form-item__error {
left: 80px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 90%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.el-select {
width: 100%;
}
.form-buttonx-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.product-fun-dialog {
.insert-div {
width: 100%;
margin-bottom: 10px;
padding-top: 10px;
padding-left: 30px;
}
.el-transfer-panel {
// margin-left: 10px;
width: 225px;
}
.el-transfer__buttons {
padding: 0px 10px;
}
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.fw {
.el-input--mini {
width: 155px;
}
}
.el-form-item__error {
left: 120px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 92%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.form-buttonb-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.product-custom-fun {
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.fw {
.el-input--mini {
width: 155px;
}
}
.el-form-item__error {
left: 120px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 92%;
}
.el-select {
width: 100%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.form-buttona-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.product-prop-standard-dialog {
.insert-div {
width: 100%;
margin-bottom: 10px;
padding-top: 10px;
padding-left: 30px;
}
.el-transfer-panel {
// margin-left: 10px;
width: 225px;
}
.el-transfer__buttons {
padding: 0px 10px;
}
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.fw {
.el-input--mini {
width: 155px;
}
}
.el-form-item__error {
left: 120px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 92%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.form-buttonb-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.product-prop-custom-dialog {
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.fw {
.el-input--mini {
width: 155px;
}
}
.el-form-item__error {
left: 120px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 92%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.form-buttona-div {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
width: 100%;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.model-function-dialog {
.el-textarea {
width: 92%;
}
.el-input {
width: 92%;
}
.question-button.el-button--text {
padding-bottom: 0px;
color: rgb(204, 204, 204);
background: 0 0;
padding-left: 0;
padding-right: 0;
font-size: 18px;
padding-top: 0px;
margin-top: 0px;
}
.fw {
.el-input--mini {
width: 155px;
}
}
.el-form-item__error {
left: 120px;
}
.el-dialog__body {
padding: 0px;
padding-right: 20px;
}
.el-dialog__header {
border-bottom: 1px solid rgb(116, 115, 115);
}
.el-form--label-top .el-form-item__label {
padding-top: 23px;
padding-bottom: 0px;
}
.el-form-item {
margin-bottom: -17px;
width: 92%;
}
.el-form-item--mini .el-form-item__content,
.el-form-item--mini .el-form-item__label {
padding-left: 40px;
}
.el-select {
width: 100%;
}
.form-bottom-prod-details {
margin-top: 30px;
height: 50px;
border-top: 1px solid rgb(116, 115, 115);
text-align: right;
padding-top: 15px;
width: calc(100% + 20px);
.el-button {
margin-right: 10px;
margin-left: 0px;
}
}
.funType-div {
// margin-left: 40px;
}
}
.sr {
.el-form-item {
margin-bottom: -17px;
width: 100%;
}
}
.iot-project-details-warp .info-tabs .el-tabs__content::-webkit-scrollbar {
/*滚动条整体样式*/
width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
height: 3px;
}
.iot-project-details-warp
.info-tabs
.el-tabs__content::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
box-shadow: inset 0 0 5px #9e9d9d;
background: #ffffff;
}
.iot-project-details-warp
.info-tabs
.el-tabs__content::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px #f6f6f6;
border-radius: 10px;
background: #ffffff;
}
</style>

Some files were not shown because too many files have changed in this diff Show More