mirror of
https://github.com/veops/cmdb.git
synced 2025-08-09 22:26:09 +08:00
Modify code organization
This commit is contained in:
45
cmdb-ui/src/components/tools/Breadcrumb.vue
Normal file
45
cmdb-ui/src/components/tools/Breadcrumb.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<a-breadcrumb class="breadcrumb">
|
||||
<a-breadcrumb-item v-for="(item, index) in breadList" :key="item.name">
|
||||
<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>
|
||||
</a-breadcrumb-item>
|
||||
</a-breadcrumb>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
name: '',
|
||||
breadList: []
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getBreadcrumb()
|
||||
},
|
||||
methods: {
|
||||
getBreadcrumb () {
|
||||
this.breadList = []
|
||||
// this.breadList.push({name: 'index', path: '/dashboard/', meta: {title: '首页'}})
|
||||
|
||||
this.name = this.$route.name
|
||||
this.$route.matched.forEach(item => {
|
||||
// item.name !== 'index' && this.breadList.push(item)
|
||||
this.breadList.push(item)
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route () {
|
||||
this.getBreadcrumb()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
5
cmdb-ui/src/components/tools/DetailList.vue
Normal file
5
cmdb-ui/src/components/tools/DetailList.vue
Normal file
@@ -0,0 +1,5 @@
|
||||
<script>
|
||||
/* WARNING: 兼容老引入,请勿继续使用 */
|
||||
import DescriptionList from '@/components/DescriptionList'
|
||||
export default DescriptionList
|
||||
</script>
|
67
cmdb-ui/src/components/tools/HeadInfo.vue
Normal file
67
cmdb-ui/src/components/tools/HeadInfo.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="head-info" :class="center && 'center'">
|
||||
<span>{{ title }}</span>
|
||||
<p>{{ content }}</p>
|
||||
<em v-if="bordered"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HeadInfo',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bordered: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
center: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.head-info {
|
||||
position: relative;
|
||||
text-align: left;
|
||||
padding: 0 32px 0 0;
|
||||
min-width: 125px;
|
||||
|
||||
&.center {
|
||||
text-align: center;
|
||||
padding: 0 32px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: rgba(0, 0, 0, .45);
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
p {
|
||||
color: rgba(0, 0, 0, .85);
|
||||
font-size: 24px;
|
||||
line-height: 32px;
|
||||
margin: 0;
|
||||
}
|
||||
em {
|
||||
background-color: #e8e8e8;
|
||||
position: absolute;
|
||||
height: 56px;
|
||||
width: 1px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
30
cmdb-ui/src/components/tools/Logo.vue
Normal file
30
cmdb-ui/src/components/tools/Logo.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<div class="logo">
|
||||
<router-link :to="{name:'cmdb'}">
|
||||
<h1 v-if="showTitle">{{ title }}</h1>
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LogoSvg from '@/assets/logo.svg?inline'
|
||||
|
||||
export default {
|
||||
name: 'Logo',
|
||||
components: {
|
||||
LogoSvg
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: 'CMDB',
|
||||
required: false
|
||||
},
|
||||
showTitle: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
required: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
34
cmdb-ui/src/components/tools/TopMenu.vue
Normal file
34
cmdb-ui/src/components/tools/TopMenu.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<div class="top-menu" v-if="routes.length > 2">
|
||||
<a-menu v-model="current" mode="horizontal">
|
||||
<a-menu-item :key="route.name" v-for="route in routes.slice(0, routes.length - 1)">
|
||||
<router-link :to="{name: route.name}">{{ route.meta.title }}</router-link>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
routes: store.getters.addRouters,
|
||||
current: [store.getters.addRouters[0].name]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.top-menu {
|
||||
display: inline-block;
|
||||
}
|
||||
.ant-menu-horizontal {
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
.ant-menu-horizontal > .ant-menu-item {
|
||||
border-bottom: 0;
|
||||
}
|
||||
</style>
|
89
cmdb-ui/src/components/tools/TwoStepCaptcha.vue
Normal file
89
cmdb-ui/src/components/tools/TwoStepCaptcha.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<!-- 两步验证 -->
|
||||
<a-modal
|
||||
centered
|
||||
v-model="visible"
|
||||
@cancel="handleCancel"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<div slot="title" :style="{ textAlign: 'center' }">两步验证</div>
|
||||
<template slot="footer">
|
||||
<div :style="{ textAlign: 'center' }">
|
||||
<a-button key="back" @click="handleCancel">返回</a-button>
|
||||
<a-button key="submit" type="primary" :loading="stepLoading" @click="handleStepOk">
|
||||
继续
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<a-spin :spinning="stepLoading">
|
||||
<a-form layout="vertical" :auto-form-create="(form)=>{this.form = form}">
|
||||
<div class="step-form-wrapper">
|
||||
<p style="text-align: center" v-if="!stepLoading">请在手机中打开 Google Authenticator 或两步验证 APP<br />输入 6 位动态码</p>
|
||||
<p style="text-align: center" v-else>正在验证..<br/>请稍后</p>
|
||||
<a-form-item
|
||||
:style="{ textAlign: 'center' }"
|
||||
hasFeedback
|
||||
fieldDecoratorId="stepCode"
|
||||
:fieldDecoratorOptions="{rules: [{ required: true, message: '请输入 6 位动态码!', pattern: /^\d{6}$/, len: 6 }]}"
|
||||
>
|
||||
<a-input :style="{ textAlign: 'center' }" @keyup.enter.native="handleStepOk" placeholder="000000" />
|
||||
</a-form-item>
|
||||
<p style="text-align: center">
|
||||
<a @click="onForgeStepCode">遗失手机?</a>
|
||||
</p>
|
||||
</div>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
stepLoading: false,
|
||||
|
||||
form: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleStepOk () {
|
||||
const vm = this
|
||||
this.stepLoading = true
|
||||
this.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
console.log('values', values)
|
||||
setTimeout(() => {
|
||||
vm.stepLoading = false
|
||||
vm.$emit('success', { values })
|
||||
}, 2000)
|
||||
return
|
||||
}
|
||||
this.stepLoading = false
|
||||
this.$emit('error', { err })
|
||||
})
|
||||
},
|
||||
handleCancel () {
|
||||
this.visible = false
|
||||
this.$emit('cancel')
|
||||
},
|
||||
onForgeStepCode () {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.step-form-wrapper {
|
||||
margin: 0 auto;
|
||||
width: 80%;
|
||||
max-width: 400px;
|
||||
}
|
||||
</style>
|
73
cmdb-ui/src/components/tools/UserMenu.vue
Normal file
73
cmdb-ui/src/components/tools/UserMenu.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div class="user-wrapper">
|
||||
<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>
|
||||
</span>
|
||||
</a>
|
||||
<!-- <a href="https://pro.loacg.com/docs/getting-started" target="_blank">
|
||||
<span class="action">
|
||||
<a-icon type="question-circle-o"></a-icon>
|
||||
</span>
|
||||
</a>
|
||||
<notice-icon class="action"/> -->
|
||||
<a-dropdown>
|
||||
<span class="action ant-dropdown-link user-dropdown-menu">
|
||||
<a-avatar class="avatar" size="small" :src="avatar()"/>
|
||||
<span>{{ nickname() }}</span>
|
||||
</span>
|
||||
<a-menu slot="overlay" class="user-dropdown-menu-wrapper">
|
||||
<!-- <a-menu-item key="0">
|
||||
<router-link :to="{ name: 'center' }">
|
||||
<a-icon type="user"/>
|
||||
<span>个人中心</span>
|
||||
</router-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="1">
|
||||
<router-link :to="{ name: 'settings' }">
|
||||
<a-icon type="setting"/>
|
||||
<span>账户设置</span>
|
||||
</router-link>
|
||||
</a-menu-item>
|
||||
<a-menu-divider/> -->
|
||||
<a-menu-item key="3">
|
||||
<a href="javascript:;" @click="handleLogout">
|
||||
<a-icon type="logout"/>
|
||||
<span>退出登录</span>
|
||||
</a>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NoticeIcon from '@/components/NoticeIcon'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'UserMenu',
|
||||
components: {
|
||||
NoticeIcon
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['Logout']),
|
||||
...mapGetters(['nickname', 'avatar']),
|
||||
handleLogout () {
|
||||
const that = this
|
||||
|
||||
this.$confirm({
|
||||
title: '提示',
|
||||
content: '真的要注销登录吗 ?',
|
||||
onOk () {
|
||||
return that.Logout()
|
||||
},
|
||||
onCancel () {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
0
cmdb-ui/src/components/tools/index.js
Normal file
0
cmdb-ui/src/components/tools/index.js
Normal file
Reference in New Issue
Block a user