init
This commit is contained in:
284
src/views/401.vue
Normal file
284
src/views/401.vue
Normal file
@@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<div class="error-container">
|
||||
<div class="error-content">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="12" :md="12" :sm="24" :xl="12" :xs="24">
|
||||
<div class="pic-error">
|
||||
<img alt="401" class="pic-error-parent" src="@/assets/error_images/401.png" />
|
||||
<img alt="401" class="pic-error-child left" src="@/assets/error_images/cloud.png" />
|
||||
<img alt="401" class="pic-error-child" src="@/assets/error_images/cloud.png" />
|
||||
<img alt="401" class="pic-error-child" src="@/assets/error_images/cloud.png" />
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="12" :md="12" :sm="24" :xl="12" :xs="24">
|
||||
<div class="bullshit">
|
||||
<div class="bullshit-oops">
|
||||
{{ oops }}
|
||||
</div>
|
||||
<div class="bullshit-headline">
|
||||
{{ headline }}
|
||||
</div>
|
||||
<div class="bullshit-info">
|
||||
{{ info }}
|
||||
</div>
|
||||
<a class="bullshit-return-home" href="#/index">{{ jumpTime }}s {{ btn }}</a>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Page401',
|
||||
data() {
|
||||
return {
|
||||
jumpTime: 5,
|
||||
oops: '抱歉!',
|
||||
headline: '您没有操作权限...',
|
||||
info: '当前帐号没有操作权限,请联系管理员。',
|
||||
btn: '返回',
|
||||
timer: 0,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.timeChange()
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
timeChange() {
|
||||
this.timer = setInterval(() => {
|
||||
if (this.jumpTime) {
|
||||
this.jumpTime--
|
||||
} else {
|
||||
this.$router.push({ path: '/' })
|
||||
this.$store.dispatch('tabsBar/delOthersRoutes', {
|
||||
path: '/',
|
||||
})
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
}, 1000)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.error-container {
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
.error-content {
|
||||
.pic-error {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 120%;
|
||||
overflow: hidden;
|
||||
|
||||
&-parent {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-child {
|
||||
position: absolute;
|
||||
|
||||
&.left {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
width: 80px;
|
||||
opacity: 0;
|
||||
animation-name: cloudLeft;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&.mid {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
width: 46px;
|
||||
opacity: 0;
|
||||
animation-name: cloudMid;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&.right {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
width: 62px;
|
||||
opacity: 0;
|
||||
animation-name: cloudRight;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
@keyframes cloudLeft {
|
||||
0% {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
20% {
|
||||
top: 33px;
|
||||
left: 188px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
80% {
|
||||
top: 81px;
|
||||
left: 92px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 97px;
|
||||
left: 60px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes cloudMid {
|
||||
0% {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
20% {
|
||||
top: 40px;
|
||||
left: 360px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
70% {
|
||||
top: 130px;
|
||||
left: 180px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 160px;
|
||||
left: 120px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes cloudRight {
|
||||
0% {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
20% {
|
||||
top: 120px;
|
||||
left: 460px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
80% {
|
||||
top: 180px;
|
||||
left: 340px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 200px;
|
||||
left: 300px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bullshit {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 300px;
|
||||
padding: 30px 0;
|
||||
overflow: hidden;
|
||||
|
||||
&-oops {
|
||||
margin-bottom: 20px;
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
line-height: 40px;
|
||||
color: $base-color-blue;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&-headline {
|
||||
margin-bottom: 10px;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
line-height: 24px;
|
||||
color: #222;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&-info {
|
||||
margin-bottom: 30px;
|
||||
font-size: 13px;
|
||||
line-height: 21px;
|
||||
color: $base-color-gray;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&-return-home {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 110px;
|
||||
height: 36px;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
background: $base-color-blue;
|
||||
border-radius: 100px;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.3s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(60px);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
284
src/views/404.vue
Normal file
284
src/views/404.vue
Normal file
@@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<div class="error-container">
|
||||
<div class="error-content">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="12" :md="12" :sm="24" :xl="12" :xs="24">
|
||||
<div class="pic-error">
|
||||
<img alt="401" class="pic-error-parent" src="@/assets/error_images/404.png" />
|
||||
<img alt="401" class="pic-error-child left" src="@/assets/error_images/cloud.png" />
|
||||
<img alt="401" class="pic-error-child" src="@/assets/error_images/cloud.png" />
|
||||
<img alt="401" class="pic-error-child" src="@/assets/error_images/cloud.png" />
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="12" :md="12" :sm="24" :xl="12" :xs="24">
|
||||
<div class="bullshit">
|
||||
<div class="bullshit-oops">
|
||||
{{ oops }}
|
||||
</div>
|
||||
<div class="bullshit-headline">
|
||||
{{ headline }}
|
||||
</div>
|
||||
<div class="bullshit-info">
|
||||
{{ info }}
|
||||
</div>
|
||||
<a class="bullshit-return-home" href="#/index">{{ jumpTime }}s {{ btn }}</a>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Page404',
|
||||
data() {
|
||||
return {
|
||||
jumpTime: 5,
|
||||
oops: '抱歉!',
|
||||
headline: '当前页面不存在...',
|
||||
info: '请检查您输入的网址是否正确,或点击下面的按钮返回首页。',
|
||||
btn: '返回首页',
|
||||
timer: 0,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.timeChange()
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
timeChange() {
|
||||
this.timer = setInterval(() => {
|
||||
if (this.jumpTime) {
|
||||
this.jumpTime--
|
||||
} else {
|
||||
this.$router.push({ path: '/' })
|
||||
this.$store.dispatch('tabsBar/delOthersRoutes', {
|
||||
path: '/',
|
||||
})
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
}, 1000)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.error-container {
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
.error-content {
|
||||
.pic-error {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 120%;
|
||||
overflow: hidden;
|
||||
|
||||
&-parent {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-child {
|
||||
position: absolute;
|
||||
|
||||
&.left {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
width: 80px;
|
||||
opacity: 0;
|
||||
animation-name: cloudLeft;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&.mid {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
width: 46px;
|
||||
opacity: 0;
|
||||
animation-name: cloudMid;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&.right {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
width: 62px;
|
||||
opacity: 0;
|
||||
animation-name: cloudRight;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
@keyframes cloudLeft {
|
||||
0% {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
20% {
|
||||
top: 33px;
|
||||
left: 188px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
80% {
|
||||
top: 81px;
|
||||
left: 92px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 97px;
|
||||
left: 60px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes cloudMid {
|
||||
0% {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
20% {
|
||||
top: 40px;
|
||||
left: 360px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
70% {
|
||||
top: 130px;
|
||||
left: 180px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 160px;
|
||||
left: 120px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes cloudRight {
|
||||
0% {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
20% {
|
||||
top: 120px;
|
||||
left: 460px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
80% {
|
||||
top: 180px;
|
||||
left: 340px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 200px;
|
||||
left: 300px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bullshit {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 300px;
|
||||
padding: 30px 0;
|
||||
overflow: hidden;
|
||||
|
||||
&-oops {
|
||||
margin-bottom: 20px;
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
line-height: 40px;
|
||||
color: $base-color-blue;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&-headline {
|
||||
margin-bottom: 10px;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
line-height: 24px;
|
||||
color: #222;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&-info {
|
||||
margin-bottom: 30px;
|
||||
font-size: 13px;
|
||||
line-height: 21px;
|
||||
color: $base-color-gray;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&-return-home {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 110px;
|
||||
height: 36px;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
background: $base-color-blue;
|
||||
border-radius: 100px;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.3s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(60px);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<el-dialog :title="title" :visible.sync="dialogFormVisible" width="500px" @close="close">
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="权限码" prop="permission">
|
||||
<el-input v-model="form.permission" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="desc">
|
||||
<el-input v-model="form.desc" autocomplete="off" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doEdit, doAdd } from '@/api/roleManagement'
|
||||
|
||||
export default {
|
||||
name: 'RoleManagementEdit',
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
form: {
|
||||
name: '',
|
||||
permission: '',
|
||||
desc: '',
|
||||
},
|
||||
rules: {
|
||||
permission: [{ required: true, trigger: 'blur', message: '请输入权限码' }],
|
||||
name: [{ required: true, trigger: 'blur', message: '请输入名称' }],
|
||||
},
|
||||
title: '',
|
||||
dialogFormVisible: false,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
showEdit(row) {
|
||||
if (!row) {
|
||||
this.title = '添加'
|
||||
} else {
|
||||
this.title = '编辑'
|
||||
this.form = {
|
||||
name: row.name,
|
||||
permission: row.permission,
|
||||
desc: row.desc,
|
||||
}
|
||||
this.id = row.id
|
||||
}
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
close() {
|
||||
this.$refs['form'].resetFields()
|
||||
this.form = this.$options.data().form
|
||||
this.dialogFormVisible = false
|
||||
},
|
||||
save() {
|
||||
this.$refs['form'].validate(async (valid) => {
|
||||
if (valid) {
|
||||
if (this.id) {
|
||||
const { msg } = await doEdit(this.id, this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
} else {
|
||||
const { msg } = await doAdd(this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
}
|
||||
this.$emit('fetch-data')
|
||||
this.close()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
82
src/views/cxshMini/anli/article/index.vue
Normal file
82
src/views/cxshMini/anli/article/index.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<div class="cxshMini-article-container">
|
||||
<el-button style="margin-bottom: 10px" type="primary" @click="handlePublish">发布</el-button>
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules">
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input v-model.trim="form.username" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" prop="password">
|
||||
<el-input v-model.trim="form.password" autocomplete="off" type="password" />
|
||||
</el-form-item>
|
||||
<el-form-item label="昵称" prop="nickname">
|
||||
<el-input v-model.trim="form.nickname" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="权限" prop="permissions">
|
||||
<el-select v-model="form.permissions" multiple placeholder="请选择权限">
|
||||
<el-option v-for="item in permissionList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="应用" prop="appId">
|
||||
<el-select v-model="form.appId" placeholder="请选择应用">
|
||||
<el-option v-for="item in applicationList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="头像" prop="avatar">
|
||||
<single-upload
|
||||
style="width: 100px; height: 100px"
|
||||
upload-url="http://127.0.0.1:3999/management/api/common/upload"
|
||||
@upload-success="handleUploadSuccess"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<quill-editor v-model="content" :options="editorOptions" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { quillEditor } from 'vue-quill-editor'
|
||||
import 'quill/dist/quill.snow.css'
|
||||
import SingleUpload from '@/components/SingleUpload'
|
||||
|
||||
export default {
|
||||
name: 'CxshMiniArticle',
|
||||
components: { quillEditor, SingleUpload },
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
username: '',
|
||||
password: '',
|
||||
nickname: '',
|
||||
permissions: '',
|
||||
appId: '',
|
||||
avatar: '',
|
||||
},
|
||||
permissionList: [],
|
||||
applicationList: [],
|
||||
rules: {
|
||||
username: [{ required: true, trigger: 'blur', message: '请输入用户名' }],
|
||||
password: [{ required: true, trigger: 'blur', message: '请输入密码' }],
|
||||
permissions: [{ required: true, trigger: 'blur', message: '请选择权限' }],
|
||||
appId: [{ required: true, trigger: 'blur', message: '请选择应用' }],
|
||||
},
|
||||
content: '',
|
||||
editorOptions: {
|
||||
theme: 'snow',
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
handlePublish() {
|
||||
console.log(11111, this.content)
|
||||
console.log('发布')
|
||||
},
|
||||
async fetchData() {},
|
||||
handleUploadSuccess(res) {
|
||||
this.form.avatar = res.data.url
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<el-dialog :title="title" :visible.sync="dialogFormVisible" width="500px" @close="close">
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="desc">
|
||||
<el-input v-model="form.desc" autocomplete="off" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doEdit, doAdd } from '@/api/roleManagement'
|
||||
|
||||
export default {
|
||||
name: 'CxshMiniAnliCategoryEdit',
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
form: {
|
||||
name: '',
|
||||
desc: '',
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, trigger: 'blur', message: '请输入名称' }],
|
||||
},
|
||||
title: '',
|
||||
dialogFormVisible: false,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
showEdit(row) {
|
||||
if (!row) {
|
||||
this.title = '添加'
|
||||
} else {
|
||||
this.title = '编辑'
|
||||
this.form = {
|
||||
name: row.name,
|
||||
permission: row.permission,
|
||||
desc: row.desc,
|
||||
}
|
||||
this.id = row.id
|
||||
}
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
close() {
|
||||
this.$refs['form'].resetFields()
|
||||
this.form = this.$options.data().form
|
||||
this.dialogFormVisible = false
|
||||
},
|
||||
save() {
|
||||
this.$refs['form'].validate(async (valid) => {
|
||||
if (valid) {
|
||||
if (this.id) {
|
||||
const { msg } = await doEdit(this.id, this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
} else {
|
||||
const { msg } = await doAdd(this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
}
|
||||
this.$emit('fetch-data')
|
||||
this.close()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
130
src/views/cxshMini/anli/category/index.vue
Normal file
130
src/views/cxshMini/anli/category/index.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div class="cxshMini-anli-category-container">
|
||||
<vab-query-form>
|
||||
<vab-query-form-left-panel :span="12">
|
||||
<el-button icon="el-icon-plus" type="primary" @click="handleEdit">添加</el-button>
|
||||
<el-button icon="el-icon-delete" type="danger" @click="handleDelete">批量删除</el-button>
|
||||
</vab-query-form-left-panel>
|
||||
<vab-query-form-right-panel :span="12">
|
||||
<el-form :inline="true" :model="queryForm" @submit.native.prevent>
|
||||
<el-form-item>
|
||||
<el-input v-model.trim="queryForm.permission" clearable placeholder="请输入查询条件" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</vab-query-form-right-panel>
|
||||
</vab-query-form>
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" :element-loading-text="elementLoadingText" @selection-change="setSelectRows">
|
||||
<el-table-column show-overflow-tooltip type="selection" />
|
||||
<el-table-column label="名称" prop="name" show-overflow-tooltip />
|
||||
<el-table-column label="权限码" prop="permission" show-overflow-tooltip />
|
||||
<el-table-column label="描述" prop="desc" show-overflow-tooltip />
|
||||
<el-table-column label="操作" show-overflow-tooltip width="200">
|
||||
<template #default="{ row }">
|
||||
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="text" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="queryForm.pageNo"
|
||||
:layout="layout"
|
||||
:page-size="queryForm.pageSize"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
<edit ref="edit" @fetch-data="fetchData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doDelete, getList } from '@/api/roleManagement'
|
||||
import Edit from './components/CxshMiniAnliCategoryEdit'
|
||||
|
||||
export default {
|
||||
name: 'CxshMiniAnliCategory',
|
||||
components: { Edit },
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true,
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
total: 0,
|
||||
selectRows: '',
|
||||
elementLoadingText: '正在加载...',
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
permission: '',
|
||||
},
|
||||
timeOutID: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
clearTimeout(this.timeOutID)
|
||||
},
|
||||
methods: {
|
||||
setSelectRows(val) {
|
||||
this.selectRows = val
|
||||
},
|
||||
handleEdit(row) {
|
||||
if (row.id) {
|
||||
this.$refs['edit'].showEdit(row)
|
||||
} else {
|
||||
this.$refs['edit'].showEdit()
|
||||
}
|
||||
},
|
||||
handleDelete(row) {
|
||||
if (row.id) {
|
||||
this.$baseConfirm('你确定要删除当前项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: [row.id] })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
if (this.selectRows.length > 0) {
|
||||
const ids = this.selectRows.map((item) => item.id).join()
|
||||
this.$baseConfirm('你确定要删除选中项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: ids.split(',') })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
this.$baseMessage('未选中任何行', 'error')
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.pageNo = val
|
||||
this.fetchData()
|
||||
},
|
||||
queryData() {
|
||||
this.queryForm.pageNo = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
this.listLoading = true
|
||||
const { data } = await getList(this.queryForm)
|
||||
this.list = data.list
|
||||
this.total = data.totalCount
|
||||
this.timeOutID = setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 300)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
100
src/views/cxshMini/home/banner/components/AppManagementEdit.vue
Normal file
100
src/views/cxshMini/home/banner/components/AppManagementEdit.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<el-dialog :title="title" :visible.sync="dialogFormVisible" width="500px" @close="close">
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select v-model="form.type" placeholder="请选择 APP 类型">
|
||||
<el-option label="小程序" :value="1" />
|
||||
<el-option label="H5" :value="2" />
|
||||
<el-option label="后台管理" :value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input v-model="form.description" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="APP图标" prop="appIcon">
|
||||
<single-upload
|
||||
style="width: 100px; height: 100px"
|
||||
upload-url="http://127.0.0.1:3999/management/api/common/upload"
|
||||
@upload-success="handleUploadSuccess"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doEdit, doAdd } from '@/api/appManagement'
|
||||
import SingleUpload from '@/components/SingleUpload'
|
||||
|
||||
export default {
|
||||
name: 'AppManagementEdit',
|
||||
components: { SingleUpload },
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
form: {
|
||||
name: '',
|
||||
type: '',
|
||||
description: '',
|
||||
icon: '',
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, trigger: 'blur', message: '请输入名称' }],
|
||||
type: [{ required: true, trigger: 'blur', message: '请选择类型' }],
|
||||
},
|
||||
title: '',
|
||||
dialogFormVisible: false,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
handleUploadSuccess(url) {
|
||||
this.form.icon = url
|
||||
},
|
||||
showEdit(row) {
|
||||
if (!row) {
|
||||
this.title = '添加'
|
||||
} else {
|
||||
this.title = '编辑'
|
||||
this.form = {
|
||||
name: row.name,
|
||||
description: row.description,
|
||||
icon: row.icon,
|
||||
}
|
||||
this.id = row.id
|
||||
}
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
close() {
|
||||
this.$refs['form'].resetFields()
|
||||
this.form = this.$options.data().form
|
||||
this.dialogFormVisible = false
|
||||
},
|
||||
save() {
|
||||
this.$refs['form'].validate(async (valid) => {
|
||||
if (valid) {
|
||||
if (this.id) {
|
||||
const { msg } = await doEdit(this.id, this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
} else {
|
||||
const { msg } = await doAdd(this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
}
|
||||
this.$emit('fetch-data')
|
||||
this.close()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
146
src/views/cxshMini/home/banner/index.vue
Normal file
146
src/views/cxshMini/home/banner/index.vue
Normal file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<div class="appManagement-container">
|
||||
<el-divider content-position="left">
|
||||
演示环境仅做基础功能展示,若想实现不同角色的真实菜单配置,需将settings.js路由加载模式改为all模式,由后端全面接管路由渲染与权限控制
|
||||
</el-divider>
|
||||
<vab-query-form>
|
||||
<vab-query-form-left-panel :span="12">
|
||||
<el-button icon="el-icon-plus" type="primary" @click="handleEdit">添加</el-button>
|
||||
<el-button icon="el-icon-delete" type="danger" @click="handleDelete">批量删除</el-button>
|
||||
</vab-query-form-left-panel>
|
||||
<vab-query-form-right-panel :span="12">
|
||||
<el-form :inline="true" :model="queryForm" @submit.native.prevent>
|
||||
<el-form-item>
|
||||
<el-input v-model.trim="queryForm.permission" clearable placeholder="请输入查询条件" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</vab-query-form-right-panel>
|
||||
</vab-query-form>
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" :element-loading-text="elementLoadingText" @selection-change="setSelectRows">
|
||||
<el-table-column show-overflow-tooltip type="selection" />
|
||||
<el-table-column align="center" label="图标" width="100">
|
||||
<template slot-scope="scope">
|
||||
<!-- 使用 show-overflow-tooltip 显示图片,并添加 tooltip -->
|
||||
<el-tooltip class="item" :content="scope.row.name" effect="dark" placement="top">
|
||||
<img alt="image" :src="scope.row.icon" style="width: 50px; height: 50px; object-fit: cover; border-radius: 50%" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="名称" prop="name" show-overflow-tooltip />
|
||||
<el-table-column align="center" label="类型" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ row.type === 1 ? '小程序' : row.type === 2 ? 'H5' : '后台管理' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="描述" prop="description" show-overflow-tooltip />
|
||||
<el-table-column label="操作" show-overflow-tooltip width="200">
|
||||
<template #default="{ row }">
|
||||
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="text" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="queryForm.pageNo"
|
||||
:layout="layout"
|
||||
:page-size="queryForm.pageSize"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
<edit ref="edit" @fetch-data="fetchData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doDelete, getList } from '@/api/appManagement'
|
||||
import { formatTime } from '@/utils'
|
||||
import Edit from './components/AppManagementEdit'
|
||||
|
||||
export default {
|
||||
name: 'AppManagement',
|
||||
components: { Edit },
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true,
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
total: 0,
|
||||
selectRows: '',
|
||||
elementLoadingText: '正在加载...',
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
permission: '',
|
||||
},
|
||||
timeOutID: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
clearTimeout(this.timeOutID)
|
||||
},
|
||||
methods: {
|
||||
setSelectRows(val) {
|
||||
this.selectRows = val
|
||||
},
|
||||
handleEdit(row) {
|
||||
if (row.id) {
|
||||
this.$refs['edit'].showEdit(row)
|
||||
} else {
|
||||
this.$refs['edit'].showEdit()
|
||||
}
|
||||
},
|
||||
handleDelete(row) {
|
||||
if (row.id) {
|
||||
this.$baseConfirm('你确定要删除当前项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: [row.id] })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
if (this.selectRows.length > 0) {
|
||||
const ids = this.selectRows.map((item) => item.id).join()
|
||||
this.$baseConfirm('你确定要删除选中项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: ids.split(',') })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
this.$baseMessage('未选中任何行', 'error')
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.pageNo = val
|
||||
this.fetchData()
|
||||
},
|
||||
queryData() {
|
||||
this.queryForm.pageNo = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
this.listLoading = true
|
||||
const { data } = await getList(this.queryForm)
|
||||
this.list = data.list
|
||||
this.total = data.totalCount
|
||||
this.timeOutID = setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 300)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<el-dialog :title="title" :visible.sync="dialogFormVisible" width="500px" @close="close">
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select v-model="form.type" placeholder="请选择 APP 类型">
|
||||
<el-option label="小程序" :value="1" />
|
||||
<el-option label="H5" :value="2" />
|
||||
<el-option label="后台管理" :value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input v-model="form.description" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="APP图标" prop="appIcon">
|
||||
<single-upload
|
||||
style="width: 100px; height: 100px"
|
||||
upload-url="http://127.0.0.1:3999/management/api/common/upload"
|
||||
@upload-success="handleUploadSuccess"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doEdit, doAdd } from '@/api/appManagement'
|
||||
import SingleUpload from '@/components/SingleUpload'
|
||||
|
||||
export default {
|
||||
name: 'AppManagementEdit',
|
||||
components: { SingleUpload },
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
form: {
|
||||
name: '',
|
||||
type: '',
|
||||
description: '',
|
||||
icon: '',
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, trigger: 'blur', message: '请输入名称' }],
|
||||
type: [{ required: true, trigger: 'blur', message: '请选择类型' }],
|
||||
},
|
||||
title: '',
|
||||
dialogFormVisible: false,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
handleUploadSuccess(url) {
|
||||
this.form.icon = url
|
||||
},
|
||||
showEdit(row) {
|
||||
if (!row) {
|
||||
this.title = '添加'
|
||||
} else {
|
||||
this.title = '编辑'
|
||||
this.form = {
|
||||
name: row.name,
|
||||
description: row.description,
|
||||
icon: row.icon,
|
||||
}
|
||||
this.id = row.id
|
||||
}
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
close() {
|
||||
this.$refs['form'].resetFields()
|
||||
this.form = this.$options.data().form
|
||||
this.dialogFormVisible = false
|
||||
},
|
||||
save() {
|
||||
this.$refs['form'].validate(async (valid) => {
|
||||
if (valid) {
|
||||
if (this.id) {
|
||||
const { msg } = await doEdit(this.id, this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
} else {
|
||||
const { msg } = await doAdd(this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
}
|
||||
this.$emit('fetch-data')
|
||||
this.close()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
146
src/views/cxshMini/lianxi/member/index.vue
Normal file
146
src/views/cxshMini/lianxi/member/index.vue
Normal file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<div class="appManagement-container">
|
||||
<el-divider content-position="left">
|
||||
演示环境仅做基础功能展示,若想实现不同角色的真实菜单配置,需将settings.js路由加载模式改为all模式,由后端全面接管路由渲染与权限控制
|
||||
</el-divider>
|
||||
<vab-query-form>
|
||||
<vab-query-form-left-panel :span="12">
|
||||
<el-button icon="el-icon-plus" type="primary" @click="handleEdit">添加</el-button>
|
||||
<el-button icon="el-icon-delete" type="danger" @click="handleDelete">批量删除</el-button>
|
||||
</vab-query-form-left-panel>
|
||||
<vab-query-form-right-panel :span="12">
|
||||
<el-form :inline="true" :model="queryForm" @submit.native.prevent>
|
||||
<el-form-item>
|
||||
<el-input v-model.trim="queryForm.permission" clearable placeholder="请输入查询条件" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</vab-query-form-right-panel>
|
||||
</vab-query-form>
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" :element-loading-text="elementLoadingText" @selection-change="setSelectRows">
|
||||
<el-table-column show-overflow-tooltip type="selection" />
|
||||
<el-table-column align="center" label="图标" width="100">
|
||||
<template slot-scope="scope">
|
||||
<!-- 使用 show-overflow-tooltip 显示图片,并添加 tooltip -->
|
||||
<el-tooltip class="item" :content="scope.row.name" effect="dark" placement="top">
|
||||
<img alt="image" :src="scope.row.icon" style="width: 50px; height: 50px; object-fit: cover; border-radius: 50%" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="名称" prop="name" show-overflow-tooltip />
|
||||
<el-table-column align="center" label="类型" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ row.type === 1 ? '小程序' : row.type === 2 ? 'H5' : '后台管理' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="描述" prop="description" show-overflow-tooltip />
|
||||
<el-table-column label="操作" show-overflow-tooltip width="200">
|
||||
<template #default="{ row }">
|
||||
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="text" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="queryForm.pageNo"
|
||||
:layout="layout"
|
||||
:page-size="queryForm.pageSize"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
<edit ref="edit" @fetch-data="fetchData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doDelete, getList } from '@/api/appManagement'
|
||||
import { formatTime } from '@/utils'
|
||||
import Edit from './components/AppManagementEdit'
|
||||
|
||||
export default {
|
||||
name: 'AppManagement',
|
||||
components: { Edit },
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true,
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
total: 0,
|
||||
selectRows: '',
|
||||
elementLoadingText: '正在加载...',
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
permission: '',
|
||||
},
|
||||
timeOutID: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
clearTimeout(this.timeOutID)
|
||||
},
|
||||
methods: {
|
||||
setSelectRows(val) {
|
||||
this.selectRows = val
|
||||
},
|
||||
handleEdit(row) {
|
||||
if (row.id) {
|
||||
this.$refs['edit'].showEdit(row)
|
||||
} else {
|
||||
this.$refs['edit'].showEdit()
|
||||
}
|
||||
},
|
||||
handleDelete(row) {
|
||||
if (row.id) {
|
||||
this.$baseConfirm('你确定要删除当前项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: [row.id] })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
if (this.selectRows.length > 0) {
|
||||
const ids = this.selectRows.map((item) => item.id).join()
|
||||
this.$baseConfirm('你确定要删除选中项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: ids.split(',') })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
this.$baseMessage('未选中任何行', 'error')
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.pageNo = val
|
||||
this.fetchData()
|
||||
},
|
||||
queryData() {
|
||||
this.queryForm.pageNo = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
this.listLoading = true
|
||||
const { data } = await getList(this.queryForm)
|
||||
this.list = data.list
|
||||
this.total = data.totalCount
|
||||
this.timeOutID = setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 300)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
83
src/views/index/components/Plan.vue
Normal file
83
src/views/index/components/Plan.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<vab-icon icon="send-plane-2-line" />
|
||||
<!-- 计划 -->
|
||||
<el-tag class="card-header-tag" type="success">祝用框架的小伙伴都能住上别墅,开上保时捷</el-tag>
|
||||
</template>
|
||||
<el-table :data="tableData" height="283px" row-key="title">
|
||||
<el-table-column align="center" label="拖拽" width="50px">
|
||||
<template #default="{}">
|
||||
<vab-icon :icon="['fas', 'arrows-alt']" style="cursor: pointer" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="20px" />
|
||||
<el-table-column label="目标" prop="title" width="230px" />
|
||||
<el-table-column label="进度" width="220px">
|
||||
<template #default="{ row }">
|
||||
<el-progress :color="row.color" :percentage="row.percentage" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="50px" />
|
||||
<el-table-column label="完成时间" prop="endTIme" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</template>
|
||||
<script>
|
||||
import Sortable from 'sortablejs'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableData: [
|
||||
{
|
||||
title: '帮助中小企业盈利1个亿',
|
||||
endTIme: '2099-12-31',
|
||||
percentage: 50,
|
||||
color: '#95de64',
|
||||
},
|
||||
{
|
||||
title: '帮助10万个人',
|
||||
endTIme: '2029-12-31',
|
||||
percentage: 8,
|
||||
color: '#69c0ff',
|
||||
},
|
||||
{
|
||||
title: '交个帅气的男朋友',
|
||||
endTIme: '2021-12-31',
|
||||
percentage: 76,
|
||||
color: '#1890FF',
|
||||
},
|
||||
{
|
||||
title: 'vue-admin-better标星过1K',
|
||||
endTIme: '2020-03-31',
|
||||
percentage: 100,
|
||||
color: '#ffc069',
|
||||
},
|
||||
{
|
||||
title: '活到老,学到老',
|
||||
endTIme: '2094-12-16',
|
||||
percentage: 25,
|
||||
color: '#5cdbd3',
|
||||
},
|
||||
{
|
||||
title: '变成像尤雨溪一样优秀的人',
|
||||
endTIme: '此生无望',
|
||||
percentage: 1,
|
||||
color: '#b37feb',
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const tbody = document.querySelector('.el-table__body-wrapper tbody')
|
||||
const _this = this
|
||||
Sortable.create(tbody, {
|
||||
onEnd({ newIndex, oldIndex }) {
|
||||
const currRow = _this.tableData.splice(oldIndex, 1)[0]
|
||||
_this.tableData.splice(newIndex, 0, currRow)
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
85
src/views/index/components/VersionInformation.vue
Normal file
85
src/views/index/components/VersionInformation.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<el-card class="version-information" shadow="hover">
|
||||
<template #header>
|
||||
<vab-icon icon="information-line" />
|
||||
</template>
|
||||
<el-scrollbar>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td>vue</td>
|
||||
<td>{{ dependencies['vue'] }}</td>
|
||||
<td>@vue/cli</td>
|
||||
<td>{{ devDependencies['@vue/cli-service'] }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>vuex</td>
|
||||
<td>{{ dependencies['vuex'] }}</td>
|
||||
<td>vue-router</td>
|
||||
<td>{{ dependencies['vue-router'] }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>element-ui</td>
|
||||
<td>{{ dependencies['element-ui'] }}</td>
|
||||
<td>axios</td>
|
||||
<td>{{ dependencies['axios'] }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>授权渠道</td>
|
||||
<td colspan="3">
|
||||
<a href="https://vuejs-core.cn/authorization" target="_blank">
|
||||
<el-button style="margin-left: 10px" type="primary">PRO付费版本 购买源码 ¥699</el-button>
|
||||
</a>
|
||||
<a href="https://vuejs-core.cn/authorization" target="_blank">
|
||||
<el-button style="margin-left: 10px" type="primary">Plus付费版本 购买源码 ¥799</el-button>
|
||||
</a>
|
||||
<a href="https://github.com/zxwk1998/vue-admin-better/" target="_blank">
|
||||
<el-button style="margin-left: 10px" type="warning">开源免费版</el-button>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</el-scrollbar>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { dependencies, devDependencies } from '../../../../package.json'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
updateTime: process.env.VUE_APP_UPDATE_TIME,
|
||||
dependencies,
|
||||
devDependencies,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.version-information {
|
||||
.table {
|
||||
width: 100%;
|
||||
color: #666;
|
||||
border-collapse: collapse;
|
||||
background-color: #fff;
|
||||
|
||||
td {
|
||||
position: relative;
|
||||
padding: 9px 15px;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
border: 1px solid #e6e6e6;
|
||||
|
||||
&:nth-child(odd) {
|
||||
width: 20%;
|
||||
text-align: right;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
601
src/views/index/index.vue
Normal file
601
src/views/index/index.vue
Normal file
@@ -0,0 +1,601 @@
|
||||
<template>
|
||||
<div class="index-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="24" :md="24" :sm="24" :xl="24" :xs="24">
|
||||
<el-alert v-if="noticeList">
|
||||
<div style="display: flex; align-items: center; justify-content: center">
|
||||
<a href="https://github.com/zxwk1998/vue-admin-better" target="_blank">
|
||||
<img
|
||||
src="https://img.shields.io/github/stars/zxwk1998/vue-admin-better?style=flat-square&label=Stars&logo=github"
|
||||
style="margin-right: 10px"
|
||||
/>
|
||||
</a>
|
||||
<p v-html="noticeList.notice"></p>
|
||||
</div>
|
||||
</el-alert>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="never">
|
||||
<div slot="header">
|
||||
<span>访问量</span>
|
||||
</div>
|
||||
<vab-chart autoresize :option="fwl" />
|
||||
<div class="bottom">
|
||||
<span>
|
||||
日均访问量:
|
||||
|
||||
{{ config1.endVal }}
|
||||
</span>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="never">
|
||||
<div slot="header">
|
||||
<span>授权数</span>
|
||||
</div>
|
||||
<vab-chart autoresize :option="sqs" />
|
||||
<div class="bottom">
|
||||
<span>
|
||||
总授权数:
|
||||
{{ config2.endVal }}
|
||||
</span>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col v-for="(item, index) in iconList" :key="index" :lg="3" :md="3" :sm="6" :xl="3" :xs="12">
|
||||
<router-link target="_blank" :to="item.link">
|
||||
<el-card class="icon-panel" shadow="never">
|
||||
<vab-icon :icon="['fas', item.icon]" :style="{ color: item.color }" />
|
||||
<p>{{ item.title }}</p>
|
||||
</el-card>
|
||||
</router-link>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="11" :md="24" :sm="24" :xl="11" :xs="24">
|
||||
<el-card class="card" shadow="never">
|
||||
<div slot="header">
|
||||
<span>依赖信息</span>
|
||||
<!-- <div style="float: right">部署时间:{{ updateTime }}</div> -->
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td>@vue/cli版本</td>
|
||||
<td>{{ devDependencies['@vue/cli-service'] }}</td>
|
||||
<td>vue版本</td>
|
||||
<td>{{ dependencies['vue'] }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>vuex版本</td>
|
||||
<td>{{ dependencies['vuex'] }}</td>
|
||||
<td>vue-router版本</td>
|
||||
<td>{{ dependencies['vue-router'] }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>element-ui版本</td>
|
||||
<td>{{ dependencies['element-ui'] }}</td>
|
||||
<td>axios版本</td>
|
||||
<td>{{ dependencies['axios'] }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>eslint版本</td>
|
||||
<td>{{ devDependencies['eslint'] }}</td>
|
||||
<td>prettier版本</td>
|
||||
<td>{{ devDependencies['prettier'] }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sass版本</td>
|
||||
<td>{{ devDependencies['sass'] }}</td>
|
||||
<td>mockjs版本</td>
|
||||
<td>{{ dependencies['mockjs'] }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>layouts版本</td>
|
||||
<td>{{ dependencies['layouts'] }}</td>
|
||||
<td>lodash版本</td>
|
||||
<td>{{ dependencies['lodash'] }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<el-alert :closable="false" :title="userAgent" type="info" />
|
||||
<br />
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="13" :md="13" :sm="24" :xl="13" :xs="24">
|
||||
<el-card shadow="never">
|
||||
<div slot="header">
|
||||
<span>其他信息</span>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
<vab-colorful-icon icon-class="vab" style="font-size: 140px" />
|
||||
<h1 style="font-size: 30px">vue-admin-better</h1>
|
||||
</div>
|
||||
<div class="bottom-btn">
|
||||
<el-popover placement="top" trigger="hover" width="250">
|
||||
<p>
|
||||
请我们喝杯咖啡,付款后联系qq
|
||||
783963206,我们将邀请您加入我们的讨论群,谢谢您愿意支持开源,加群获取文档、及基础模板,群内大佬众多,希望能帮到大家(如情况不允许,请勿勉强)。
|
||||
</p>
|
||||
<el-image :src="require('@/assets/zfb_kf.jpg')" />
|
||||
<a slot="reference" target="_blank">
|
||||
<el-button type="primary">QQ讨论群、基础版、文档</el-button>
|
||||
</a>
|
||||
</el-popover>
|
||||
<a href="https://github.com/zxwk1998/vue-admin-better" target="_blank">
|
||||
<el-button type="plain">vue2.x版本 github下载源码点star</el-button>
|
||||
</a>
|
||||
<a href="https://gitee.com/chu1204505056/vue-admin-better" target="_blank">
|
||||
<el-button type="plain">vue2.x版本 码云下载源码点star</el-button>
|
||||
</a>
|
||||
<a href="https://github.com/zxwk1998/vue-admin-arco" target="_blank">
|
||||
<el-button type="plain">vue3.x版本 github下载源码点star</el-button>
|
||||
</a>
|
||||
<a href="https://vuejs-core.cn/admin-pro" target="_blank">
|
||||
<el-button type="primary">Admin Pro ¥699</el-button>
|
||||
</a>
|
||||
<a href="https://vuejs-core.cn/admin-plus" target="_blank">
|
||||
<el-button type="primary">Admin Plus ¥799</el-button>
|
||||
</a>
|
||||
<a href="https://vuejs-core.cn/shop-vite" target="_blank">
|
||||
<el-button type="success">Shop Vite ¥1899</el-button>
|
||||
</a>
|
||||
<a @click="handleChangeTheme">
|
||||
<el-button type="danger">修改主题和布局</el-button>
|
||||
</a>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VabChart from '@/plugins/echarts'
|
||||
import { dependencies, devDependencies } from '../../../package.json'
|
||||
import { getNoticeList } from '@/api/notice'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {
|
||||
VabChart,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
timer: 0,
|
||||
updateTime: process.env.VUE_APP_UPDATE_TIME,
|
||||
nodeEnv: process.env.NODE_ENV,
|
||||
dependencies: dependencies,
|
||||
devDependencies: devDependencies,
|
||||
config1: {
|
||||
startVal: 0,
|
||||
endVal: this.$baseLodash.random(20000, 60000),
|
||||
decimals: 0,
|
||||
prefix: '',
|
||||
suffix: '',
|
||||
separator: ',',
|
||||
duration: 8000,
|
||||
},
|
||||
config2: {
|
||||
startVal: 0,
|
||||
endVal: this.$baseLodash.random(1000, 20000),
|
||||
decimals: 0,
|
||||
prefix: '',
|
||||
suffix: '',
|
||||
separator: ',',
|
||||
duration: 8000,
|
||||
},
|
||||
config3: {
|
||||
startVal: 0,
|
||||
endVal: this.$baseLodash.random(1000, 20000),
|
||||
decimals: 0,
|
||||
prefix: '',
|
||||
suffix: '',
|
||||
separator: ',',
|
||||
duration: 8000,
|
||||
},
|
||||
|
||||
//访问量
|
||||
fwl: {
|
||||
color: ['#1890FF', '#36CBCB', '#4ECB73', '#FBD437', '#F2637B', '#975FE5'],
|
||||
backgroundColor: 'rgba(252,252,252,0)',
|
||||
grid: {
|
||||
top: '4%',
|
||||
left: '2%',
|
||||
right: '4%',
|
||||
bottom: '0%',
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: [],
|
||||
axisTick: {
|
||||
alignWithLabel: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '访问量',
|
||||
type: 'line',
|
||||
data: [],
|
||||
smooth: true,
|
||||
areaStyle: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
//授权数
|
||||
sqs: {
|
||||
color: ['#1890FF', '#36CBCB', '#4ECB73', '#FBD437', '#F2637B', '#975FE5'],
|
||||
backgroundColor: 'rgba(252,252,252,0)',
|
||||
grid: {
|
||||
top: '4%',
|
||||
left: '2%',
|
||||
right: '4%',
|
||||
bottom: '0%',
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
/*boundaryGap: false,*/
|
||||
data: ['0时', '4时', '8时', '12时', '16时', '20时', '24时'],
|
||||
axisTick: {
|
||||
alignWithLabel: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '授权数',
|
||||
type: 'bar',
|
||||
barWidth: '60%',
|
||||
data: [10, 52, 20, 33, 39, 33, 22],
|
||||
},
|
||||
],
|
||||
},
|
||||
//词云
|
||||
cy: {
|
||||
grid: {
|
||||
top: '4%',
|
||||
left: '2%',
|
||||
right: '4%',
|
||||
bottom: '0%',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'wordCloud',
|
||||
gridSize: 15,
|
||||
sizeRange: [12, 40],
|
||||
rotationRange: [0, 0],
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
textStyle: {
|
||||
normal: {
|
||||
color() {
|
||||
const arr = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#975FE5']
|
||||
let index = Math.floor(Math.random() * arr.length)
|
||||
return arr[index]
|
||||
},
|
||||
},
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: 'vue-admin-better',
|
||||
value: 15000,
|
||||
},
|
||||
{
|
||||
name: 'element',
|
||||
value: 10081,
|
||||
},
|
||||
{
|
||||
name: 'beautiful',
|
||||
value: 9386,
|
||||
},
|
||||
|
||||
{
|
||||
name: 'vue',
|
||||
value: 6500,
|
||||
},
|
||||
{
|
||||
name: 'zxwk1998',
|
||||
value: 6000,
|
||||
},
|
||||
{
|
||||
name: 'good',
|
||||
value: 4500,
|
||||
},
|
||||
{
|
||||
name: 'success',
|
||||
value: 3800,
|
||||
},
|
||||
{
|
||||
name: 'never',
|
||||
value: 3000,
|
||||
},
|
||||
{
|
||||
name: 'boy',
|
||||
value: 2500,
|
||||
},
|
||||
{
|
||||
name: 'girl',
|
||||
value: 2300,
|
||||
},
|
||||
{
|
||||
name: 'github',
|
||||
value: 2000,
|
||||
},
|
||||
{
|
||||
name: 'hbuilder',
|
||||
value: 1900,
|
||||
},
|
||||
{
|
||||
name: 'dcloud',
|
||||
value: 1800,
|
||||
},
|
||||
{
|
||||
name: 'china',
|
||||
value: 1700,
|
||||
},
|
||||
{
|
||||
name: '1204505056',
|
||||
value: 1600,
|
||||
},
|
||||
{
|
||||
name: '972435319',
|
||||
value: 1500,
|
||||
},
|
||||
{
|
||||
name: 'young',
|
||||
value: 1200,
|
||||
},
|
||||
{
|
||||
name: 'old',
|
||||
value: 1100,
|
||||
},
|
||||
{
|
||||
name: 'vuex',
|
||||
value: 900,
|
||||
},
|
||||
{
|
||||
name: 'router',
|
||||
value: 800,
|
||||
},
|
||||
{
|
||||
name: 'money',
|
||||
value: 700,
|
||||
},
|
||||
{
|
||||
name: 'qingdao',
|
||||
value: 800,
|
||||
},
|
||||
{
|
||||
name: 'yantai',
|
||||
value: 9000,
|
||||
},
|
||||
{
|
||||
name: 'author is very cool',
|
||||
value: 9200,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
//更新日志
|
||||
reverse: true,
|
||||
activities: [],
|
||||
noticeList: [],
|
||||
//其他信息
|
||||
userAgent: navigator.userAgent,
|
||||
//卡片图标
|
||||
iconList: [
|
||||
{
|
||||
icon: 'video',
|
||||
title: '视频播放器',
|
||||
link: '/vab/player',
|
||||
color: '#ffc069',
|
||||
},
|
||||
{
|
||||
icon: 'table',
|
||||
title: '表格',
|
||||
link: '/vab/table/comprehensiveTable',
|
||||
color: '#5cdbd3',
|
||||
},
|
||||
{
|
||||
icon: 'laptop-code',
|
||||
title: '源码',
|
||||
link: 'https://github.com/zxwk1998/vue-admin-better',
|
||||
color: '#b37feb',
|
||||
},
|
||||
{
|
||||
icon: 'book',
|
||||
title: '书籍',
|
||||
link: '',
|
||||
color: '#69c0ff',
|
||||
},
|
||||
{
|
||||
icon: 'bullhorn',
|
||||
title: '公告',
|
||||
link: '',
|
||||
color: '#ff85c0',
|
||||
},
|
||||
{
|
||||
icon: 'gift',
|
||||
title: '礼物',
|
||||
link: '',
|
||||
color: '#ffd666',
|
||||
},
|
||||
|
||||
{
|
||||
icon: 'balance-scale-left',
|
||||
title: '公平的世界',
|
||||
link: '',
|
||||
color: '#ff9c6e',
|
||||
},
|
||||
{
|
||||
icon: 'coffee',
|
||||
title: '休息一下',
|
||||
link: '',
|
||||
color: '#95de64',
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
mounted() {
|
||||
let base = +new Date(2020, 1, 1)
|
||||
let oneDay = 24 * 3600 * 1000
|
||||
let date = []
|
||||
|
||||
let data = [Math.random() * 1500]
|
||||
let now = new Date(base)
|
||||
|
||||
const addData = (shift) => {
|
||||
now = [now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/')
|
||||
date.push(now)
|
||||
data.push(this.$baseLodash.random(20000, 60000))
|
||||
|
||||
if (shift) {
|
||||
date.shift()
|
||||
data.shift()
|
||||
}
|
||||
|
||||
now = new Date(+new Date(now) + oneDay)
|
||||
}
|
||||
|
||||
for (let i = 1; i < 6; i++) {
|
||||
addData()
|
||||
}
|
||||
addData(true)
|
||||
this.fwl.xAxis[0].data = date
|
||||
this.fwl.series[0].data = data
|
||||
this.timer = setInterval(() => {
|
||||
addData(true)
|
||||
this.fwl.xAxis[0].data = date
|
||||
this.fwl.series[0].data = data
|
||||
}, 3000)
|
||||
},
|
||||
methods: {
|
||||
handleClick(e) {
|
||||
this.$baseMessage(`点击了${e.name},这里可以写跳转`)
|
||||
},
|
||||
handleZrClick() {},
|
||||
handleChangeTheme() {
|
||||
this.$baseEventBus.$emit('theme')
|
||||
},
|
||||
async fetchData() {
|
||||
const res = await getNoticeList()
|
||||
this.noticeList = res.data
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.index-container {
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
background: #f5f7f8 !important;
|
||||
|
||||
::v-deep {
|
||||
.el-alert {
|
||||
padding: $base-padding;
|
||||
|
||||
&--info.is-light {
|
||||
min-height: 82px;
|
||||
padding: $base-padding;
|
||||
margin-bottom: 15px;
|
||||
color: #909399;
|
||||
background-color: $base-color-white;
|
||||
border: 1px solid #ebeef5;
|
||||
}
|
||||
}
|
||||
|
||||
.el-card__body {
|
||||
.echarts {
|
||||
width: 100%;
|
||||
height: 115px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
::v-deep {
|
||||
.el-card__body {
|
||||
.echarts {
|
||||
width: 100%;
|
||||
height: 305px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
padding-top: 20px;
|
||||
margin-top: 5px;
|
||||
color: #595959;
|
||||
text-align: left;
|
||||
border-top: 1px solid $base-border-color;
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
color: #666;
|
||||
border-collapse: collapse;
|
||||
background-color: #fff;
|
||||
|
||||
td {
|
||||
position: relative;
|
||||
min-height: 20px;
|
||||
padding: 9px 15px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
border: 1px solid #e6e6e6;
|
||||
|
||||
&:nth-child(odd) {
|
||||
width: 20%;
|
||||
text-align: right;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-panel {
|
||||
height: 117px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
svg {
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-btn {
|
||||
button {
|
||||
margin: 5px 10px 15px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
296
src/views/login/index.vue
Normal file
296
src/views/login/index.vue
Normal file
@@ -0,0 +1,296 @@
|
||||
<template>
|
||||
<div class="login-container">
|
||||
<el-row>
|
||||
<el-col :lg="16" :md="12" :sm="24" :xl="16" :xs="24">
|
||||
<div style="color: transparent">占位符</div>
|
||||
</el-col>
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="8" :xs="24">
|
||||
<el-form ref="form" class="login-form" label-position="left" :model="form" :rules="rules">
|
||||
<div class="title">hello !</div>
|
||||
<div class="title-tips">欢迎来到{{ title }}!</div>
|
||||
<el-form-item prop="username" style="margin-top: 40px">
|
||||
<span class="svg-container svg-container-admin">
|
||||
<vab-icon :icon="['fas', 'user']" />
|
||||
</span>
|
||||
<el-input v-model.trim="form.username" v-focus placeholder="请输入用户名" tabindex="1" type="text" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<span class="svg-container">
|
||||
<vab-icon :icon="['fas', 'lock']" />
|
||||
</span>
|
||||
<el-input
|
||||
:key="passwordType"
|
||||
ref="password"
|
||||
v-model.trim="form.password"
|
||||
placeholder="请输入密码"
|
||||
tabindex="2"
|
||||
:type="passwordType"
|
||||
@keyup.enter.native="handleLogin"
|
||||
/>
|
||||
<span v-if="passwordType === 'password'" class="show-password" @click="handlePassword">
|
||||
<vab-icon :icon="['fas', 'eye-slash']" />
|
||||
</span>
|
||||
<span v-else class="show-password" @click="handlePassword">
|
||||
<vab-icon :icon="['fas', 'eye']" />
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-button class="login-btn" :loading="loading" type="primary" @click="handleLogin">登录</el-button>
|
||||
<router-link to="/register">
|
||||
<div style="margin-top: 20px">注册</div>
|
||||
</router-link>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isPassword } from '@/utils/validate'
|
||||
import { mapActions } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'Login',
|
||||
directives: {
|
||||
focus: {
|
||||
inserted(el) {
|
||||
el.querySelector('input').focus()
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const validateusername = (rule, value, callback) => {
|
||||
if ('' == value) {
|
||||
callback(new Error('用户名不能为空'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
const validatePassword = (rule, value, callback) => {
|
||||
if (!isPassword(value)) {
|
||||
callback(new Error('密码不能少于6位'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
nodeEnv: process.env.NODE_ENV,
|
||||
title: this.$baseTitle,
|
||||
form: {
|
||||
username: '',
|
||||
password: '',
|
||||
},
|
||||
rules: {
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
validator: validateusername,
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
validator: validatePassword,
|
||||
},
|
||||
],
|
||||
},
|
||||
loading: false,
|
||||
passwordType: 'password',
|
||||
redirect: undefined,
|
||||
timeOutID: null,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler(route) {
|
||||
this.redirect = (route.query && route.query.redirect) || '/'
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
document.body.style.overflow = 'hidden'
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.body.style.overflow = 'auto'
|
||||
clearTimeout(this.timeOutID)
|
||||
},
|
||||
mounted() {
|
||||
this.form.username = ''
|
||||
this.form.password = ''
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
changeLogo: 'settings/changeLogo',
|
||||
}),
|
||||
handlePassword() {
|
||||
this.passwordType === 'password' ? (this.passwordType = '') : (this.passwordType = 'password')
|
||||
this.$nextTick(() => {
|
||||
this.$refs.password.focus()
|
||||
})
|
||||
},
|
||||
handleLogin() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
this.$store
|
||||
.dispatch('user/login', this.form)
|
||||
.then(() => {
|
||||
const routerPath = this.redirect === '/404' || this.redirect === '/401' ? '/' : this.redirect
|
||||
// this.changeLogo('https://file.lihailezzc.com/resource/527ac7f6b4a45cd46f9f2954dca39fd0.jpg')
|
||||
this.$router.push(routerPath).catch(() => {})
|
||||
this.loading = false
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login-container {
|
||||
height: 100vh;
|
||||
background: url('~@/assets/login_images/background.jpg') center center fixed no-repeat;
|
||||
background-size: cover;
|
||||
|
||||
.title {
|
||||
font-size: 54px;
|
||||
font-weight: 500;
|
||||
color: rgba(14, 18, 26, 1);
|
||||
}
|
||||
|
||||
.title-tips {
|
||||
margin-top: 29px;
|
||||
font-size: 26px;
|
||||
font-weight: 400;
|
||||
color: rgba(14, 18, 26, 1);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
display: inherit;
|
||||
width: 220px;
|
||||
height: 60px;
|
||||
margin-top: 5px;
|
||||
border: 0;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form {
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
margin: calc((100vh - 425px) / 2) 10% 10%;
|
||||
overflow: hidden;
|
||||
|
||||
.forget-password {
|
||||
width: 100%;
|
||||
margin-top: 40px;
|
||||
text-align: left;
|
||||
|
||||
.forget-pass {
|
||||
width: 129px;
|
||||
height: 19px;
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
color: rgba(92, 102, 240, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
margin-bottom: 10px;
|
||||
font-size: $base-font-size-default;
|
||||
color: $base-color-white;
|
||||
|
||||
span {
|
||||
&:first-of-type {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.title-container {
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
margin: 0 auto 40px auto;
|
||||
font-size: 34px;
|
||||
font-weight: bold;
|
||||
color: $base-color-blue;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.svg-container {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
left: 15px;
|
||||
z-index: $base-z-index;
|
||||
font-size: 16px;
|
||||
color: #d7dee3;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.show-password {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
right: 25px;
|
||||
font-size: 16px;
|
||||
color: #d7dee3;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.el-form-item {
|
||||
padding-right: 0;
|
||||
margin: 20px 0;
|
||||
color: #454545;
|
||||
background: transparent;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 2px;
|
||||
|
||||
&__content {
|
||||
min-height: $base-input-height;
|
||||
line-height: $base-input-height;
|
||||
}
|
||||
|
||||
&__error {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 18px;
|
||||
font-size: $base-font-size-small;
|
||||
line-height: 18px;
|
||||
color: $base-color-red;
|
||||
}
|
||||
}
|
||||
|
||||
.el-input {
|
||||
box-sizing: border-box;
|
||||
|
||||
input {
|
||||
height: 58px;
|
||||
padding-left: 45px;
|
||||
font-size: $base-font-size-default;
|
||||
line-height: 58px;
|
||||
color: $base-font-color;
|
||||
background: #f6f4fc;
|
||||
border: 0;
|
||||
caret-color: $base-font-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
147
src/views/mall/goodsList/index.vue
Normal file
147
src/views/mall/goodsList/index.vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div class="goods-list-container">
|
||||
<vab-query-form>
|
||||
<vab-query-form-right-panel :span="24">
|
||||
<el-form ref="form" :inline="true" :model="queryForm" @submit.native.prevent>
|
||||
<el-form-item>
|
||||
<el-input v-model="queryForm.title" placeholder="商品名称" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="el-icon-search" native-type="submit" type="primary" @click="handleQuery">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</vab-query-form-right-panel>
|
||||
</vab-query-form>
|
||||
<el-row :gutter="20">
|
||||
<el-col v-for="(item, index) in list" :key="index" :lg="8" :md="8" :sm="8" :xl="6" :xs="24">
|
||||
<el-card :body-style="{ padding: '0px' }" shadow="hover">
|
||||
<div class="goods-list-card-body">
|
||||
<div class="goods-list-tag-group">
|
||||
<el-tag v-if="item.isRecommend" hit type="success">推荐</el-tag>
|
||||
<el-tag v-if="item.status === 0" hit type="danger">缺货</el-tag>
|
||||
</div>
|
||||
<div class="goods-list-image-group">
|
||||
<img class="goods-list-image" :src="item.image" />
|
||||
</div>
|
||||
<div class="goods-list-title">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
<div class="goods-list-description">
|
||||
{{ item.description }}
|
||||
</div>
|
||||
<div class="goods-list-price">
|
||||
<span>¥ {{ item.price }} 元</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="queryForm.pageNo"
|
||||
:layout="layout"
|
||||
:page-size="queryForm.pageSize"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getList } from '@/api/goodsList'
|
||||
|
||||
export default {
|
||||
name: 'Goods',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
title: '',
|
||||
},
|
||||
list: null,
|
||||
listLoading: true,
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
total: 0,
|
||||
elementLoadingText: '正在加载...',
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.pageNo = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleQuery() {
|
||||
this.queryForm.pageNo = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
this.listLoading = true
|
||||
const { data, totalCount } = await getList(this.queryForm)
|
||||
this.list = data
|
||||
this.total = totalCount
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.goods-list-container {
|
||||
.goods-list-card-body {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
.goods-list-tag-group {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 5px;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.goods-list-image-group {
|
||||
height: 400px;
|
||||
overflow: hidden;
|
||||
|
||||
.goods-list-image {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
transition: all ease-in-out 0.3s;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.goods-list-title {
|
||||
margin: 8px 0;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.goods-list-description {
|
||||
font-size: 14px;
|
||||
color: #808695;
|
||||
}
|
||||
|
||||
.goods-list-price {
|
||||
margin: 8px 0;
|
||||
font-size: 14px;
|
||||
color: $base-color-orange;
|
||||
|
||||
s {
|
||||
color: #c5c8ce;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
66
src/views/mall/pay/components/Step1.vue
Normal file
66
src/views/mall/pay/components/Step1.vue
Normal file
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="form" label-width="120px" :model="form" :rules="rules">
|
||||
<el-form-item label-width="0">
|
||||
<el-alert show-icon>请务必仔细填写并核对</el-alert>
|
||||
</el-form-item>
|
||||
<el-form-item label="付款账户" prop="payAccount">
|
||||
<el-input v-model="form.payAccount" />
|
||||
</el-form-item>
|
||||
<el-form-item label="收款账户" prop="gatheringAccount">
|
||||
<el-input v-model="form.gatheringAccount" />
|
||||
</el-form-item>
|
||||
<el-form-item label="收款人姓名" prop="gatheringName">
|
||||
<el-input v-model="form.gatheringName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="转账金额" prop="price">
|
||||
<el-input v-model="form.price" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="pay-button-group">
|
||||
<el-button type="primary" @click="handleSubmit">下一步</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
payAccount: 'XXXXXXXXXXXXXXXX',
|
||||
gatheringAccount: '',
|
||||
gatheringName: 'zxwk1998',
|
||||
price: '100',
|
||||
},
|
||||
rules: {
|
||||
payAccount: [{ required: true, message: '请选择付款账户', trigger: 'blur' }],
|
||||
gatheringAccount: [
|
||||
{ required: true, message: '请输入收款账户', trigger: 'blur' },
|
||||
{ type: 'email', message: '账户名应为邮箱格式', trigger: 'blur' },
|
||||
],
|
||||
gatheringName: [{ required: true, message: '请输入收款人姓名', trigger: 'blur' }],
|
||||
price: [
|
||||
{ required: true, message: '请输入转账金额', trigger: 'blur' },
|
||||
{ pattern: /^(\d+)((?:\.\d+)?)$/, message: '请输入合法金额数字' },
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$emit('change-step', 2, this.form)
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.pay-button-group {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
78
src/views/mall/pay/components/Step2.vue
Normal file
78
src/views/mall/pay/components/Step2.vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="form" label-width="120px" :model="form" :rules="rules">
|
||||
<el-form-item label-width="0">
|
||||
<el-alert show-icon>确认转账后,资金将直接打入对方账户,无法退回。</el-alert>
|
||||
</el-form-item>
|
||||
<el-form-item label="付款账户:">
|
||||
{{ infoData.payAccount }}
|
||||
</el-form-item>
|
||||
<el-form-item label="收款账户:">
|
||||
{{ infoData.gatheringAccount }}
|
||||
</el-form-item>
|
||||
<el-form-item label="收款人姓名:">
|
||||
{{ infoData.gatheringName }}
|
||||
</el-form-item>
|
||||
<el-form-item label="转账金额:">
|
||||
<strong>
|
||||
{{ infoData.price }}
|
||||
</strong>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付密码:" prop="password">
|
||||
<el-input v-model="form.password" type="password" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="pay-button-group">
|
||||
<el-button :loading="loading" type="primary" @click="handleSubmit">提交</el-button>
|
||||
<el-button @click="handlePrev">上一步</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
infoData: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
password: '123456',
|
||||
},
|
||||
rules: {
|
||||
password: [{ required: true, message: '请输入支付密码', trigger: 'blur' }],
|
||||
},
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
setTimeout(() => {
|
||||
this.$emit('change-step', 3)
|
||||
this.loading = false
|
||||
}, 2000)
|
||||
} else {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
handlePrev() {
|
||||
this.$emit('change-step', 1)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.pay-button-group {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
93
src/views/mall/pay/components/Step3.vue
Normal file
93
src/views/mall/pay/components/Step3.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="pay-top-content">
|
||||
<vab-icon class="pay-success" :icon="['fas', 'check-circle']" />
|
||||
<p>支付成功</p>
|
||||
</div>
|
||||
<el-form ref="form" class="pay-bottom" label-width="120px" :model="form" :rules="rules">
|
||||
<el-form-item label="付款账户:">
|
||||
{{ infoData.payAccount }}
|
||||
</el-form-item>
|
||||
<el-form-item label="收款账户:">
|
||||
{{ infoData.gatheringAccount }}
|
||||
</el-form-item>
|
||||
<el-form-item label="收款人姓名:">
|
||||
{{ infoData.gatheringName }}
|
||||
</el-form-item>
|
||||
<el-form-item label="转账金额:">
|
||||
<strong>
|
||||
{{ infoData.price }}
|
||||
</strong>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="pay-button-group">
|
||||
<el-button type="primary" @click="handlePrev">再转一笔</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
infoData: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
password: '123456',
|
||||
},
|
||||
rules: {
|
||||
password: [{ required: true, message: '请输入支付密码', trigger: 'blur' }],
|
||||
},
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
setTimeout(() => {
|
||||
this.$emit('change-step', 3)
|
||||
this.loading = false
|
||||
}, 2000)
|
||||
} else {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
handlePrev() {
|
||||
this.$emit('change-step', 1)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.pay-top-content {
|
||||
text-align: center;
|
||||
|
||||
.pay-success {
|
||||
display: block;
|
||||
margin: 20px auto 5px auto;
|
||||
font-size: 40px;
|
||||
color: $base-color-green;
|
||||
}
|
||||
}
|
||||
|
||||
.pay-bottom {
|
||||
padding: 20px;
|
||||
margin-top: 20px;
|
||||
background: #f5f7f8;
|
||||
border: 1px dashed $base-color-gray;
|
||||
}
|
||||
|
||||
.pay-button-group {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
53
src/views/mall/pay/index.vue
Normal file
53
src/views/mall/pay/index.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div class="pay-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col
|
||||
:lg="{ span: 14, offset: 5 }"
|
||||
:md="{ span: 20, offset: 2 }"
|
||||
:sm="{ span: 20, offset: 2 }"
|
||||
:xl="{ span: 12, offset: 6 }"
|
||||
:xs="24"
|
||||
>
|
||||
<el-steps :active="active" align-center class="steps" :space="200">
|
||||
<el-step title="填写转账信息" />
|
||||
<el-step title="确认转账信息" />
|
||||
<el-step title="完成" />
|
||||
</el-steps>
|
||||
<step1 v-if="active === 1" @change-step="handleSetStep" />
|
||||
<step2 v-if="active === 2" :info-data="form" @change-step="handleSetStep" />
|
||||
<step3 v-if="active === 3" :info-data="form" @change-step="handleSetStep" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Step1 from './components/Step1'
|
||||
import Step2 from './components/Step2'
|
||||
import Step3 from './components/Step3'
|
||||
|
||||
export default {
|
||||
name: 'Pay',
|
||||
components: { Step1, Step2, Step3 },
|
||||
data() {
|
||||
return {
|
||||
active: 1,
|
||||
form: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSetStep(active, form) {
|
||||
this.active = active
|
||||
if (form) this.form = Object.assign(this.form, form)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.pay-container {
|
||||
.steps {
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
23
src/views/personalCenter/index.vue
Normal file
23
src/views/personalCenter/index.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div class="personalCenter-container">
|
||||
<el-tabs :tab-position="tabPosition">
|
||||
<el-tab-pane label="个人简介">个人简介</el-tab-pane>
|
||||
<el-tab-pane label="基本设置">基本设置</el-tab-pane>
|
||||
<el-tab-pane label="安全设置">安全设置</el-tab-pane>
|
||||
<el-tab-pane label="账户绑定">安全设置</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PersonalCenter',
|
||||
data() {
|
||||
return {
|
||||
tabPosition: 'left',
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<el-dialog :title="title" :visible.sync="dialogFormVisible" width="500px" @close="close">
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select v-model="form.type" placeholder="请选择 APP 类型">
|
||||
<el-option label="小程序" :value="1" />
|
||||
<el-option label="H5" :value="2" />
|
||||
<el-option label="后台管理" :value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input v-model="form.description" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="APP图标" prop="appIcon">
|
||||
<single-upload
|
||||
style="width: 100px; height: 100px"
|
||||
upload-url="http://127.0.0.1:3999/management/api/common/upload"
|
||||
@upload-success="handleUploadSuccess"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doEdit, doAdd } from '@/api/appManagement'
|
||||
import SingleUpload from '@/components/SingleUpload'
|
||||
|
||||
export default {
|
||||
name: 'AppManagementEdit',
|
||||
components: { SingleUpload },
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
form: {
|
||||
name: '',
|
||||
type: '',
|
||||
description: '',
|
||||
icon: '',
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, trigger: 'blur', message: '请输入名称' }],
|
||||
type: [{ required: true, trigger: 'blur', message: '请选择类型' }],
|
||||
},
|
||||
title: '',
|
||||
dialogFormVisible: false,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
handleUploadSuccess(url) {
|
||||
this.form.icon = url
|
||||
},
|
||||
showEdit(row) {
|
||||
if (!row) {
|
||||
this.title = '添加'
|
||||
} else {
|
||||
this.title = '编辑'
|
||||
this.form = {
|
||||
name: row.name,
|
||||
description: row.description,
|
||||
icon: row.icon,
|
||||
}
|
||||
this.id = row.id
|
||||
}
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
close() {
|
||||
this.$refs['form'].resetFields()
|
||||
this.form = this.$options.data().form
|
||||
this.dialogFormVisible = false
|
||||
},
|
||||
save() {
|
||||
this.$refs['form'].validate(async (valid) => {
|
||||
if (valid) {
|
||||
if (this.id) {
|
||||
const { msg } = await doEdit(this.id, this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
} else {
|
||||
const { msg } = await doAdd(this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
}
|
||||
this.$emit('fetch-data')
|
||||
this.close()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
146
src/views/personnelManagement/appManagement/index.vue
Normal file
146
src/views/personnelManagement/appManagement/index.vue
Normal file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<div class="appManagement-container">
|
||||
<el-divider content-position="left">
|
||||
演示环境仅做基础功能展示,若想实现不同角色的真实菜单配置,需将settings.js路由加载模式改为all模式,由后端全面接管路由渲染与权限控制
|
||||
</el-divider>
|
||||
<vab-query-form>
|
||||
<vab-query-form-left-panel :span="12">
|
||||
<el-button icon="el-icon-plus" type="primary" @click="handleEdit">添加</el-button>
|
||||
<el-button icon="el-icon-delete" type="danger" @click="handleDelete">批量删除</el-button>
|
||||
</vab-query-form-left-panel>
|
||||
<vab-query-form-right-panel :span="12">
|
||||
<el-form :inline="true" :model="queryForm" @submit.native.prevent>
|
||||
<el-form-item>
|
||||
<el-input v-model.trim="queryForm.permission" clearable placeholder="请输入查询条件" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</vab-query-form-right-panel>
|
||||
</vab-query-form>
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" :element-loading-text="elementLoadingText" @selection-change="setSelectRows">
|
||||
<el-table-column show-overflow-tooltip type="selection" />
|
||||
<el-table-column align="center" label="图标" width="100">
|
||||
<template slot-scope="scope">
|
||||
<!-- 使用 show-overflow-tooltip 显示图片,并添加 tooltip -->
|
||||
<el-tooltip class="item" :content="scope.row.name" effect="dark" placement="top">
|
||||
<img alt="image" :src="scope.row.icon" style="width: 50px; height: 50px; object-fit: cover; border-radius: 50%" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="名称" prop="name" show-overflow-tooltip />
|
||||
<el-table-column align="center" label="类型" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ row.type === 1 ? '小程序' : row.type === 2 ? 'H5' : '后台管理' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="描述" prop="description" show-overflow-tooltip />
|
||||
<el-table-column label="操作" show-overflow-tooltip width="200">
|
||||
<template #default="{ row }">
|
||||
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="text" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="queryForm.pageNo"
|
||||
:layout="layout"
|
||||
:page-size="queryForm.pageSize"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
<edit ref="edit" @fetch-data="fetchData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doDelete, getList } from '@/api/appManagement'
|
||||
import { formatTime } from '@/utils'
|
||||
import Edit from './components/AppManagementEdit'
|
||||
|
||||
export default {
|
||||
name: 'AppManagement',
|
||||
components: { Edit },
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true,
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
total: 0,
|
||||
selectRows: '',
|
||||
elementLoadingText: '正在加载...',
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
permission: '',
|
||||
},
|
||||
timeOutID: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
clearTimeout(this.timeOutID)
|
||||
},
|
||||
methods: {
|
||||
setSelectRows(val) {
|
||||
this.selectRows = val
|
||||
},
|
||||
handleEdit(row) {
|
||||
if (row.id) {
|
||||
this.$refs['edit'].showEdit(row)
|
||||
} else {
|
||||
this.$refs['edit'].showEdit()
|
||||
}
|
||||
},
|
||||
handleDelete(row) {
|
||||
if (row.id) {
|
||||
this.$baseConfirm('你确定要删除当前项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: [row.id] })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
if (this.selectRows.length > 0) {
|
||||
const ids = this.selectRows.map((item) => item.id).join()
|
||||
this.$baseConfirm('你确定要删除选中项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: ids.split(',') })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
this.$baseMessage('未选中任何行', 'error')
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.pageNo = val
|
||||
this.fetchData()
|
||||
},
|
||||
queryData() {
|
||||
this.queryForm.pageNo = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
this.listLoading = true
|
||||
const { data } = await getList(this.queryForm)
|
||||
this.list = data.list
|
||||
this.total = data.totalCount
|
||||
this.timeOutID = setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 300)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<el-dialog :title="title" :visible.sync="dialogFormVisible" width="500px" @close="close">
|
||||
<el-divider content-position="left">这里就不具体写了,请自行完善</el-divider>
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules">
|
||||
<el-form-item label="name" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="路径" prop="path">
|
||||
<el-input v-model="form.path" autocomplete="off" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doEdit } from '@/api/menuManagement'
|
||||
|
||||
export default {
|
||||
name: 'MenuManagementEdit',
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
rules: {
|
||||
id: [{ required: true, trigger: 'blur', message: '请输入路径' }],
|
||||
},
|
||||
title: '',
|
||||
dialogFormVisible: false,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
showEdit(row) {
|
||||
if (!row) {
|
||||
this.title = '添加'
|
||||
} else {
|
||||
this.title = '编辑'
|
||||
this.form = Object.assign({}, row)
|
||||
}
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
close() {
|
||||
this.$refs['form'].resetFields()
|
||||
this.form = this.$options.data().form
|
||||
this.dialogFormVisible = false
|
||||
},
|
||||
save() {
|
||||
this.$refs['form'].validate(async (valid) => {
|
||||
if (valid) {
|
||||
const { msg } = await doEdit(this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.$emit('fetch-data')
|
||||
this.close()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
147
src/views/personnelManagement/menuManagement/index.vue
Normal file
147
src/views/personnelManagement/menuManagement/index.vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div class="menuManagement-container">
|
||||
<el-divider content-position="left">
|
||||
演示环境仅做基础功能展示,若想实现不同角色的真实菜单配置,需将settings.js路由加载模式改为all模式,由后端全面接管路由渲染与权限控制
|
||||
</el-divider>
|
||||
<el-row>
|
||||
<el-col :lg="4" :md="8" :sm="24" :xl="4" :xs="24">
|
||||
<el-tree :data="data" :default-expanded-keys="['root']" node-key="id" :props="defaultProps" @node-click="handleNodeClick" />
|
||||
</el-col>
|
||||
<el-col :lg="20" :md="16" :sm="24" :xl="20" :xs="24">
|
||||
<vab-query-form>
|
||||
<vab-query-form-top-panel :span="12">
|
||||
<el-button icon="el-icon-plus" type="primary" @click="handleEdit">添加</el-button>
|
||||
</vab-query-form-top-panel>
|
||||
</vab-query-form>
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
border
|
||||
:data="list"
|
||||
default-expand-all
|
||||
:element-loading-text="elementLoadingText"
|
||||
row-key="path"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<el-table-column label="name" prop="name" show-overflow-tooltip />
|
||||
<el-table-column label="路径" prop="path" show-overflow-tooltip />
|
||||
<el-table-column label="是否隐藏" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ row.hidden ? '是' : '否' }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否一直显示当前节点" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ row.alwaysShow ? '是' : '否' }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="vue文件路径" prop="component" show-overflow-tooltip />
|
||||
<el-table-column label="重定向" prop="redirect" show-overflow-tooltip />
|
||||
<el-table-column label="标题" prop="meta.title" show-overflow-tooltip />
|
||||
<el-table-column label="图标" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.meta">
|
||||
<vab-icon v-if="row.meta.icon" :icon="['fas', row.meta.icon]" />
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否固定" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.meta">
|
||||
{{ row.meta.affix ? '是' : '否' }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否无缓存" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.meta">
|
||||
{{ row.meta.noKeepAlive ? '是' : '否' }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="badge" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.meta">
|
||||
{{ row.meta.badge }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" show-overflow-tooltip width="200">
|
||||
<template #default="{ row }">
|
||||
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="text" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<edit ref="edit" @fetch-data="fetchData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getRouterList as getList } from '@/api/router'
|
||||
import { doDelete, getTree } from '@/api/menuManagement'
|
||||
import Edit from './components/MenuManagementEdit'
|
||||
|
||||
export default {
|
||||
name: 'MenuManagement',
|
||||
components: { Edit },
|
||||
data() {
|
||||
return {
|
||||
data: [],
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
},
|
||||
list: [],
|
||||
listLoading: true,
|
||||
elementLoadingText: '正在加载...',
|
||||
timeOutID: null,
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
const roleData = await getTree()
|
||||
this.data = roleData.data
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
clearTimeout(this.timeOutID)
|
||||
},
|
||||
methods: {
|
||||
handleEdit(row) {
|
||||
if (row.path) {
|
||||
this.$refs['edit'].showEdit(row)
|
||||
} else {
|
||||
this.$refs['edit'].showEdit()
|
||||
}
|
||||
},
|
||||
handleDelete(row) {
|
||||
if (row.id) {
|
||||
this.$baseConfirm('你确定要删除当前项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: row.id })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
}
|
||||
},
|
||||
async fetchData() {
|
||||
this.listLoading = true
|
||||
|
||||
const { data } = await getList()
|
||||
this.list = data
|
||||
this.timeOutID = setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 300)
|
||||
},
|
||||
handleNodeClick() {
|
||||
this.fetchData()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<el-dialog :title="title" :visible.sync="dialogFormVisible" width="500px" @close="close">
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="权限码" prop="permission">
|
||||
<el-input v-model="form.permission" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="desc">
|
||||
<el-input v-model="form.desc" autocomplete="off" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doEdit, doAdd } from '@/api/roleManagement'
|
||||
|
||||
export default {
|
||||
name: 'RoleManagementEdit',
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
form: {
|
||||
name: '',
|
||||
permission: '',
|
||||
desc: '',
|
||||
},
|
||||
rules: {
|
||||
permission: [{ required: true, trigger: 'blur', message: '请输入权限码' }],
|
||||
name: [{ required: true, trigger: 'blur', message: '请输入名称' }],
|
||||
},
|
||||
title: '',
|
||||
dialogFormVisible: false,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
showEdit(row) {
|
||||
if (!row) {
|
||||
this.title = '添加'
|
||||
} else {
|
||||
this.title = '编辑'
|
||||
this.form = {
|
||||
name: row.name,
|
||||
permission: row.permission,
|
||||
desc: row.desc,
|
||||
}
|
||||
this.id = row.id
|
||||
}
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
close() {
|
||||
this.$refs['form'].resetFields()
|
||||
this.form = this.$options.data().form
|
||||
this.dialogFormVisible = false
|
||||
},
|
||||
save() {
|
||||
this.$refs['form'].validate(async (valid) => {
|
||||
if (valid) {
|
||||
if (this.id) {
|
||||
const { msg } = await doEdit(this.id, this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
} else {
|
||||
const { msg } = await doAdd(this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
}
|
||||
this.$emit('fetch-data')
|
||||
this.close()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
133
src/views/personnelManagement/roleManagement/index.vue
Normal file
133
src/views/personnelManagement/roleManagement/index.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div class="roleManagement-container">
|
||||
<el-divider content-position="left">
|
||||
演示环境仅做基础功能展示,若想实现不同角色的真实菜单配置,需将settings.js路由加载模式改为all模式,由后端全面接管路由渲染与权限控制
|
||||
</el-divider>
|
||||
<vab-query-form>
|
||||
<vab-query-form-left-panel :span="12">
|
||||
<el-button icon="el-icon-plus" type="primary" @click="handleEdit">添加</el-button>
|
||||
<el-button icon="el-icon-delete" type="danger" @click="handleDelete">批量删除</el-button>
|
||||
</vab-query-form-left-panel>
|
||||
<vab-query-form-right-panel :span="12">
|
||||
<el-form :inline="true" :model="queryForm" @submit.native.prevent>
|
||||
<el-form-item>
|
||||
<el-input v-model.trim="queryForm.permission" clearable placeholder="请输入查询条件" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</vab-query-form-right-panel>
|
||||
</vab-query-form>
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" :element-loading-text="elementLoadingText" @selection-change="setSelectRows">
|
||||
<el-table-column show-overflow-tooltip type="selection" />
|
||||
<el-table-column label="名称" prop="name" show-overflow-tooltip />
|
||||
<el-table-column label="权限码" prop="permission" show-overflow-tooltip />
|
||||
<el-table-column label="描述" prop="desc" show-overflow-tooltip />
|
||||
<el-table-column label="操作" show-overflow-tooltip width="200">
|
||||
<template #default="{ row }">
|
||||
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="text" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="queryForm.pageNo"
|
||||
:layout="layout"
|
||||
:page-size="queryForm.pageSize"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
<edit ref="edit" @fetch-data="fetchData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doDelete, getList } from '@/api/roleManagement'
|
||||
import Edit from './components/RoleManagementEdit'
|
||||
|
||||
export default {
|
||||
name: 'RoleManagement',
|
||||
components: { Edit },
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true,
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
total: 0,
|
||||
selectRows: '',
|
||||
elementLoadingText: '正在加载...',
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
permission: '',
|
||||
},
|
||||
timeOutID: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
clearTimeout(this.timeOutID)
|
||||
},
|
||||
methods: {
|
||||
setSelectRows(val) {
|
||||
this.selectRows = val
|
||||
},
|
||||
handleEdit(row) {
|
||||
if (row.id) {
|
||||
this.$refs['edit'].showEdit(row)
|
||||
} else {
|
||||
this.$refs['edit'].showEdit()
|
||||
}
|
||||
},
|
||||
handleDelete(row) {
|
||||
if (row.id) {
|
||||
this.$baseConfirm('你确定要删除当前项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: [row.id] })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
if (this.selectRows.length > 0) {
|
||||
const ids = this.selectRows.map((item) => item.id).join()
|
||||
this.$baseConfirm('你确定要删除选中项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: ids.split(',') })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
this.$baseMessage('未选中任何行', 'error')
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.pageNo = val
|
||||
this.fetchData()
|
||||
},
|
||||
queryData() {
|
||||
this.queryForm.pageNo = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
this.listLoading = true
|
||||
const { data } = await getList(this.queryForm)
|
||||
this.list = data.list
|
||||
this.total = data.totalCount
|
||||
this.timeOutID = setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 300)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<el-dialog :title="title" :visible.sync="dialogFormVisible" width="500px" @close="close">
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules">
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input v-model.trim="form.username" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" prop="password">
|
||||
<el-input v-model.trim="form.password" autocomplete="off" type="password" />
|
||||
</el-form-item>
|
||||
<el-form-item label="昵称" prop="nickname">
|
||||
<el-input v-model.trim="form.nickname" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="权限" prop="permissions">
|
||||
<el-select v-model="form.permissions" multiple placeholder="请选择权限">
|
||||
<el-option v-for="item in permissionList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="应用" prop="appId">
|
||||
<el-select v-model="form.appId" placeholder="请选择应用">
|
||||
<el-option v-for="item in applicationList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="头像" prop="avatar">
|
||||
<single-upload
|
||||
style="width: 100px; height: 100px"
|
||||
upload-url="http://127.0.0.1:3999/management/api/common/upload"
|
||||
@upload-success="handleUploadSuccess"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doEdit } from '@/api/userManagement'
|
||||
import { getList } from '@/api/roleManagement'
|
||||
import { getList as getApplicationList } from '@/api/appManagement'
|
||||
import SingleUpload from '@/components/SingleUpload'
|
||||
export default {
|
||||
name: 'UserManagementEdit',
|
||||
components: { SingleUpload },
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
username: '',
|
||||
password: '',
|
||||
nickname: '',
|
||||
permissions: '',
|
||||
appId: '',
|
||||
},
|
||||
permissionList: [],
|
||||
applicationList: [],
|
||||
rules: {
|
||||
username: [{ required: true, trigger: 'blur', message: '请输入用户名' }],
|
||||
password: [{ required: true, trigger: 'blur', message: '请输入密码' }],
|
||||
permissions: [{ required: true, trigger: 'blur', message: '请选择权限' }],
|
||||
appId: [{ required: true, trigger: 'blur', message: '请选择应用' }],
|
||||
},
|
||||
title: '',
|
||||
dialogFormVisible: false,
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 100,
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchRoleData()
|
||||
this.fetchApplicationData()
|
||||
},
|
||||
methods: {
|
||||
showEdit(row) {
|
||||
if (!row) {
|
||||
this.title = '添加'
|
||||
} else {
|
||||
this.title = '编辑'
|
||||
this.form = Object.assign({}, row)
|
||||
}
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
close() {
|
||||
this.$refs['form'].resetFields()
|
||||
this.form = this.$options.data().form
|
||||
this.dialogFormVisible = false
|
||||
},
|
||||
save() {
|
||||
this.$refs['form'].validate(async (valid) => {
|
||||
if (valid) {
|
||||
const { msg } = await doEdit(this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.$emit('fetch-data')
|
||||
this.close()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
async fetchRoleData() {
|
||||
this.listLoading = true
|
||||
const { data } = await getList(this.queryForm)
|
||||
this.permissionList = data.list
|
||||
},
|
||||
async fetchApplicationData() {
|
||||
const { data } = await getApplicationList(this.queryForm)
|
||||
this.applicationList = data.list
|
||||
},
|
||||
handleUploadSuccess(url) {
|
||||
this.form.avatar = url
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
152
src/views/personnelManagement/userManagement/index.vue
Normal file
152
src/views/personnelManagement/userManagement/index.vue
Normal file
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<div class="userManagement-container">
|
||||
<vab-query-form>
|
||||
<vab-query-form-left-panel :span="12">
|
||||
<el-button icon="el-icon-plus" type="primary" @click="handleEdit">添加</el-button>
|
||||
<el-button icon="el-icon-delete" type="danger" @click="handleDelete">批量删除</el-button>
|
||||
</vab-query-form-left-panel>
|
||||
<vab-query-form-right-panel :span="12">
|
||||
<el-form :inline="true" :model="queryForm" @submit.native.prevent>
|
||||
<el-form-item>
|
||||
<el-input v-model.trim="queryForm.username" clearable placeholder="请输入用户名" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</vab-query-form-right-panel>
|
||||
</vab-query-form>
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" :element-loading-text="elementLoadingText" @selection-change="setSelectRows">
|
||||
<el-table-column show-overflow-tooltip type="selection" />
|
||||
<el-table-column align="center" label="头像" width="100">
|
||||
<template slot-scope="scope">
|
||||
<!-- 使用 show-overflow-tooltip 显示图片,并添加 tooltip -->
|
||||
<el-tooltip class="item" :content="scope.row.name" effect="dark" placement="top">
|
||||
<img alt="image" :src="scope.row.avatar" style="width: 50px; height: 50px; object-fit: cover; border-radius: 50%" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="用户名" prop="username" show-overflow-tooltip />
|
||||
<el-table-column align="center" label="APP" prop="appName" show-overflow-tooltip />
|
||||
|
||||
<el-table-column align="center" label="权限" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-tag v-for="(item, index) in row.permissionsName" :key="index">
|
||||
{{ item }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="修改时间" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ formatTime(row.updatedAt) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="操作" show-overflow-tooltip width="200">
|
||||
<template #default="{ row }">
|
||||
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="text" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="queryForm.pageNo"
|
||||
:layout="layout"
|
||||
:page-size="queryForm.pageSize"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
<edit ref="edit" @fetch-data="fetchData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doDelete, getList } from '@/api/userManagement'
|
||||
import Edit from './components/UserManagementEdit'
|
||||
import { formatTime } from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'UserManagement',
|
||||
components: { Edit },
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true,
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
total: 0,
|
||||
selectRows: '',
|
||||
elementLoadingText: '正在加载...',
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
username: '',
|
||||
},
|
||||
timeOutID: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
clearTimeout(this.timeOutID)
|
||||
},
|
||||
methods: {
|
||||
formatTime,
|
||||
setSelectRows(val) {
|
||||
this.selectRows = val
|
||||
},
|
||||
handleEdit(row) {
|
||||
if (row.id) {
|
||||
this.$refs['edit'].showEdit(row)
|
||||
} else {
|
||||
this.$refs['edit'].showEdit()
|
||||
}
|
||||
},
|
||||
handleDelete(row) {
|
||||
if (row.id) {
|
||||
this.$baseConfirm('你确定要删除当前项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: row.id })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
if (this.selectRows.length > 0) {
|
||||
const ids = this.selectRows.map((item) => item.id).join()
|
||||
this.$baseConfirm('你确定要删除选中项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
this.$baseMessage('未选中任何行', 'error')
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.pageNo = val
|
||||
this.fetchData()
|
||||
},
|
||||
queryData() {
|
||||
this.queryForm.pageNo = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
this.listLoading = true
|
||||
const { data } = await getList(this.queryForm)
|
||||
this.list = data.list
|
||||
this.total = data.totalCount
|
||||
this.timeOutID = setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 300)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
332
src/views/register/index.vue
Normal file
332
src/views/register/index.vue
Normal file
@@ -0,0 +1,332 @@
|
||||
<template>
|
||||
<div class="register-container">
|
||||
<el-row>
|
||||
<el-col :lg="16" :md="12" :sm="24" :xl="16" :xs="24">
|
||||
<div style="color: transparent">占位符</div>
|
||||
</el-col>
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="8" :xs="24">
|
||||
<el-form ref="registerForm" class="register-form" :model="form" :rules="registerRules" size="mini">
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model.trim="form.username"
|
||||
v-focus
|
||||
auto-complete="off"
|
||||
placeholder="请输入用户名"
|
||||
style="margin-top: 20px"
|
||||
type="text"
|
||||
>
|
||||
<vab-icon slot="prefix" :icon="['fas', 'user-alt']" />
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="phone">
|
||||
<el-input v-model.trim="form.phone" autocomplete="off" maxlength="11" placeholder="请输入手机号" show-word-limit type="text">
|
||||
<vab-icon slot="prefix" :icon="['fas', 'mobile-alt']" />
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="phoneCode" style="position: relative">
|
||||
<el-input v-model.trim="form.phoneCode" placeholder="手机验证码" type="text">
|
||||
<vab-icon slot="prefix" :icon="['fas', 'envelope-open']" />
|
||||
</el-input>
|
||||
<el-button class="show-pwd phone-code" :disabled="isGetphone" type="primary" @click="getPhoneCode">
|
||||
{{ phoneCode }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input v-model.trim="form.password" autocomplete="new-password" placeholder="设置密码" type="password">
|
||||
<vab-icon slot="prefix" :icon="['fas', 'unlock']" />
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="register-btn" type="primary" @click.native.prevent="handleReister">注册</el-button>
|
||||
<router-link to="/login">
|
||||
<div style="margin-top: 20px">登录</div>
|
||||
</router-link>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { isPassword, isPhone } from '@/utils/validate'
|
||||
import { register } from '@/api/user'
|
||||
|
||||
export default {
|
||||
username: 'Register',
|
||||
directives: {
|
||||
focus: {
|
||||
inserted(el) {
|
||||
el.querySelector('input').focus()
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const validateusername = (rule, value, callback) => {
|
||||
if ('' == value) {
|
||||
callback(new Error('用户名不能为空'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
const validatePassword = (rule, value, callback) => {
|
||||
if (!isPassword(value)) {
|
||||
callback(new Error('密码不能少于6位'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
const validatePhone = (rule, value, callback) => {
|
||||
if (!isPhone(value)) {
|
||||
callback(new Error('请输入正确的手机号'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
isGetphone: false,
|
||||
getPhoneIntval: null,
|
||||
phoneCode: '获取验证码',
|
||||
showRegister: false,
|
||||
nodeEnv: process.env.NODE_ENV,
|
||||
title: this.$baseTitle,
|
||||
form: {},
|
||||
registerRules: {
|
||||
username: [
|
||||
{ required: true, trigger: 'blur', message: '请输入用户名' },
|
||||
{ max: 20, trigger: 'blur', message: '最多不能超过20个字' },
|
||||
{ validator: validateusername, trigger: 'blur' },
|
||||
],
|
||||
phone: [
|
||||
{ required: true, trigger: 'blur', message: '请输入手机号码' },
|
||||
{ validator: validatePhone, trigger: 'blur' },
|
||||
],
|
||||
password: [
|
||||
{ required: true, trigger: 'blur', message: '请输入密码' },
|
||||
{ validator: validatePassword, trigger: 'blur' },
|
||||
],
|
||||
phoneCode: [{ required: true, trigger: 'blur', message: '请输入手机验证码' }],
|
||||
},
|
||||
loading: false,
|
||||
passwordType: 'password',
|
||||
}
|
||||
},
|
||||
created() {
|
||||
document.body.style.overflow = 'hidden'
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.body.style.overflow = 'auto'
|
||||
clearInterval(this.getPhoneIntval)
|
||||
this.getPhoneIntval = null
|
||||
},
|
||||
methods: {
|
||||
getPhoneCode() {
|
||||
if (!isPhone(this.form.phone)) {
|
||||
//this.$baseMessage('请输入手机号', 'error')
|
||||
this.$refs['registerForm'].validateField('phone')
|
||||
return
|
||||
}
|
||||
this.isGetphone = true
|
||||
let n = 60
|
||||
this.getPhoneIntval = setInterval(() => {
|
||||
if (n > 0) {
|
||||
n--
|
||||
this.phoneCode = `重新获取(${n}s)`
|
||||
} else {
|
||||
clearInterval(this.getPhoneIntval)
|
||||
this.getPhoneIntval = null
|
||||
this.phoneCode = '获取验证码'
|
||||
this.isGetphone = false
|
||||
}
|
||||
}, 1000)
|
||||
},
|
||||
handleReister() {
|
||||
this.$refs['registerForm'].validate(async (valid) => {
|
||||
if (valid) {
|
||||
const param = {
|
||||
username: this.form.username,
|
||||
phone: this.form.phone,
|
||||
password: this.form.password,
|
||||
phoneCode: this.form.phoneCode,
|
||||
}
|
||||
const { msg } = await register(param)
|
||||
this.$baseMessage(msg, 'success')
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.register-container {
|
||||
height: 100vh;
|
||||
background: url('~@/assets/login_images/background.jpg') center center fixed no-repeat;
|
||||
background-size: cover;
|
||||
|
||||
.title {
|
||||
font-size: 54px;
|
||||
font-weight: 500;
|
||||
color: rgba(14, 18, 26, 1);
|
||||
}
|
||||
|
||||
.title-tips {
|
||||
margin-top: 29px;
|
||||
font-size: 26px;
|
||||
font-weight: 400;
|
||||
color: rgba(14, 18, 26, 1);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.register-btn {
|
||||
display: inherit;
|
||||
width: 220px;
|
||||
height: 60px;
|
||||
margin-top: 5px;
|
||||
border: 0;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
.register-form {
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
margin: calc((100vh - 499px) / 2) 10% 10%;
|
||||
overflow: hidden;
|
||||
|
||||
.forget-password {
|
||||
width: 100%;
|
||||
margin-top: 40px;
|
||||
text-align: left;
|
||||
|
||||
.forget-password {
|
||||
width: 129px;
|
||||
height: 19px;
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
color: rgba(92, 102, 240, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.per-code {
|
||||
width: 100px;
|
||||
height: 36px;
|
||||
font-size: 20px;
|
||||
line-height: 36px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
background: #bbc1ce;
|
||||
}
|
||||
|
||||
.phone-code {
|
||||
width: 120px;
|
||||
height: 36px;
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
margin-bottom: 10px;
|
||||
font-size: $base-font-size-default;
|
||||
color: $base-color-white;
|
||||
|
||||
span {
|
||||
&:first-of-type {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.title-container {
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
margin: 0 auto 40px auto;
|
||||
font-size: 34px;
|
||||
font-weight: bold;
|
||||
color: $base-color-blue;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.svg-container {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
left: 15px;
|
||||
z-index: $base-z-index;
|
||||
font-size: 16px;
|
||||
color: #d7dee3;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.show-pwd {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
right: 25px;
|
||||
font-size: 16px;
|
||||
color: $base-font-color;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.el-form-item {
|
||||
padding-right: 0;
|
||||
margin: 20px 0;
|
||||
color: #454545;
|
||||
background: transparent;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 2px;
|
||||
|
||||
&__content {
|
||||
min-height: $base-input-height;
|
||||
line-height: $base-input-height;
|
||||
}
|
||||
|
||||
&__error {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 18px;
|
||||
font-size: $base-font-size-small;
|
||||
line-height: 18px;
|
||||
color: $base-color-red;
|
||||
}
|
||||
}
|
||||
|
||||
.el-input {
|
||||
box-sizing: border-box;
|
||||
|
||||
.el-input__count {
|
||||
.el-input__count-inner {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__prefix {
|
||||
left: 15px;
|
||||
line-height: 56px;
|
||||
|
||||
.svg-inline--fa {
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
height: 58px;
|
||||
padding-left: 45px;
|
||||
font-size: $base-font-size-default;
|
||||
line-height: 58px;
|
||||
color: $base-font-color;
|
||||
background: #f6f4fc;
|
||||
border: 0;
|
||||
caret-color: $base-font-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
16
src/views/test/index.vue
Normal file
16
src/views/test/index.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div class="test-container">
|
||||
<el-divider content-position="left">你可以在这里写demo</el-divider>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'Test',
|
||||
data() {
|
||||
return { show: true }
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
methods: {},
|
||||
}
|
||||
</script>
|
||||
20
src/views/vab/backToTop/index.vue
Normal file
20
src/views/vab/backToTop/index.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div class="back-to-top-container">
|
||||
<div v-for="(item, index) in 100" :key="index" style="padding: 20px">测试滚轮显示返回顶部-{{ index }}</div>
|
||||
<!-- <el-tooltip placement="top" content="返回顶部"><vab-back-to-top transition-name="fade" /></el-tooltip> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'BackToTop',
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.placeholder-container div {
|
||||
margin: 10px;
|
||||
}
|
||||
</style>
|
||||
176
src/views/vab/element/index.vue
Normal file
176
src/views/vab/element/index.vue
Normal file
@@ -0,0 +1,176 @@
|
||||
<template>
|
||||
<div class="element-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="18" :md="18" :sm="24" :xl="16" :xs="24">
|
||||
<el-button type="primary" @click="dialogVisible = !dialogVisible">element全部文档点这里</el-button>
|
||||
<el-dialog :fullscreen="true" title="element文档" :visible.sync="dialogVisible">
|
||||
<iframe class="element-iframe" frameborder="0" src="https://element.eleme.cn/#/zh-CN/component/installation"></iframe>
|
||||
</el-dialog>
|
||||
<el-divider content-position="left">
|
||||
Tag 标签
|
||||
<a href="https://element.eleme.cn/#/zh-CN/component/tag" target="_blank">文档</a>
|
||||
</el-divider>
|
||||
<el-tag>标签一</el-tag>
|
||||
<el-tag type="success">标签二</el-tag>
|
||||
<el-tag type="info">标签三</el-tag>
|
||||
<el-tag type="warning">标签四</el-tag>
|
||||
<el-tag type="danger">标签五</el-tag>
|
||||
<el-tag effect="dark">标签一</el-tag>
|
||||
<el-tag effect="dark" type="success">标签二</el-tag>
|
||||
<el-tag effect="dark" type="info">标签三</el-tag>
|
||||
<el-tag effect="dark" type="warning">标签四</el-tag>
|
||||
<el-tag effect="dark" type="danger">标签五</el-tag>
|
||||
|
||||
<el-divider content-position="left">
|
||||
进度条
|
||||
<a href="https://element.eleme.cn/#/zh-CN/component/progress" target="_blank">文档</a>
|
||||
</el-divider>
|
||||
<el-progress :percentage="50" />
|
||||
<el-progress :percentage="100" status="success" />
|
||||
<el-progress :percentage="100" status="warning" />
|
||||
<el-progress :percentage="50" status="exception" />
|
||||
<el-progress :percentage="70" :stroke-width="26" :text-inside="true" />
|
||||
<el-progress :percentage="100" status="success" :stroke-width="24" :text-inside="true" />
|
||||
<el-progress :percentage="80" status="warning" :stroke-width="22" :text-inside="true" />
|
||||
<el-progress :percentage="50" status="exception" :stroke-width="20" :text-inside="true" />
|
||||
<el-progress :percentage="0" type="circle" />
|
||||
<el-progress :percentage="25" type="circle" />
|
||||
<el-progress :percentage="100" status="success" type="circle" />
|
||||
<el-progress :percentage="70" status="warning" type="circle" />
|
||||
<el-progress :percentage="50" status="exception" type="circle" />
|
||||
|
||||
<el-divider content-position="left">
|
||||
按钮
|
||||
<a href="https://element.eleme.cn/#/zh-CN/component/button" target="_blank">文档</a>
|
||||
</el-divider>
|
||||
<el-button>默认按钮</el-button>
|
||||
<el-button type="primary">主要按钮</el-button>
|
||||
<el-button type="success">成功按钮</el-button>
|
||||
<el-button type="info">信息按钮</el-button>
|
||||
<el-button type="warning">警告按钮</el-button>
|
||||
<el-button type="danger">危险按钮</el-button>
|
||||
<el-button plain>朴素按钮</el-button>
|
||||
<el-button plain type="primary">主要按钮</el-button>
|
||||
<el-button plain type="success">成功按钮</el-button>
|
||||
<el-button plain type="info">信息按钮</el-button>
|
||||
<el-button plain type="warning">警告按钮</el-button>
|
||||
<el-button plain type="danger">危险按钮</el-button>
|
||||
<el-button round>圆角按钮</el-button>
|
||||
<el-button round type="primary">主要按钮</el-button>
|
||||
<el-button round type="success">成功按钮</el-button>
|
||||
<el-button round type="info">信息按钮</el-button>
|
||||
<el-button round type="warning">警告按钮</el-button>
|
||||
<el-button round type="danger">危险按钮</el-button>
|
||||
<el-button circle icon="el-icon-search" />
|
||||
<el-button circle icon="el-icon-edit" type="primary" />
|
||||
<el-button circle icon="el-icon-check" type="success" />
|
||||
<el-button circle icon="el-icon-message" type="info" />
|
||||
<el-button circle icon="el-icon-star-off" type="warning" />
|
||||
<el-button circle icon="el-icon-delete" type="danger" />
|
||||
<el-button disabled>默认按钮</el-button>
|
||||
<el-button disabled type="primary">主要按钮</el-button>
|
||||
<el-button disabled type="success">成功按钮</el-button>
|
||||
<el-button disabled type="info">信息按钮</el-button>
|
||||
<el-button disabled type="warning">警告按钮</el-button>
|
||||
<el-button disabled type="danger">危险按钮</el-button>
|
||||
<el-button icon="el-icon-edit" type="primary" />
|
||||
<el-button icon="el-icon-share" type="primary" />
|
||||
<el-button icon="el-icon-delete" type="primary" />
|
||||
<el-button icon="el-icon-search" type="primary">搜索</el-button>
|
||||
<el-button type="primary">
|
||||
上传
|
||||
<i class="el-icon-upload el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-button :loading="true" type="primary">加载中</el-button>
|
||||
|
||||
<el-divider content-position="left">
|
||||
文字链接
|
||||
<a href="https://element.eleme.cn/#/zh-CN/component/link" target="_blank">文档</a>
|
||||
</el-divider>
|
||||
<el-link href="https://element.eleme.io" target="_blank">默认链接</el-link>
|
||||
<el-link type="primary">主要链接</el-link>
|
||||
<el-link type="success">成功链接</el-link>
|
||||
<el-link type="warning">警告链接</el-link>
|
||||
<el-link type="danger">危险链接</el-link>
|
||||
<el-link type="info">信息链接</el-link>
|
||||
<el-link disabled>默认链接</el-link>
|
||||
<el-link disabled type="primary">主要链接</el-link>
|
||||
<el-link disabled type="success">成功链接</el-link>
|
||||
<el-link disabled type="warning">警告链接</el-link>
|
||||
<el-link disabled type="danger">危险链接</el-link>
|
||||
<el-link disabled type="info">信息链接</el-link>
|
||||
<el-link :underline="false">无下划线</el-link>
|
||||
<el-link>有下划线</el-link>
|
||||
<el-divider content-position="left">
|
||||
头像
|
||||
<a href="https://element.eleme.cn/#/zh-CN/component/avatar" target="_blank">文档</a>
|
||||
</el-divider>
|
||||
<el-avatar icon="el-icon-user-solid" />
|
||||
<el-divider content-position="left">
|
||||
页头
|
||||
<a href="https://element.eleme.cn/#/zh-CN/component/page-header" target="_blank">文档</a>
|
||||
</el-divider>
|
||||
<el-page-header content="详情页面" />
|
||||
<el-divider content-position="left">
|
||||
面包屑
|
||||
<a href="https://element.eleme.cn/#/zh-CN/component/breadcrumb" target="_blank">文档</a>
|
||||
</el-divider>
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item><a href="/">活动管理</a></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>活动列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>活动详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Element',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
methods: {},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.element-container {
|
||||
::v-deep {
|
||||
.el-dialog__wrapper {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.el-tag,
|
||||
.el-button,
|
||||
.el-link {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.el-progress {
|
||||
margin: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.element-iframe {
|
||||
position: absolute;
|
||||
top: 55px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 89vh;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
13
src/views/vab/errorLog/components/ErrorTest.vue
Normal file
13
src/views/vab/errorLog/components/ErrorTest.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<!-- js代码错误实时提醒测试 -->
|
||||
<div>{{ zxwk1998jiayou.zxwk1998jiayou }}</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ErrorTest',
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
24
src/views/vab/errorLog/index.vue
Normal file
24
src/views/vab/errorLog/index.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<div class="errorLog-container">
|
||||
<el-divider content-position="left">这里会在顶部navbar上模拟一个控制台错误日志</el-divider>
|
||||
<el-button type="primary" @click="handleError">点击模拟一个zxwk1998jiayou的错误</el-button>
|
||||
<error-test v-if="show" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ErrorTest from './components/ErrorTest'
|
||||
|
||||
export default {
|
||||
name: 'ErrorLog',
|
||||
components: { ErrorTest },
|
||||
data() {
|
||||
return { show: false }
|
||||
},
|
||||
methods: {
|
||||
handleError() {
|
||||
this.show = true
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
97
src/views/vab/form/index.vue
Normal file
97
src/views/vab/form/index.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="form-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="8" :xs="24">
|
||||
<el-form ref="ruleForm" class="demo-ruleForm" label-width="100px" :model="ruleForm" :rules="rules">
|
||||
<el-form-item label="活动名称" prop="name">
|
||||
<el-input v-model="ruleForm.name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="活动区域" prop="region">
|
||||
<el-select v-model="ruleForm.region" placeholder="请选择活动区域">
|
||||
<el-option label="区域一" value="shanghai" />
|
||||
<el-option label="区域二" value="beijing" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="即时配送" prop="delivery">
|
||||
<el-switch v-model="ruleForm.delivery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="活动性质" prop="type">
|
||||
<el-checkbox-group v-model="ruleForm.type">
|
||||
<el-checkbox label="美食/餐厅线上活动" name="type" />
|
||||
<el-checkbox label="地推活动" name="type" />
|
||||
<el-checkbox label="线下主题活动" name="type" />
|
||||
<el-checkbox label="单纯品牌曝光" name="type" />
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="特殊资源" prop="resource">
|
||||
<el-radio-group v-model="ruleForm.resource">
|
||||
<el-radio label="线上品牌商赞助" />
|
||||
<el-radio label="线下场地免费" />
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动形式" prop="desc">
|
||||
<el-input v-model="ruleForm.desc" type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
|
||||
<el-button @click="resetForm('ruleForm')">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Form',
|
||||
data() {
|
||||
return {
|
||||
ruleForm: {
|
||||
name: '',
|
||||
region: '',
|
||||
delivery: false,
|
||||
type: [],
|
||||
resource: '',
|
||||
desc: '',
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: '请输入活动名称', trigger: 'blur' },
|
||||
{
|
||||
min: 3,
|
||||
max: 5,
|
||||
message: '长度在 3 到 5 个字符',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
region: [{ required: true, message: '请选择活动区域', trigger: 'change' }],
|
||||
type: [
|
||||
{
|
||||
type: 'array',
|
||||
required: true,
|
||||
message: '请至少选择一个活动性质',
|
||||
trigger: 'change',
|
||||
},
|
||||
],
|
||||
resource: [{ required: true, message: '请选择活动资源', trigger: 'change' }],
|
||||
desc: [{ required: true, message: '请填写活动形式', trigger: 'blur' }],
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitForm(formName) {
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
alert('submit!')
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
139
src/views/vab/icon/colorfulIcon.vue
Normal file
139
src/views/vab/icon/colorfulIcon.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div class="colorful-icon-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-divider content-position="left">多彩图标在演示环境中使用的是cdn加速服务,开发时需存储到本地,点击图标即可复制源码</el-divider>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form :inline="true" label-width="80px" @submit.native.prevent>
|
||||
<el-form-item label="图标名称">
|
||||
<el-input v-model="queryForm.title" />
|
||||
</el-form-item>
|
||||
<el-form-item label-width="0">
|
||||
<el-button native-type="submit" type="primary" @click="queryData">搜索</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<!-- <el-form-item label-width="0">
|
||||
<el-input :value="copyText" type="text"></el-input>
|
||||
</el-form-item>-->
|
||||
</el-form>
|
||||
</el-col>
|
||||
|
||||
<el-col v-for="(item, index) in queryIcon" :key="index" :lg="2" :md="3" :sm="8" :xl="2" :xs="6">
|
||||
<el-card shadow="hover" style="cursor: pointer" @click.native="handleCopyIcon(index, $event)">
|
||||
<vab-colorful-icon :icon-class="`https://gcore.jsdelivr.net/gh/zxwk1998/zx-colorful-icon@master/${item}.svg`" />
|
||||
</el-card>
|
||||
<div class="icon-text">
|
||||
{{ item }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-pagination
|
||||
:background="background"
|
||||
:current-page="queryForm.pageNo"
|
||||
:layout="layout"
|
||||
:page-size="queryForm.pageSize"
|
||||
:page-sizes="[72, 144, 216, 288]"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getIconList } from '@/api/colorfulIcon'
|
||||
import clip from '@/utils/clipboard'
|
||||
|
||||
export default {
|
||||
name: 'ColorfulIcon',
|
||||
data() {
|
||||
return {
|
||||
copyText: '',
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
total: 0,
|
||||
background: true,
|
||||
height: 0,
|
||||
selectRows: '',
|
||||
elementLoadingText: '正在加载...',
|
||||
queryIcon: [],
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 72,
|
||||
title: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.pageNo = val
|
||||
this.fetchData()
|
||||
},
|
||||
queryData() {
|
||||
this.queryForm.pageNo = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
const { data, totalCount } = await getIconList(this.queryForm)
|
||||
this.queryIcon = data
|
||||
this.allIcon = data
|
||||
this.total = totalCount
|
||||
},
|
||||
handleCopyIcon(index, event) {
|
||||
//const copyText = `<vab-colorful-icon icon-class="https://gcore.jsdelivr.net/gh/zxwk1998/zx-colorful-icon@master/${this.queryIcon[index]}.svg" />`;
|
||||
const copyText = `<vab-colorful-icon icon-class="${this.queryIcon[index]}" />`
|
||||
this.copyText = copyText
|
||||
clip(copyText, event)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.colorful-icon-container {
|
||||
::v-deep {
|
||||
.el-card__body {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
|
||||
svg:not(:root) {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: $base-color-gray;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
pointer-events: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.svg-external-icon {
|
||||
width: 20px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-text {
|
||||
height: 30px;
|
||||
margin-top: -15px;
|
||||
overflow: hidden;
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
128
src/views/vab/icon/index.vue
Normal file
128
src/views/vab/icon/index.vue
Normal file
@@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<div class="icon-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-divider content-position="left">点击图标即可复制源码</el-divider>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form :inline="true" label-width="80px" @submit.native.prevent>
|
||||
<el-form-item label="图标名称">
|
||||
<el-input v-model="queryForm.title" />
|
||||
</el-form-item>
|
||||
<el-form-item label-width="0">
|
||||
<el-button native-type="submit" type="primary" @click="queryData">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
|
||||
<el-col v-for="(item, index) in queryIcon" :key="index" :lg="2" :md="3" :sm="8" :xl="2" :xs="6">
|
||||
<el-card shadow="hover" style="cursor: pointer" @click.native="handleCopyIcon(index, $event)">
|
||||
<vab-icon :icon="['fas', item]" />
|
||||
</el-card>
|
||||
<div class="icon-text">
|
||||
{{ item }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-pagination
|
||||
:background="background"
|
||||
:current-page="queryForm.pageNo"
|
||||
:layout="layout"
|
||||
:page-size="queryForm.pageSize"
|
||||
:page-sizes="[72, 144, 216, 288]"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import clip from '@/utils/clipboard'
|
||||
import { getIconList } from '@/api/icon'
|
||||
|
||||
export default {
|
||||
name: 'AwesomeIcon',
|
||||
data() {
|
||||
return {
|
||||
copyText: '',
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
total: 0,
|
||||
background: true,
|
||||
height: 0,
|
||||
selectRows: '',
|
||||
elementLoadingText: '正在加载...',
|
||||
queryIcon: [],
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 72,
|
||||
title: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.pageNo = val
|
||||
this.fetchData()
|
||||
},
|
||||
queryData() {
|
||||
this.queryForm.pageNo = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
const { data, totalCount } = await getIconList(this.queryForm)
|
||||
this.queryIcon = data
|
||||
this.allIcon = data
|
||||
this.total = totalCount
|
||||
},
|
||||
handleCopyIcon(index, event) {
|
||||
const copyText = `<vab-icon :icon="['fas', '${this.queryIcon[index]}']"></vab-icon>`
|
||||
this.copyText = copyText
|
||||
clip(copyText, event)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.icon-container {
|
||||
::v-deep {
|
||||
.el-card__body {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
|
||||
svg:not(:root).svg-inline--fa {
|
||||
font-size: 18px;
|
||||
color: $base-color-gray;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
pointer-events: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-text {
|
||||
height: 30px;
|
||||
margin-top: -15px;
|
||||
overflow: hidden;
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
63
src/views/vab/loading/index.vue
Normal file
63
src/views/vab/loading/index.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div class="loading-container">
|
||||
<el-divider content-position="left">传统loading</el-divider>
|
||||
<el-button type="primary" @click="handleLoading()">默认效果</el-button>
|
||||
<el-button type="primary" @click="handleLoading(1)">效果1</el-button>
|
||||
<el-button type="primary" @click="handleLoading(2)">效果2</el-button>
|
||||
<el-button type="primary" @click="handleLoading(3)">效果3</el-button>
|
||||
<el-button type="primary" @click="handleLoading(4)">效果4</el-button>
|
||||
<el-button type="primary" @click="handleLoading(5)">效果5</el-button>
|
||||
<el-button type="primary" @click="handleLoading(6)">效果6</el-button>
|
||||
<el-button type="primary" @click="handleLoading(7)">效果7</el-button>
|
||||
<el-button type="primary" @click="handleLoading(8)">效果8</el-button>
|
||||
<el-button type="primary" @click="handleLoading(9)">效果9</el-button>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<el-divider content-position="left">多彩loading</el-divider>
|
||||
<el-button type="primary" @click="handleColorfullLoading(1)">效果1</el-button>
|
||||
<el-button type="primary" @click="handleColorfullLoading(2)">效果2</el-button>
|
||||
<el-button type="primary" @click="handleColorfullLoading(3)">效果3</el-button>
|
||||
<el-button type="primary" @click="handleColorfullLoading(4)">效果4</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Loading',
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
handleLoading(index) {
|
||||
const Loading = this.$baseLoading(index)
|
||||
setTimeout(() => {
|
||||
Loading.close()
|
||||
}, 3000)
|
||||
},
|
||||
handleColorfullLoading(index) {
|
||||
const Loading = this.$baseColorfullLoading(index)
|
||||
setTimeout(() => {
|
||||
Loading.close()
|
||||
}, 3000)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.loading-container {
|
||||
::v-deep {
|
||||
.el-button {
|
||||
margin-top: 10px;
|
||||
margin-right: 10px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.el-button + .el-button {
|
||||
margin-right: 10px;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
229
src/views/vab/lodash/index.vue
Normal file
229
src/views/vab/lodash/index.vue
Normal file
@@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<div class="lodash-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-card shadow="hover">
|
||||
<el-link href="https://www.lodashjs.com/" target="_blank" type="primary">lodashjs官网</el-link>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>去除数组array中的最后一个元素</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.initial([1, 2, 3])
|
||||
<br />
|
||||
// => [1, 2]
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>返回数组 array的第一个元素</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.head([1, 2, 3])
|
||||
<br />
|
||||
// => 1
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>合并数组</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.concat([1],[2])
|
||||
<br />
|
||||
// => [1,2]
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>左切片</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.drop([1, 2, 3],2切除的数量)
|
||||
<br />
|
||||
// => [3]
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>右切片</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.dropRight([1, 2, 3],2切除的数量)
|
||||
<br />
|
||||
// => [1]
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>修改拼接</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.join(['a', 'b', 'c'], '~');
|
||||
<br />
|
||||
// => 'a~b~c'
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>获取数组最后一个元素</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.last(['a', 'b', 'c']);
|
||||
<br />
|
||||
// => 'c'
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>数组去重</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.uniq(['a', 'b', 'a']);
|
||||
<br />
|
||||
// => ['a','b']
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>获取数组的最大值</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.max([4, 2, 8, 6])
|
||||
<br />
|
||||
// => 8
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>获取数组的最小值</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.min([4, 2, 8, 6])
|
||||
<br />
|
||||
// => 2
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>四舍五入(保留任意位小数)</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.round(4.006,2保持几位小数)
|
||||
<br />
|
||||
// => 4.01
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>数组内数据相加</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.sum([4, 2, 8, 6])
|
||||
<br />
|
||||
// => 20
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>返回随机数</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.random(0, 5)
|
||||
<br />
|
||||
// => 0到5任意数
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>返回数组内的随机数</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.sample([1, 2, 3, 4])
|
||||
<br />
|
||||
// => 数组1到4任意数
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24">
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>事件防抖动</span>
|
||||
</div>
|
||||
<div class="lodash-content">
|
||||
this.$baseLodash.debounce(@click的事件,延迟的毫秒数)
|
||||
<br />
|
||||
// => 点击后多久不可以点击
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Lodash',
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
methods: {},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.lodash-container {
|
||||
text-align: left;
|
||||
|
||||
::v-deep {
|
||||
.lodash-content {
|
||||
min-height: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
77
src/views/vab/more/index.vue
Normal file
77
src/views/vab/more/index.vue
Normal file
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="more-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="8" :md="24" :sm="24" :xl="8" :xs="24">
|
||||
<el-card>
|
||||
<div slot="header">
|
||||
开源版本
|
||||
<el-button style="float: right; padding: 3px 0" type="text">永久免费 个人/商业使用</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<ul>
|
||||
<li>永久开源免费,支持横纵布局切换</li>
|
||||
<li>
|
||||
保留浏览器控制台打印即可免费商用,页面中的作者信息可全部去除,无需保留,可快速入手框架,包含打包优化,公共外框布局layout本地化及自定义教程,如需自定义版权及作者信息¥299(自愿原则)
|
||||
</li>
|
||||
<li>
|
||||
开源地址
|
||||
<a href="https://github.com/zxwk1998/vue-admin-better" target="_blank">如果有幸帮到了你,麻烦给个star</a>
|
||||
</li>
|
||||
<li>提供讨论群专属文档,QQ群 972435319、1139183756</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="8" :md="24" :sm="24" :xl="8" :xs="24">
|
||||
<el-card>
|
||||
<div slot="header">
|
||||
VIP群
|
||||
<el-button style="float: right; padding: 3px 0" type="text">¥100(2021年1月起不再提供此服务)</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<ul>
|
||||
<li>为避免引起误解,不再针对开源用户提供付费vip群</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'More',
|
||||
components: {},
|
||||
data() {
|
||||
return { nodeEnv: process.env.NODE_ENV }
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
methods: {},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.more-container {
|
||||
::v-deep {
|
||||
.el-card__body {
|
||||
> div {
|
||||
min-height: 220px;
|
||||
padding: 20px;
|
||||
|
||||
> ul {
|
||||
> li {
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
> img {
|
||||
display: block;
|
||||
margin: 40px auto;
|
||||
border: 1px solid #dedede;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
7
src/views/vab/nested/menu1/index.vue
Normal file
7
src/views/vab/nested/menu1/index.vue
Normal file
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div class="menu1-container">
|
||||
<el-alert :closable="false" title="嵌套路由 1" type="success">
|
||||
<router-view />
|
||||
</el-alert>
|
||||
</div>
|
||||
</template>
|
||||
13
src/views/vab/nested/menu1/menu1-1/index.vue
Normal file
13
src/views/vab/nested/menu1/menu1-1/index.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div class="menu1-1-container">
|
||||
<el-alert :closable="false" title="嵌套路由 1-1" type="success">
|
||||
<router-view />
|
||||
</el-alert>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
[class*='-container'] {
|
||||
padding: 15px;
|
||||
background: $base-color-white;
|
||||
}
|
||||
</style>
|
||||
11
src/views/vab/nested/menu1/menu1-1/menu1-1-1/index.vue
Normal file
11
src/views/vab/nested/menu1/menu1-1/menu1-1-1/index.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div class="menu1-1-1-container">
|
||||
<el-alert :closable="false" title="嵌套路由 1-1-1" type="success" />
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
[class*='-container'] {
|
||||
padding: 15px;
|
||||
background: $base-color-white;
|
||||
}
|
||||
</style>
|
||||
121
src/views/vab/permissions/index.vue
Normal file
121
src/views/vab/permissions/index.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="permissions-container">
|
||||
<el-divider content-position="left">intelligence模式,前端根据permissions拦截路由(演示环境,默认使用此方案)</el-divider>
|
||||
|
||||
<el-form ref="form" :inline="true" :model="form">
|
||||
<el-form-item label="切换账号">
|
||||
<el-radio-group v-model="form.account">
|
||||
<el-radio label="admin">admin</el-radio>
|
||||
<el-radio label="editor">editor</el-radio>
|
||||
<el-radio label="test">test</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleChangePermission">切换权限</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="当前账号拥有的权限">
|
||||
{{ JSON.stringify(permissions) }}
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-divider content-position="left">按钮级权限演示</el-divider>
|
||||
<el-button v-permissions="['admin']" type="primary">我是拥有["admin"]权限的按钮</el-button>
|
||||
<el-button v-permissions="['editor']" type="primary">我是拥有["editor"]权限的按钮</el-button>
|
||||
<el-button v-permissions="['test']" type="primary">我是拥有["test"]权限的按钮</el-button>
|
||||
<br />
|
||||
<br />
|
||||
<el-divider content-position="left">all模式,路由以及view文件引入全部交给后端(权限复杂,且随时变更,建议使用此方案)</el-divider>
|
||||
<p>
|
||||
settings.js配置authentication为all即可完全交由后端控制,mock中有后端接口示例,权限繁琐,有几十种权限的项目直接用这种,
|
||||
由于演示环境是mock数据模拟,可能无法展现此功能的配置,只做如下展示,便于您的理解
|
||||
</p>
|
||||
<br />
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="12" :md="12" :sm="24" :xl="12" :xs="24">
|
||||
<el-table
|
||||
border
|
||||
:data="tableData"
|
||||
default-expand-all
|
||||
row-key="path"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<el-table-column label="name" prop="name" show-overflow-tooltip />
|
||||
<el-table-column label="path" prop="path" show-overflow-tooltip />
|
||||
<el-table-column label="component" prop="component" show-overflow-tooltip />
|
||||
<el-table-column label="redirect" prop="redirect" show-overflow-tooltip />
|
||||
<el-table-column label="标题" prop="meta.title" show-overflow-tooltip />
|
||||
<el-table-column label="图标" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.meta">
|
||||
<vab-icon v-if="row.meta.icon" :icon="['fas', row.meta.icon]" />
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否固定" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.meta">
|
||||
{{ row.meta.affix }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否无缓存" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.meta">
|
||||
{{ row.meta.noKeepAlive }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="badge" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.meta">
|
||||
{{ row.meta.badge }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { tokenTableName } from '@/config'
|
||||
import { getRouterList } from '@/api/router'
|
||||
|
||||
export default {
|
||||
name: 'Permissions',
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
account: '',
|
||||
},
|
||||
tableData: [],
|
||||
res: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
username: 'user/username',
|
||||
permissions: 'user/permissions',
|
||||
}),
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
mounted() {
|
||||
this.form.account = this.username
|
||||
},
|
||||
methods: {
|
||||
handleChangePermission() {
|
||||
localStorage.setItem(tokenTableName, `${this.form.account}-accessToken`)
|
||||
location.reload()
|
||||
},
|
||||
async fetchData() {
|
||||
const res = await getRouterList()
|
||||
this.tableData = res.data
|
||||
this.res = res
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
70
src/views/vab/table/components/TableEdit.vue
Normal file
70
src/views/vab/table/components/TableEdit.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<el-dialog :title="title" :visible.sync="dialogFormVisible" width="500px" @close="close">
|
||||
<el-form ref="form" label-width="80px" :model="form" :rules="rules">
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input v-model.trim="form.title" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="作者" prop="author">
|
||||
<el-input v-model.trim="form.author" autocomplete="off" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">取 消</el-button>
|
||||
<el-button type="primary" @click="save">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doEdit } from '@/api/table'
|
||||
|
||||
export default {
|
||||
name: 'TableEdit',
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
title: '',
|
||||
author: '',
|
||||
},
|
||||
rules: {
|
||||
title: [{ required: true, trigger: 'blur', message: '请输入标题' }],
|
||||
author: [{ required: true, trigger: 'blur', message: '请输入作者' }],
|
||||
},
|
||||
title: '',
|
||||
dialogFormVisible: false,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
showEdit(row) {
|
||||
if (!row) {
|
||||
this.title = '添加'
|
||||
} else {
|
||||
this.title = '编辑'
|
||||
this.form = Object.assign({}, row)
|
||||
}
|
||||
this.dialogFormVisible = true
|
||||
},
|
||||
close() {
|
||||
this.$refs['form'].resetFields()
|
||||
this.form = this.$options.data().form
|
||||
this.dialogFormVisible = false
|
||||
this.$emit('fetch-data')
|
||||
},
|
||||
save() {
|
||||
this.$refs['form'].validate(async (valid) => {
|
||||
if (valid) {
|
||||
const { msg } = await doEdit(this.form)
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.$refs['form'].resetFields()
|
||||
this.dialogFormVisible = false
|
||||
this.$emit('fetch-data')
|
||||
this.form = this.$options.data().form
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
220
src/views/vab/table/index.vue
Normal file
220
src/views/vab/table/index.vue
Normal file
@@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<div class="table-container">
|
||||
<vab-query-form>
|
||||
<vab-query-form-left-panel>
|
||||
<el-button icon="el-icon-plus" type="primary" @click="handleAdd">添加</el-button>
|
||||
<el-button icon="el-icon-delete" type="danger" @click="handleDelete">删除</el-button>
|
||||
<el-button type="primary" @click="testMessage">baseMessage</el-button>
|
||||
<el-button type="primary" @click="testALert">baseAlert</el-button>
|
||||
<el-button type="primary" @click="testConfirm">baseConfirm</el-button>
|
||||
<el-button type="primary" @click="testNotify">baseNotify</el-button>
|
||||
</vab-query-form-left-panel>
|
||||
<vab-query-form-right-panel>
|
||||
<el-form ref="form" :inline="true" :model="queryForm" @submit.native.prevent>
|
||||
<el-form-item>
|
||||
<el-input v-model="queryForm.title" placeholder="标题" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="el-icon-search" native-type="submit" type="primary" @click="handleQuery">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</vab-query-form-right-panel>
|
||||
</vab-query-form>
|
||||
|
||||
<el-table
|
||||
ref="tableSort"
|
||||
v-loading="listLoading"
|
||||
:data="list"
|
||||
:element-loading-text="elementLoadingText"
|
||||
:height="height"
|
||||
@selection-change="setSelectRows"
|
||||
@sort-change="tableSortChange"
|
||||
>
|
||||
<el-table-column show-overflow-tooltip type="selection" width="55" />
|
||||
<el-table-column label="序号" show-overflow-tooltip width="95">
|
||||
<template #default="scope">
|
||||
{{ scope.$index + 1 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="标题" prop="title" show-overflow-tooltip />
|
||||
<el-table-column label="作者" prop="author" show-overflow-tooltip />
|
||||
<el-table-column label="头像" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-image v-if="imgShow" :preview-src-list="imageList" :src="row.img" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="点击量" prop="pageViews" show-overflow-tooltip sortable />
|
||||
<el-table-column label="状态" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-tooltip class="item" :content="row.status" effect="dark" placement="top-start">
|
||||
<el-tag :type="row.status | statusFilter">
|
||||
{{ row.status }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="时间" prop="datetime" show-overflow-tooltip width="200" />
|
||||
<el-table-column label="操作" show-overflow-tooltip width="180px">
|
||||
<template #default="{ row }">
|
||||
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="text" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
:background="background"
|
||||
:current-page="queryForm.pageNo"
|
||||
:layout="layout"
|
||||
:page-size="queryForm.pageSize"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
<table-edit ref="edit" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { doDelete, getList } from '@/api/table'
|
||||
import TableEdit from './components/TableEdit'
|
||||
|
||||
export default {
|
||||
name: 'ComprehensiveTable',
|
||||
components: {
|
||||
TableEdit,
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'gray',
|
||||
deleted: 'danger',
|
||||
}
|
||||
return statusMap[status]
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
imgShow: true,
|
||||
list: [],
|
||||
imageList: [],
|
||||
listLoading: true,
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
total: 0,
|
||||
background: true,
|
||||
selectRows: '',
|
||||
elementLoadingText: '正在加载...',
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
title: '',
|
||||
},
|
||||
timeOutID: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
height() {
|
||||
return this.$baseTableHeight()
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearTimeout(this.timeOutID)
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
tableSortChange() {
|
||||
const imageList = []
|
||||
this.$refs.tableSort.tableData.forEach((item, index) => {
|
||||
imageList.push(item.img)
|
||||
})
|
||||
this.imageList = imageList
|
||||
},
|
||||
setSelectRows(val) {
|
||||
this.selectRows = val
|
||||
},
|
||||
handleAdd() {
|
||||
this.$refs['edit'].showEdit()
|
||||
},
|
||||
handleEdit(row) {
|
||||
this.$refs['edit'].showEdit(row)
|
||||
},
|
||||
handleDelete(row) {
|
||||
if (row.id) {
|
||||
this.$baseConfirm('你确定要删除当前项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: row.id })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
if (this.selectRows.length > 0) {
|
||||
const ids = this.selectRows.map((item) => item.id).join()
|
||||
this.$baseConfirm('你确定要删除选中项吗', null, async () => {
|
||||
const { msg } = await doDelete({ ids: ids })
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.fetchData()
|
||||
})
|
||||
} else {
|
||||
this.$baseMessage('未选中任何行', 'error')
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.pageNo = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleQuery() {
|
||||
this.queryForm.pageNo = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
this.listLoading = true
|
||||
const { data, totalCount } = await getList(this.queryForm)
|
||||
this.list = data
|
||||
const imageList = []
|
||||
data.forEach((item, index) => {
|
||||
imageList.push(item.img)
|
||||
})
|
||||
this.imageList = imageList
|
||||
this.total = totalCount
|
||||
this.timeOutID = setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 500)
|
||||
},
|
||||
testMessage() {
|
||||
this.$baseMessage('test1', 'success')
|
||||
},
|
||||
testALert() {
|
||||
this.$baseAlert('11')
|
||||
this.$baseAlert('11', '自定义标题', () => {
|
||||
/* 可以写回调; */
|
||||
})
|
||||
this.$baseAlert('11', null, () => {
|
||||
/* 可以写回调; */
|
||||
})
|
||||
},
|
||||
testConfirm() {
|
||||
this.$baseConfirm(
|
||||
'你确定要执行该操作?',
|
||||
null,
|
||||
() => {
|
||||
/* 可以写回调; */
|
||||
},
|
||||
() => {
|
||||
/* 可以写回调; */
|
||||
}
|
||||
)
|
||||
},
|
||||
testNotify() {
|
||||
this.$baseNotify('测试消息提示', 'test', 'success', 'bottom-right')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
440
src/views/vab/tree/index.vue
Normal file
440
src/views/vab/tree/index.vue
Normal file
@@ -0,0 +1,440 @@
|
||||
<template>
|
||||
<div class="tree-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="6" :md="24" :sm="24" :xl="6" :xs="24">
|
||||
<el-divider content-position="left">常规树</el-divider>
|
||||
<el-input v-model="filterText" placeholder="输入关键字过滤" />
|
||||
<el-tree
|
||||
ref="demoTree"
|
||||
class="vab-filter-tree"
|
||||
:data="data2"
|
||||
:default-checked-keys="defaultCheckedKeys"
|
||||
:default-expanded-keys="defaultExpendedKeys"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
:highlight-current="true"
|
||||
node-key="id"
|
||||
:props="defaultProps"
|
||||
show-checkbox
|
||||
@check="checkNode"
|
||||
@node-click="nodeClick"
|
||||
@node-collapse="nodeCollapse"
|
||||
@node-expand="nodeExpand"
|
||||
>
|
||||
<template #defalut="{ node, data }" class="vab-custom-tree-node">
|
||||
<span class="vab-tree-item">
|
||||
<i v-if="node.data.rank == 4" class="el-icon-s-custom"></i>
|
||||
{{ node.label }}
|
||||
</span>
|
||||
<span class="vab-tree-options">
|
||||
<a v-if="node.data.rank !== 4" class="vab-tree-btn" title="添加" @click="() => append(node, data, 0)">
|
||||
<i class="el-icon-plus"></i>
|
||||
</a>
|
||||
<a class="vab-tree-btn" title="编辑" @click="() => edit(node, data, 1)">
|
||||
<i class="el-icon-edit"></i>
|
||||
</a>
|
||||
<a v-if="node.data.rank !== 1" class="vab-tree-btn" title="刪除" @click="() => remove(node, data)">
|
||||
<i class="el-icon-delete"></i>
|
||||
</a>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="24" :sm="24" :xl="6" :xs="24">
|
||||
<el-divider content-position="left">懒加载树</el-divider>
|
||||
<el-input v-model.lazy="keyW" class="input-with-select" placeholder="请输入内容" :value="keyW" @keyup.enter.native="showTreeList" />
|
||||
<div v-show="isShow" class="blur-tree">
|
||||
<el-tree
|
||||
ref="treeFilter"
|
||||
class="vab-filter-tree"
|
||||
:data="filterDevLlist"
|
||||
default-expand-all
|
||||
:expand-on-click-node="false"
|
||||
highlight-current
|
||||
node-key="indexCode"
|
||||
:props="defaultProps"
|
||||
@node-click="nodeClick"
|
||||
>
|
||||
<template #defalut="{ node }" class="vab-custom-tree-node">
|
||||
<span class="vab-tree-item">
|
||||
<i v-if="node.data.rank == 4" class="el-icon-s-custom"></i>
|
||||
{{ node.label }}
|
||||
</span>
|
||||
<span class="vab-tree-options">
|
||||
<a v-if="node.data.rank !== 4" class="vab-tree-btn" title="添加">
|
||||
<i class="el-icon-plus"></i>
|
||||
</a>
|
||||
<a class="vab-tree-btn" title="编辑">
|
||||
<i class="el-icon-edit"></i>
|
||||
</a>
|
||||
<a v-if="node.data.rank !== 1" class="vab-tree-btn" title="刪除">
|
||||
<i class="el-icon-delete"></i>
|
||||
</a>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
<div v-show="!isShow" class="el-tree-wrap">
|
||||
<el-tree
|
||||
ref="tree"
|
||||
v-loading="loading"
|
||||
class="vab-filter-tree"
|
||||
:expand-on-click-node="false"
|
||||
highlight-current
|
||||
lazy
|
||||
:load="loadNode"
|
||||
node-key="indexCode"
|
||||
:props="defaultProps"
|
||||
@node-click="nodeClick"
|
||||
>
|
||||
<template #defalut="{ node }" class="vab-custom-tree-node">
|
||||
<span class="vab-tree-item">
|
||||
<i v-if="node.data.rank == 4" class="el-icon-s-custom"></i>
|
||||
{{ node.label }}
|
||||
</span>
|
||||
<span class="vab-tree-options">
|
||||
<!-- <a v-if="node.data.rank !== 4" class="vab-tree-btn" title="添加""><i class="el-icon-plus"></i></a> -->
|
||||
<a class="vab-tree-btn" title="编辑">
|
||||
<i class="el-icon-edit"></i>
|
||||
</a>
|
||||
<a v-if="node.data.rank !== 1" class="vab-tree-btn" title="刪除">
|
||||
<i class="el-icon-delete"></i>
|
||||
</a>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="24" :sm="24" :xl="6" :xs="24">
|
||||
<el-divider content-position="left">单选树</el-divider>
|
||||
<el-select
|
||||
ref="singleTree"
|
||||
v-model="singleSelectTreeVal"
|
||||
class="vab-tree-select"
|
||||
clearable
|
||||
popper-class="select-tree-popper"
|
||||
value-key="id"
|
||||
@clear="selectTreeClearHandle('single')"
|
||||
>
|
||||
<el-option :value="singleSelectTreeKey">
|
||||
<el-tree
|
||||
id="singleSelectTree"
|
||||
ref="singleSelectTree"
|
||||
:current-node-key="singleSelectTreeKey"
|
||||
:data="selectTreeData"
|
||||
:default-expanded-keys="selectTreeDefaultSelectedKeys"
|
||||
:highlight-current="true"
|
||||
node-key="id"
|
||||
:props="selectTreeDefaultProps"
|
||||
@node-click="selectTreeNodeClick"
|
||||
>
|
||||
<template #defalut="{ node }" class="vab-custom-tree-node">
|
||||
<span class="vab-tree-item">{{ node.label }}</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="24" :sm="24" :xl="6" :xs="24">
|
||||
<el-divider content-position="left">多选树</el-divider>
|
||||
<el-select
|
||||
v-model="multipleSelectTreeVal"
|
||||
class="vab-tree-select"
|
||||
clearable
|
||||
collapse-tags
|
||||
multiple
|
||||
popper-class="select-tree-popper"
|
||||
@change="changeMultipleSelectTreeHandle"
|
||||
@clear="selectTreeClearHandle('multiple')"
|
||||
@remove-tag="removeSelectTreeTag"
|
||||
>
|
||||
<el-option :value="multipleSelectTreeKey">
|
||||
<el-tree
|
||||
id="multipleSelectTree"
|
||||
ref="multipleSelectTree"
|
||||
:current-node-key="multipleSelectTreeKey"
|
||||
:data="selectTreeData"
|
||||
:default-checked-keys="selectTreeDefaultSelectedKeys"
|
||||
:default-expanded-keys="selectTreeDefaultSelectedKeys"
|
||||
:highlight-current="true"
|
||||
node-key="id"
|
||||
:props="selectTreeDefaultProps"
|
||||
show-checkbox
|
||||
@check="multipleSelectTreeCheckNode"
|
||||
/>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--添加/编辑节点弹框-------------------start-->
|
||||
<el-dialog
|
||||
class="tree-operate-dialog"
|
||||
:title="dialogTitle"
|
||||
:visible.sync="treeDialogVisible"
|
||||
width="400px"
|
||||
@close="treeDialogVisible = false"
|
||||
>
|
||||
<el-form ref="treeForm" :model="treeForm">
|
||||
<el-form-item label="节点名称" required>
|
||||
<el-input v-model="treeForm.name" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="treeDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="saveTree">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!--添加/编辑节点弹框-------------------end-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getTreeList } from '@/api/tree'
|
||||
|
||||
export default {
|
||||
name: 'Tree',
|
||||
data() {
|
||||
return {
|
||||
dialogTitle: '添加节点',
|
||||
treeFlag: 0,
|
||||
treeDialogVisible: false,
|
||||
treeForm: {
|
||||
id: '',
|
||||
name: '',
|
||||
},
|
||||
checkNodeKeys: [],
|
||||
filterText: '',
|
||||
data2: [],
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
},
|
||||
defaultExpendedKeys: [],
|
||||
defaultCheckedKeys: [],
|
||||
loading: true,
|
||||
keyW: '',
|
||||
filterDevLlist: [],
|
||||
isShow: false,
|
||||
updateTree: true,
|
||||
/* 单选树-多选树---------开始 */
|
||||
selectLevel: 4, // 树可选叶子level等级
|
||||
singleSelectTreeVal: '', //单选树默认label值
|
||||
singleSelectTreeKey: '', //单选树默认key值
|
||||
selectTreeData: [], //单选树的值
|
||||
selectTreeDefaultSelectedKeys: [], //单选树默认展开的key值数组
|
||||
selectTreeDefaultProps: {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
},
|
||||
multipleSelectTreeVal: [], //多选树默认label值
|
||||
multipleSelectTreeKey: '', //多选树默认key值
|
||||
/* 单选树-多选树---------结束 */
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.demoTree.filter(val)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.getTreeListFuc(1)
|
||||
this.setCheckedKeys()
|
||||
// 初始化单选树
|
||||
this.initSingleTree('single')
|
||||
// 初始化多选树
|
||||
this.initSingleTree('multiple')
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 树level小于n级展开方法
|
||||
openTree(treeData, n) {
|
||||
const each = (data) => {
|
||||
data.forEach((e) => {
|
||||
if (e.rank <= n) {
|
||||
this.defaultExpendedKeys.push(e.id)
|
||||
}
|
||||
if (e.children.length > 0) {
|
||||
each(e.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
each(treeData)
|
||||
},
|
||||
// 获取tree数据
|
||||
async getTreeListFuc(flag) {
|
||||
const { data } = await getTreeList()
|
||||
this.data2 = data
|
||||
if (flag) {
|
||||
this.openTree(this.data2, 2)
|
||||
}
|
||||
},
|
||||
// 节点过滤操作
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
return data.name.indexOf(value) !== -1
|
||||
},
|
||||
// 添加节点操作
|
||||
append(node, data, flag) {
|
||||
this.treeFlag = flag
|
||||
this.dialogTitle = '添加节点'
|
||||
this.treeForm = {
|
||||
id: '',
|
||||
name: '',
|
||||
}
|
||||
this.treeDialogVisible = true
|
||||
},
|
||||
// 编辑节点操作
|
||||
edit(node, data, flag) {
|
||||
this.treeFlag = flag
|
||||
this.dialogTitle = '编辑节点'
|
||||
this.treeForm = {
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
}
|
||||
this.treeDialogVisible = true
|
||||
},
|
||||
// 删除节点操作
|
||||
remove(node, data) {
|
||||
this.$baseConfirm('你确定要删除该节点?', null, async () => {
|
||||
const { msg } = getTreeList()
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.getTreeListFuc(0)
|
||||
})
|
||||
},
|
||||
// 保存添加和编辑
|
||||
saveTree() {
|
||||
this.$refs.treeForm.validate(async (valid) => {
|
||||
if (valid) {
|
||||
const { msg } = await getTreeList()
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.treeDialogVisible = false
|
||||
this.getTreeListFuc(0)
|
||||
}
|
||||
})
|
||||
},
|
||||
// 设置节点选中
|
||||
setCheckedKeys() {
|
||||
this.$refs.demoTree.setCheckedKeys([1])
|
||||
},
|
||||
// 点击叶子节点
|
||||
nodeClick(data, node, el) {},
|
||||
// 节点选中操作
|
||||
checkNode(data, node, el) {
|
||||
this.checkNodeKeys = node.checkedKeys
|
||||
},
|
||||
// 节点展开操作
|
||||
nodeExpand(data, node, el) {
|
||||
this.defaultExpendedKeys.push(data.id)
|
||||
},
|
||||
// 节点关闭操作
|
||||
nodeCollapse(data, node, el) {
|
||||
this.defaultExpendedKeys.splice(
|
||||
this.defaultExpendedKeys.findIndex((item) => item.id === data.id),
|
||||
1
|
||||
)
|
||||
},
|
||||
async loadNode(node, resolve) {
|
||||
if (node.level === 0) {
|
||||
const { data } = await getTreeList()
|
||||
this.loading = false
|
||||
return resolve(data)
|
||||
} else {
|
||||
const { data } = await getTreeList()
|
||||
return resolve(res.data)
|
||||
}
|
||||
},
|
||||
//懒加载树输入框筛选方法
|
||||
async showTreeList(value) {
|
||||
if (typeof value === 'string') {
|
||||
this.keyW = value.trim()
|
||||
}
|
||||
if (this.keyW.length !== 0) {
|
||||
// 请求后台返回查询结果
|
||||
let treeOption = {}
|
||||
treeOption = {
|
||||
keyWord: this.keyW,
|
||||
}
|
||||
const { data } = await getTreeList()
|
||||
this.filterDevLlist = data
|
||||
this.isShow = true
|
||||
} else {
|
||||
this.isShow = false
|
||||
}
|
||||
},
|
||||
/* 单选/多选树方法-------------------开始 */
|
||||
// 初始化单选树的值
|
||||
async initSingleTree(treeType) {
|
||||
const { data } = await getTreeList()
|
||||
this.selectTreeData = data
|
||||
this.$nextTick(() => {
|
||||
this.selectTreeDefaultSelectedKeys = this.singleSelectTreeKey.split(',') // 设置默认展开
|
||||
if (treeType == 'single') {
|
||||
//单选树
|
||||
this.$refs.singleSelectTree.setCurrentKey(this.singleSelectTreeKey) // 设置默认选中
|
||||
} else {
|
||||
// 多选树
|
||||
this.$refs.multipleSelectTree.setCheckedKeys(this.selectTreeDefaultSelectedKeys)
|
||||
}
|
||||
})
|
||||
},
|
||||
// 清除单选树选中
|
||||
selectTreeClearHandle(type) {
|
||||
this.selectTreeDefaultSelectedKeys = []
|
||||
this.clearSelected()
|
||||
if (type == 'single') {
|
||||
this.singleSelectTreeVal = ''
|
||||
this.singleSelectTreeKey = ''
|
||||
this.$refs.singleSelectTree.setCurrentKey('') // 设置默认选中
|
||||
} else {
|
||||
this.multipleSelectTreeVal = []
|
||||
this.multipleSelectTreeKey = ''
|
||||
this.$refs.multipleSelectTree.setCheckedKeys([])
|
||||
}
|
||||
},
|
||||
/* 清空选中样式 */
|
||||
clearSelected() {
|
||||
const allNode = document.querySelectorAll('#singleSelectTree .el-tree-node')
|
||||
allNode.forEach((element) => element.classList.remove('is-current'))
|
||||
},
|
||||
// select多选时移除某项操作
|
||||
removeSelectTreeTag(val) {
|
||||
const stack = JSON.parse(JSON.stringify(this.selectTreeData))
|
||||
while (stack.length) {
|
||||
const curr = stack.shift()
|
||||
if (curr.name == val) {
|
||||
return this.$refs.multipleSelectTree.setChecked(curr.id, false)
|
||||
}
|
||||
if (curr.children && curr.children.length) {
|
||||
stack.unshift(...curr.children)
|
||||
}
|
||||
}
|
||||
},
|
||||
changeMultipleSelectTreeHandle(val) {},
|
||||
// 点击叶子节点
|
||||
selectTreeNodeClick(data, node, el) {
|
||||
if (data.rank >= this.selectLevel) {
|
||||
this.singleSelectTreeVal = data.name
|
||||
this.singleSelectTreeKey = data.id
|
||||
this.$refs.singleTree.blur()
|
||||
}
|
||||
},
|
||||
// 节点选中操作
|
||||
multipleSelectTreeCheckNode(data, node, el) {
|
||||
const checkedNodes = this.$refs.multipleSelectTree.getCheckedNodes()
|
||||
const keyArr = []
|
||||
const valueArr = []
|
||||
checkedNodes.forEach((item) => {
|
||||
if (item.rank >= this.selectLevel) {
|
||||
keyArr.push(item.id)
|
||||
valueArr.push(item.name)
|
||||
}
|
||||
})
|
||||
this.multipleSelectTreeVal = valueArr
|
||||
this.multipleSelectTreeKey = keyArr.join(',')
|
||||
},
|
||||
/* 单选/多选树方法-------------------结束 */
|
||||
},
|
||||
}
|
||||
</script>
|
||||
26
src/views/vab/upload/index.vue
Normal file
26
src/views/vab/upload/index.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<div class="upload-container">
|
||||
<el-divider content-position="left">演示环境可能无法模拟上传</el-divider>
|
||||
<vab-upload ref="vabUpload" :limit="1" name="file" :size="2" url="/upload" />
|
||||
<el-button type="primary" @click="handleShow({ key: 'value' })">模拟上传</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VabUpload from '@/components/VabUpload'
|
||||
|
||||
export default {
|
||||
name: 'Upload',
|
||||
components: {
|
||||
VabUpload,
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
handleShow(data) {
|
||||
this.$refs['vabUpload'].handleShow(data)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
85
src/views/vab/webSocket/index.vue
Normal file
85
src/views/vab/webSocket/index.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<div class="webSocket-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="8" :md="12" :sm="24" :xl="8" :xs="24">
|
||||
<el-alert :closable="false" type="success">webSocket连接{{ status }}!</el-alert>
|
||||
<br />
|
||||
<el-form ref="form" label-width="100px" :model="form" :rules="rules">
|
||||
<el-form-item label="地址">
|
||||
<el-input v-model="url" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="消息" prop="message">
|
||||
<el-input v-model="form.message" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submit">发送消息</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="返回信息汇总">
|
||||
{{ data }}
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'WebSocket',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
url: 'ws://123.207.136.134:9010/ajaxchattest',
|
||||
webSocket: null,
|
||||
data: [],
|
||||
status: '',
|
||||
form: { message: null },
|
||||
rules: {
|
||||
message: [{ required: true, message: '请输入消息', trigger: 'blur' }],
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
destroyed() {
|
||||
this.webSocket.close()
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
this.$refs['form'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.send(this.form.message)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
init() {
|
||||
const wsuri = this.url
|
||||
this.webSocket = new WebSocket(wsuri)
|
||||
this.webSocket.onmessage = this.onmessage
|
||||
this.webSocket.onopen = this.onopen
|
||||
this.webSocket.onerror = this.onerror
|
||||
this.webSocket.onclose = this.onclose
|
||||
},
|
||||
onopen() {
|
||||
this.status = '成功'
|
||||
},
|
||||
onerror() {
|
||||
this.status = '失败'
|
||||
this.initWebSocket()
|
||||
},
|
||||
onmessage({ data }) {
|
||||
//截掉测试webSocket地址广告
|
||||
this.data.push(data.substring(0, data.length - 66))
|
||||
},
|
||||
send(Data) {
|
||||
this.webSocket.send(Data)
|
||||
},
|
||||
onclose(e) {
|
||||
this.status = '断开'
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user