Merge branch 'hotfix/12-16'
Former-commit-id: a24414bc5eb7e16004e918424d8c2fcf434779c1
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
# No Mock 构建
|
||||||
|
|
||||||
|
# 指定构建模式
|
||||||
|
NODE_ENV=production
|
||||||
|
|
||||||
|
# 标记当前是 No Mock 构建
|
||||||
|
VUE_APP_BUILD_MODE=nomock
|
||||||
Generated
+4589
-6055
File diff suppressed because it is too large
Load Diff
+6
-3
@@ -1,17 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "d2-admin",
|
"name": "d2-admin",
|
||||||
"version": "1.5.9",
|
"version": "1.6.9",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve --open",
|
"serve": "vue-cli-service serve --open",
|
||||||
"start": "npm run serve",
|
"start": "npm run serve",
|
||||||
"dev": "npm run serve",
|
"dev": "npm run serve",
|
||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
|
"build:nomock": "vue-cli-service build --mode nomock",
|
||||||
"build:travis": "vue-cli-service build --mode travis",
|
"build:travis": "vue-cli-service build --mode travis",
|
||||||
"lint": "vue-cli-service lint --fix",
|
"lint": "vue-cli-service lint --fix",
|
||||||
"test:unit": "vue-cli-service test:unit"
|
"test:unit": "vue-cli-service test:unit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@d2-projects/vue-filters-date": "^1.0.2",
|
||||||
"axios": "^0.17.1",
|
"axios": "^0.17.1",
|
||||||
"babel-polyfill": "^6.26.0",
|
"babel-polyfill": "^6.26.0",
|
||||||
"better-scroll": "^1.12.1",
|
"better-scroll": "^1.12.1",
|
||||||
@@ -21,11 +23,11 @@
|
|||||||
"fuse.js": "^3.2.1",
|
"fuse.js": "^3.2.1",
|
||||||
"hotkeys-js": "^3.3.6",
|
"hotkeys-js": "^3.3.6",
|
||||||
"js-cookie": "^2.2.0",
|
"js-cookie": "^2.2.0",
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.10",
|
||||||
"lowdb": "^1.0.0",
|
"lowdb": "^1.0.0",
|
||||||
"mockjs": "^1.0.1-beta3",
|
"mockjs": "^1.0.1-beta3",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"particles.js": "^2.0.0",
|
"qs": "^6.6.0",
|
||||||
"screenfull": "^3.3.2",
|
"screenfull": "^3.3.2",
|
||||||
"ua-parser-js": "^0.7.18",
|
"ua-parser-js": "^0.7.18",
|
||||||
"vue": "^2.5.17",
|
"vue": "^2.5.17",
|
||||||
@@ -48,6 +50,7 @@
|
|||||||
"sass-loader": "^7.0.1",
|
"sass-loader": "^7.0.1",
|
||||||
"svg-sprite-loader": "^3.8.0",
|
"svg-sprite-loader": "^3.8.0",
|
||||||
"text-loader": "0.0.1",
|
"text-loader": "0.0.1",
|
||||||
|
"uglifyjs-webpack-plugin": "^2.0.1",
|
||||||
"vue-template-compiler": "^2.5.17"
|
"vue-template-compiler": "^2.5.17"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// 优化显示
|
// 优化显示
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// element 样式补丁
|
// element 样式补丁
|
||||||
|
|
||||||
.el-card {
|
.el-card {
|
||||||
&.is-always-shadow {
|
&.is-always-shadow {
|
||||||
box-shadow: 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5);
|
box-shadow: 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
@import '~@/assets/style/public.scss';
|
|
||||||
@import '~@/assets/style/theme/theme-base.scss';
|
@import '~@/assets/style/theme/theme-base.scss';
|
||||||
|
|
||||||
@import '~@/assets/style/theme/d2/index.scss';
|
@import '~@/assets/style/theme/d2/index.scss';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div v-if="$slots.header" class="d2-container-card__header" ref="header">
|
<div v-if="$slots.header" class="d2-container-card__header" ref="header">
|
||||||
<slot name="header"/>
|
<slot name="header"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="d2-container-card__body">
|
<div class="d2-container-card__body" ref="body">
|
||||||
<div class="d2-container-card__body-card">
|
<div class="d2-container-card__body-card">
|
||||||
<slot/>
|
<slot/>
|
||||||
</div>
|
</div>
|
||||||
@@ -15,7 +15,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import scroll from './mixins/normal'
|
||||||
export default {
|
export default {
|
||||||
name: 'd2-container-card'
|
name: 'd2-container-card',
|
||||||
|
mixins: [
|
||||||
|
scroll
|
||||||
|
],
|
||||||
|
mounted () {
|
||||||
|
// 增加滚动事件监听
|
||||||
|
this.addScrollListener()
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
// 移除滚动事件监听
|
||||||
|
this.removeScrollListener()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div v-if="$slots.header" class="d2-container-full__header" ref="header">
|
<div v-if="$slots.header" class="d2-container-full__header" ref="header">
|
||||||
<slot name="header"/>
|
<slot name="header"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="d2-container-full__body">
|
<div class="d2-container-full__body" ref="body">
|
||||||
<slot/>
|
<slot/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="$slots.footer" class="d2-container-full__footer" ref="footer">
|
<div v-if="$slots.footer" class="d2-container-full__footer" ref="footer">
|
||||||
@@ -13,7 +13,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import scroll from './mixins/normal'
|
||||||
export default {
|
export default {
|
||||||
name: 'd2-container-full'
|
name: 'd2-container-full',
|
||||||
|
mixins: [
|
||||||
|
scroll
|
||||||
|
],
|
||||||
|
mounted () {
|
||||||
|
// 增加滚动事件监听
|
||||||
|
this.addScrollListener()
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
// 移除滚动事件监听
|
||||||
|
this.removeScrollListener()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div v-if="$slots.header" class="d2-container-ghost__header" ref="header">
|
<div v-if="$slots.header" class="d2-container-ghost__header" ref="header">
|
||||||
<slot name="header"/>
|
<slot name="header"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="d2-container-ghost__body">
|
<div class="d2-container-ghost__body" ref="body">
|
||||||
<slot/>
|
<slot/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="$slots.footer" class="d2-container-ghost__footer" ref="footer">
|
<div v-if="$slots.footer" class="d2-container-ghost__footer" ref="footer">
|
||||||
@@ -11,3 +11,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import scroll from './mixins/normal'
|
||||||
|
export default {
|
||||||
|
name: 'd2-container-ghost',
|
||||||
|
mixins: [
|
||||||
|
scroll
|
||||||
|
],
|
||||||
|
mounted () {
|
||||||
|
// 增加滚动事件监听
|
||||||
|
this.addScrollListener()
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
// 移除滚动事件监听
|
||||||
|
this.removeScrollListener()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="d2-source"
|
||||||
|
:class="{ 'd2-source--active': isActive }"
|
||||||
|
@click="handleClick">
|
||||||
|
<d2-icon name="code"/> SourceCode
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 文件路径
|
||||||
|
filename: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
isActive: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
// 一秒后显示按钮
|
||||||
|
setTimeout(() => {
|
||||||
|
this.isActive = true
|
||||||
|
}, 500)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 点击按钮的时候跳转到源代码
|
||||||
|
handleClick () {
|
||||||
|
const file = this.filename.split('?')[0]
|
||||||
|
const url = file
|
||||||
|
? `https://github.com/d2-projects/d2-admin-start-kit/blob/master/${file}`
|
||||||
|
: 'https://github.com/d2-projects/d2-admin-start-kit'
|
||||||
|
this.$open(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.d2-source {
|
||||||
|
$borderRadius: 4px;
|
||||||
|
$paddingLR: 15px;
|
||||||
|
$paddingTB: 7px;
|
||||||
|
$fontSize: 12px;
|
||||||
|
$rightOuter: $paddingLR / 2;
|
||||||
|
opacity: 0;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 9999;
|
||||||
|
right: - $borderRadius - $rightOuter;
|
||||||
|
bottom: 20px;
|
||||||
|
font-size: $fontSize;
|
||||||
|
line-height: $fontSize;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: $borderRadius;
|
||||||
|
padding: $paddingTB $paddingLR;
|
||||||
|
padding-right: $borderRadius + $paddingLR;
|
||||||
|
background-color: rgba(#000, .7);
|
||||||
|
border: 1px solid #000;
|
||||||
|
color: #FFF;
|
||||||
|
transition: all .3s;
|
||||||
|
@extend %unable-select;
|
||||||
|
&.d2-source--active {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
right: - $borderRadius;
|
||||||
|
background-color: rgba(#000, .9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import BScroll from 'better-scroll'
|
import BScroll from 'better-scroll'
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
// 滚动优化的选项
|
||||||
betterScrollOptions: {
|
betterScrollOptions: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: false,
|
required: false,
|
||||||
@@ -20,6 +21,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
scrollInit () {
|
scrollInit () {
|
||||||
|
// 初始化 bs
|
||||||
this.BS = new BScroll(this.$refs.wrapper, Object.assign({
|
this.BS = new BScroll(this.$refs.wrapper, Object.assign({
|
||||||
mouseWheel: true,
|
mouseWheel: true,
|
||||||
scrollbar: {
|
scrollbar: {
|
||||||
@@ -27,6 +29,11 @@ export default {
|
|||||||
interactive: false
|
interactive: false
|
||||||
}
|
}
|
||||||
}, this.betterScrollOptions))
|
}, this.betterScrollOptions))
|
||||||
|
// 滚动时发出事件 并且统一返回的数据格式
|
||||||
|
this.BS.on('scroll', ({ x, y }) => this.$emit('scroll', {
|
||||||
|
x: -x,
|
||||||
|
y: -y
|
||||||
|
}))
|
||||||
},
|
},
|
||||||
scrollDestroy () {
|
scrollDestroy () {
|
||||||
// https://github.com/d2-projects/d2-admin/issues/75
|
// https://github.com/d2-projects/d2-admin/issues/75
|
||||||
@@ -36,6 +43,19 @@ export default {
|
|||||||
delete this.BS
|
delete this.BS
|
||||||
this.BS = null
|
this.BS = null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
// 外部调用的方法 返回顶部
|
||||||
|
scrollToTop () {
|
||||||
|
if (this.BS) this.BS.scrollTo(0, 0, 300)
|
||||||
|
},
|
||||||
|
// 手动发出滚动事件
|
||||||
|
scroll () {
|
||||||
|
if (this.BS) {
|
||||||
|
this.$emit('scroll', {
|
||||||
|
x: -this.BS.x,
|
||||||
|
y: -this.BS.y
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
// 提供滚动方面的功能
|
||||||
|
// 非滚动优化模式通用
|
||||||
|
|
||||||
|
import { throttle } from 'lodash'
|
||||||
|
|
||||||
|
// 生成滚动事件的 handler
|
||||||
|
function handleMaker (wait) {
|
||||||
|
return throttle(e => {
|
||||||
|
this.$emit('scroll', {
|
||||||
|
x: e.target.scrollLeft,
|
||||||
|
y: e.target.scrollTop
|
||||||
|
})
|
||||||
|
}, wait)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 滚动事件节流间隔
|
||||||
|
scrollDelay: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
handleScroll: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
scrollDelay (val) {
|
||||||
|
// 移除旧的监听
|
||||||
|
this.removeScrollListener()
|
||||||
|
// 生成新的 handle 方法
|
||||||
|
this.handleScroll = handleMaker.call(this, val)
|
||||||
|
// 添加新的监听
|
||||||
|
this.addScrollListener()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 增加滚动事件监听
|
||||||
|
addScrollListener () {
|
||||||
|
if (typeof this.handleScroll !== 'function') {
|
||||||
|
// mounted 生命周期内调用这个方法的时候会进入这里的判断
|
||||||
|
this.handleScroll = handleMaker.call(this, this.scrollDelay)
|
||||||
|
}
|
||||||
|
// 添加监听
|
||||||
|
this.$refs.body.addEventListener('scroll', this.handleScroll)
|
||||||
|
},
|
||||||
|
// 移除滚动事件监听
|
||||||
|
removeScrollListener () {
|
||||||
|
this.$refs.body.removeEventListener('scroll', this.handleScroll)
|
||||||
|
},
|
||||||
|
// 外部调用的方法 返回顶部
|
||||||
|
scrollToTop () {
|
||||||
|
const smoothscroll = () => {
|
||||||
|
const body = this.$refs.body
|
||||||
|
const currentScroll = body.scrollTop
|
||||||
|
if (currentScroll > 0) {
|
||||||
|
window.requestAnimationFrame(smoothscroll)
|
||||||
|
body.scrollTo(0, currentScroll - (currentScroll / 5))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
smoothscroll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
// 组件
|
||||||
|
import d2ContainerFull from './components/d2-container-full.vue'
|
||||||
|
import d2ContainerFullBs from './components/d2-container-full-bs.vue'
|
||||||
|
import d2ContainerGhost from './components/d2-container-ghost.vue'
|
||||||
|
import d2ContainerGhostBs from './components/d2-container-ghost-bs.vue'
|
||||||
|
import d2ContainerCard from './components/d2-container-card.vue'
|
||||||
|
import d2ContainerCardBs from './components/d2-container-card-bs.vue'
|
||||||
|
import d2Source from './components/d2-source.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'd2-container',
|
||||||
|
props: {
|
||||||
|
// 容器样式
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: 'full'
|
||||||
|
},
|
||||||
|
// 滚动优化
|
||||||
|
betterScroll: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 始终返回渲染组件
|
||||||
|
component () {
|
||||||
|
if (this.type === 'card' && !this.betterScroll) return d2ContainerCard
|
||||||
|
if (this.type === 'card' && this.betterScroll) return d2ContainerCardBs
|
||||||
|
if (this.type === 'ghost' && !this.betterScroll) return d2ContainerGhost
|
||||||
|
if (this.type === 'ghost' && this.betterScroll) return d2ContainerGhostBs
|
||||||
|
if (this.type === 'full' && !this.betterScroll) return d2ContainerFull
|
||||||
|
if (this.type === 'full' && this.betterScroll) return d2ContainerFullBs
|
||||||
|
else {
|
||||||
|
return 'div'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render (h) {
|
||||||
|
const slots = [
|
||||||
|
h('div', this.$slots.default)
|
||||||
|
]
|
||||||
|
if (this.$slots.header) slots.push(h('div', { slot: 'header' }, [ this.$slots.header ]))
|
||||||
|
if (this.$slots.footer) slots.push(h('div', { slot: 'footer' }, [ this.$slots.footer ]))
|
||||||
|
return h('div', {
|
||||||
|
ref: 'container',
|
||||||
|
class: 'container-component'
|
||||||
|
}, [
|
||||||
|
h(this.component, {
|
||||||
|
ref: 'component',
|
||||||
|
props: this.$attrs,
|
||||||
|
on: {
|
||||||
|
scroll: e => this.$emit('scroll', e)
|
||||||
|
}
|
||||||
|
}, slots),
|
||||||
|
// 只在预览和开发模式下显示源码按钮
|
||||||
|
process.env.VUE_APP_BUILD_MODE === 'TRAVIS' || process.env.NODE_ENV === 'development' ? h(d2Source, {
|
||||||
|
props: this.$attrs
|
||||||
|
}) : undefined
|
||||||
|
])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 返回顶部
|
||||||
|
scrollToTop () {
|
||||||
|
this.$refs.component.scrollToTop()
|
||||||
|
// 如果开启了 better scroll 还需要手动触发一遍 scroll 事件
|
||||||
|
const bs = this.$refs.component.BS
|
||||||
|
if (bs) this.$refs.component.scroll()
|
||||||
|
},
|
||||||
|
// 用法同原生方法 scrollBy
|
||||||
|
scrollBy (x = 0, y = 0, time = 300) {
|
||||||
|
if (this.betterScroll) {
|
||||||
|
const bs = this.$refs.component.BS
|
||||||
|
if (bs) {
|
||||||
|
bs.scrollBy(-x, -y, time)
|
||||||
|
// 手动触发一遍 scroll 事件
|
||||||
|
this.$refs.component.scroll()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$refs.component.$refs.body.scrollBy(x, y)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 用法同原生方法 scrollTo
|
||||||
|
scrollTo (x = 0, y = 0, time = 300) {
|
||||||
|
if (this.betterScroll) {
|
||||||
|
const bs = this.$refs.component.BS
|
||||||
|
if (bs) {
|
||||||
|
bs.scrollTo(-x, -y, time)
|
||||||
|
// 手动触发一遍 scroll 事件
|
||||||
|
this.$refs.component.scroll()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$refs.component.$refs.body.scrollTo(x, y)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 用法同原生方法 scrollTop
|
||||||
|
scrollTop (top = 0, time = 300) {
|
||||||
|
if (this.betterScroll) {
|
||||||
|
const bs = this.$refs.component.BS
|
||||||
|
if (bs) {
|
||||||
|
bs.scrollTo(bs.x, -top, time)
|
||||||
|
// 手动触发一遍 scroll 事件
|
||||||
|
this.$refs.component.scroll()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$refs.component.$refs.body.scrollTop = top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="container-component" ref="container">
|
|
||||||
<!-- [card] 卡片容器 -->
|
|
||||||
<d2-container-card v-if="type === 'card' && !betterScroll">
|
|
||||||
<slot v-if="$slots.header" name="header" slot="header"/>
|
|
||||||
<slot/>
|
|
||||||
<slot v-if="$slots.footer" name="footer" slot="footer"/>
|
|
||||||
</d2-container-card>
|
|
||||||
<!-- [card] 卡片容器 滚动优化 -->
|
|
||||||
<d2-container-card-bs v-bind="$attrs" v-if="type === 'card' && betterScroll">
|
|
||||||
<slot v-if="$slots.header" name="header" slot="header"/>
|
|
||||||
<slot/>
|
|
||||||
<slot v-if="$slots.footer" name="footer" slot="footer"/>
|
|
||||||
</d2-container-card-bs>
|
|
||||||
<!-- [ghost] 隐形容器 -->
|
|
||||||
<d2-container-ghost v-if="type === 'ghost' && !betterScroll">
|
|
||||||
<slot v-if="$slots.header" name="header" slot="header"/>
|
|
||||||
<slot/>
|
|
||||||
<slot v-if="$slots.footer" name="footer" slot="footer"/>
|
|
||||||
</d2-container-ghost>
|
|
||||||
<!-- [ghost] 隐形容器 滚动优化 -->
|
|
||||||
<d2-container-ghost-bs v-bind="$attrs" v-if="type === 'ghost' && betterScroll">
|
|
||||||
<slot v-if="$slots.header" name="header" slot="header"/>
|
|
||||||
<slot/>
|
|
||||||
<slot v-if="$slots.footer" name="footer" slot="footer"/>
|
|
||||||
</d2-container-ghost-bs>
|
|
||||||
<!-- [container-full] 填充 -->
|
|
||||||
<d2-container-full v-if="type === 'full' && !betterScroll">
|
|
||||||
<slot v-if="$slots.header" name="header" slot="header"/>
|
|
||||||
<slot/>
|
|
||||||
<slot v-if="$slots.footer" name="footer" slot="footer"/>
|
|
||||||
</d2-container-full>
|
|
||||||
<!-- [container-full-bs] 填充 滚动优化 -->
|
|
||||||
<d2-container-full-bs v-bind="$attrs" v-if="type === 'full' && betterScroll">
|
|
||||||
<slot v-if="$slots.header" name="header" slot="header"/>
|
|
||||||
<slot/>
|
|
||||||
<slot v-if="$slots.footer" name="footer" slot="footer"/>
|
|
||||||
</d2-container-full-bs>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// 组件
|
|
||||||
import d2ContainerFull from './components/d2-container-full.vue'
|
|
||||||
import d2ContainerFullBs from './components/d2-container-full-bs.vue'
|
|
||||||
import d2ContainerGhost from './components/d2-container-ghost.vue'
|
|
||||||
import d2ContainerGhostBs from './components/d2-container-ghost-bs.vue'
|
|
||||||
import d2ContainerCard from './components/d2-container-card.vue'
|
|
||||||
import d2ContainerCardBs from './components/d2-container-card-bs.vue'
|
|
||||||
export default {
|
|
||||||
name: 'd2-container',
|
|
||||||
components: {
|
|
||||||
'd2-container-full': d2ContainerFull,
|
|
||||||
'd2-container-full-bs': d2ContainerFullBs,
|
|
||||||
'd2-container-ghost': d2ContainerGhost,
|
|
||||||
'd2-container-ghost-bs': d2ContainerGhostBs,
|
|
||||||
'd2-container-card': d2ContainerCard,
|
|
||||||
'd2-container-card-bs': d2ContainerCardBs
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
// 容器样式
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
default: 'full'
|
|
||||||
},
|
|
||||||
// 滚动优化
|
|
||||||
betterScroll: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -3,8 +3,9 @@
|
|||||||
<div class="d2-page-cover__logo">
|
<div class="d2-page-cover__logo">
|
||||||
<slot/>
|
<slot/>
|
||||||
</div>
|
</div>
|
||||||
<p class="d2-page-cover__title">{{title}}</p>
|
<p class="d2-page-cover__title">D2 Admin {{$version}}</p>
|
||||||
<p class="d2-page-cover__sub-title d2-mt-0">{{subTitle}}</p>
|
<p class="d2-page-cover__sub-title">优雅的中后台集成方案</p>
|
||||||
|
<p class="d2-page-cover__build-time">FINAL BUILD TIME {{$buildTime}}</p>
|
||||||
<slot name="footer"/>
|
<slot name="footer"/>
|
||||||
<a target="blank" href="https://github.com/d2-projects/d2-admin">
|
<a target="blank" href="https://github.com/d2-projects/d2-admin">
|
||||||
<img
|
<img
|
||||||
@@ -15,25 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
default: 'Title'
|
|
||||||
},
|
|
||||||
subTitle: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
default: 'subTitle'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '~@/assets/style/public.scss';
|
|
||||||
.d2-page-cover {
|
.d2-page-cover {
|
||||||
@extend %full;
|
@extend %full;
|
||||||
@extend %unable-select;
|
@extend %unable-select;
|
||||||
@@ -47,10 +30,21 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.d2-page-cover__title {
|
.d2-page-cover__title {
|
||||||
|
margin: 0px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-weight: bold;
|
||||||
color: $color-text-main;
|
color: $color-text-main;
|
||||||
}
|
}
|
||||||
.d2-page-cover__sub-title {
|
.d2-page-cover__sub-title {
|
||||||
color: $color-text-sub;
|
margin: 0px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: $color-text-normal;
|
||||||
|
}
|
||||||
|
.d2-page-cover__build-time {
|
||||||
|
margin: 0px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: $color-text-placehoder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-menu-item :index="menu.path || uniqueId">
|
<el-menu-item :index="menu.path || uniqueId">
|
||||||
<i v-if="menu.icon" :class="`fa fa-${menu.icon}`"></i>
|
<i v-if="menu.icon" :class="`fa fa-${menu.icon}`"></i>
|
||||||
<d2-icon-svg v-else-if="menu.iconSvg" :name="menu.iconSvg"/>
|
<i v-if="menu.icon === undefined & !menu.iconSvg" class="fa fa-file-o"></i>
|
||||||
<i v-else class="fa fa-file-o"></i>
|
<d2-icon-svg v-if="menu.iconSvg" :name="menu.iconSvg"/>
|
||||||
<span slot="title">{{menu.title || '未命名菜单'}}</span>
|
<span slot="title">{{menu.title || '未命名菜单'}}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
<el-submenu :index="menu.path || uniqueId">
|
<el-submenu :index="menu.path || uniqueId">
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<i v-if="menu.icon" :class="`fa fa-${menu.icon}`"></i>
|
<i v-if="menu.icon" :class="`fa fa-${menu.icon}`"></i>
|
||||||
<d2-icon-svg v-else-if="menu.iconSvg" :name="menu.iconSvg"/>
|
<i v-if="menu.icon === undefined & !menu.iconSvg" class="fa fa-folder-o"></i>
|
||||||
<i v-else class="fa fa-folder-o"></i>
|
<d2-icon-svg v-if="menu.iconSvg" :name="menu.iconSvg"/>
|
||||||
<span slot="title">{{menu.title}}</span>
|
<span slot="title">{{menu.title}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-for="(child, childIndex) in menu.children">
|
<template v-for="(child, childIndex) in menu.children">
|
||||||
|
|||||||
@@ -165,7 +165,6 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '~@/assets/style/public.scss';
|
|
||||||
.d2-error-log-list__expand-group {
|
.d2-error-log-list__expand-group {
|
||||||
.d2-error-log-list__expand {
|
.d2-error-log-list__expand {
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '~@/assets/style/public.scss';
|
|
||||||
.theme-preview {
|
.theme-preview {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
|
|||||||
@@ -55,12 +55,12 @@ export default {
|
|||||||
}, 500)
|
}, 500)
|
||||||
},
|
},
|
||||||
// 监听路由 控制侧边栏激活状态
|
// 监听路由 控制侧边栏激活状态
|
||||||
'$route.matched': {
|
'$route': {
|
||||||
handler (val) {
|
handler ({ fullPath }) {
|
||||||
this.active = val[val.length - 1].path
|
this.active = fullPath
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.aside.length > 0 && this.$refs.menu) {
|
if (this.aside.length > 0 && this.$refs.menu) {
|
||||||
this.$refs.menu.activeIndex = this.active
|
this.$refs.menu.activeIndex = fullPath
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '~@/assets/style/public.scss';
|
|
||||||
.d2-panel-search-item {
|
.d2-panel-search-item {
|
||||||
height: 64px;
|
height: 64px;
|
||||||
margin: 0px -20px;
|
margin: 0px -20px;
|
||||||
|
|||||||
@@ -183,7 +183,6 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '~@/assets/style/public.scss';
|
|
||||||
.panel-search {
|
.panel-search {
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
.panel-search__input-group {
|
.panel-search__input-group {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
:x="contentmenuX"
|
:x="contentmenuX"
|
||||||
:y="contentmenuY">
|
:y="contentmenuY">
|
||||||
<d2-contextmenu-list
|
<d2-contextmenu-list
|
||||||
:menulist="tagName === 'index' ? contextmenuListIndex : contextmenuList"
|
:menulist="tagName === '/index' ? contextmenuListIndex : contextmenuList"
|
||||||
@rowClick="contextmenuClick"/>
|
@rowClick="contextmenuClick"/>
|
||||||
</d2-contextmenu>
|
</d2-contextmenu>
|
||||||
<el-tabs
|
<el-tabs
|
||||||
@@ -19,10 +19,10 @@
|
|||||||
@edit="handleTabsEdit"
|
@edit="handleTabsEdit"
|
||||||
@contextmenu.native="handleContextmenu">
|
@contextmenu.native="handleContextmenu">
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
v-for="(page, index) in opened"
|
v-for="page in opened"
|
||||||
:key="index"
|
:key="page.fullPath"
|
||||||
:label="page.meta.title || '未命名'"
|
:label="page.meta.title || '未命名'"
|
||||||
:name="page.name"/>
|
:name="page.fullPath"/>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -79,7 +79,7 @@ export default {
|
|||||||
{ icon: 'times', title: '关闭其它', value: 'other' },
|
{ icon: 'times', title: '关闭其它', value: 'other' },
|
||||||
{ icon: 'times-circle', title: '关闭全部', value: 'all' }
|
{ icon: 'times-circle', title: '关闭全部', value: 'all' }
|
||||||
],
|
],
|
||||||
tagName: 'index'
|
tagName: '/index'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -163,7 +163,7 @@ export default {
|
|||||||
*/
|
*/
|
||||||
handleClick (tab, event) {
|
handleClick (tab, event) {
|
||||||
// 找到点击的页面在 tag 列表里是哪个
|
// 找到点击的页面在 tag 列表里是哪个
|
||||||
const page = this.opened.find(page => page.name === tab.name)
|
const page = this.opened.find(page => page.fullPath === tab.name)
|
||||||
const { name, params, query } = page
|
const { name, params, query } = page
|
||||||
if (page) {
|
if (page) {
|
||||||
this.$router.push({ name, params, query })
|
this.$router.push({ name, params, query })
|
||||||
|
|||||||
@@ -81,6 +81,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import d2MenuSide from './components/menu-side'
|
||||||
|
import d2MenuHeader from './components/menu-header'
|
||||||
|
import d2Tabs from './components/tabs'
|
||||||
|
import d2HeaderFullscreen from './components/header-fullscreen'
|
||||||
|
import d2HeaderSearch from './components/header-search'
|
||||||
|
import d2HeaderSize from './components/header-size'
|
||||||
|
import d2HeaderTheme from './components/header-theme'
|
||||||
|
import d2HeaderUser from './components/header-user'
|
||||||
|
import d2HeaderErrorLog from './components/header-error-log'
|
||||||
import { mapState, mapGetters, mapActions } from 'vuex'
|
import { mapState, mapGetters, mapActions } from 'vuex'
|
||||||
import mixinSearch from './mixins/search'
|
import mixinSearch from './mixins/search'
|
||||||
export default {
|
export default {
|
||||||
@@ -89,15 +98,15 @@ export default {
|
|||||||
mixinSearch
|
mixinSearch
|
||||||
],
|
],
|
||||||
components: {
|
components: {
|
||||||
'd2-menu-side': () => import('./components/menu-side'),
|
d2MenuSide,
|
||||||
'd2-menu-header': () => import('./components/menu-header'),
|
d2MenuHeader,
|
||||||
'd2-tabs': () => import('./components/tabs'),
|
d2Tabs,
|
||||||
'd2-header-fullscreen': () => import('./components/header-fullscreen'),
|
d2HeaderFullscreen,
|
||||||
'd2-header-search': () => import('./components/header-search'),
|
d2HeaderSearch,
|
||||||
'd2-header-size': () => import('./components/header-size'),
|
d2HeaderSize,
|
||||||
'd2-header-theme': () => import('./components/header-theme'),
|
d2HeaderTheme,
|
||||||
'd2-header-user': () => import('./components/header-user'),
|
d2HeaderUser,
|
||||||
'd2-header-error-log': () => import('./components/header-error-log')
|
d2HeaderErrorLog
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
import setting from '@/setting.js'
|
|
||||||
|
|
||||||
const cookies = {}
|
const cookies = {}
|
||||||
|
|
||||||
@@ -14,7 +13,7 @@ cookies.set = function (name = 'default', value = '', cookieSetting = {}) {
|
|||||||
expires: 1
|
expires: 1
|
||||||
}
|
}
|
||||||
Object.assign(currentCookieSetting, cookieSetting)
|
Object.assign(currentCookieSetting, cookieSetting)
|
||||||
Cookies.set(`d2admin-${setting.releases.version}-${name}`, value, currentCookieSetting)
|
Cookies.set(`d2admin-${process.env.VUE_APP_VERSION}-${name}`, value, currentCookieSetting)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,7 +21,7 @@ cookies.set = function (name = 'default', value = '', cookieSetting = {}) {
|
|||||||
* @param {String} name cookie name
|
* @param {String} name cookie name
|
||||||
*/
|
*/
|
||||||
cookies.get = function (name = 'default') {
|
cookies.get = function (name = 'default') {
|
||||||
return Cookies.get(`d2admin-${setting.releases.version}-${name}`)
|
return Cookies.get(`d2admin-${process.env.VUE_APP_VERSION}-${name}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,7 +36,7 @@ cookies.getAll = function () {
|
|||||||
* @param {String} name cookie name
|
* @param {String} name cookie name
|
||||||
*/
|
*/
|
||||||
cookies.remove = function (name = 'default') {
|
cookies.remove = function (name = 'default') {
|
||||||
return Cookies.remove(`d2admin-${setting.releases.version}-${name}`)
|
return Cookies.remove(`d2admin-${process.env.VUE_APP_VERSION}-${name}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default cookies
|
export default cookies
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import low from 'lowdb'
|
import low from 'lowdb'
|
||||||
import LocalStorage from 'lowdb/adapters/LocalStorage'
|
import LocalStorage from 'lowdb/adapters/LocalStorage'
|
||||||
import setting from '@/setting.js'
|
|
||||||
|
|
||||||
const adapter = new LocalStorage(`d2admin-${setting.releases.version}`)
|
const adapter = new LocalStorage(`d2admin-${process.env.VUE_APP_VERSION}`)
|
||||||
const db = low(adapter)
|
const db = low(adapter)
|
||||||
|
|
||||||
db
|
db
|
||||||
+7
-5
@@ -1,8 +1,10 @@
|
|||||||
import log from './util.log.js'
|
import cookies from './util.cookies'
|
||||||
import cookies from './util.cookies.js'
|
import db from './util.db'
|
||||||
|
import log from './util.log'
|
||||||
|
|
||||||
let util = {
|
const util = {
|
||||||
cookies,
|
cookies,
|
||||||
|
db,
|
||||||
log
|
log
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,10 +25,10 @@ util.open = function (url) {
|
|||||||
var a = document.createElement('a')
|
var a = document.createElement('a')
|
||||||
a.setAttribute('href', url)
|
a.setAttribute('href', url)
|
||||||
a.setAttribute('target', '_blank')
|
a.setAttribute('target', '_blank')
|
||||||
a.setAttribute('id', 'd2admin-menu-link')
|
a.setAttribute('id', 'd2admin-link-temp')
|
||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
document.body.removeChild(document.getElementById('d2admin-menu-link'))
|
document.body.removeChild(document.getElementById('d2admin-link-temp'))
|
||||||
}
|
}
|
||||||
|
|
||||||
export default util
|
export default util
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import Vue from 'vue'
|
|||||||
import App from './App'
|
import App from './App'
|
||||||
// store
|
// store
|
||||||
import store from '@/store/index'
|
import store from '@/store/index'
|
||||||
// 模拟数据
|
|
||||||
import '@/mock'
|
|
||||||
// 多国语
|
// 多国语
|
||||||
import i18n from './i18n'
|
import i18n from './i18n'
|
||||||
// 核心插件
|
// 核心插件
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
const userDB = [
|
||||||
|
{ username: 'admin', password: 'admin', uuid: 'admin-uuid', name: '管理员' },
|
||||||
|
{ username: 'editor', password: 'editor', uuid: 'editor-uuid', name: '编辑' },
|
||||||
|
{ username: 'user1', password: 'user1', uuid: 'user1-uuid', name: '用户1' }
|
||||||
|
]
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
path: '/api/login',
|
||||||
|
method: 'post',
|
||||||
|
handle ({ body }) {
|
||||||
|
const user = userDB.find(e => e.username === body.username && e.password === body.password)
|
||||||
|
if (user) {
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
msg: '登录成功',
|
||||||
|
data: {
|
||||||
|
...user,
|
||||||
|
token: '8dfhassad0asdjwoeiruty'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: 401,
|
||||||
|
msg: '用户名或密码错误',
|
||||||
|
data: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
import Mock from 'mockjs'
|
|
||||||
|
|
||||||
const userDB = [
|
|
||||||
{
|
|
||||||
username: 'admin',
|
|
||||||
password: 'admin',
|
|
||||||
uuid: 'admin-uuid',
|
|
||||||
name: '管理员'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
username: 'editor',
|
|
||||||
password: 'editor',
|
|
||||||
uuid: 'editor-uuid',
|
|
||||||
name: '编辑'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
username: 'user1',
|
|
||||||
password: 'user1',
|
|
||||||
uuid: 'user1-uuid',
|
|
||||||
name: '用户1'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
Mock.mock('/api/login', 'post', ({ url, type, body }) => {
|
|
||||||
const bodyObj = JSON.parse(body)
|
|
||||||
const user = userDB.find(e => e.username === bodyObj.username && e.password === bodyObj.password)
|
|
||||||
if (user) {
|
|
||||||
return {
|
|
||||||
code: 0,
|
|
||||||
msg: '登录成功',
|
|
||||||
data: {
|
|
||||||
...user,
|
|
||||||
token: 'd787syv8dys8cas80d9s0a0d8f79ads56f7s4d56f879a8as89fd980s7dg'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
code: 401,
|
|
||||||
msg: '用户名或密码错误',
|
|
||||||
data: {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import Mock from 'mockjs'
|
||||||
|
import qs from 'qs'
|
||||||
|
import withCredentials from './patch/withCredentials'
|
||||||
|
|
||||||
|
/* 补丁 */
|
||||||
|
withCredentials(Mock)
|
||||||
|
|
||||||
|
/* Mock 默认配置 */
|
||||||
|
Mock.setup({ timeout: '200-300' })
|
||||||
|
|
||||||
|
/* 扩展 [生成器] */
|
||||||
|
const Generator = (prop, template) => {
|
||||||
|
const obj = {}
|
||||||
|
obj[prop] = [template]
|
||||||
|
return Mock.mock(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 扩展 [循环] */
|
||||||
|
const Repeat = (num, itemTemplate) => Generator(`data|${num}`, itemTemplate).data
|
||||||
|
|
||||||
|
const CustomExtends = {
|
||||||
|
Generator,
|
||||||
|
Repeat,
|
||||||
|
Mock,
|
||||||
|
Random: Mock.Random
|
||||||
|
}
|
||||||
|
|
||||||
|
const extend = (prop, value) => {
|
||||||
|
CustomExtends[prop] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 装配配置组 */
|
||||||
|
const wired = ({ url, type, body }) => ({
|
||||||
|
method: type,
|
||||||
|
params: qs.parse(url.split('?').length > 1 ? url.split('?')[1] : ''),
|
||||||
|
body: JSON.parse(body),
|
||||||
|
url: qs.parse(url.split('?')[0]),
|
||||||
|
...CustomExtends
|
||||||
|
})
|
||||||
|
|
||||||
|
const setup = (path, method, handle) => {
|
||||||
|
Mock.mock(
|
||||||
|
RegExp(path),
|
||||||
|
method,
|
||||||
|
typeof handle === 'function' ? o => handle(wired(o)) : handle
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const load = (collection) => {
|
||||||
|
collection.map(({ path, method, handle }) => {
|
||||||
|
if (method === '*') {
|
||||||
|
method = [
|
||||||
|
'get',
|
||||||
|
'head',
|
||||||
|
'post',
|
||||||
|
'put',
|
||||||
|
'delete',
|
||||||
|
'connect',
|
||||||
|
'options',
|
||||||
|
'trace',
|
||||||
|
'patch'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if (typeof method === 'string' && method.indexOf('|') > -1) method = method.split('|')
|
||||||
|
if (method instanceof Array) {
|
||||||
|
method.map(item => setup(path, item, handle))
|
||||||
|
} else {
|
||||||
|
setup(path, method, handle)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { setup, load, extend }
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export default function (Mock) {
|
||||||
|
// http://cnine.me/note/FrontEnd/mock-lose-cookies-dbg.html
|
||||||
|
Mock.XHR.prototype.__send = Mock.XHR.prototype.send
|
||||||
|
Mock.XHR.prototype.send = function () {
|
||||||
|
if (this.custom.xhr) this.custom.xhr.withCredentials = this.withCredentials || false
|
||||||
|
this.__send.apply(this, arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-11
@@ -1,15 +1,10 @@
|
|||||||
import Mock from 'mockjs'
|
import d2Mock from './d2-mock'
|
||||||
|
|
||||||
// 补丁 解决 mock.js 影响 Cookie 携带
|
|
||||||
import PatchCookie from './patch/cookie'
|
|
||||||
|
|
||||||
PatchCookie(Mock)
|
|
||||||
|
|
||||||
// 导入所有的接口
|
|
||||||
const req = context => context.keys().map(context)
|
const req = context => context.keys().map(context)
|
||||||
req(require.context('./api/', true, /\.js$/))
|
const options = req(require.context('./api/', true, /\.js$/))
|
||||||
|
.filter(e => e.default)
|
||||||
|
.map(e => e.default)
|
||||||
|
|
||||||
// 设置全局延时 没有延时的话有时候会检测不到数据变化 建议保留
|
options.forEach(option => {
|
||||||
Mock.setup({
|
d2Mock.load(option)
|
||||||
timeout: '300-600'
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
export default function (Mock) {
|
|
||||||
// 解决 Mock 情况下,携带 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题
|
|
||||||
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
|
|
||||||
Mock.XHR.prototype.send = function () {
|
|
||||||
if (this.custom.xhr) {
|
|
||||||
this.custom.xhr.withCredentials = this.withCredentials || false
|
|
||||||
}
|
|
||||||
this.proxy_send(...arguments)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<d2-container>
|
<d2-container :filename="filename">
|
||||||
<template slot="header">Page 1 header</template>
|
<template slot="header">Page 1 header</template>
|
||||||
Hello World
|
Hello World
|
||||||
<template slot="footer">footer</template>
|
|
||||||
</d2-container>
|
</d2-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'page1'
|
name: 'page1',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
filename: __filename
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<d2-container>
|
<d2-container :filename="filename">
|
||||||
<template slot="header">Page 2 header</template>
|
<template slot="header">Page 2 header</template>
|
||||||
Hello World
|
Hello World
|
||||||
<template slot="footer">footer</template>
|
|
||||||
</d2-container>
|
</d2-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'page2'
|
name: 'page2',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
filename: __filename
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<d2-container>
|
<d2-container :filename="filename">
|
||||||
<template slot="header">Page 3 header</template>
|
<template slot="header">Page 3 header</template>
|
||||||
Hello World
|
Hello World
|
||||||
<template slot="footer">footer</template>
|
|
||||||
</d2-container>
|
</d2-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'page3'
|
name: 'page3',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
filename: __filename
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '~@/assets/style/public.scss';
|
|
||||||
.page {
|
.page {
|
||||||
background: #303133;
|
background: #303133;
|
||||||
background-blend-mode: multiply,multiply;
|
background-blend-mode: multiply,multiply;
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<d2-container class="page">
|
<d2-container :filename="filename" class="page">
|
||||||
<d2-page-cover
|
<d2-page-cover>
|
||||||
:title="`D2 Admin ${version}`"
|
|
||||||
sub-title="优雅的中后台集成方案">
|
|
||||||
<d2-icon-svg
|
<d2-icon-svg
|
||||||
class="page__logo"
|
class="page__logo"
|
||||||
name="d2-admin"/>
|
name="d2-admin"/>
|
||||||
@@ -35,7 +33,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from 'vuex'
|
|
||||||
import D2HelpBtn from './components/d2-help-btn'
|
import D2HelpBtn from './components/d2-help-btn'
|
||||||
import D2Badge from './components/d2-badge'
|
import D2Badge from './components/d2-badge'
|
||||||
export default {
|
export default {
|
||||||
@@ -43,16 +40,15 @@ export default {
|
|||||||
D2HelpBtn,
|
D2HelpBtn,
|
||||||
D2Badge
|
D2Badge
|
||||||
},
|
},
|
||||||
computed: {
|
data () {
|
||||||
...mapState('d2admin/releases', [
|
return {
|
||||||
'version'
|
filename: __filename
|
||||||
])
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '~@/assets/style/public.scss';
|
|
||||||
.page {
|
.page {
|
||||||
.page__logo {
|
.page__logo {
|
||||||
width: 120px;
|
width: 120px;
|
||||||
@@ -60,7 +56,7 @@ export default {
|
|||||||
.page__btn-group {
|
.page__btn-group {
|
||||||
color: $color-text-placehoder;
|
color: $color-text-placehoder;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
margin-top: -10px;
|
margin-top: 0px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
span {
|
span {
|
||||||
color: $color-text-sub;
|
color: $color-text-sub;
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
// 例子插件配置地址
|
|
||||||
// https://vincentgarreau.com/particles.js/#default
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
export default {
|
|
||||||
"particles": {
|
|
||||||
"number": {
|
|
||||||
"value": 6,
|
|
||||||
"density": {
|
|
||||||
"enable": true,
|
|
||||||
"value_area": 800
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color": {
|
|
||||||
"value": "#444"
|
|
||||||
},
|
|
||||||
"shape": {
|
|
||||||
"type": "polygon",
|
|
||||||
"stroke": {
|
|
||||||
"width": 0,
|
|
||||||
"color": "#000"
|
|
||||||
},
|
|
||||||
"polygon": {
|
|
||||||
"nb_sides": 6
|
|
||||||
},
|
|
||||||
"image": {
|
|
||||||
"src": "img/github.svg",
|
|
||||||
"width": 100,
|
|
||||||
"height": 100
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"opacity": {
|
|
||||||
"value": 0.3,
|
|
||||||
"random": true,
|
|
||||||
"anim": {
|
|
||||||
"enable": false,
|
|
||||||
"speed": 1,
|
|
||||||
"opacity_min": 0.1,
|
|
||||||
"sync": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"value": 160,
|
|
||||||
"random": false,
|
|
||||||
"anim": {
|
|
||||||
"enable": true,
|
|
||||||
"speed": 10,
|
|
||||||
"size_min": 40,
|
|
||||||
"sync": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"line_linked": {
|
|
||||||
"enable": false,
|
|
||||||
"distance": 200,
|
|
||||||
"color": "#ffffff",
|
|
||||||
"opacity": 1,
|
|
||||||
"width": 2
|
|
||||||
},
|
|
||||||
"move": {
|
|
||||||
"enable": true,
|
|
||||||
"speed": 8,
|
|
||||||
"direction": "none",
|
|
||||||
"random": false,
|
|
||||||
"straight": false,
|
|
||||||
"out_mode": "out",
|
|
||||||
"bounce": false,
|
|
||||||
"attract": {
|
|
||||||
"enable": false,
|
|
||||||
"rotateX": 600,
|
|
||||||
"rotateY": 1200
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interactivity": {
|
|
||||||
"detect_on": "canvas",
|
|
||||||
"events": {
|
|
||||||
"onhover": {
|
|
||||||
"enable": false,
|
|
||||||
"mode": "grab"
|
|
||||||
},
|
|
||||||
"onclick": {
|
|
||||||
"enable": false,
|
|
||||||
"mode": "push"
|
|
||||||
},
|
|
||||||
"resize": true
|
|
||||||
},
|
|
||||||
"modes": {
|
|
||||||
"grab": {
|
|
||||||
"distance": 400,
|
|
||||||
"line_linked": {
|
|
||||||
"opacity": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bubble": {
|
|
||||||
"distance": 400,
|
|
||||||
"size": 40,
|
|
||||||
"duration": 2,
|
|
||||||
"opacity": 8,
|
|
||||||
"speed": 3
|
|
||||||
},
|
|
||||||
"repulse": {
|
|
||||||
"distance": 200,
|
|
||||||
"duration": 0.4
|
|
||||||
},
|
|
||||||
"push": {
|
|
||||||
"particles_nb": 4
|
|
||||||
},
|
|
||||||
"remove": {
|
|
||||||
"particles_nb": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"retina_detect": true
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
export default {
|
|
||||||
"particles": {
|
|
||||||
"number": {
|
|
||||||
"value": 80,
|
|
||||||
"density": {
|
|
||||||
"enable": true,
|
|
||||||
"value_area": 800
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color": {
|
|
||||||
"value": "#DCDFE6"
|
|
||||||
},
|
|
||||||
"shape": {
|
|
||||||
"type": "circle",
|
|
||||||
"stroke": {
|
|
||||||
"width": 0,
|
|
||||||
"color": "#000000"
|
|
||||||
},
|
|
||||||
"polygon": {
|
|
||||||
"nb_sides": 5
|
|
||||||
},
|
|
||||||
"image": {
|
|
||||||
"src": "img/github.svg",
|
|
||||||
"width": 100,
|
|
||||||
"height": 100
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"opacity": {
|
|
||||||
"value": 1,
|
|
||||||
"random": false,
|
|
||||||
"anim": {
|
|
||||||
"enable": false,
|
|
||||||
"speed": 1,
|
|
||||||
"opacity_min": 0.1,
|
|
||||||
"sync": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"value": 4,
|
|
||||||
"random": true,
|
|
||||||
"anim": {
|
|
||||||
"enable": false,
|
|
||||||
"speed": 40,
|
|
||||||
"size_min": 0.1,
|
|
||||||
"sync": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"line_linked": {
|
|
||||||
"enable": true,
|
|
||||||
"distance": 150,
|
|
||||||
"color": "#DCDFE6",
|
|
||||||
"opacity": 0.4,
|
|
||||||
"width": 2
|
|
||||||
},
|
|
||||||
"move": {
|
|
||||||
"enable": true,
|
|
||||||
"speed": 6,
|
|
||||||
"direction": "none",
|
|
||||||
"random": false,
|
|
||||||
"straight": false,
|
|
||||||
"out_mode": "out",
|
|
||||||
"bounce": false,
|
|
||||||
"attract": {
|
|
||||||
"enable": false,
|
|
||||||
"rotateX": 600,
|
|
||||||
"rotateY": 1200
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interactivity": {
|
|
||||||
"detect_on": "canvas",
|
|
||||||
"events": {
|
|
||||||
"onhover": {
|
|
||||||
"enable": true,
|
|
||||||
"mode": "repulse"
|
|
||||||
},
|
|
||||||
"onclick": {
|
|
||||||
"enable": true,
|
|
||||||
"mode": "push"
|
|
||||||
},
|
|
||||||
"resize": true
|
|
||||||
},
|
|
||||||
"modes": {
|
|
||||||
"grab": {
|
|
||||||
"distance": 400,
|
|
||||||
"line_linked": {
|
|
||||||
"opacity": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bubble": {
|
|
||||||
"distance": 400,
|
|
||||||
"size": 40,
|
|
||||||
"duration": 2,
|
|
||||||
"opacity": 8,
|
|
||||||
"speed": 3
|
|
||||||
},
|
|
||||||
"repulse": {
|
|
||||||
"distance": 200,
|
|
||||||
"duration": 0.4
|
|
||||||
},
|
|
||||||
"push": {
|
|
||||||
"particles_nb": 4
|
|
||||||
},
|
|
||||||
"remove": {
|
|
||||||
"particles_nb": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"retina_detect": true
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
export default {
|
|
||||||
"particles": {
|
|
||||||
"number": {
|
|
||||||
"value": 160,
|
|
||||||
"density": {
|
|
||||||
"enable": true,
|
|
||||||
"value_area": 800
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color": {
|
|
||||||
"value": "#ffffff"
|
|
||||||
},
|
|
||||||
"shape": {
|
|
||||||
"type": "circle",
|
|
||||||
"stroke": {
|
|
||||||
"width": 0,
|
|
||||||
"color": "#000000"
|
|
||||||
},
|
|
||||||
"polygon": {
|
|
||||||
"nb_sides": 5
|
|
||||||
},
|
|
||||||
"image": {
|
|
||||||
"src": "img/github.svg",
|
|
||||||
"width": 100,
|
|
||||||
"height": 100
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"opacity": {
|
|
||||||
"value": 1,
|
|
||||||
"random": true,
|
|
||||||
"anim": {
|
|
||||||
"enable": true,
|
|
||||||
"speed": 1,
|
|
||||||
"opacity_min": 0,
|
|
||||||
"sync": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"value": 3,
|
|
||||||
"random": true,
|
|
||||||
"anim": {
|
|
||||||
"enable": false,
|
|
||||||
"speed": 4,
|
|
||||||
"size_min": 0.3,
|
|
||||||
"sync": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"line_linked": {
|
|
||||||
"enable": false,
|
|
||||||
"distance": 150,
|
|
||||||
"color": "#ffffff",
|
|
||||||
"opacity": 0.4,
|
|
||||||
"width": 1
|
|
||||||
},
|
|
||||||
"move": {
|
|
||||||
"enable": true,
|
|
||||||
"speed": 1,
|
|
||||||
"direction": "none",
|
|
||||||
"random": true,
|
|
||||||
"straight": false,
|
|
||||||
"out_mode": "out",
|
|
||||||
"bounce": false,
|
|
||||||
"attract": {
|
|
||||||
"enable": false,
|
|
||||||
"rotateX": 600,
|
|
||||||
"rotateY": 600
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interactivity": {
|
|
||||||
"detect_on": "canvas",
|
|
||||||
"events": {
|
|
||||||
"onhover": {
|
|
||||||
"enable": true,
|
|
||||||
"mode": "bubble"
|
|
||||||
},
|
|
||||||
"onclick": {
|
|
||||||
"enable": true,
|
|
||||||
"mode": "repulse"
|
|
||||||
},
|
|
||||||
"resize": true
|
|
||||||
},
|
|
||||||
"modes": {
|
|
||||||
"grab": {
|
|
||||||
"distance": 400,
|
|
||||||
"line_linked": {
|
|
||||||
"opacity": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bubble": {
|
|
||||||
"distance": 250,
|
|
||||||
"size": 0,
|
|
||||||
"duration": 2,
|
|
||||||
"opacity": 0,
|
|
||||||
"speed": 3
|
|
||||||
},
|
|
||||||
"repulse": {
|
|
||||||
"distance": 400,
|
|
||||||
"duration": 0.4
|
|
||||||
},
|
|
||||||
"push": {
|
|
||||||
"particles_nb": 4
|
|
||||||
},
|
|
||||||
"remove": {
|
|
||||||
"particles_nb": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"retina_detect": true
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
export default {
|
|
||||||
"particles": {
|
|
||||||
"number": {
|
|
||||||
"value": 400,
|
|
||||||
"density": {
|
|
||||||
"enable": true,
|
|
||||||
"value_area": 800
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color": {
|
|
||||||
"value": "#fff"
|
|
||||||
},
|
|
||||||
"shape": {
|
|
||||||
"type": "circle",
|
|
||||||
"stroke": {
|
|
||||||
"width": 0,
|
|
||||||
"color": "#000000"
|
|
||||||
},
|
|
||||||
"polygon": {
|
|
||||||
"nb_sides": 5
|
|
||||||
},
|
|
||||||
"image": {
|
|
||||||
"src": "img/github.svg",
|
|
||||||
"width": 100,
|
|
||||||
"height": 100
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"opacity": {
|
|
||||||
"value": 0.5,
|
|
||||||
"random": true,
|
|
||||||
"anim": {
|
|
||||||
"enable": false,
|
|
||||||
"speed": 1,
|
|
||||||
"opacity_min": 0.1,
|
|
||||||
"sync": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"value": 10,
|
|
||||||
"random": true,
|
|
||||||
"anim": {
|
|
||||||
"enable": false,
|
|
||||||
"speed": 40,
|
|
||||||
"size_min": 0.1,
|
|
||||||
"sync": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"line_linked": {
|
|
||||||
"enable": false,
|
|
||||||
"distance": 500,
|
|
||||||
"color": "#ffffff",
|
|
||||||
"opacity": 0.4,
|
|
||||||
"width": 2
|
|
||||||
},
|
|
||||||
"move": {
|
|
||||||
"enable": true,
|
|
||||||
"speed": 6,
|
|
||||||
"direction": "bottom",
|
|
||||||
"random": false,
|
|
||||||
"straight": false,
|
|
||||||
"out_mode": "out",
|
|
||||||
"bounce": false,
|
|
||||||
"attract": {
|
|
||||||
"enable": false,
|
|
||||||
"rotateX": 600,
|
|
||||||
"rotateY": 1200
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"interactivity": {
|
|
||||||
"detect_on": "canvas",
|
|
||||||
"events": {
|
|
||||||
"onhover": {
|
|
||||||
"enable": true,
|
|
||||||
"mode": "bubble"
|
|
||||||
},
|
|
||||||
"onclick": {
|
|
||||||
"enable": true,
|
|
||||||
"mode": "repulse"
|
|
||||||
},
|
|
||||||
"resize": true
|
|
||||||
},
|
|
||||||
"modes": {
|
|
||||||
"grab": {
|
|
||||||
"distance": 400,
|
|
||||||
"line_linked": {
|
|
||||||
"opacity": 0.5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bubble": {
|
|
||||||
"distance": 400,
|
|
||||||
"size": 4,
|
|
||||||
"duration": 0.3,
|
|
||||||
"opacity": 1,
|
|
||||||
"speed": 3
|
|
||||||
},
|
|
||||||
"repulse": {
|
|
||||||
"distance": 200,
|
|
||||||
"duration": 0.4
|
|
||||||
},
|
|
||||||
"push": {
|
|
||||||
"particles_nb": 4
|
|
||||||
},
|
|
||||||
"remove": {
|
|
||||||
"particles_nb": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"retina_detect": true
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
+314
-50
@@ -1,41 +1,77 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login-page">
|
<div class="page-login">
|
||||||
<div class="layer bg" id="login"></div>
|
<div class="page-login--layer page-login--layer-area">
|
||||||
<div class="layer flex-center">
|
<ul class="circles">
|
||||||
<!-- logo部分 -->
|
<li v-for="n in 10" :key="n"></li>
|
||||||
<div class="logo-group">
|
</ul>
|
||||||
<img src="./image/logo.png" alt="logo">
|
</div>
|
||||||
|
<div
|
||||||
|
class="page-login--layer page-login--layer-time"
|
||||||
|
flex="main:center cross:center">
|
||||||
|
{{time}}
|
||||||
|
</div>
|
||||||
|
<div class="page-login--layer">
|
||||||
|
<div
|
||||||
|
class="page-login--content"
|
||||||
|
flex="dir:top main:justify cross:center box:justify">
|
||||||
|
<div class="page-login--content-header">
|
||||||
|
<p class="page-login--content-header-motto">
|
||||||
|
时间是一切财富中最宝贵的财富。 <span>—— 德奥弗拉斯多</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="page-login--content-main"
|
||||||
|
flex="dir:top main:center cross:center">
|
||||||
|
<!-- logo -->
|
||||||
|
<img class="page-login--logo" src="./image/logo@2x.png">
|
||||||
|
<!-- 表单 -->
|
||||||
|
<div class="page-login--form">
|
||||||
|
<el-card shadow="never">
|
||||||
|
<el-form ref="loginForm" label-position="top" :rules="rules" :model="formLogin" size="default">
|
||||||
|
<el-form-item prop="username">
|
||||||
|
<el-input type="text" v-model="formLogin.username" placeholder="用户名">
|
||||||
|
<i slot="prepend" class="fa fa-user-circle-o"></i>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="password">
|
||||||
|
<el-input type="password" v-model="formLogin.password" placeholder="密码">
|
||||||
|
<i slot="prepend" class="fa fa-keyboard-o"></i>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="code">
|
||||||
|
<el-input type="text" v-model="formLogin.code" placeholder="- - - -">
|
||||||
|
<template slot="prepend">验证码</template>
|
||||||
|
<template slot="append">
|
||||||
|
<img class="login-code" src="./image/login-code.png">
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-button size="default" @click="submit" type="primary" class="button-login">登录</el-button>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
<p
|
||||||
|
class="page-login--options"
|
||||||
|
flex="main:justify cross:center">
|
||||||
|
<span><d2-icon name="question-circle"/> 忘记密码</span>
|
||||||
|
<span>注册用户</span>
|
||||||
|
</p>
|
||||||
|
<!-- 快速登录按钮 -->
|
||||||
|
<el-button class="page-login--quick" size="default" type="info" @click="dialogVisible = true">
|
||||||
|
快速选择用户(测试功能)
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="page-login--content-footer">
|
||||||
|
<p class="page-login--content-footer-options">
|
||||||
|
<a href="#">帮助</a>
|
||||||
|
<a href="#">隐私</a>
|
||||||
|
<a href="#">条款</a>
|
||||||
|
</p>
|
||||||
|
<p class="page-login--content-footer-copyright">
|
||||||
|
Copyright <d2-icon name="copyright"/> 2018 D2 Projects 开源组织出品 <a href="https://github.com/FairyEver">@FairyEver</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 表单部分 -->
|
|
||||||
<div class="form-group">
|
|
||||||
<el-card>
|
|
||||||
<el-form ref="loginForm" label-position="top" :rules="rules" :model="formLogin" size="default">
|
|
||||||
<el-form-item prop="username">
|
|
||||||
<el-input type="text" v-model="formLogin.username" placeholder="用户名">
|
|
||||||
<i slot="prepend" class="fa fa-user-circle-o"></i>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item prop="password">
|
|
||||||
<el-input type="password" v-model="formLogin.password" placeholder="密码">
|
|
||||||
<i slot="prepend" class="fa fa-keyboard-o"></i>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item prop="code">
|
|
||||||
<el-input type="text" v-model="formLogin.code" placeholder="- - - -">
|
|
||||||
<template slot="prepend">验证码</template>
|
|
||||||
<template slot="append">
|
|
||||||
<img class="login-code" src="./image/login-code.png">
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-button size="default" @click="submit" type="primary" class="button-login">登录</el-button>
|
|
||||||
</el-form>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
<!-- 快速登录按钮 -->
|
|
||||||
<el-button size="default" type="info" class="button-help" @click="dialogVisible = true">
|
|
||||||
快速选择用户(测试功能)
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
title="快速选择用户"
|
title="快速选择用户"
|
||||||
@@ -43,7 +79,7 @@
|
|||||||
width="400px">
|
width="400px">
|
||||||
<el-row :gutter="10" style="margin: -20px 0px -10px 0px;">
|
<el-row :gutter="10" style="margin: -20px 0px -10px 0px;">
|
||||||
<el-col v-for="(user, index) in users" :key="index" :span="8">
|
<el-col v-for="(user, index) in users" :key="index" :span="8">
|
||||||
<div class="user-btn" @click="handleUserBtnClick(user)">
|
<div class="page-login--quick-user" @click="handleUserBtnClick(user)">
|
||||||
<d2-icon name="user-circle-o"/>
|
<d2-icon name="user-circle-o"/>
|
||||||
<span>{{user.name}}</span>
|
<span>{{user.name}}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -54,13 +90,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/* eslint-disable */
|
import dayjs from 'dayjs'
|
||||||
require('particles.js')
|
|
||||||
import config from './config/default'
|
|
||||||
import { mapActions } from 'vuex'
|
import { mapActions } from 'vuex'
|
||||||
export default {
|
export default {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
timeInterval: null,
|
||||||
|
time: dayjs().format('HH:mm:ss'),
|
||||||
// 快速选择用户
|
// 快速选择用户
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
users: [
|
users: [
|
||||||
@@ -101,22 +137,20 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
// 初始化例子插件
|
this.timeInterval = setInterval(() => {
|
||||||
particlesJS('login', config)
|
this.refreshTime()
|
||||||
|
}, 1000)
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
// 销毁 particlesJS
|
clearInterval(this.timeInterval)
|
||||||
// thanks https://github.com/d2-projects/d2-admin/issues/65
|
|
||||||
// ref https://github.com/VincentGarreau/particles.js/issues/63
|
|
||||||
if (pJSDom && pJSDom.length > 0) {
|
|
||||||
pJSDom[0].pJS.fn.vendors.destroypJS()
|
|
||||||
pJSDom = []
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions('d2admin/account', [
|
...mapActions('d2admin/account', [
|
||||||
'login'
|
'login'
|
||||||
]),
|
]),
|
||||||
|
refreshTime () {
|
||||||
|
this.time = dayjs().format('HH:mm:ss')
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @description 接收选择一个用户快速登录的事件
|
* @description 接收选择一个用户快速登录的事件
|
||||||
* @param {Object} user 用户信息
|
* @param {Object} user 用户信息
|
||||||
@@ -141,6 +175,10 @@ export default {
|
|||||||
username: this.formLogin.username,
|
username: this.formLogin.username,
|
||||||
password: this.formLogin.password
|
password: this.formLogin.password
|
||||||
})
|
})
|
||||||
|
.then(() => {
|
||||||
|
// 重定向对象不存在则返回顶层路径
|
||||||
|
this.$router.replace(this.$route.query.redirect || '/')
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
// 登录表单校验失败
|
// 登录表单校验失败
|
||||||
this.$message.error('表单校验失败')
|
this.$message.error('表单校验失败')
|
||||||
@@ -152,5 +190,231 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import './style.scss';
|
.page-login {
|
||||||
|
@extend %unable-select;
|
||||||
|
$backgroundColor: #F0F2F5;
|
||||||
|
// ---
|
||||||
|
background-color: $backgroundColor;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
// 层
|
||||||
|
.page-login--layer {
|
||||||
|
@extend %full;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.page-login--layer-area {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
// 时间
|
||||||
|
.page-login--layer-time {
|
||||||
|
font-size: 24em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: rgba(0, 0, 0, 0.03);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
// 登陆页面控件的容器
|
||||||
|
.page-login--content {
|
||||||
|
height: 100%;
|
||||||
|
min-height: 500px;
|
||||||
|
}
|
||||||
|
// header
|
||||||
|
.page-login--content-header {
|
||||||
|
padding: 1em 0;
|
||||||
|
.page-login--content-header-motto {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
color: $color-text-normal;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
span {
|
||||||
|
color: $color-text-sub;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// main
|
||||||
|
.page-login--logo {
|
||||||
|
width: 240px;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
margin-top: -2em;
|
||||||
|
}
|
||||||
|
// 登录表单
|
||||||
|
.page-login--form {
|
||||||
|
width: 280px;
|
||||||
|
// 卡片
|
||||||
|
.el-card {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
// 登录按钮
|
||||||
|
.button-login {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
// 输入框左边的图表区域缩窄
|
||||||
|
.el-input-group__prepend {
|
||||||
|
padding: 0px 14px;
|
||||||
|
}
|
||||||
|
.login-code {
|
||||||
|
height: 40px - 2px;
|
||||||
|
display: block;
|
||||||
|
margin: 0px -20px;
|
||||||
|
border-top-right-radius: 2px;
|
||||||
|
border-bottom-right-radius: 2px;
|
||||||
|
}
|
||||||
|
// 登陆选项
|
||||||
|
.page-login--options {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $color-primary;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.page-login--quick {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 快速选择用户面板
|
||||||
|
.page-login--quick-user {
|
||||||
|
@extend %flex-center-col;
|
||||||
|
padding: 10px 0px;
|
||||||
|
border-radius: 4px;
|
||||||
|
&:hover {
|
||||||
|
background-color: $color-bg;
|
||||||
|
i {
|
||||||
|
color: $color-text-normal;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
color: $color-text-normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i {
|
||||||
|
font-size: 36px;
|
||||||
|
color: $color-text-sub;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 10px;
|
||||||
|
color: $color-text-sub;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// footer
|
||||||
|
.page-login--content-footer {
|
||||||
|
padding: 1em 0;
|
||||||
|
.page-login--content-footer-options {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
a {
|
||||||
|
color: $color-text-normal;
|
||||||
|
margin: 0 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.page-login--content-footer-copyright {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: $color-text-normal;
|
||||||
|
a {
|
||||||
|
color: $color-text-normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 背景
|
||||||
|
.circles {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
li {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
list-style: none;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background: #FFF;
|
||||||
|
animation: animate 25s linear infinite;
|
||||||
|
bottom: -200px;
|
||||||
|
@keyframes animate {
|
||||||
|
0%{
|
||||||
|
transform: translateY(0) rotate(0deg);
|
||||||
|
opacity: 1;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
100%{
|
||||||
|
transform: translateY(-1000px) rotate(720deg);
|
||||||
|
opacity: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(1) {
|
||||||
|
left: 15%;
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
&:nth-child(2) {
|
||||||
|
left: 5%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
animation-delay: 2s;
|
||||||
|
animation-duration: 12s;
|
||||||
|
}
|
||||||
|
&:nth-child(3) {
|
||||||
|
left: 70%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
animation-delay: 4s;
|
||||||
|
}
|
||||||
|
&:nth-child(4) {
|
||||||
|
left: 40%;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
animation-duration: 18s;
|
||||||
|
}
|
||||||
|
&:nth-child(5) {
|
||||||
|
left: 65%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
&:nth-child(6) {
|
||||||
|
left: 75%;
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
animation-delay: 3s;
|
||||||
|
}
|
||||||
|
&:nth-child(7) {
|
||||||
|
left: 35%;
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
animation-delay: 7s;
|
||||||
|
}
|
||||||
|
&:nth-child(8) {
|
||||||
|
left: 50%;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
animation-delay: 15s;
|
||||||
|
animation-duration: 45s;
|
||||||
|
}
|
||||||
|
&:nth-child(9) {
|
||||||
|
left: 20%;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
animation-delay: 2s;
|
||||||
|
animation-duration: 35s;
|
||||||
|
}
|
||||||
|
&:nth-child(10) {
|
||||||
|
left: 85%;
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
animation-duration: 11s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
@import '~@/assets/style/public.scss';
|
|
||||||
.login-page {
|
|
||||||
background-color: #EDF4FA;
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
// 层
|
|
||||||
.layer {
|
|
||||||
position: absolute;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
&.flex-center {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 背景
|
|
||||||
.bg {
|
|
||||||
canvas {
|
|
||||||
display: block;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// logo
|
|
||||||
.logo-group {
|
|
||||||
margin-top: -75px - 70px;
|
|
||||||
position: relative;
|
|
||||||
top: 75px;
|
|
||||||
img {
|
|
||||||
height: 140px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 登录表单
|
|
||||||
.form-group {
|
|
||||||
width: 300px;
|
|
||||||
// 重新设置卡片阴影
|
|
||||||
.el-card {
|
|
||||||
box-shadow: 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5);
|
|
||||||
.el-card__body {
|
|
||||||
padding-top: 70px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 登录按钮
|
|
||||||
.button-login {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
// 输入框左边的图表区域缩窄
|
|
||||||
.el-input-group__prepend {
|
|
||||||
padding: 0px 14px;
|
|
||||||
}
|
|
||||||
.login-code {
|
|
||||||
height: 40px - 2px;
|
|
||||||
display: block;
|
|
||||||
margin: 0px -20px;
|
|
||||||
border-top-right-radius: 2px;
|
|
||||||
border-bottom-right-radius: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 帮助按钮
|
|
||||||
.button-help {
|
|
||||||
width: 300px;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
.user-btn {
|
|
||||||
@extend %flex-center-col;
|
|
||||||
@extend %unable-select;
|
|
||||||
padding: 10px 0px;
|
|
||||||
border-radius: 4px;
|
|
||||||
&:hover {
|
|
||||||
background-color: $color-bg;
|
|
||||||
i {
|
|
||||||
color: $color-text-normal;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
color: $color-text-normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i {
|
|
||||||
font-size: 36px;
|
|
||||||
color: $color-text-sub;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
font-size: 12px;
|
|
||||||
margin-top: 10px;
|
|
||||||
color: $color-text-sub;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -41,13 +41,9 @@ const service = axios.create({
|
|||||||
service.interceptors.request.use(
|
service.interceptors.request.use(
|
||||||
config => {
|
config => {
|
||||||
// 在请求发送之前做一些处理
|
// 在请求发送之前做一些处理
|
||||||
if (!(/^https:\/\/|http:\/\//.test(config.url))) {
|
const token = util.cookies.get('token')
|
||||||
const token = util.cookies.get('token')
|
// 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
|
||||||
if (token && token !== 'undefined') {
|
config.headers['X-Token'] = token
|
||||||
// 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
|
|
||||||
config.headers['X-Token'] = token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import 'flex.css'
|
|||||||
import '@/components'
|
import '@/components'
|
||||||
// svg 图标
|
// svg 图标
|
||||||
import '@/assets/svg-icons'
|
import '@/assets/svg-icons'
|
||||||
|
// 过滤器
|
||||||
|
import d2VueFiltersDate from '@d2-projects/vue-filters-date'
|
||||||
// 功能插件
|
// 功能插件
|
||||||
import pluginError from '@/plugin/error'
|
import pluginError from '@/plugin/error'
|
||||||
import pluginLog from '@/plugin/log'
|
import pluginLog from '@/plugin/log'
|
||||||
@@ -14,14 +16,21 @@ import pluginOpen from '@/plugin/open'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
async install (Vue, options) {
|
async install (Vue, options) {
|
||||||
// 设置为 false 以阻止 vue 在启动时生成生产提示。https://cn.vuejs.org/v2/api/#productionTip
|
// 设置为 false 以阻止 vue 在启动时生成生产提示
|
||||||
|
// https://cn.vuejs.org/v2/api/#productionTip
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
// 当前环境
|
// 当前环境
|
||||||
Vue.prototype.$env = process.env.NODE_ENV
|
Vue.prototype.$env = process.env.NODE_ENV
|
||||||
// 当前的 baseUrl
|
// 当前的 baseUrl
|
||||||
Vue.prototype.$baseUrl = process.env.BASE_URL
|
Vue.prototype.$baseUrl = process.env.BASE_URL
|
||||||
|
// 当前版本
|
||||||
|
Vue.prototype.$version = process.env.VUE_APP_VERSION
|
||||||
|
// 构建时间
|
||||||
|
Vue.prototype.$buildTime = process.env.VUE_APP_BUILD_TIME
|
||||||
// Element
|
// Element
|
||||||
Vue.use(ElementUI)
|
Vue.use(ElementUI)
|
||||||
|
// 过滤器 日期模块
|
||||||
|
Vue.use(d2VueFiltersDate)
|
||||||
// 插件
|
// 插件
|
||||||
Vue.use(pluginError)
|
Vue.use(pluginError)
|
||||||
Vue.use(pluginLog)
|
Vue.use(pluginLog)
|
||||||
|
|||||||
+10
-8
@@ -29,21 +29,23 @@ router.beforeEach((to, from, next) => {
|
|||||||
// 关闭搜索面板
|
// 关闭搜索面板
|
||||||
store.commit('d2admin/search/set', false)
|
store.commit('d2admin/search/set', false)
|
||||||
// 验证当前路由所有的匹配中是否需要有登录验证的
|
// 验证当前路由所有的匹配中是否需要有登录验证的
|
||||||
if (to.matched.some(r => r.meta.requiresAuth)) {
|
if (to.matched.some(r => r.meta.auth)) {
|
||||||
// 这里暂时将cookie里是否存有token作为验证是否登录的条件
|
// 这里暂时将cookie里是否存有token作为验证是否登录的条件
|
||||||
// 请根据自身业务需要修改
|
// 请根据自身业务需要修改
|
||||||
const token = util.cookies.get('token')
|
const token = util.cookies.get('token')
|
||||||
if (token && token !== 'undefined') {
|
if (token && token !== 'undefined') {
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
// 将当前预计打开的页面完整地址临时存储 登录后继续跳转
|
|
||||||
// 这个 cookie(redirect) 会在登录后自动删除
|
|
||||||
util.cookies.set('redirect', to.fullPath)
|
|
||||||
// 没有登录的时候跳转到登录界面
|
// 没有登录的时候跳转到登录界面
|
||||||
|
// 携带上登陆成功之后需要跳转的页面完整路径
|
||||||
next({
|
next({
|
||||||
name: 'login'
|
name: 'login',
|
||||||
|
query: {
|
||||||
|
redirect: to.fullPath
|
||||||
|
}
|
||||||
})
|
})
|
||||||
NProgress.done() // next(...)重定向不会触发router.afterEach钩子,需要手动hack一下
|
// https://github.com/d2-projects/d2-admin/issues/138
|
||||||
|
NProgress.done()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 不需要身份校验 直接通过
|
// 不需要身份校验 直接通过
|
||||||
@@ -56,9 +58,9 @@ router.afterEach(to => {
|
|||||||
NProgress.done()
|
NProgress.done()
|
||||||
// 需要的信息
|
// 需要的信息
|
||||||
const app = router.app
|
const app = router.app
|
||||||
const { name, params, query } = to
|
const { name, params, query, fullPath } = to
|
||||||
// 多页控制 打开新的页面
|
// 多页控制 打开新的页面
|
||||||
app.$store.dispatch('d2admin/page/open', { name, params, query })
|
app.$store.dispatch('d2admin/page/open', { name, params, query, fullPath })
|
||||||
// 更改标题
|
// 更改标题
|
||||||
util.title(to.meta.title)
|
util.title(to.meta.title)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import demo from './modules/demo'
|
|||||||
|
|
||||||
import layoutHeaderAside from '@/layout/header-aside'
|
import layoutHeaderAside from '@/layout/header-aside'
|
||||||
|
|
||||||
const meta = { requiresAuth: true }
|
const meta = { auth: true }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在主框架内显示
|
* 在主框架内显示
|
||||||
|
|||||||
+2
-7
@@ -1,5 +1,3 @@
|
|||||||
import { version } from '../package'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// 快捷键
|
// 快捷键
|
||||||
// 支持快捷键 例如 ctrl+shift+s
|
// 支持快捷键 例如 ctrl+shift+s
|
||||||
@@ -18,17 +16,14 @@ export default {
|
|||||||
opened: [
|
opened: [
|
||||||
{
|
{
|
||||||
name: 'index',
|
name: 'index',
|
||||||
|
fullPath: '/index',
|
||||||
meta: {
|
meta: {
|
||||||
title: '首页',
|
title: '首页',
|
||||||
requiresAuth: false
|
auth: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
// 版本
|
|
||||||
releases: {
|
|
||||||
version
|
|
||||||
},
|
|
||||||
// 菜单搜索
|
// 菜单搜索
|
||||||
search: {
|
search: {
|
||||||
enable: true
|
enable: true
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import util from '@/libs/util.js'
|
import util from '@/libs/util.js'
|
||||||
import { AccountLogin } from '@/api/sys/login'
|
import { AccountLogin } from '@api/sys.login'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
@@ -10,45 +10,41 @@ export default {
|
|||||||
* @param {Object} param vm {Object} vue 实例
|
* @param {Object} param vm {Object} vue 实例
|
||||||
* @param {Object} param username {String} 用户账号
|
* @param {Object} param username {String} 用户账号
|
||||||
* @param {Object} param password {String} 密码
|
* @param {Object} param password {String} 密码
|
||||||
* @param {Object} param route {Object} 登录成功后定向的路由对象
|
* @param {Object} param route {Object} 登录成功后定向的路由对象 任何 vue-router 支持的格式
|
||||||
*/
|
*/
|
||||||
login ({ dispatch }, {
|
login ({ dispatch }, {
|
||||||
vm,
|
vm,
|
||||||
username,
|
username,
|
||||||
password,
|
password
|
||||||
route = {
|
|
||||||
name: 'index'
|
|
||||||
}
|
|
||||||
}) {
|
}) {
|
||||||
// 开始请求登录接口
|
return new Promise((resolve, reject) => {
|
||||||
AccountLogin({
|
// 开始请求登录接口
|
||||||
username,
|
AccountLogin({
|
||||||
password
|
username,
|
||||||
|
password
|
||||||
|
})
|
||||||
|
.then(async res => {
|
||||||
|
// 设置 cookie 一定要存 uuid 和 token 两个 cookie
|
||||||
|
// 整个系统依赖这两个数据进行校验和存储
|
||||||
|
// uuid 是用户身份唯一标识 用户注册的时候确定 并且不可改变 不可重复
|
||||||
|
// token 代表用户当前登录状态 建议在网络请求中携带 token
|
||||||
|
// 如有必要 token 需要定时更新,默认保存一天
|
||||||
|
util.cookies.set('uuid', res.uuid)
|
||||||
|
util.cookies.set('token', res.token)
|
||||||
|
// 设置 vuex 用户信息
|
||||||
|
await dispatch('d2admin/user/set', {
|
||||||
|
name: res.name
|
||||||
|
}, { root: true })
|
||||||
|
// 用户登录后从持久化数据加载一系列的设置
|
||||||
|
await dispatch('load')
|
||||||
|
// 结束
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('err: ', err)
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.then(async res => {
|
|
||||||
// 设置 cookie 一定要存 uuid 和 token 两个 cookie
|
|
||||||
// 整个系统依赖这两个数据进行校验和存储
|
|
||||||
// uuid 是用户身份唯一标识 用户注册的时候确定 并且不可改变 不可重复
|
|
||||||
// token 代表用户当前登录状态 建议在网络请求中携带 token
|
|
||||||
// 如有必要 token 需要定时更新,默认保存一天
|
|
||||||
util.cookies.set('uuid', res.uuid)
|
|
||||||
util.cookies.set('token', res.token)
|
|
||||||
// 设置 vuex 用户信息
|
|
||||||
await dispatch('d2admin/user/set', {
|
|
||||||
name: res.name
|
|
||||||
}, { root: true })
|
|
||||||
// 用户登录后从持久化数据加载一系列的设置
|
|
||||||
await dispatch('load')
|
|
||||||
// 更新路由 尝试去获取 cookie 里保存的需要重定向的页面完整地址
|
|
||||||
const path = util.cookies.get('redirect')
|
|
||||||
// 根据是否存有重定向页面判断如何重定向
|
|
||||||
vm.$router.replace(path ? { path } : route)
|
|
||||||
// 删除 cookie 中保存的重定向页面
|
|
||||||
util.cookies.remove('redirect')
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log('err: ', err)
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @description 注销用户并返回登录页面
|
* @description 注销用户并返回登录页面
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import db from '@/libs/db.js'
|
import util from '@/libs/util'
|
||||||
import util from '@/libs/util.js'
|
import { cloneDeep } from 'lodash'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 检查路径是否存在 不存在的话初始化
|
* @description 检查路径是否存在 不存在的话初始化
|
||||||
@@ -19,9 +19,16 @@ function pathInit ({
|
|||||||
}) {
|
}) {
|
||||||
const uuid = util.cookies.get('uuid') || 'ghost-uuid'
|
const uuid = util.cookies.get('uuid') || 'ghost-uuid'
|
||||||
const currentPath = `${dbName}.${user ? `user.${uuid}` : 'public'}${path ? `.${path}` : ''}`
|
const currentPath = `${dbName}.${user ? `user.${uuid}` : 'public'}${path ? `.${path}` : ''}`
|
||||||
const value = db.get(currentPath).value()
|
const value = util.db.get(currentPath).value()
|
||||||
|
// console.group('pathInit')
|
||||||
|
// console.log('dbName', dbName)
|
||||||
|
// console.log('path', path)
|
||||||
|
// console.log('user', user)
|
||||||
|
// console.log('defaultValue', defaultValue)
|
||||||
|
// console.log('value', value)
|
||||||
|
// console.groupEnd()
|
||||||
if (!(value !== undefined && validator(value))) {
|
if (!(value !== undefined && validator(value))) {
|
||||||
db
|
util.db
|
||||||
.set(currentPath, defaultValue)
|
.set(currentPath, defaultValue)
|
||||||
.write()
|
.write()
|
||||||
}
|
}
|
||||||
@@ -45,7 +52,7 @@ export default {
|
|||||||
value = '',
|
value = '',
|
||||||
user = false
|
user = false
|
||||||
}) {
|
}) {
|
||||||
db.set(pathInit({
|
util.db.set(pathInit({
|
||||||
dbName,
|
dbName,
|
||||||
path,
|
path,
|
||||||
user
|
user
|
||||||
@@ -66,12 +73,12 @@ export default {
|
|||||||
user = false
|
user = false
|
||||||
}) {
|
}) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
resolve(db.get(pathInit({
|
resolve(cloneDeep(util.db.get(pathInit({
|
||||||
dbName,
|
dbName,
|
||||||
path,
|
path,
|
||||||
user,
|
user,
|
||||||
defaultValue
|
defaultValue
|
||||||
})).value())
|
})).value()))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -83,7 +90,7 @@ export default {
|
|||||||
user = false
|
user = false
|
||||||
} = {}) {
|
} = {}) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
resolve(db.get(pathInit({
|
resolve(util.db.get(pathInit({
|
||||||
dbName: 'database',
|
dbName: 'database',
|
||||||
path: '',
|
path: '',
|
||||||
user,
|
user,
|
||||||
@@ -100,7 +107,7 @@ export default {
|
|||||||
user = false
|
user = false
|
||||||
} = {}) {
|
} = {}) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
resolve(db.get(pathInit({
|
resolve(util.db.get(pathInit({
|
||||||
dbName: 'database',
|
dbName: 'database',
|
||||||
path: '',
|
path: '',
|
||||||
user,
|
user,
|
||||||
@@ -118,11 +125,11 @@ export default {
|
|||||||
*/
|
*/
|
||||||
databasePage (context, {
|
databasePage (context, {
|
||||||
vm,
|
vm,
|
||||||
basis = 'name',
|
basis = 'fullPath',
|
||||||
user = false
|
user = false
|
||||||
} = {}) {
|
} = {}) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
resolve(db.get(pathInit({
|
resolve(util.db.get(pathInit({
|
||||||
dbName: 'database',
|
dbName: 'database',
|
||||||
path: `$page.${vm.$route[basis]}`,
|
path: `$page.${vm.$route[basis]}`,
|
||||||
user,
|
user,
|
||||||
@@ -139,11 +146,11 @@ export default {
|
|||||||
*/
|
*/
|
||||||
databasePageClear (context, {
|
databasePageClear (context, {
|
||||||
vm,
|
vm,
|
||||||
basis = 'name',
|
basis = 'fullPath',
|
||||||
user = false
|
user = false
|
||||||
} = {}) {
|
} = {}) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
resolve(db.get(pathInit({
|
resolve(util.db.get(pathInit({
|
||||||
dbName: 'database',
|
dbName: 'database',
|
||||||
path: `$page.${vm.$route[basis]}`,
|
path: `$page.${vm.$route[basis]}`,
|
||||||
user,
|
user,
|
||||||
@@ -161,16 +168,16 @@ export default {
|
|||||||
*/
|
*/
|
||||||
pageSet (context, {
|
pageSet (context, {
|
||||||
vm,
|
vm,
|
||||||
basis = 'name',
|
basis = 'fullPath',
|
||||||
user = false
|
user = false
|
||||||
}) {
|
}) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
resolve(db.get(pathInit({
|
resolve(util.db.get(pathInit({
|
||||||
dbName: 'database',
|
dbName: 'database',
|
||||||
path: `$page.${vm.$route[basis]}.$data`,
|
path: `$page.${vm.$route[basis]}.$data`,
|
||||||
user,
|
user,
|
||||||
validator: () => false,
|
validator: () => false,
|
||||||
defaultValue: vm.$data
|
defaultValue: cloneDeep(vm.$data)
|
||||||
})))
|
})))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -183,16 +190,16 @@ export default {
|
|||||||
*/
|
*/
|
||||||
pageGet (context, {
|
pageGet (context, {
|
||||||
vm,
|
vm,
|
||||||
basis = 'name',
|
basis = 'fullPath',
|
||||||
user = false
|
user = false
|
||||||
}) {
|
}) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
resolve(db.get(pathInit({
|
resolve(cloneDeep(util.db.get(pathInit({
|
||||||
dbName: 'database',
|
dbName: 'database',
|
||||||
path: `$page.${vm.$route[basis]}.$data`,
|
path: `$page.${vm.$route[basis]}.$data`,
|
||||||
user,
|
user,
|
||||||
defaultValue: vm.$data
|
defaultValue: cloneDeep(vm.$data)
|
||||||
})).value())
|
})).value()))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -204,11 +211,11 @@ export default {
|
|||||||
*/
|
*/
|
||||||
pageClear (context, {
|
pageClear (context, {
|
||||||
vm,
|
vm,
|
||||||
basis = 'name',
|
basis = 'fullPath',
|
||||||
user = false
|
user = false
|
||||||
}) {
|
}) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
resolve(db.get(pathInit({
|
resolve(util.db.get(pathInit({
|
||||||
dbName: 'database',
|
dbName: 'database',
|
||||||
path: `$page.${vm.$route[basis]}.$data`,
|
path: `$page.${vm.$route[basis]}.$data`,
|
||||||
user,
|
user,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { remove, get } from 'lodash'
|
import { get } from 'lodash'
|
||||||
|
|
||||||
// 设置文件
|
// 设置文件
|
||||||
import setting from '@/setting.js'
|
import setting from '@/setting.js'
|
||||||
@@ -34,14 +34,14 @@ export default {
|
|||||||
user: true
|
user: true
|
||||||
}, { root: true })
|
}, { root: true })
|
||||||
// 在处理函数中进行数据优化 过滤掉现在已经失效的页签或者已经改变了信息的页签
|
// 在处理函数中进行数据优化 过滤掉现在已经失效的页签或者已经改变了信息的页签
|
||||||
// 以 name 字段为准
|
// 以 fullPath 字段为准
|
||||||
// 如果页面过多的话可能需要优化算法
|
// 如果页面过多的话可能需要优化算法
|
||||||
// valid 有效列表 1, 1, 0, 1 => 有效, 有效, 失效, 有效
|
// valid 有效列表 1, 1, 0, 1 => 有效, 有效, 失效, 有效
|
||||||
const valid = []
|
const valid = []
|
||||||
// 处理数据
|
// 处理数据
|
||||||
state.opened = value.map(opened => {
|
state.opened = value.map(opened => {
|
||||||
// 忽略首页
|
// 忽略首页
|
||||||
if (opened.name === 'index') {
|
if (opened.fullPath === '/index') {
|
||||||
valid.push(1)
|
valid.push(1)
|
||||||
return opened
|
return opened
|
||||||
}
|
}
|
||||||
@@ -80,19 +80,16 @@ export default {
|
|||||||
* @class opened
|
* @class opened
|
||||||
* @description 更新页面列表上的某一项
|
* @description 更新页面列表上的某一项
|
||||||
* @param {Object} state vuex state
|
* @param {Object} state vuex state
|
||||||
* @param {Object} param { index, params, query } 路由信息
|
* @param {Object} param { index, params, query, fullPath } 路由信息
|
||||||
*/
|
*/
|
||||||
openedUpdate ({ state, commit, dispatch }, { index, params, query }) {
|
openedUpdate ({ state, commit, dispatch }, { index, params, query, fullPath }) {
|
||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
// 更新页面列表某一项
|
// 更新页面列表某一项
|
||||||
let page = state.opened[index]
|
let page = state.opened[index]
|
||||||
page.params = params || page.params
|
page.params = params || page.params
|
||||||
page.query = query || page.query
|
page.query = query || page.query
|
||||||
|
page.fullPath = fullPath || page.fullPath
|
||||||
state.opened.splice(index, 1, page)
|
state.opened.splice(index, 1, page)
|
||||||
// 增加缓存设置
|
|
||||||
if (isKeepAlive(page)) {
|
|
||||||
commit('keepAlivePush', page.name)
|
|
||||||
}
|
|
||||||
// 持久化
|
// 持久化
|
||||||
await dispatch('opend2db')
|
await dispatch('opend2db')
|
||||||
// end
|
// end
|
||||||
@@ -105,12 +102,13 @@ export default {
|
|||||||
* @param {Object} state vuex state
|
* @param {Object} state vuex state
|
||||||
* @param {Object} param new tag info
|
* @param {Object} param new tag info
|
||||||
*/
|
*/
|
||||||
add ({ state, commit, dispatch }, { tag, params, query }) {
|
add ({ state, commit, dispatch }, { tag, params, query, fullPath }) {
|
||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
// 设置新的 tag 在新打开一个以前没打开过的页面时使用
|
// 设置新的 tag 在新打开一个以前没打开过的页面时使用
|
||||||
let newTag = tag
|
let newTag = tag
|
||||||
newTag.params = params || newTag.params
|
newTag.params = params || newTag.params
|
||||||
newTag.query = query || newTag.query
|
newTag.query = query || newTag.query
|
||||||
|
newTag.fullPath = fullPath || newTag.fullPath
|
||||||
// 添加进当前显示的页面数组
|
// 添加进当前显示的页面数组
|
||||||
state.opened.push(newTag)
|
state.opened.push(newTag)
|
||||||
// 如果这个页面需要缓存 将其添加到缓存设置
|
// 如果这个页面需要缓存 将其添加到缓存设置
|
||||||
@@ -127,25 +125,26 @@ export default {
|
|||||||
* @class current
|
* @class current
|
||||||
* @description 打开一个新的页面
|
* @description 打开一个新的页面
|
||||||
* @param {Object} state vuex state
|
* @param {Object} state vuex state
|
||||||
* @param {Object} param { name, params, query } 路由信息
|
* @param {Object} param { name, params, query, fullPath } 路由信息
|
||||||
*/
|
*/
|
||||||
open ({ state, commit, dispatch }, { name, params, query }) {
|
open ({ state, commit, dispatch }, { name, params, query, fullPath }) {
|
||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
// 已经打开的页面
|
// 已经打开的页面
|
||||||
let opened = state.opened
|
let opened = state.opened
|
||||||
// 判断此页面是否已经打开 并且记录位置
|
// 判断此页面是否已经打开 并且记录位置
|
||||||
let pageOpendIndex = 0
|
let pageOpendIndex = 0
|
||||||
const pageOpend = opened.find((page, index) => {
|
const pageOpend = opened.find((page, index) => {
|
||||||
const same = page.name === name
|
const same = page.fullPath === fullPath
|
||||||
pageOpendIndex = same ? index : pageOpendIndex
|
pageOpendIndex = same ? index : pageOpendIndex
|
||||||
return same
|
return same
|
||||||
})
|
})
|
||||||
if (pageOpend) {
|
if (pageOpend) {
|
||||||
// 页面以前打开过 但是新的页面可能 name 一样,参数不一样
|
// 页面以前打开过
|
||||||
await dispatch('openedUpdate', {
|
await dispatch('openedUpdate', {
|
||||||
index: pageOpendIndex,
|
index: pageOpendIndex,
|
||||||
params,
|
params,
|
||||||
query
|
query,
|
||||||
|
fullPath
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 页面以前没有打开过
|
// 页面以前没有打开过
|
||||||
@@ -153,13 +152,14 @@ export default {
|
|||||||
// 如果这里没有找到 page 代表这个路由虽然在框架内 但是不参与标签页显示
|
// 如果这里没有找到 page 代表这个路由虽然在框架内 但是不参与标签页显示
|
||||||
if (page) {
|
if (page) {
|
||||||
await dispatch('add', {
|
await dispatch('add', {
|
||||||
tag: page,
|
tag: Object.assign({}, page),
|
||||||
params,
|
params,
|
||||||
query
|
query,
|
||||||
|
fullPath
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commit('currentSet', name)
|
commit('currentSet', fullPath)
|
||||||
// end
|
// end
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
@@ -180,7 +180,7 @@ export default {
|
|||||||
// 去找一个新的页面
|
// 去找一个新的页面
|
||||||
let len = state.opened.length
|
let len = state.opened.length
|
||||||
for (let i = 1; i < len; i++) {
|
for (let i = 1; i < len; i++) {
|
||||||
if (state.opened[i].name === tagName) {
|
if (state.opened[i].fullPath === tagName) {
|
||||||
if (i < len - 1) {
|
if (i < len - 1) {
|
||||||
newPage = state.opened[i + 1]
|
newPage = state.opened[i + 1]
|
||||||
} else {
|
} else {
|
||||||
@@ -191,12 +191,12 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 找到这个页面在已经打开的数据里是第几个
|
// 找到这个页面在已经打开的数据里是第几个
|
||||||
const index = state.opened.findIndex(page => page.name === tagName)
|
const index = state.opened.findIndex(page => page.fullPath === tagName)
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
|
// 如果这个页面是缓存的页面 将其在缓存设置中删除
|
||||||
|
commit('keepAliveRemove', state.opened[index].name)
|
||||||
// 更新数据 删除关闭的页面
|
// 更新数据 删除关闭的页面
|
||||||
state.opened.splice(index, 1)
|
state.opened.splice(index, 1)
|
||||||
// 如果这个页面是缓存的页面 将其在缓存设置中删除
|
|
||||||
commit('keepAliveRemove', tagName)
|
|
||||||
}
|
}
|
||||||
// 持久化
|
// 持久化
|
||||||
await dispatch('opend2db')
|
await dispatch('opend2db')
|
||||||
@@ -225,7 +225,7 @@ export default {
|
|||||||
const pageAim = pageSelect || state.current
|
const pageAim = pageSelect || state.current
|
||||||
let currentIndex = 0
|
let currentIndex = 0
|
||||||
state.opened.forEach((page, index) => {
|
state.opened.forEach((page, index) => {
|
||||||
if (page.name === pageAim) {
|
if (page.fullPath === pageAim) {
|
||||||
currentIndex = index
|
currentIndex = index
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -234,10 +234,8 @@ export default {
|
|||||||
state.opened.splice(1, currentIndex - 1).forEach(({ name }) => commit('keepAliveRemove', name))
|
state.opened.splice(1, currentIndex - 1).forEach(({ name }) => commit('keepAliveRemove', name))
|
||||||
}
|
}
|
||||||
state.current = pageAim
|
state.current = pageAim
|
||||||
if (vm && vm.$route.name !== pageAim) {
|
if (vm && vm.$route.fullPath !== pageAim) {
|
||||||
vm.$router.push({
|
vm.$router.push(pageAim)
|
||||||
name: pageAim
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
// 持久化
|
// 持久化
|
||||||
await dispatch('opend2db')
|
await dispatch('opend2db')
|
||||||
@@ -256,7 +254,7 @@ export default {
|
|||||||
const pageAim = pageSelect || state.current
|
const pageAim = pageSelect || state.current
|
||||||
let currentIndex = 0
|
let currentIndex = 0
|
||||||
state.opened.forEach((page, index) => {
|
state.opened.forEach((page, index) => {
|
||||||
if (page.name === pageAim) {
|
if (page.fullPath === pageAim) {
|
||||||
currentIndex = index
|
currentIndex = index
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -264,10 +262,8 @@ export default {
|
|||||||
state.opened.splice(currentIndex + 1).forEach(({ name }) => commit('keepAliveRemove', name))
|
state.opened.splice(currentIndex + 1).forEach(({ name }) => commit('keepAliveRemove', name))
|
||||||
// 设置当前的页面
|
// 设置当前的页面
|
||||||
state.current = pageAim
|
state.current = pageAim
|
||||||
if (vm && vm.$route.name !== pageAim) {
|
if (vm && vm.$route.fullPath !== pageAim) {
|
||||||
vm.$router.push({
|
vm.$router.push(pageAim)
|
||||||
name: pageAim
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
// 持久化
|
// 持久化
|
||||||
await dispatch('opend2db')
|
await dispatch('opend2db')
|
||||||
@@ -286,7 +282,7 @@ export default {
|
|||||||
const pageAim = pageSelect || state.current
|
const pageAim = pageSelect || state.current
|
||||||
let currentIndex = 0
|
let currentIndex = 0
|
||||||
state.opened.forEach((page, index) => {
|
state.opened.forEach((page, index) => {
|
||||||
if (page.name === pageAim) {
|
if (page.fullPath === pageAim) {
|
||||||
currentIndex = index
|
currentIndex = index
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -299,10 +295,8 @@ export default {
|
|||||||
}
|
}
|
||||||
// 设置新的页面
|
// 设置新的页面
|
||||||
state.current = pageAim
|
state.current = pageAim
|
||||||
if (vm && vm.$route.name !== pageAim) {
|
if (vm && vm.$route.fullPath !== pageAim) {
|
||||||
vm.$router.push({
|
vm.$router.push(pageAim)
|
||||||
name: pageAim
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
// 持久化
|
// 持久化
|
||||||
await dispatch('opend2db')
|
await dispatch('opend2db')
|
||||||
@@ -349,8 +343,12 @@ export default {
|
|||||||
*/
|
*/
|
||||||
keepAliveRemove (state, name) {
|
keepAliveRemove (state, name) {
|
||||||
const list = [ ...state.keepAlive ]
|
const list = [ ...state.keepAlive ]
|
||||||
remove(list, item => item === name)
|
const index = list.findIndex(item => item === name)
|
||||||
state.keepAlive = list
|
|
||||||
|
if (index !== -1) {
|
||||||
|
list.splice(index, 1)
|
||||||
|
state.keepAlive = list
|
||||||
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @description 增加一个页面的缓存设置
|
* @description 增加一个页面的缓存设置
|
||||||
@@ -360,7 +358,7 @@ export default {
|
|||||||
keepAlivePush (state, name) {
|
keepAlivePush (state, name) {
|
||||||
const keep = [ ...state.keepAlive ]
|
const keep = [ ...state.keepAlive ]
|
||||||
keep.push(name)
|
keep.push(name)
|
||||||
state.keepAlive = Array.from(new Set(keep))
|
state.keepAlive = keep
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @description 清空页面缓存设置
|
* @description 清空页面缓存设置
|
||||||
@@ -371,12 +369,12 @@ export default {
|
|||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @class current
|
* @class current
|
||||||
* @description 设置当前激活的页面 name
|
* @description 设置当前激活的页面 fullPath
|
||||||
* @param {Object} state vuex state
|
* @param {Object} state vuex state
|
||||||
* @param {String} name new name
|
* @param {String} fullPath new fullPath
|
||||||
*/
|
*/
|
||||||
currentSet (state, name) {
|
currentSet (state, fullPath) {
|
||||||
state.current = name
|
state.current = fullPath
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @class pool
|
* @class pool
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
import util from '@/libs/util.js'
|
import util from '@/libs/util.js'
|
||||||
import setting from '@/setting.js'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: {
|
|
||||||
// D2Admin 版本
|
|
||||||
version: setting.releases.version
|
|
||||||
},
|
|
||||||
mutations: {
|
mutations: {
|
||||||
/**
|
/**
|
||||||
* @description 显示版本信息
|
* @description 显示版本信息
|
||||||
* @param {Object} state vuex state
|
* @param {Object} state vuex state
|
||||||
*/
|
*/
|
||||||
versionShow (state) {
|
versionShow () {
|
||||||
util.log.capsule('D2Admin', `v${state.version}`)
|
util.log.capsule('D2Admin', `v${process.env.VUE_APP_VERSION}`)
|
||||||
console.log('Github https://github.com/d2-projects/d2-admin')
|
console.log('Github https://github.com/d2-projects/d2-admin')
|
||||||
console.log('Doc https://doc.d2admin.fairyever.com/zh/')
|
console.log('Doc https://doc.d2admin.fairyever.com/zh/')
|
||||||
console.log('请不要吝啬您的 star,谢谢 ~')
|
console.log('请不要吝啬您的 star,谢谢 ~')
|
||||||
|
|||||||
@@ -48,12 +48,25 @@ export default {
|
|||||||
load ({ state, commit, dispatch }) {
|
load ({ state, commit, dispatch }) {
|
||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
// store 赋值
|
// store 赋值
|
||||||
state.activeName = await dispatch('d2admin/db/get', {
|
let activeName = await dispatch('d2admin/db/get', {
|
||||||
dbName: 'sys',
|
dbName: 'sys',
|
||||||
path: 'theme.activeName',
|
path: 'theme.activeName',
|
||||||
defaultValue: state.list[0].name,
|
defaultValue: state.list[0].name,
|
||||||
user: true
|
user: true
|
||||||
}, { root: true })
|
}, { root: true })
|
||||||
|
// 检查这个主题在主题列表里是否存在
|
||||||
|
if (state.list.find(e => e.name === activeName)) {
|
||||||
|
state.activeName = activeName
|
||||||
|
} else {
|
||||||
|
state.activeName = state.list[0].name
|
||||||
|
// 持久化
|
||||||
|
await dispatch('d2admin/db/set', {
|
||||||
|
dbName: 'sys',
|
||||||
|
path: 'theme.activeName',
|
||||||
|
value: state.activeName,
|
||||||
|
user: true
|
||||||
|
}, { root: true })
|
||||||
|
}
|
||||||
// 将 vuex 中的主题应用到 dom
|
// 将 vuex 中的主题应用到 dom
|
||||||
commit('dom')
|
commit('dom')
|
||||||
// end
|
// end
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
|
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||||
|
|
||||||
// 拼接路径
|
// 拼接路径
|
||||||
const resolve = dir => require('path').join(__dirname, dir)
|
const resolve = dir => require('path').join(__dirname, dir)
|
||||||
|
|
||||||
|
// 增加环境变量
|
||||||
|
process.env.VUE_APP_VERSION = require('./package.json').version
|
||||||
|
process.env.VUE_APP_BUILD_TIME = require('dayjs')().format('YYYY-M-D HH:mm:ss')
|
||||||
|
|
||||||
// 基础路径 注意发布之前要先修改这里
|
// 基础路径 注意发布之前要先修改这里
|
||||||
let baseUrl = '/'
|
let baseUrl = '/'
|
||||||
|
|
||||||
@@ -10,11 +16,52 @@ module.exports = {
|
|||||||
devServer: {
|
devServer: {
|
||||||
publicPath: baseUrl // 和 baseUrl 保持一致
|
publicPath: baseUrl // 和 baseUrl 保持一致
|
||||||
},
|
},
|
||||||
|
css: {
|
||||||
|
loaderOptions: {
|
||||||
|
// 设置 scss 公用变量文件
|
||||||
|
sass: {
|
||||||
|
data: `@import '~@/assets/style/public.scss';`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
// 默认设置: https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-service/lib/config/base.js
|
// 默认设置: https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-service/lib/config/base.js
|
||||||
chainWebpack: config => {
|
chainWebpack: config => {
|
||||||
|
/**
|
||||||
|
* 删除懒加载模块的 prefetch preload,降低带宽压力
|
||||||
|
* https://cli.vuejs.org/zh/guide/html-and-static-assets.html#prefetch
|
||||||
|
* https://cli.vuejs.org/zh/guide/html-and-static-assets.html#preload
|
||||||
|
* 而且预渲染时生成的 prefetch 标签是 modern 版本的,低版本浏览器是不需要的
|
||||||
|
*/
|
||||||
|
config.plugins
|
||||||
|
.delete('prefetch')
|
||||||
|
.delete('preload')
|
||||||
// 解决 cli3 热更新失效 https://github.com/vuejs/vue-cli/issues/1559
|
// 解决 cli3 热更新失效 https://github.com/vuejs/vue-cli/issues/1559
|
||||||
config.resolve
|
config.resolve
|
||||||
.symlinks(true)
|
.symlinks(true)
|
||||||
|
config
|
||||||
|
// 开发环境
|
||||||
|
.when(process.env.NODE_ENV === 'development',
|
||||||
|
// sourcemap不包含列信息
|
||||||
|
config => config.devtool('cheap-source-map')
|
||||||
|
)
|
||||||
|
// 非开发环境
|
||||||
|
.when(process.env.NODE_ENV !== 'development', config => {
|
||||||
|
config.optimization
|
||||||
|
.minimizer([
|
||||||
|
new UglifyJsPlugin({
|
||||||
|
uglifyOptions: {
|
||||||
|
// 移除 console
|
||||||
|
// 其它优化选项 https://segmentfault.com/a/1190000010874406
|
||||||
|
compress: {
|
||||||
|
warnings: false,
|
||||||
|
drop_console: true,
|
||||||
|
drop_debugger: true,
|
||||||
|
pure_funcs: ['console.log']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
])
|
||||||
|
})
|
||||||
// markdown
|
// markdown
|
||||||
config.module
|
config.module
|
||||||
.rule('md')
|
.rule('md')
|
||||||
@@ -52,10 +99,21 @@ module.exports = {
|
|||||||
// 重新设置 alias
|
// 重新设置 alias
|
||||||
config.resolve.alias
|
config.resolve.alias
|
||||||
.set('@', resolve('src'))
|
.set('@', resolve('src'))
|
||||||
|
.set('@api', resolve('src/api'))
|
||||||
|
// node
|
||||||
|
config.node
|
||||||
|
.set('__dirname', true)
|
||||||
|
.set('__filename', true)
|
||||||
// babel-polyfill 加入 entry
|
// babel-polyfill 加入 entry
|
||||||
const entry = config.entry('app')
|
const entry = config.entry('app')
|
||||||
entry
|
entry
|
||||||
.add('babel-polyfill')
|
.add('babel-polyfill')
|
||||||
.end()
|
.end()
|
||||||
|
// 判断环境加入模拟数据
|
||||||
|
if (process.env.VUE_APP_BUILD_MODE !== 'nomock') {
|
||||||
|
entry
|
||||||
|
.add('@/mock')
|
||||||
|
.end()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user