mirror of https://github.com/veops/cmdb.git
commit
acf881dcb7
|
@ -33,6 +33,7 @@
|
|||
"vue": "^2.6.10",
|
||||
"vue-clipboard2": "^0.2.1",
|
||||
"vue-cropper": "0.4.4",
|
||||
"vue-i18n": "^8.15.3",
|
||||
"vue-json-excel": "^0.2.98",
|
||||
"vue-ls": "^3.2.0",
|
||||
"vue-quill-editor": "^3.0.6",
|
||||
|
@ -62,11 +63,11 @@
|
|||
"eslint-plugin-vue": "^5.2.3",
|
||||
"less": "^3.0.4",
|
||||
"less-loader": "^5.0.0",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"vue-svg-icon-loader": "^2.1.1",
|
||||
"webpack-theme-color-replacer": "^1.2.17",
|
||||
"opencollective": "^1.0.3",
|
||||
"opencollective-postinstall": "^2.0.2"
|
||||
"opencollective-postinstall": "^2.0.2",
|
||||
"vue-svg-icon-loader": "^2.1.1",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"webpack-theme-color-replacer": "^1.2.17"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
|
||||
import i18n from '@/locales'
|
||||
import { AppDeviceEnquire } from '@/utils/mixin'
|
||||
import { mixin } from '@/store/i18n-mixin'
|
||||
|
||||
export default {
|
||||
mixins: [AppDeviceEnquire],
|
||||
mixins: [AppDeviceEnquire, mixin],
|
||||
provide () {
|
||||
return {
|
||||
reload: this.reload
|
||||
|
@ -19,11 +20,16 @@ export default {
|
|||
},
|
||||
data () {
|
||||
return {
|
||||
locale: zhCN,
|
||||
locale: {},
|
||||
alive: true
|
||||
}
|
||||
},
|
||||
mounted () {},
|
||||
created () {
|
||||
this.$watch('currentLang', () => {
|
||||
this.locale = i18n.getLocaleMessage(this.currentLang).antLocale
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
reload () {
|
||||
this.alive = false
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<div class="header-index-wide">
|
||||
<div class="header-index-left">
|
||||
<logo class="top-nav-header" :show-title="device !== 'mobile'"/>
|
||||
<s-menu v-if="device !== 'mobile'" mode="horizontal" :menu="menus" :theme="theme" />
|
||||
<s-menu v-if="device !== 'mobile'" mode="horizontal" :menu="menus" :theme="theme" :i18n-render="i18nRender" />
|
||||
<a-icon v-else class="trigger" :type="collapsed ? 'menu-fold' : 'menu-unfold'" @click="toggle" />
|
||||
</div>
|
||||
<top-menu></top-menu>
|
||||
|
@ -33,6 +33,7 @@ import TopMenu from '../tools/TopMenu'
|
|||
import SMenu from '../Menu/'
|
||||
import Logo from '../tools/Logo'
|
||||
import { mixin } from '@/utils/mixin'
|
||||
import { i18nRender } from '@/locales'
|
||||
|
||||
export default {
|
||||
name: 'GlobalHeader',
|
||||
|
@ -79,6 +80,7 @@ export default {
|
|||
document.addEventListener('scroll', this.handleScroll, { passive: true })
|
||||
},
|
||||
methods: {
|
||||
i18nRender,
|
||||
handleScroll () {
|
||||
if (!this.autoHideHeader) {
|
||||
return
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
:menu="menus"
|
||||
:theme="theme"
|
||||
:mode="mode"
|
||||
:i18n-render="i18nRender"
|
||||
@select="onSelect"
|
||||
style="padding: 16px 0px;"></s-menu>
|
||||
</a-layout-sider>
|
||||
|
@ -20,6 +21,7 @@
|
|||
<script>
|
||||
import Logo from '@/components/tools/Logo'
|
||||
import SMenu from './index'
|
||||
import { i18nRender } from '@/locales'
|
||||
import { mixin, mixinDevice } from '@/utils/mixin'
|
||||
|
||||
export default {
|
||||
|
@ -53,6 +55,7 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
i18nRender,
|
||||
onSelect (obj) {
|
||||
this.$emit('menuSelect', obj)
|
||||
}
|
||||
|
|
|
@ -1,31 +1,99 @@
|
|||
import Menu from 'ant-design-vue/es/menu'
|
||||
import Icon from 'ant-design-vue/es/icon'
|
||||
import { Menu, Icon } from 'ant-design-vue'
|
||||
|
||||
const { Item, SubMenu } = Menu
|
||||
|
||||
export default {
|
||||
name: 'SMenu',
|
||||
props: {
|
||||
menu: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'dark'
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inline'
|
||||
},
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
const menuProps = {
|
||||
menu: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'dark'
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inline'
|
||||
},
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
i18nRender: {
|
||||
type: Function,
|
||||
required: false
|
||||
}
|
||||
}
|
||||
|
||||
const defaultI18nRender = (key) => `${key}`
|
||||
|
||||
// render
|
||||
const renderItem = (h, menu, i18nRender) => {
|
||||
if (!menu.hidden) {
|
||||
// const localeKey = `menu.${menu.name}`
|
||||
// const localeKey = menu.meta && menu.meta.title
|
||||
// i18nRender(localeKey)
|
||||
return menu.children && !menu.hideChildrenInMenu ? renderSubMenu(h, menu, i18nRender) : renderMenuItem(h, menu, i18nRender)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const renderMenuItem = (h, menu, i18nRender) => {
|
||||
const target = menu.meta.target || null
|
||||
const CustomTag = target && 'a' || 'router-link'
|
||||
const props = { to: { name: menu.name } }
|
||||
const attrs = { href: menu.path, target: menu.meta.target }
|
||||
|
||||
if (menu.children && menu.hideChildrenInMenu) {
|
||||
// 把有子菜单的 并且 父菜单是要隐藏子菜单的
|
||||
// 都给子菜单增加一个 hidden 属性
|
||||
// 用来给刷新页面时, selectedKeys 做控制用
|
||||
menu.children.forEach(item => {
|
||||
item.meta = Object.assign(item.meta, { hidden: true })
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Menu.Item {...{ key: menu.path }}>
|
||||
<CustomTag {...{ props, attrs }}>
|
||||
{renderIcon(h, menu.meta.icon)}
|
||||
<span>{i18nRender(menu.meta.title)}</span>
|
||||
</CustomTag>
|
||||
</Menu.Item>
|
||||
)
|
||||
}
|
||||
|
||||
const renderSubMenu = (h, menu, i18nRender) => {
|
||||
const itemArr = []
|
||||
if (!menu.hideChildrenInMenu) {
|
||||
menu.children.forEach(item => itemArr.push(renderItem(h, item, i18nRender)))
|
||||
}
|
||||
return (
|
||||
<Menu.SubMenu {...{ key: menu.path }}>
|
||||
<span slot="title">
|
||||
{renderIcon(h, menu.meta.icon)}
|
||||
<span>{i18nRender(menu.meta.title)}</span>
|
||||
</span>
|
||||
{itemArr}
|
||||
</Menu.SubMenu>
|
||||
)
|
||||
}
|
||||
|
||||
const renderIcon = (h, icon) => {
|
||||
if (icon === 'none' || icon === undefined) {
|
||||
return null
|
||||
}
|
||||
const props = {}
|
||||
typeof (icon) === 'object' ? props.component = icon : props.type = icon
|
||||
return (
|
||||
<Icon {...{ props }}/>
|
||||
)
|
||||
}
|
||||
|
||||
const SMenu = {
|
||||
name: 'SMenu',
|
||||
props: menuProps,
|
||||
data () {
|
||||
return {
|
||||
openKeys: [],
|
||||
|
@ -41,24 +109,20 @@ export default {
|
|||
}
|
||||
},
|
||||
created () {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
this.updateMenu()
|
||||
},
|
||||
watch: {
|
||||
collapsed (val) {
|
||||
if (val) {
|
||||
this.$watch('collapsed', collapsed => {
|
||||
if (collapsed) {
|
||||
this.cachedOpenKeys = this.openKeys.concat()
|
||||
this.openKeys = []
|
||||
} else {
|
||||
this.openKeys = this.cachedOpenKeys
|
||||
}
|
||||
},
|
||||
$route: function () {
|
||||
})
|
||||
this.$watch('$route', () => {
|
||||
this.updateMenu()
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
mounted () {
|
||||
this.updateMenu()
|
||||
},
|
||||
methods: {
|
||||
// select menu item
|
||||
|
@ -78,7 +142,6 @@ export default {
|
|||
},
|
||||
updateMenu () {
|
||||
const routes = this.$route.matched.concat()
|
||||
|
||||
const { hidden } = this.$route.meta
|
||||
if (routes.length >= 3 && hidden) {
|
||||
routes.pop()
|
||||
|
@ -94,67 +157,10 @@ export default {
|
|||
}
|
||||
|
||||
this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
|
||||
},
|
||||
// render
|
||||
renderItem (menu) {
|
||||
if (!menu.hidden) {
|
||||
return menu.children && !menu.hideChildrenInMenu ? this.renderSubMenu(menu) : this.renderMenuItem(menu)
|
||||
}
|
||||
return null
|
||||
},
|
||||
renderMenuItem (menu) {
|
||||
const target = menu.meta.target || null
|
||||
const tag = target && 'a' || 'router-link'
|
||||
const props = { to: { name: menu.name } }
|
||||
const attrs = { href: menu.path, target: menu.meta.target }
|
||||
|
||||
if (menu.children && menu.hideChildrenInMenu) {
|
||||
// 把有子菜单的 并且 父菜单是要隐藏子菜单的
|
||||
// 都给子菜单增加一个 hidden 属性
|
||||
// 用来给刷新页面时, selectedKeys 做控制用
|
||||
menu.children.forEach(item => {
|
||||
item.meta = Object.assign(item.meta, { hidden: true })
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Item {...{ key: menu.path }}>
|
||||
<tag {...{ props, attrs }}>
|
||||
{this.renderIcon(menu.meta.icon)}
|
||||
<span>{menu.meta.title}</span>
|
||||
</tag>
|
||||
</Item>
|
||||
)
|
||||
},
|
||||
renderSubMenu (menu) {
|
||||
const itemArr = []
|
||||
if (!menu.hideChildrenInMenu) {
|
||||
menu.children.forEach(item => itemArr.push(this.renderItem(item)))
|
||||
}
|
||||
return (
|
||||
<SubMenu {...{ key: menu.path }}>
|
||||
<span slot="title">
|
||||
{this.renderIcon(menu.meta.icon)}
|
||||
<span>{menu.meta.title}</span>
|
||||
</span>
|
||||
{itemArr}
|
||||
</SubMenu>
|
||||
)
|
||||
},
|
||||
renderIcon (icon) {
|
||||
if (icon === 'none' || icon === undefined) {
|
||||
return null
|
||||
}
|
||||
const props = {}
|
||||
typeof (icon) === 'object' ? props.component = icon : props.type = icon
|
||||
return (
|
||||
<Icon {... { props }} />
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
render () {
|
||||
const { mode, theme, menu } = this
|
||||
render (h) {
|
||||
const { mode, theme, menu, i18nRender = defaultI18nRender } = this
|
||||
const props = {
|
||||
mode: mode,
|
||||
theme: theme,
|
||||
|
@ -172,7 +178,7 @@ export default {
|
|||
if (item.hidden) {
|
||||
return null
|
||||
}
|
||||
return this.renderItem(item)
|
||||
return renderItem(h, item, i18nRender)
|
||||
})
|
||||
// {...{ props, on: on }}
|
||||
return (
|
||||
|
@ -182,3 +188,5 @@ export default {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default SMenu
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
import Menu from 'ant-design-vue/es/menu'
|
||||
import Icon from 'ant-design-vue/es/icon'
|
||||
|
||||
const { Item, SubMenu } = Menu
|
||||
|
||||
export default {
|
||||
name: 'SMenu',
|
||||
props: {
|
||||
menu: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'dark'
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inline'
|
||||
},
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
openKeys: [],
|
||||
selectedKeys: [],
|
||||
cachedOpenKeys: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
rootSubmenuKeys: vm => {
|
||||
const keys = []
|
||||
vm.menu.forEach(item => keys.push(item.path))
|
||||
return keys
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.updateMenu()
|
||||
},
|
||||
watch: {
|
||||
collapsed (val) {
|
||||
if (val) {
|
||||
this.cachedOpenKeys = this.openKeys.concat()
|
||||
this.openKeys = []
|
||||
} else {
|
||||
this.openKeys = this.cachedOpenKeys
|
||||
}
|
||||
},
|
||||
$route: function () {
|
||||
this.updateMenu()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
renderIcon: function (h, icon) {
|
||||
if (icon === 'none' || icon === undefined) {
|
||||
return null
|
||||
}
|
||||
const props = {}
|
||||
typeof (icon) === 'object' ? props.component = icon : props.type = icon
|
||||
return h(Icon, { props: { ...props } })
|
||||
},
|
||||
renderMenuItem: function (h, menu, pIndex, index) {
|
||||
const target = menu.meta.target || null
|
||||
return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index }, [
|
||||
h('router-link', { attrs: { to: { name: menu.name }, target: target } }, [
|
||||
this.renderIcon(h, menu.meta.icon),
|
||||
h('span', [menu.meta.title])
|
||||
])
|
||||
])
|
||||
},
|
||||
renderSubMenu: function (h, menu, pIndex, index) {
|
||||
const this2_ = this
|
||||
const subItem = [h('span', { slot: 'title' }, [this.renderIcon(h, menu.meta.icon), h('span', [menu.meta.title])])]
|
||||
const itemArr = []
|
||||
const pIndex_ = pIndex + '_' + index
|
||||
console.log('menu', menu)
|
||||
if (!menu.hideChildrenInMenu) {
|
||||
menu.children.forEach(function (item, i) {
|
||||
itemArr.push(this2_.renderItem(h, item, pIndex_, i))
|
||||
})
|
||||
}
|
||||
return h(SubMenu, { key: menu.path ? menu.path : 'submenu_' + pIndex + '_' + index }, subItem.concat(itemArr))
|
||||
},
|
||||
renderItem: function (h, menu, pIndex, index) {
|
||||
if (!menu.hidden) {
|
||||
return menu.children && !menu.hideChildrenInMenu
|
||||
? this.renderSubMenu(h, menu, pIndex, index)
|
||||
: this.renderMenuItem(h, menu, pIndex, index)
|
||||
}
|
||||
},
|
||||
renderMenu: function (h, menuTree) {
|
||||
const this2_ = this
|
||||
const menuArr = []
|
||||
menuTree.forEach(function (menu, i) {
|
||||
if (!menu.hidden) {
|
||||
menuArr.push(this2_.renderItem(h, menu, '0', i))
|
||||
}
|
||||
})
|
||||
return menuArr
|
||||
},
|
||||
onOpenChange (openKeys) {
|
||||
const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
|
||||
if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
|
||||
this.openKeys = openKeys
|
||||
} else {
|
||||
this.openKeys = latestOpenKey ? [latestOpenKey] : []
|
||||
}
|
||||
},
|
||||
updateMenu () {
|
||||
const routes = this.$route.matched.concat()
|
||||
|
||||
if (routes.length >= 4 && this.$route.meta.hidden) {
|
||||
routes.pop()
|
||||
this.selectedKeys = [routes[2].path]
|
||||
} else {
|
||||
this.selectedKeys = [routes.pop().path]
|
||||
}
|
||||
|
||||
const openKeys = []
|
||||
if (this.mode === 'inline') {
|
||||
routes.forEach(item => {
|
||||
openKeys.push(item.path)
|
||||
})
|
||||
}
|
||||
|
||||
this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
|
||||
}
|
||||
},
|
||||
render (h) {
|
||||
return h(
|
||||
Menu,
|
||||
{
|
||||
props: {
|
||||
theme: this.$props.theme,
|
||||
mode: this.$props.mode,
|
||||
openKeys: this.openKeys,
|
||||
selectedKeys: this.selectedKeys
|
||||
},
|
||||
on: {
|
||||
openChange: this.onOpenChange,
|
||||
select: obj => {
|
||||
this.selectedKeys = obj.selectedKeys
|
||||
this.$emit('select', obj)
|
||||
}
|
||||
}
|
||||
},
|
||||
this.renderMenu(h, this.menu)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="page-header">
|
||||
<div class="page-header-index-wide">
|
||||
<s-breadcrumb />
|
||||
<s-breadcrumb :i18n-render="i18nRender" />
|
||||
<div class="detail">
|
||||
<div class="main" v-if="!$route.meta.hiddenHeaderContent">
|
||||
<div class="row">
|
||||
|
@ -32,7 +32,9 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
/* eslint-disable */
|
||||
import Breadcrumb from '@/components/tools/Breadcrumb'
|
||||
import { i18nRender } from '@/locales'
|
||||
|
||||
export default {
|
||||
name: 'PageHeader',
|
||||
|
@ -58,6 +60,9 @@ export default {
|
|||
},
|
||||
data () {
|
||||
return {}
|
||||
},
|
||||
methods () {
|
||||
i18nRender
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -4,14 +4,20 @@
|
|||
<router-link
|
||||
v-if="item.name != name && index != 1"
|
||||
:to="{ path: item.path === '' ? '/' : item.path }"
|
||||
>{{ item.meta.title }}</router-link>
|
||||
<span v-else>{{ item.meta.title }}</span>
|
||||
>{{ i18nRender(item.meta.title) }}</router-link>
|
||||
<span v-else>{{ i18nRender(item.meta.title) }}</span>
|
||||
</a-breadcrumb-item>
|
||||
</a-breadcrumb>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
i18nRender: {
|
||||
type: Function,
|
||||
default: (r) => `${r}`
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
name: '',
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<template>
|
||||
<a-dropdown>
|
||||
<span class="action global-lang">
|
||||
<a-icon type="global" style="font-size: 16px"/>
|
||||
</span>
|
||||
<a-menu slot="overlay" style="width: 150px;" @click="SwitchLang">
|
||||
<a-menu-item key="zh-CN">
|
||||
<a rel="noopener noreferrer">
|
||||
<span role="img" aria-label="简体中文">🇨🇳</span> 简体中文
|
||||
</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="en-US">
|
||||
<a rel="noopener noreferrer">
|
||||
<span role="img" aria-label="English">🇬🇧</span> English
|
||||
</a>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mixin as langMixin } from '@/store/i18n-mixin'
|
||||
|
||||
export default {
|
||||
name: 'LangSelect',
|
||||
mixins: [langMixin],
|
||||
data () {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
SwitchLang (row) {
|
||||
this.setLang(row.key)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -3,7 +3,7 @@
|
|||
<div class="content-box">
|
||||
<a href="https://github.com/pycook/cmdb" target="_blank">
|
||||
<span class="action">
|
||||
源代码 -> <a-icon type="github" style="font-size: 20px; color: #002140"></a-icon>
|
||||
{{ $t('tip.sourceCode') }} -> <a-icon type="github" style="font-size: 20px; color: #002140"></a-icon>
|
||||
</span>
|
||||
</a>
|
||||
<!-- <a href="https://pro.loacg.com/docs/getting-started" target="_blank">
|
||||
|
@ -39,6 +39,7 @@
|
|||
</a-menu-item>
|
||||
</a-menu>
|
||||
</a-dropdown>
|
||||
<lang-select v-if="showLocale" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -46,11 +47,18 @@
|
|||
<script>
|
||||
import NoticeIcon from '@/components/NoticeIcon'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import LangSelect from '@/components/tools/LangSelect'
|
||||
import { showLocale } from '@/locales'
|
||||
|
||||
export default {
|
||||
name: 'UserMenu',
|
||||
components: {
|
||||
NoticeIcon
|
||||
NoticeIcon, LangSelect
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
showLocale: showLocale
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['Logout']),
|
||||
|
|
|
@ -10,21 +10,21 @@ const cmdbRouter = [
|
|||
path: '/preference',
|
||||
component: () => import('@/views/cmdb/preference'),
|
||||
name: 'cmdb_preference',
|
||||
meta: { title: '我的订阅', icon: 'book', keepAlive: true }
|
||||
meta: { title: 'menu.preference', icon: 'book', keepAlive: true }
|
||||
},
|
||||
// relation views
|
||||
{
|
||||
path: '/relation_views',
|
||||
component: () => import('@/views/cmdb/relation_views'),
|
||||
name: 'cmdb_relation_views',
|
||||
meta: { title: '关系视图', icon: 'link', keepAlive: true },
|
||||
meta: { title: 'menu.relationViews', icon: 'link', keepAlive: true },
|
||||
hideChildrenInMenu: true,
|
||||
children: [
|
||||
{
|
||||
path: '/relation_views/:viewId',
|
||||
name: 'cmdb_relation_views_item',
|
||||
component: () => import('@/views/cmdb/relation_views'),
|
||||
meta: { title: '关系视图', keepAlive: true },
|
||||
meta: { title: 'menu.relationViews', keepAlive: true },
|
||||
hidden: true
|
||||
}]
|
||||
},
|
||||
|
@ -33,14 +33,14 @@ const cmdbRouter = [
|
|||
path: '/tree_views',
|
||||
component: () => import('@/views/cmdb/tree_views'),
|
||||
name: 'cmdb_tree_views',
|
||||
meta: { title: '树形视图', icon: 'share-alt', keepAlive: true },
|
||||
meta: { title: 'menu.treeViews', icon: 'share-alt', keepAlive: true },
|
||||
hideChildrenInMenu: true,
|
||||
children: [
|
||||
{
|
||||
path: '/tree_views/:typeId',
|
||||
name: 'cmdb_tree_views_item',
|
||||
component: () => import('@/views/cmdb/tree_views'),
|
||||
meta: { title: '树形视图', keepAlive: true },
|
||||
meta: { title: 'menu.treeViews', keepAlive: true },
|
||||
hidden: true
|
||||
}]
|
||||
},
|
||||
|
@ -49,28 +49,28 @@ const cmdbRouter = [
|
|||
path: '/batch',
|
||||
component: () => import('@/views/cmdb/batch'),
|
||||
name: 'cmdb_batch',
|
||||
meta: { 'title': '批量导入', icon: 'upload', keepAlive: true }
|
||||
meta: { 'title': 'menu.batch', icon: 'upload', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: '/config//ci_types',
|
||||
name: 'cmdb_ci_type',
|
||||
component: RouteView,
|
||||
redirect: '/ci_types',
|
||||
meta: { title: '模型配置', icon: 'setting', permission: ['admin'] },
|
||||
meta: { title: 'menu.ciType', icon: 'setting', permission: ['admin'] },
|
||||
children: [
|
||||
{
|
||||
path: '/config/ci_types',
|
||||
name: 'ci_type',
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('@/views/cmdb/modeling/ci_type/list'),
|
||||
meta: { title: '模型管理', keepAlive: true }
|
||||
meta: { title: 'menu.ciModelManager', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: '/config/ci_types/:CITypeName/detail/:CITypeId',
|
||||
name: 'ci_type_detail',
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('@/views/cmdb/modeling/ci_type/detail'),
|
||||
meta: { title: '模型管理', keepAlive: true, hidden: true },
|
||||
meta: { title: 'menu.ciModelManager', keepAlive: true, hidden: true },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
|
@ -78,21 +78,21 @@ const cmdbRouter = [
|
|||
name: 'attributes',
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('@/views/cmdb/modeling/attributes/index'),
|
||||
meta: { title: '属性库', keepAlive: true }
|
||||
meta: { title: 'menu.ciPropertyRep', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: '/config/relation_type',
|
||||
name: 'relation_type',
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('@/views/cmdb/modeling/relation_type/index'),
|
||||
meta: { title: '关系类型', keepAlive: true }
|
||||
meta: { title: 'menu.ciRelationType', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: '/config/preference_relation',
|
||||
name: 'preference_relation',
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('@/views/cmdb/modeling/preference_relation/index'),
|
||||
meta: { title: '关系视图定义', keepAlive: true }
|
||||
meta: { title: 'menu.ciRelationViewDefine', keepAlive: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -101,35 +101,35 @@ const cmdbRouter = [
|
|||
name: 'cmdb_acl',
|
||||
component: RouteView,
|
||||
redirect: '/acl/users',
|
||||
meta: { title: '权限管理', icon: 'safety-certificate', permission: ['admin'] },
|
||||
meta: { title: 'menu.acl', icon: 'safety-certificate', permission: ['admin'] },
|
||||
children: [
|
||||
{
|
||||
path: '/acl/users',
|
||||
name: 'cmdb_acl_users',
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('@/views/acl/users'),
|
||||
meta: { title: '用户管理', keepAlive: true }
|
||||
meta: { title: 'menu.aclUsersManager', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: '/acl/roles',
|
||||
name: 'cmdb_acl_roles',
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('@/views/acl/roles'),
|
||||
meta: { title: '角色管理', keepAlive: true }
|
||||
meta: { title: 'menu.aclRolesManager', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: '/acl/resources',
|
||||
name: 'cmdb_acl_resources',
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('@/views/acl/resources'),
|
||||
meta: { title: '资源管理', keepAlive: true }
|
||||
meta: { title: 'menu.aclResourceManager', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: '/acl/resource_types',
|
||||
name: 'cmdb_acl_resource_types',
|
||||
hideChildrenInMenu: true,
|
||||
component: () => import('@/views/acl/resource_types'),
|
||||
meta: { title: '资源类型', keepAlive: true }
|
||||
meta: { title: 'menu.aclResourceType', keepAlive: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
// default language
|
||||
import enUS from './lang/en-US'
|
||||
import zhCN from './lang/zh-CN'
|
||||
// change default accept-language
|
||||
import { axios } from '@/utils/request'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
export const defaultLang = 'zh-CN'
|
||||
export const showLocale = true
|
||||
|
||||
const messages = {
|
||||
'en-US': {
|
||||
...enUS
|
||||
},
|
||||
'zh-CN': {
|
||||
...zhCN
|
||||
}
|
||||
}
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: defaultLang,
|
||||
fallbackLocale: defaultLang,
|
||||
messages
|
||||
})
|
||||
|
||||
export default i18n
|
||||
|
||||
const loadedLanguages = [defaultLang]
|
||||
|
||||
// 从缓存設置中加载当前语言
|
||||
|
||||
function setI18nLanguage (lang) {
|
||||
i18n.locale = lang
|
||||
axios.defaults.headers.common['Accept-Language'] = lang
|
||||
document.querySelector('html').setAttribute('lang', lang)
|
||||
return lang
|
||||
}
|
||||
|
||||
export function i18nRender (key) {
|
||||
return i18n.t(key)
|
||||
}
|
||||
|
||||
export function loadLanguageAsync (lang = defaultLang) {
|
||||
return new Promise(resolve => {
|
||||
// 缓存语言设置
|
||||
Vue.ls.set('lang', lang)
|
||||
if (i18n.locale !== lang) {
|
||||
if (!loadedLanguages.includes(lang)) {
|
||||
return import(/* webpackChunkName: "lang-[request]" */ `./lang/${lang}`).then(msg => {
|
||||
i18n.setLocaleMessage(lang, msg.default)
|
||||
loadedLanguages.push(lang)
|
||||
return setI18nLanguage(lang)
|
||||
})
|
||||
}
|
||||
return resolve(setI18nLanguage(lang))
|
||||
}
|
||||
return resolve(lang)
|
||||
})
|
||||
}
|
||||
|
||||
// if (Vue.ls.get('lang') !== null && defaultLang !== Vue.ls.get('lang')) {
|
||||
// loadLanguageAsync(localStorage.lang)
|
||||
// }
|
|
@ -0,0 +1,72 @@
|
|||
/* eslint-disable */
|
||||
import enUS from 'ant-design-vue/es/locale-provider/en_US'
|
||||
export default {
|
||||
antLocale: enUS,
|
||||
menu: {
|
||||
preference: 'Preference',
|
||||
relationViews: 'RelationViews',
|
||||
treeViews: 'TreeViews',
|
||||
batch: 'Batch',
|
||||
ciType: 'CiType',
|
||||
acl: 'ACL',
|
||||
ciModelManager: 'Model',
|
||||
ciPropertyRep: 'Propertys',
|
||||
ciRelationType: 'RelationType',
|
||||
ciRelationViewDefine: 'RelationViewDefine',
|
||||
aclUsersManager: 'Users',
|
||||
aclRolesManager: 'Roles',
|
||||
aclResourceManager: 'Resources',
|
||||
aclResourceType: 'ResourceType'
|
||||
},
|
||||
button: {
|
||||
cancel: 'Cancel',
|
||||
submit: 'Submit',
|
||||
query: 'Query',
|
||||
add: 'Add',
|
||||
delete: 'Delete',
|
||||
yes: 'Yes',
|
||||
no: 'No',
|
||||
reset: 'Reset',
|
||||
subscribe: 'Subscribe',
|
||||
download: 'Download',
|
||||
upload: 'Upload'
|
||||
},
|
||||
tip: {
|
||||
sourceCode: 'view on',
|
||||
subscribed: 'Subscribed',
|
||||
unsubscribed: 'Unsubscribed',
|
||||
unfold: 'Unfold',
|
||||
fold: 'Fold',
|
||||
detail: 'Detail',
|
||||
delete: 'Delete',
|
||||
edit: 'Edit',
|
||||
operate: 'Operate',
|
||||
clear: 'Clear',
|
||||
modify: 'Modify',
|
||||
pleaseSelect: 'please select'
|
||||
},
|
||||
ci: {
|
||||
selected: 'Selected',
|
||||
batchOperate: 'Batch operate'
|
||||
|
||||
},
|
||||
preference: {
|
||||
subscribeModel: 'Subscribe Model',
|
||||
resourceView: 'Resource View',
|
||||
subFormTip: 'You can either define a tree view or subscribe to a resource view, which will be presented separately in sidebar'
|
||||
},
|
||||
batch: {
|
||||
modelType: 'Model Type',
|
||||
pleaseSelectModelType: 'please select model type',
|
||||
uploadResult: 'upload result',
|
||||
dragFileHere: 'click or drag file to here!',
|
||||
suportFileType: 'suport file type'
|
||||
},
|
||||
ciType: {
|
||||
add: 'Add',
|
||||
editModel: 'edit model',
|
||||
modelName: 'model name',
|
||||
alias: 'alias',
|
||||
uniqueFlag: 'unique flag'
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/* eslint-disable */
|
||||
import zhCN from 'ant-design-vue/es/locale-provider/zh_CN'
|
||||
export default {
|
||||
antLocale: zhCN,
|
||||
menu: {
|
||||
preference: '我的订阅',
|
||||
relationViews: '关系视图',
|
||||
treeViews: '树状视图',
|
||||
batch: '批量导入',
|
||||
ciType: '模型配置',
|
||||
acl: '权限管理',
|
||||
ciModelManager: '模型管理',
|
||||
ciPropertyRep: '属性库',
|
||||
ciRelationType: '关系类型',
|
||||
ciRelationViewDefine: '关系视图定义',
|
||||
aclUsersManager: '用户管理',
|
||||
aclRolesManager: '角色管理',
|
||||
aclResourceManager: '资源管理',
|
||||
aclResourceType: '资源类型'
|
||||
},
|
||||
button: {
|
||||
cancel: '取消',
|
||||
submit: '提交',
|
||||
query: '查询',
|
||||
add: '新增',
|
||||
delete: '删除',
|
||||
yes: '是',
|
||||
no: '否',
|
||||
reset: '重置',
|
||||
subscribe: '订阅',
|
||||
download: '下载模板',
|
||||
upload: '上传'
|
||||
},
|
||||
tip: {
|
||||
sourceCode: '源代码',
|
||||
subscribed: '已订阅',
|
||||
unsubscribed: '未订阅',
|
||||
unfold: '展开',
|
||||
fold: '收起',
|
||||
detail: '详情',
|
||||
delete: '删除',
|
||||
edit: '编辑',
|
||||
operate: '操作',
|
||||
clear: '清空',
|
||||
modify: '修改',
|
||||
pleaseSelect: '请选择'
|
||||
},
|
||||
ci: {
|
||||
selected: '已选择',
|
||||
batchOperate: '批量操作'
|
||||
|
||||
},
|
||||
preference: {
|
||||
subscribeModel: '订阅模型',
|
||||
resourceView: '资源视图',
|
||||
subFormTip: '既可以定义树形视图, 也可以订阅资源视图, 资源视图会在SideBar单独呈现'
|
||||
},
|
||||
batch: {
|
||||
modelType: '模板类型',
|
||||
pleaseSelectModelType: '请选择模板类型',
|
||||
uploadResult: '上传结果',
|
||||
dragFileHere: '点击或拖拽文件至此上传!',
|
||||
suportFileType: '支持文件类型'
|
||||
},
|
||||
ciType: {
|
||||
add: '新增',
|
||||
editModel: '编辑模型',
|
||||
modelName: '模型名(英文)',
|
||||
alias: '别名',
|
||||
uniqueFlag: '唯一标识'
|
||||
}
|
||||
}
|
|
@ -5,7 +5,8 @@ import Vue from 'vue'
|
|||
import EventBus from './EventBus'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store/'
|
||||
import store from './store'
|
||||
import i18n from './locales'
|
||||
import { VueAxios } from './utils/request'
|
||||
|
||||
import bootstrap from './core/bootstrap'
|
||||
|
@ -22,6 +23,7 @@ Vue.use(VueAxios)
|
|||
new Vue({
|
||||
router,
|
||||
store,
|
||||
i18n,
|
||||
created: bootstrap,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
|
|
|
@ -8,12 +8,20 @@ import notification from 'ant-design-vue/es/notification'
|
|||
import { setDocumentTitle, domTitle } from '@/utils/domUtil'
|
||||
import config from '@/config/defaultSettings'
|
||||
import { ACCESS_TOKEN } from './store/mutation-types'
|
||||
import i18n from '@/locales'
|
||||
|
||||
NProgress.configure({ showSpinner: false }) // NProgress Configuration
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
NProgress.start() // start progress bar
|
||||
to.meta && (typeof to.meta.title !== 'undefined' && setDocumentTitle(`${to.meta.title} - ${domTitle}`))
|
||||
var displayTitle
|
||||
|
||||
if (to.meta && to.meta.title && to.meta.title.split('.')[0] === 'menu') {
|
||||
displayTitle = i18n.messages[i18n.locale].menu[to.meta.title.split('.')[1]]
|
||||
} else if (to.meta && to.meta.title) {
|
||||
displayTitle = to.meta.title
|
||||
}
|
||||
to.meta && (typeof to.meta.title !== 'undefined' && setDocumentTitle(`${displayTitle} - ${domTitle}`))
|
||||
if ((config.useSSO || (!config.useSSO && Vue.ls.get(ACCESS_TOKEN))) && store.getters.roles.length === 0) {
|
||||
store
|
||||
.dispatch('GetInfo')
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import { mapState } from 'vuex'
|
||||
|
||||
const mixin = {
|
||||
computed: {
|
||||
...mapState({
|
||||
currentLang: state => state.i18n.lang
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
setLang (lang) {
|
||||
this.$store.dispatch('SetLang', lang)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { mixin }
|
|
@ -3,6 +3,7 @@ import Vuex from 'vuex'
|
|||
|
||||
import app from './modules/app'
|
||||
import user from './modules/user'
|
||||
import i18n from './modules/i18n'
|
||||
import permission from './modules/permission'
|
||||
import getters from './getters'
|
||||
|
||||
|
@ -12,7 +13,8 @@ export default new Vuex.Store({
|
|||
modules: {
|
||||
app,
|
||||
user,
|
||||
permission
|
||||
permission,
|
||||
i18n
|
||||
},
|
||||
state: {
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { loadLanguageAsync } from '@/locales'
|
||||
|
||||
const i18n = {
|
||||
state: {
|
||||
lang: 'en-US'
|
||||
},
|
||||
mutations: {
|
||||
SET_LANG: (state, lang) => {
|
||||
state.lang = lang
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
// 设置界面语言
|
||||
SetLang ({ commit }, lang) {
|
||||
return new Promise(resolve => {
|
||||
commit('SET_LANG', lang)
|
||||
loadLanguageAsync(lang)
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default i18n
|
|
@ -28,7 +28,7 @@
|
|||
</a-row>
|
||||
|
||||
<template slot="footer">
|
||||
<a-button key="back" @click="cancelHandel">取消</a-button>
|
||||
<a-button key="back" @click="cancelHandel">{{ $t('button.cancel') }}</a-button>
|
||||
<a-button key="submit" type="primary" :loading="confirmLoading" @click="okHandel">保存</a-button>
|
||||
</template>
|
||||
</a-modal>
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
>
|
||||
<a-button @click="handleAddParent" type="primary" style="margin-right: 1rem">关联父角色</a-button>
|
||||
<a-button @click="handleAddChild" type="primary" style="margin-right: 1rem">关联子角色</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
</a-form-item>
|
||||
<div class="btn-group">
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">添加</a-button>
|
||||
<a-button @click="closeForm">取消</a-button>
|
||||
<a-button @click="closeForm">{{ $t('button.cancel') }}</a-button>
|
||||
</div>
|
||||
|
||||
</a-form>
|
||||
|
|
|
@ -60,8 +60,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -66,8 +66,8 @@
|
|||
background: '#fff',
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
</div>
|
||||
|
||||
</a-form>
|
||||
|
|
|
@ -133,8 +133,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
@click="() => handleReset(clearFilters, column)"
|
||||
size="small"
|
||||
style="width: 90px"
|
||||
>重置</a-button>
|
||||
>{{ $t('button.reset') }}</a-button>
|
||||
</div>
|
||||
<a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
|
||||
|
||||
|
@ -61,7 +61,7 @@
|
|||
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
<a @click="handleEdit(record)">编辑</a>
|
||||
<a @click="handleEdit(record)">{{ $t('tip.edit') }}</a>
|
||||
<a-divider type="vertical"/>
|
||||
|
||||
<a-popconfirm
|
||||
|
@ -71,7 +71,7 @@
|
|||
okText="是"
|
||||
cancelText="否"
|
||||
>
|
||||
<a>删除</a>
|
||||
<a>{{ $t('tip.delete') }}</a>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</span>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
@click="() => handleReset(clearFilters, column)"
|
||||
size="small"
|
||||
style="width: 90px"
|
||||
>重置</a-button>
|
||||
>{{ $t('button.reset') }}</a-button>
|
||||
</div>
|
||||
<a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
|
||||
|
||||
|
@ -61,7 +61,7 @@
|
|||
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
<a @click="handleEdit(record)">编辑</a>
|
||||
<a @click="handleEdit(record)">{{ $t('tip.edit') }}</a>
|
||||
<a-divider type="vertical"/>
|
||||
|
||||
<a-popconfirm
|
||||
|
@ -71,7 +71,7 @@
|
|||
okText="是"
|
||||
cancelText="否"
|
||||
>
|
||||
<a>删除</a>
|
||||
<a>{{ $t('tip.delete') }}</a>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</span>
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
@click="() => handleReset(clearFilters, column)"
|
||||
size="small"
|
||||
style="width: 90px"
|
||||
>重置</a-button>
|
||||
>{{ $t('button.reset') }}</a-button>
|
||||
</div>
|
||||
<a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
|
||||
|
||||
|
@ -81,7 +81,7 @@
|
|||
okText="是"
|
||||
cancelText="否"
|
||||
>
|
||||
<a>删除</a>
|
||||
<a>{{ $t('tip.delete') }}</a>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</span>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
@click="() => handleReset(clearFilters, column)"
|
||||
size="small"
|
||||
style="width: 90px"
|
||||
>重置</a-button>
|
||||
>{{ $t('button.reset') }}</a-button>
|
||||
</div>
|
||||
<a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
|
||||
|
||||
|
@ -70,7 +70,7 @@
|
|||
okText="是"
|
||||
cancelText="否"
|
||||
>
|
||||
<a>删除</a>
|
||||
<a>{{ $t('tip.delete') }}</a>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</span>
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
@click="() => handleReset(clearFilters, column)"
|
||||
size="small"
|
||||
style="width: 90px"
|
||||
>重置</a-button>
|
||||
>{{ $t('button.reset') }}</a-button>
|
||||
</div>
|
||||
<a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
|
||||
|
||||
|
@ -71,7 +71,7 @@
|
|||
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
<a @click="handleEdit(record)">编辑</a>
|
||||
<a @click="handleEdit(record)">{{ $t('tip.edit') }}</a>
|
||||
<a-divider type="vertical"/>
|
||||
|
||||
<a-popconfirm
|
||||
|
@ -81,7 +81,7 @@
|
|||
okText="是"
|
||||
cancelText="否"
|
||||
>
|
||||
<a>删除</a>
|
||||
<a>{{ $t('tip.delete') }}</a>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</span>
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
<a-row>
|
||||
<a-col :span="18">
|
||||
<a-card style="height: 605px">
|
||||
<a-button class="ant-btn-primary" style="margin-left: 10px;" :disabled="uploadFlag" id="upload-button" @click="uploadData">上传</a-button>
|
||||
<a-button class="ant-btn-primary" style="margin-left: 10px;" :disabled="uploadFlag" id="upload-button" @click="uploadData">{{ $t('button.upload') }}</a-button>
|
||||
<upload-file-form v-if="displayUpload" ref="fileEditor"></upload-file-form>
|
||||
<ci-table v-if="editorOnline" :ciTypeAttrs="ciTypeAttrs" ref="onlineEditor"></ci-table>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<div style="min-height: 604px; background: white">
|
||||
<a-card title="上传结果">
|
||||
<a-card :title="$t('batch.uploadResult')">
|
||||
<upload-result v-if="beginLoad" :upLoadData="needDataList" :ciType="ciType" :unique-field="uniqueField"></upload-result>
|
||||
</a-card>
|
||||
</div>
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
<a-form :form="form" style="max-width: 500px; margin: 30px auto 0;">
|
||||
<a-row>
|
||||
<a-col :span="18">
|
||||
<a-form-item label="模板类型" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-form-item :label="$t('batch.modelType')" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select
|
||||
placeholder="--请选择模板类型--"
|
||||
:placeholder="$t('batch.pleaseSelectModelType')"
|
||||
v-decorator="['ciTypes', { rules: [{required: true, message: '模板类型必须选择'}] }]"
|
||||
@change="selectCiType"
|
||||
>
|
||||
|
@ -19,7 +19,7 @@
|
|||
style="margin-left: 20px"
|
||||
:disabled="downLoadButtonDis"
|
||||
@click="downLoadExcel"
|
||||
>下载模板</a-button>
|
||||
>{{ $t('button.download') }}</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<p class="ant-upload-drag-icon">
|
||||
<a-icon type="inbox" />
|
||||
</p>
|
||||
<p class="ant-upload-text">点击或拖拽文件至此上传!</p>
|
||||
<p class="ant-upload-hint">支持文件类型:xls</p>
|
||||
<p class="ant-upload-text">{{ $t('batch.dragFileHere') }}</p>
|
||||
<p class="ant-upload-hint">{{ $t('batch.suportFileType') }} : xls</p>
|
||||
</a-upload-dragger>
|
||||
</a-form>
|
||||
<a-divider>or</a-divider>
|
||||
|
|
|
@ -73,14 +73,14 @@
|
|||
class="table-page-search-submitButtons"
|
||||
:style="advanced && { float: 'right', overflow: 'hidden' } || {} "
|
||||
>
|
||||
<a-button type="primary" @click="$emit('refresh', true)" v-if="preferenceAttrList.length">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="() => queryParam = {}" v-if="preferenceAttrList.length">重置</a-button>
|
||||
<a-button type="primary" @click="$emit('refresh', true)" v-if="preferenceAttrList.length">{{ $t('button.query') }}</a-button>
|
||||
<a-button style="margin-left: 8px" @click="() => queryParam = {}" v-if="preferenceAttrList.length">{{ $t('button.reset') }}</a-button>
|
||||
<a
|
||||
@click="toggleAdvanced"
|
||||
style="margin-left: 8px"
|
||||
v-if="preferenceAttrList.length > 4"
|
||||
>
|
||||
{{ advanced ? '收起' : '展开' }}
|
||||
{{ advanced ? $t('tip.fold') : $t('tip.unfold') }}
|
||||
<a-icon :type="advanced ? 'up' : 'down'" />
|
||||
</a>
|
||||
</span>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
@click="() => handleReset(clearFilters, column)"
|
||||
size="small"
|
||||
style="width: 90px"
|
||||
>重置</a-button>
|
||||
>{{ $t('button.reset') }}</a-button>
|
||||
</div>
|
||||
<a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
|
||||
|
||||
|
@ -69,7 +69,7 @@
|
|||
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
<a @click="handleEdit(record)">编辑</a>
|
||||
<a @click="handleEdit(record)">{{ $t('tip.edit') }}</a>
|
||||
<a-divider type="vertical"/>
|
||||
|
||||
<a-popconfirm
|
||||
|
@ -78,7 +78,7 @@
|
|||
okText="是"
|
||||
cancelText="否"
|
||||
>
|
||||
<a>删除</a>
|
||||
<a>{{ $t('tip.delete') }}</a>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</span>
|
||||
|
|
|
@ -148,8 +148,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
<a @click="handleEdit(record)">编辑</a>
|
||||
<a @click="handleEdit(record)">{{ $t('tip.edit') }}</a>
|
||||
<a-divider type="vertical"/>
|
||||
|
||||
<a-popconfirm
|
||||
|
@ -77,7 +77,7 @@
|
|||
okText="是"
|
||||
cancelText="否"
|
||||
>
|
||||
<a>删除</a>
|
||||
<a>{{ $t('tip.delete') }}</a>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</span>
|
||||
|
@ -124,8 +124,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleBatchUpdateSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onBatchBindAttrActionClose">取消</a-button>
|
||||
<a-button @click="handleBatchUpdateSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onBatchBindAttrActionClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
</a-form>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
<a @click="handleDelete(record)">删除</a>
|
||||
<a @click="handleDelete(record)">{{ $t('tip.delete') }}</a>
|
||||
</template>
|
||||
</span>
|
||||
|
||||
|
@ -65,8 +65,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
</a-form>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
<a @click="handleDelete(record)">删除</a>
|
||||
<a @click="handleDelete(record)">{{ $t('tip.delete') }}</a>
|
||||
</template>
|
||||
</span>
|
||||
|
||||
|
@ -64,8 +64,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
</a-form>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
ref="addGroupInput"
|
||||
v-model.trim="newGroupName" />
|
||||
<a @click="handleCreateGroup" style="margin-right: 0.5rem">保存</a>
|
||||
<a @click="handleCancelCreateGroup">取消</a>
|
||||
<a @click="handleCancelCreateGroup">{{ $t('button.cancel') }}</a>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
|||
ref="editGroupInput"
|
||||
v-model.trim="CITypeGroup.name" />
|
||||
<a @click="handleSaveGroupName(index, CITypeGroup)" style="margin-right: 0.5rem">保存</a>
|
||||
<a @click="handleCancelGroupName(index, CITypeGroup)">取消</a>
|
||||
<a @click="handleCancelGroupName(index, CITypeGroup)">{{ $t('button.cancel') }}</a>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -125,8 +125,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
</a-form>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
<a @click="handleDelete(record)">删除</a>
|
||||
<a @click="handleDelete(record)">{{ $t('tip.delete') }}</a>
|
||||
</template>
|
||||
</span>
|
||||
|
||||
|
@ -91,8 +91,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
</a-form>
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
@click="() => handleReset(clearFilters, column)"
|
||||
size="small"
|
||||
style="width: 90px"
|
||||
>重置</a-button>
|
||||
>{{ $t('button.reset') }}</a-button>
|
||||
</div>
|
||||
<a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
|
||||
|
||||
|
@ -57,7 +57,7 @@
|
|||
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<template>
|
||||
<a @click="handleEdit(record)">编辑</a>
|
||||
<a @click="handleEdit(record)">{{ $t('tip.edit') }}</a>
|
||||
<a-divider type="vertical"/>
|
||||
|
||||
<a-popconfirm
|
||||
|
@ -67,7 +67,7 @@
|
|||
okText="是"
|
||||
cancelText="否"
|
||||
>
|
||||
<a>删除</a>
|
||||
<a>{{ $t('tip.delete') }}</a>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</span>
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
|
||||
}"
|
||||
>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">确定</a-button>
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button @click="handleSubmit" type="primary" style="margin-right: 1rem">{{ $t('button.submit') }}</a-button>
|
||||
<a-button @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
<span
|
||||
:class="item.is_subscribed?'subscribe-success':'unsubscribe'"
|
||||
slot="title"
|
||||
>{{ item.is_subscribed ? "已订阅" : "未订阅" }}</span>
|
||||
>{{ item.is_subscribed ? $t('tip.subscribed') : $t('tip.unsubscribed') }}</span>
|
||||
</a-card-meta>
|
||||
<template class="ant-card-actions" slot="actions">
|
||||
<a :disabled="!item.is_subscribed" @click="unsubscribe(item.id)">取消</a>
|
||||
<a @click="showDrawer(item.id, item.alias || item.name)">订阅</a>
|
||||
<a :disabled="!item.is_subscribed" @click="unsubscribe(item.id)">{{ $t('button.cancel') }}</a>
|
||||
<a @click="showDrawer(item.id, item.alias || item.name)">{{ $t('button.subscribe') }}</a>
|
||||
</template>
|
||||
</a-card>
|
||||
</template>
|
||||
|
@ -31,20 +31,20 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-drawer
|
||||
:title="'订阅模型: ' + typeName"
|
||||
:title="$t('preference.subscribeModel') +':'+ typeName"
|
||||
:width="600"
|
||||
@close="onClose"
|
||||
:visible="visible"
|
||||
:wrapStyle="{height: 'calc(100% - 108px)', overflow: 'auto', paddingBottom: '108px'}"
|
||||
>
|
||||
<a-alert message="既可以定义树形视图, 也可以订阅资源视图, 资源视图会在SideBar单独呈现" type="info" showIcon />
|
||||
<a-alert :message="$t('preference.subFormTip')" type="info" showIcon />
|
||||
<a-divider>
|
||||
树形视图
|
||||
{{ $t('menu.treeViews') }}
|
||||
<span
|
||||
v-if="treeSubscribed"
|
||||
style="font-weight: 500; font-size: 12px; color: green"
|
||||
>已订阅</span>
|
||||
<span style="font-weight: 500; font-size: 12px; color: red" v-else>未订阅</span>
|
||||
>{{ $t('tip.subscribed') }}</span>
|
||||
<span style="font-weight: 500; font-size: 12px; color: red" v-else>{{ $t('tip.unsubscribed') }}</span>
|
||||
</a-divider>
|
||||
<a-select
|
||||
ref="tree"
|
||||
|
@ -60,17 +60,17 @@
|
|||
@click="subTreeSubmit"
|
||||
type="primary"
|
||||
:style="{float: 'right', marginTop: '10px'}"
|
||||
>订阅</a-button>
|
||||
>{{ $t('button.subscribe') }}</a-button>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<a-divider>
|
||||
资源视图
|
||||
{{ $t('preference.resourceView') }}
|
||||
<span
|
||||
v-if="instanceSubscribed"
|
||||
style="font-weight: 500; font-size: 12px; color: green"
|
||||
>已订阅</span>
|
||||
<span style="font-weight: 500; font-size: 12px; color: red" v-else>未订阅</span>
|
||||
>{{ $t('tip.subscribed') }}</span>
|
||||
<span style="font-weight: 500; font-size: 12px; color: red" v-else>{{ $t('tip.unsubscribed') }}</span>
|
||||
</a-divider>
|
||||
<template>
|
||||
<a-transfer
|
||||
|
@ -101,8 +101,8 @@
|
|||
textAlign: 'right',
|
||||
}"
|
||||
>
|
||||
<a-button :style="{marginRight: '8px'}" @click="onClose">取消</a-button>
|
||||
<a-button @click="subInstanceSubmit" type="primary">订阅</a-button>
|
||||
<a-button :style="{marginRight: '8px'}" @click="onClose">{{ $t('button.cancel') }}</a-button>
|
||||
<a-button @click="subInstanceSubmit" type="primary">{{ $t('button.subscribe') }}</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</div>
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
class="login-button"
|
||||
:loading="state.loginBtn"
|
||||
:disabled="state.loginBtn"
|
||||
>确定</a-button>
|
||||
>{{ $t('button.submit') }}</a-button>
|
||||
</a-form-item>
|
||||
|
||||
</a-form>
|
||||
|
|
|
@ -11976,6 +11976,11 @@ vue-hot-reload-api@^2.3.0:
|
|||
resolved "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.3.tgz#2756f46cb3258054c5f4723de8ae7e87302a1ccf"
|
||||
integrity sha512-KmvZVtmM26BQOMK1rwUZsrqxEGeKiYSZGA7SNWE6uExx8UX/cj9hq2MRV/wWC3Cq6AoeDGk57rL9YMFRel/q+g==
|
||||
|
||||
vue-i18n@^8.15.3:
|
||||
version "8.15.3"
|
||||
resolved "https://registry.npm.taobao.org/vue-i18n/download/vue-i18n-8.15.3.tgz#9f947802d9b734fcb92e2ce724da654f2f9fc0f4"
|
||||
integrity sha1-n5R4Atm3NPy5LiznJNplTy+fwPQ=
|
||||
|
||||
vue-jest@^3.0.5:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.npm.taobao.org/vue-jest/download/vue-jest-3.0.5.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-jest%2Fdownload%2Fvue-jest-3.0.5.tgz#d6f124b542dcbff207bf9296c19413f4c40b70c9"
|
||||
|
|
Loading…
Reference in New Issue