mirror of
https://gitee.com/log4j/pig-ui.git
synced 2024-12-23 05:40:20 +08:00
完美对接avue
This commit is contained in:
parent
f53a1eb045
commit
5f06a00511
@ -1,6 +1,6 @@
|
||||
// see http://vuejs-templates.github.io/webpack for documentation.
|
||||
var path = require('path')
|
||||
|
||||
var baseUrl = 'http://218.70.11.118:7777';
|
||||
module.exports = {
|
||||
build: {
|
||||
env: require('./prod.env'),
|
||||
@ -30,17 +30,17 @@ module.exports = {
|
||||
assetsPublicPath: '/',
|
||||
proxyTable: {
|
||||
'/auth': {
|
||||
target: 'http://api.frps.shop',
|
||||
target: baseUrl,
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^/auth' : '/auth'
|
||||
'^/auth': '/auth'
|
||||
}
|
||||
},
|
||||
'/admin': {
|
||||
target: 'http://api.frps.shop',
|
||||
target: baseUrl,
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^/admin' : '/admin'
|
||||
'^/admin': '/admin'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -27,6 +27,7 @@
|
||||
"mockjs": "^1.0.1-beta3",
|
||||
"vue": "2.5.2",
|
||||
"vue-axios": "^2.0.2",
|
||||
"vue-image-crop-upload": "^2.2.3",
|
||||
"vue-router": "^3.0.0",
|
||||
"vue-server-renderer": "2.5.2",
|
||||
"vue-template-compiler": "2.5.2",
|
||||
|
@ -1,19 +1,7 @@
|
||||
import { userTableData, roleTableData } from '@/mock/admin'
|
||||
import { DIC } from '@/const/dic'
|
||||
export const getUserData = (page) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve({ data: userTableData });
|
||||
})
|
||||
}
|
||||
|
||||
export const getRoleData = (page) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve({ data: roleTableData });
|
||||
})
|
||||
}
|
||||
|
||||
export const getDic = (type) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve({ data: DIC[type] });
|
||||
resolve({ data: {} });
|
||||
})
|
||||
}
|
39
src/api/dept.js
Normal file
39
src/api/dept.js
Normal file
@ -0,0 +1,39 @@
|
||||
import request from '@/router/axios'
|
||||
|
||||
export function fetchTree(query) {
|
||||
return request({
|
||||
url: '/admin/dept/tree',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj) {
|
||||
return request({
|
||||
url: '/admin/dept/',
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function getObj(id) {
|
||||
return request({
|
||||
url: '/admin/dept/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function delObj(id) {
|
||||
return request({
|
||||
url: '/admin/dept/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj) {
|
||||
return request({
|
||||
url: '/admin/dept/',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
46
src/api/dict.js
Normal file
46
src/api/dict.js
Normal file
@ -0,0 +1,46 @@
|
||||
import request from '@/router/axios'
|
||||
|
||||
export function fetchList(query) {
|
||||
return request({
|
||||
url: '/admin/dict/dictPage',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj) {
|
||||
return request({
|
||||
url: '/admin/user/',
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function getObj(id) {
|
||||
return request({
|
||||
url: '/admin/user/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function delObj(row) {
|
||||
return request({
|
||||
url: '/admin/dict/' + row.id + '/' + row.type,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj) {
|
||||
return request({
|
||||
url: '/admin/user/',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function remote(type) {
|
||||
return request({
|
||||
url: '/admin/dict/type/' + type,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
39
src/api/log.js
Normal file
39
src/api/log.js
Normal file
@ -0,0 +1,39 @@
|
||||
import request from '@/router/axios'
|
||||
|
||||
export function fetchList(query) {
|
||||
return request({
|
||||
url: '/admin/log/logPage',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function delObj(id) {
|
||||
return request({
|
||||
url: '/admin/log/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj) {
|
||||
return request({
|
||||
url: '/admin/user/',
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function getObj(id) {
|
||||
return request({
|
||||
url: '/admin/user/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj) {
|
||||
return request({
|
||||
url: '/admin/user/',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
@ -24,7 +24,7 @@ export const getUserInfo = () => {
|
||||
|
||||
export const logout = (accesstoken, refreshToken) => {
|
||||
return request({
|
||||
url: '/auth/removeToken',
|
||||
url: '/auth/authentication/removeToken',
|
||||
method: 'post',
|
||||
params: { accesstoken, refreshToken }
|
||||
})
|
||||
|
@ -4,4 +4,55 @@ export function GetMenu() {
|
||||
url: '/admin/menu/getUserTree',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
}
|
||||
export function fetchTree(query) {
|
||||
return request({
|
||||
url: '/admin/menu/tree',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchAll() {
|
||||
return request({
|
||||
url: '/admin/menu/navMenu',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchUserTree() {
|
||||
return request({
|
||||
url: '/admin/menu/userTree',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj) {
|
||||
return request({
|
||||
url: '/admin/menu/',
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function getObj(id) {
|
||||
return request({
|
||||
url: '/admin/menu/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function delObj(id) {
|
||||
return request({
|
||||
url: '/admin/menu/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj) {
|
||||
return request({
|
||||
url: '/admin/menu/',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
8
src/api/qiniu.js
Normal file
8
src/api/qiniu.js
Normal file
@ -0,0 +1,8 @@
|
||||
import request from '@/router/axios'
|
||||
|
||||
export function getToken() {
|
||||
return request({
|
||||
url: '/zuul/admin/user/upload', // 假地址,自行替换
|
||||
method: 'post'
|
||||
})
|
||||
}
|
79
src/api/role.js
Normal file
79
src/api/role.js
Normal file
@ -0,0 +1,79 @@
|
||||
import request from '@/router/axios'
|
||||
|
||||
export function roleList() {
|
||||
return request({
|
||||
url: '/admin/role/roleList',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchList(query) {
|
||||
return request({
|
||||
url: '/admin/role/rolePage',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function deptRoleList(deptId) {
|
||||
return request({
|
||||
url: '/admin/role/roleList/' + deptId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getObj(id) {
|
||||
return request({
|
||||
url: '/admin/role/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj) {
|
||||
return request({
|
||||
url: '/admin/role/',
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj) {
|
||||
return request({
|
||||
url: '/admin/role/',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function delObj(id) {
|
||||
return request({
|
||||
url: '/admin/role/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function permissionUpd(roleId, menuIds) {
|
||||
return request({
|
||||
url: '/admin/role/roleMenuUpd',
|
||||
method: 'put',
|
||||
params: {
|
||||
roleId: roleId,
|
||||
menuIds: menuIds
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchRoleTree(roleName) {
|
||||
return request({
|
||||
url: '/admin/menu/roleTree/' + roleName,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchDeptTree(query) {
|
||||
return request({
|
||||
url: '/admin/dept/tree',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
40
src/api/user.js
Normal file
40
src/api/user.js
Normal file
@ -0,0 +1,40 @@
|
||||
import request from '@/router/axios'
|
||||
|
||||
export function fetchList(query) {
|
||||
return request({
|
||||
url: '/admin/user/userPage',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj) {
|
||||
return request({
|
||||
url: '/admin/user/',
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function getObj(id) {
|
||||
return request({
|
||||
url: '/admin/user/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function delObj(id) {
|
||||
return request({
|
||||
url: '/admin/user/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj) {
|
||||
return request({
|
||||
url: '/admin/user',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
@ -1,111 +1,85 @@
|
||||
<template>
|
||||
<div class="crud-container pull-auto">
|
||||
<!-- <div class="crud-header">
|
||||
<!-- <div class="crud-header">
|
||||
<el-button type="primary" @click="handleAdd" size="small">新 增</el-button>
|
||||
<el-button @click="toggleSelection([tableData[1]])" size="small">切换第二选中状态</el-button>
|
||||
<el-button @click="toggleSelection()" size="small">取消选择</el-button>
|
||||
</div> -->
|
||||
<el-table
|
||||
:data="tableData"
|
||||
ref="table"
|
||||
style="width:100%;min-height:430px;"
|
||||
:border="tableOption.border"
|
||||
v-loading="tableLoading"
|
||||
@selection-change="handleSelectionChange" >
|
||||
<el-table :data="tableData" :height="tableOption.height" ref="table" style="width:99.5%;margin:0 auto;box-sizing:border-box;" :border="tableOption.border" v-loading="tableLoading" @selection-change="handleSelectionChange">
|
||||
<!-- 选择框 -->
|
||||
<template v-if="tableOption.selection">
|
||||
<el-table-column
|
||||
type="selection"
|
||||
width="55">
|
||||
</el-table-column>
|
||||
<el-table-column type="selection" width="55">
|
||||
</el-table-column>
|
||||
</template>
|
||||
<!-- 序号 -->
|
||||
<template v-if="tableOption.index">
|
||||
<el-table-column
|
||||
type="index"
|
||||
width="50">
|
||||
<el-table-column type="index" width="50">
|
||||
</el-table-column>
|
||||
</template>
|
||||
<!-- 循环列 -->
|
||||
<template v-for="(column,index) in tableOption.column">
|
||||
<el-table-column
|
||||
:width="column.width"
|
||||
:label="column.label"
|
||||
:fixed="column.fixed"
|
||||
:sortable="column.sortable" v-if="!column.hide">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="!column.overHidden" v-html="handleDetail(scope.row,column)"></span>
|
||||
<el-popover v-else trigger="hover" placement="top">
|
||||
<p>{{column.label}}: {{ scope.row[column.prop]}}</p>
|
||||
<div slot="reference" class="name-wrapper">
|
||||
<span v-html="handleDetail(scope.row,column)" class="crud--overflow"></span>
|
||||
</div>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :width="column.width" :label="column.label" :fixed="column.fixed" :sortable="column.sortable" v-if="!column.hide">
|
||||
<template slot-scope="scope">
|
||||
<slot :row="scope.row" :dic="DIC[column.dicData]" :name="column.prop" v-if="column.solt"></slot>
|
||||
<span v-else-if="!column.overHidden" v-html="handleDetail(scope.row,column)"></span>
|
||||
<el-popover v-else trigger="hover" placement="top">
|
||||
<p>{{column.label}}: {{ scope.row[column.prop]}}</p>
|
||||
<div slot="reference" class="name-wrapper">
|
||||
<span v-html="handleDetail(scope.row,column)" class="crud--overflow"></span>
|
||||
</div>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<el-table-column label="操作" :width="width">
|
||||
<template slot-scope="scope" >
|
||||
<template v-if="menu">
|
||||
<el-button type="primary" icon="el-icon-edit" size="small" @click="handleEdit(scope.row,scope.$index)">编 辑</el-button>
|
||||
<el-button type="danger" icon="el-icon-delete" size="small" @click="handleDel(scope.row,scope.$index)">删 除</el-button>
|
||||
</template>
|
||||
<slot :row="scope.row"></slot>
|
||||
<el-table-column label="操作" :width="width" v-if="tableOption.menu==undefined?true:tableOption.menu">
|
||||
<template slot-scope="scope">
|
||||
<template v-if="menu">
|
||||
<el-button type="primary" icon="el-icon-edit" size="small" @click="handleEdit(scope.row,scope.$index)" v-if="tableOption.editBtn==undefined?true:tableOption.meeditBtnnu">编 辑</el-button>
|
||||
<el-button type="danger" icon="el-icon-delete" size="small" @click="handleDel(scope.row,scope.$index)" v-if="tableOption.delBtn==undefined?true:tableOption.delBtn">删 除</el-button>
|
||||
</template>
|
||||
<slot :row="scope.row" name="menu"></slot>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination class="crud-pagination pull-right"
|
||||
:current-page.sync="page.currentPage"
|
||||
:background = "page.background?page.background:true"
|
||||
:page-size="page.pageSize"
|
||||
@current-change="handleCurrentChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="page.total"></el-pagination>
|
||||
<el-dialog
|
||||
:title="boxType==0?'新增':'编辑'"
|
||||
:visible.sync="boxVisible"
|
||||
width="50%" :before-close="boxhandleClose">
|
||||
<el-pagination v-if="tableOption.page==undefined?true:tableOption.page" class="crud-pagination pull-right" :current-page.sync="page.currentPage" :background="page.background?page.background:true" :page-size="page.pageSize" @current-change="handleCurrentChange" layout="total, sizes, prev, pager, next, jumper" :total="page.total"></el-pagination>
|
||||
<el-dialog :title="boxType==0?'新增':'编辑'" :visible.sync="boxVisible" width="50%" :before-close="boxhandleClose">
|
||||
<el-form ref="tableForm" :model="tableForm" label-width="80px" :rules="tableFormRules">
|
||||
<el-row :gutter="20" :span="24">
|
||||
<el-row :gutter="20" :span="24">
|
||||
<template v-for="(column,index) in tableOption.column">
|
||||
<el-col :span="column.span||12">
|
||||
<el-form-item :label="column.label" :prop="column.prop" v-if="!column.visdiplay">
|
||||
<template v-if="column.type == 'select'">
|
||||
<el-select v-model="tableForm[column.prop]" :placeholder="'请选择'+column.label">
|
||||
<el-option
|
||||
v-for="(item,index) in DIC[column.dicData]"
|
||||
:key="index"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
<el-select v-model="tableForm[column.prop]" :placeholder="'请选择'+column.label">
|
||||
<el-option v-for="(item,index) in DIC[column.dicData]" :key="index" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-if="column.type == 'radio'">
|
||||
<el-radio v-for="(item,index) in DIC[column.dicData]" v-model="tableForm[column.prop]" :label="item.value" :key="index">{{item.label}}</el-radio>
|
||||
<el-radio v-for="(item,index) in DIC[column.dicData]" v-model="tableForm[column.prop]" :label="item.value" :key="index">{{item.label}}</el-radio>
|
||||
</template>
|
||||
<template v-if="column.type == 'date'">
|
||||
<el-date-picker v-model="tableForm[column.prop]" type="date" :placeholder="'请输入'+column.label"> </el-date-picker>
|
||||
<el-date-picker v-model="tableForm[column.prop]" type="date" :placeholder="'请输入'+column.label"> </el-date-picker>
|
||||
</template>
|
||||
<template v-if="column.type == 'checkbox'">
|
||||
<el-checkbox-group v-model="tableForm[column.prop]">
|
||||
<el-checkbox v-for="(item,index) in DIC[column.dicData]" :label="item.value" :key="index">{{item.label}}</el-checkbox>
|
||||
<el-checkbox-group v-model="tableForm[column.prop]">
|
||||
<el-checkbox v-for="(item,index) in DIC[column.dicData]" :label="item.value" :key="index">{{item.label}}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</template>
|
||||
<template v-if="!column.type">
|
||||
<el-input v-model="tableForm[column.prop]" :placeholder="'请输入'+column.label"></el-input>
|
||||
<el-input v-model="tableForm[column.prop]" :placeholder="'请输入'+column.label"></el-input>
|
||||
</template>
|
||||
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</template>
|
||||
</el-row >
|
||||
</el-row>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="handleUpdate" v-if="boxType==1">修 改</el-button>
|
||||
<el-button type="primary" @click="handleSave" v-else>新 增</el-button>
|
||||
<el-button @click="boxVisible = false">取 消</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="handleUpdate" v-if="boxType==1">修 改</el-button>
|
||||
<el-button type="primary" @click="handleSave" v-else>新 增</el-button>
|
||||
<el-button @click="boxVisible = false">取 消</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@ -141,11 +115,13 @@ export default {
|
||||
beforeOpen: Function,
|
||||
page: {
|
||||
type: Object,
|
||||
default: {
|
||||
total: 0, //总页数
|
||||
currentPage: 0, //当前页数
|
||||
pageSize: 10, //每页显示多少条
|
||||
background: true //背景颜色
|
||||
default() {
|
||||
return {
|
||||
total: 0, //总页数
|
||||
currentPage: 0, //当前页数
|
||||
pageSize: 10, //每页显示多少条
|
||||
background: true //背景颜色
|
||||
};
|
||||
}
|
||||
},
|
||||
tableLoading: {
|
||||
@ -199,6 +175,9 @@ export default {
|
||||
handleCurrentChange(val) {
|
||||
this.$emit("handleCurrentChange", val);
|
||||
},
|
||||
findByvalue(dic, val) {
|
||||
return findByvalue(dic, val);
|
||||
},
|
||||
// 选中实例
|
||||
toggleSelection(rows) {
|
||||
if (rows) {
|
||||
@ -217,13 +196,19 @@ export default {
|
||||
//处理数据
|
||||
handleDetail(row, column) {
|
||||
let result = "";
|
||||
if (column.type) {
|
||||
result = findByvalue(this.DIC[column.dicData], row[column.prop]);
|
||||
} else {
|
||||
result = row[column.prop];
|
||||
}
|
||||
if (column.dataDetail) {
|
||||
result = column.dataDetail(result);
|
||||
if (column.type) {
|
||||
result = findByvalue(this.DIC[column.dicData], row[column.prop]);
|
||||
} else {
|
||||
result = row[column.prop];
|
||||
}
|
||||
result = column.dataDetail(row);
|
||||
} else {
|
||||
if (column.type) {
|
||||
result = findByvalue(this.DIC[column.dicData], row[column.prop]);
|
||||
} else {
|
||||
result = row[column.prop];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
103
src/components/datashow/boxData.vue
Normal file
103
src/components/datashow/boxData.vue
Normal file
@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<div class="pull-auto">
|
||||
<el-row :span="24">
|
||||
<template v-for="item in data">
|
||||
<el-col :span="span">
|
||||
<div class="item" :style="{background:item.color}">
|
||||
<div class="item-header">
|
||||
<p>{{item.title}}</p>
|
||||
<span>{{item.subtitle}}</span>
|
||||
</div>
|
||||
<div class="item-body">
|
||||
<h2>{{item.count}}</h2>
|
||||
</div>
|
||||
<div class="item-footer">
|
||||
<span>{{item.allcount}}</span>
|
||||
<p>{{item.text}}</p>
|
||||
</div>
|
||||
<p class="item-tip">{{item.key}}</p>
|
||||
</div>
|
||||
</el-col>
|
||||
</template>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "datashow",
|
||||
data() {
|
||||
return {
|
||||
span: this.option.span || 6,
|
||||
data: this.option.data || []
|
||||
};
|
||||
},
|
||||
props: {
|
||||
option: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
position: relative;
|
||||
margin: 15px;
|
||||
padding: 12px;
|
||||
height: 144px;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
}
|
||||
.item-header {
|
||||
position: relative;
|
||||
& > p {
|
||||
margin: 0px;
|
||||
font-size: 14px;
|
||||
}
|
||||
& > span {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
}
|
||||
.item-body {
|
||||
& > h2 {
|
||||
margin: 0;
|
||||
font-size: 32px;
|
||||
line-height: 60px;
|
||||
}
|
||||
}
|
||||
.item-footer {
|
||||
line-height: 16px;
|
||||
& > span {
|
||||
font-size: 10px;
|
||||
}
|
||||
& > p {
|
||||
margin: 0px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.item-tip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
border: 2px solid #fff;
|
||||
border-radius: 100%;
|
||||
font-size: 48px;
|
||||
transform: rotate(-40deg);
|
||||
opacity: 0.1;
|
||||
}
|
||||
</style>
|
88
src/components/datashow/cardData.vue
Normal file
88
src/components/datashow/cardData.vue
Normal file
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div class="pull-auto">
|
||||
<el-row :span="24">
|
||||
<template v-for="item,index in data">
|
||||
<el-col :span="span">
|
||||
<div class="item">
|
||||
<img :src="item.src" class="item-img" />
|
||||
<div class="item-text" :style="{color:colorText,backgroundColor:bgText}">
|
||||
<h3>{{item.name}}</h3>
|
||||
<p>{{item.text}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</template>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "cardData",
|
||||
data() {
|
||||
return {
|
||||
span: this.option.span || 6,
|
||||
data: this.option.data || [],
|
||||
colorText: this.option.colorText || "#fff",
|
||||
bgText: this.option.bgText || "#2e323f",
|
||||
borderColor: this.option.borderColor || "#2e323f"
|
||||
};
|
||||
},
|
||||
props: {
|
||||
option: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
watch: {},
|
||||
computed: {},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$height: 340px;
|
||||
.item {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 50px;
|
||||
width: 230px;
|
||||
height: $height;
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
border-color: #fff;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
&:hover .item-text {
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
.item-img {
|
||||
width: 100%;
|
||||
background: red;
|
||||
border-radius: 5px;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
.item-text {
|
||||
position: absolute;
|
||||
top: 150px;
|
||||
padding: 20px 15px;
|
||||
width: 100%;
|
||||
height: $height;
|
||||
overflow: auto;
|
||||
box-sizing: border-box;
|
||||
border-radius: 5px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
opacity: 0.9;
|
||||
transition: top 0.4s;
|
||||
& > p {
|
||||
font-size: 12px;
|
||||
line-height: 25px;
|
||||
text-indent: 2em;
|
||||
}
|
||||
}
|
||||
</style>
|
77
src/components/datashow/easyData.vue
Normal file
77
src/components/datashow/easyData.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="pull-auto easyData-contailer">
|
||||
<el-row :span="24">
|
||||
<template v-for="item in data">
|
||||
<el-col :span="span">
|
||||
<div class="item" :class="[{'item--easy':discount}]">
|
||||
<div class="item-icon" :style="{color:color}">
|
||||
<i :class="item.icon"></i>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span>{{item.title}}</span>
|
||||
<h3 :style="{color:color}">{{item.count}}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</template>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "easyData",
|
||||
data() {
|
||||
return {
|
||||
span: this.option.span || 6,
|
||||
data: this.option.data,
|
||||
color: this.option.color || "rgb(63, 161, 255)",
|
||||
discount: this.option.discount || false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
option: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.easyData-contailer {
|
||||
}
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 80px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.item-icon {
|
||||
margin-top: 3px;
|
||||
margin-right: 8px;
|
||||
& > i {
|
||||
font-size: 46px !important;
|
||||
}
|
||||
}
|
||||
.item-info {
|
||||
line-height: 25px;
|
||||
& > span {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.item--easy {
|
||||
flex-direction: column;
|
||||
& > .item-icon {
|
||||
margin: 0;
|
||||
}
|
||||
& > .item-info {
|
||||
margin-top: -15px;
|
||||
& > span {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -12,13 +12,13 @@
|
||||
|
||||
|
||||
let baseUrl = '';
|
||||
let iconfontVersion = 'j0ic7mgvwddt2o6r';
|
||||
let iconfontUrl = `//at.alicdn.com/t/font_567566_${iconfontVersion}.css`;
|
||||
let iconfontVersion = ['567566_lgiis24af44bcsor', '599693_c3ju5pfa6altmx6r'];
|
||||
let iconfontUrl = `//at.alicdn.com/t/font_$key.css`;
|
||||
let codeUrl = `/admin/code`
|
||||
if (process.env.NODE_ENV == 'development') {
|
||||
baseUrl = `http://api.frps.shop`;
|
||||
baseUrl = `http://218.70.11.118`;
|
||||
} else if (process.env.NODE_ENV == 'production') {
|
||||
baseUrl = `http://api.frps.shop`;
|
||||
baseUrl = `http://218.70.11.118`;
|
||||
}
|
||||
|
||||
export { baseUrl, iconfontUrl, codeUrl }
|
||||
export { baseUrl, iconfontUrl, iconfontVersion, codeUrl }
|
||||
|
@ -1,54 +0,0 @@
|
||||
export const userOption = {
|
||||
border: true,
|
||||
index: true,
|
||||
selection: false,
|
||||
dic: ['GRADE', 'STATE'],
|
||||
column: [
|
||||
{
|
||||
label: "用户名",
|
||||
prop: "username",
|
||||
width: "150",
|
||||
rules: [{ required: true, message: "请输入用户名", trigger: "blur" }]
|
||||
},
|
||||
{
|
||||
label: "角色",
|
||||
prop: "grade",
|
||||
type: "checkbox",
|
||||
dicData: 'GRADE'
|
||||
},
|
||||
{
|
||||
label: "创建时间",
|
||||
prop: "date",
|
||||
type: "date",
|
||||
visdiplay: true,
|
||||
},
|
||||
{
|
||||
label: "状态",
|
||||
prop: "state",
|
||||
dataDetail: val => {
|
||||
return `<span class="el-tag ${val == '有效' ? 'el-tag--success' : 'el-tag--danger'}">${val}</span>`;
|
||||
},
|
||||
type: "radio",
|
||||
dicData: 'STATE'
|
||||
}
|
||||
]
|
||||
};
|
||||
export const roleOption = {
|
||||
border: true,
|
||||
index: true,
|
||||
selection: false,
|
||||
column: [
|
||||
{
|
||||
label: "角色名称",
|
||||
prop: "name",
|
||||
width: "150",
|
||||
rules: [{ required: true, message: "请输入用户名", trigger: "blur" }]
|
||||
},
|
||||
{
|
||||
label: "创建时间",
|
||||
prop: "date",
|
||||
visdiplay: true,
|
||||
type: "date",
|
||||
}
|
||||
]
|
||||
};
|
@ -1,27 +0,0 @@
|
||||
export const DIC = {
|
||||
SEX: [{
|
||||
label: '男',
|
||||
value: 0
|
||||
}, {
|
||||
label: '女',
|
||||
value: 1
|
||||
}],
|
||||
|
||||
STATE: [{
|
||||
label: '有效',
|
||||
value: 0
|
||||
}, {
|
||||
label: '无效',
|
||||
value: 1
|
||||
}],
|
||||
GRADE: [
|
||||
{
|
||||
label: "管理员",
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
label: "二级管理员",
|
||||
value: 1
|
||||
}
|
||||
]
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
export default {
|
||||
dic: ['GRADE', 'SEX'],
|
||||
column: [
|
||||
{
|
||||
label: "用户名",
|
||||
prop: "username",
|
||||
rules: [{ required: true, message: "请输入用户名", trigger: "blur" }]
|
||||
},
|
||||
{
|
||||
label: "姓名",
|
||||
prop: "name"
|
||||
},
|
||||
{
|
||||
label: "类型",
|
||||
prop: "type",
|
||||
type: "select",
|
||||
dicData: 'GRADE'
|
||||
},
|
||||
{
|
||||
label: "性别",
|
||||
prop: "sex",
|
||||
type: "radio",
|
||||
dicData: 'SEX'
|
||||
},
|
||||
{
|
||||
label: "权限",
|
||||
prop: "grade",
|
||||
span: 24,
|
||||
type: "checkbox",
|
||||
dicData: 'GRADE'
|
||||
},
|
||||
{
|
||||
label: "地址",
|
||||
disabled: true,
|
||||
span: 24,
|
||||
prop: "address",
|
||||
}
|
||||
]
|
||||
};
|
@ -1,43 +0,0 @@
|
||||
export default {
|
||||
border: true,
|
||||
index: true,
|
||||
selection: true,
|
||||
dic: ['GRADE', 'SEX'],
|
||||
column: [
|
||||
{
|
||||
label: "用户名",
|
||||
prop: "username",
|
||||
width: "150",
|
||||
dataDetail: val => {
|
||||
return `<span class="el-tag el-tag--success">${val}</span>`;
|
||||
},
|
||||
rules: [{ required: true, message: "请输入用户名", trigger: "blur" }]
|
||||
},
|
||||
{
|
||||
label: "姓名",
|
||||
prop: "name"
|
||||
},
|
||||
{
|
||||
label: "类型",
|
||||
prop: "type",
|
||||
dataDetail: val => {
|
||||
return `<span class="el-tag">${val}</span>`;
|
||||
},
|
||||
type: "select",
|
||||
dicData: 'GRADE'
|
||||
},
|
||||
{
|
||||
label: "权限",
|
||||
prop: "grade",
|
||||
type: "checkbox",
|
||||
dicData: 'GRADE'
|
||||
},
|
||||
{
|
||||
label: "地址",
|
||||
prop: "address",
|
||||
width: "300",
|
||||
span: 24,
|
||||
overHidden: true
|
||||
}
|
||||
]
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
export default [
|
||||
'Avue 是一个基于vue+vuex+vue-router快速后台管理模板,采用token交互验证方式。',
|
||||
'您可以 Avue 为基础,不只限制于vue的页面,你可以嵌入任意第三方网站,基于iframe框架。',
|
||||
'Avue 构建简单上手快,最大程度上帮助企业节省时间成本和费用开支。'
|
||||
'是一个基于Spring Cloud、oAuth2.0开发基于Vue前后分离的开发平台',
|
||||
' 是一个基于vue+vuex+vue-router快速后台管理系统,采用token交互验证方式。',
|
||||
'最大程度上帮助企业节省时间成本和费用开支。 ',
|
||||
'QQ群:23754102'
|
||||
]
|
||||
|
49
src/directive/clipboard/clipboard.js
Normal file
49
src/directive/clipboard/clipboard.js
Normal file
@ -0,0 +1,49 @@
|
||||
// Inspired by https://github.com/Inndy/vue-clipboard2
|
||||
const Clipboard = require('clipboard')
|
||||
if (!Clipboard) {
|
||||
throw new Error('you shold npm install `clipboard` --save at first ')
|
||||
}
|
||||
|
||||
export default {
|
||||
bind(el, binding) {
|
||||
if (binding.arg === 'success') {
|
||||
el._v_clipboard_success = binding.value
|
||||
} else if (binding.arg === 'error') {
|
||||
el._v_clipboard_error = binding.value
|
||||
} else {
|
||||
const clipboard = new Clipboard(el, {
|
||||
text() { return binding.value },
|
||||
action() { return binding.arg === 'cut' ? 'cut' : 'copy' }
|
||||
})
|
||||
clipboard.on('success', e => {
|
||||
const callback = el._v_clipboard_success
|
||||
callback && callback(e) // eslint-disable-line
|
||||
})
|
||||
clipboard.on('error', e => {
|
||||
const callback = el._v_clipboard_error
|
||||
callback && callback(e) // eslint-disable-line
|
||||
})
|
||||
el._v_clipboard = clipboard
|
||||
}
|
||||
},
|
||||
update(el, binding) {
|
||||
if (binding.arg === 'success') {
|
||||
el._v_clipboard_success = binding.value
|
||||
} else if (binding.arg === 'error') {
|
||||
el._v_clipboard_error = binding.value
|
||||
} else {
|
||||
el._v_clipboard.text = function() { return binding.value }
|
||||
el._v_clipboard.action = function() { return binding.arg === 'cut' ? 'cut' : 'copy' }
|
||||
}
|
||||
},
|
||||
unbind(el, binding) {
|
||||
if (binding.arg === 'success') {
|
||||
delete el._v_clipboard_success
|
||||
} else if (binding.arg === 'error') {
|
||||
delete el._v_clipboard_error
|
||||
} else {
|
||||
el._v_clipboard.destroy()
|
||||
delete el._v_clipboard
|
||||
}
|
||||
}
|
||||
}
|
13
src/directive/clipboard/index.js
Normal file
13
src/directive/clipboard/index.js
Normal file
@ -0,0 +1,13 @@
|
||||
import Clipboard from './clipboard'
|
||||
|
||||
const install = function(Vue) {
|
||||
Vue.directive('Clipboard', Clipboard)
|
||||
}
|
||||
|
||||
if (window.Vue) {
|
||||
window.clipboard = Clipboard
|
||||
Vue.use(install); // eslint-disable-line
|
||||
}
|
||||
|
||||
Clipboard.install = install
|
||||
export default Clipboard
|
91
src/directive/sticky.js
Normal file
91
src/directive/sticky.js
Normal file
@ -0,0 +1,91 @@
|
||||
const vueSticky = {}
|
||||
let listenAction
|
||||
vueSticky.install = Vue => {
|
||||
Vue.directive('sticky', {
|
||||
inserted(el, binding) {
|
||||
const params = binding.value || {}
|
||||
const stickyTop = params.stickyTop || 0
|
||||
const zIndex = params.zIndex || 1000
|
||||
const elStyle = el.style
|
||||
|
||||
elStyle.position = '-webkit-sticky'
|
||||
elStyle.position = 'sticky'
|
||||
// if the browser support css sticky(Currently Safari, Firefox and Chrome Canary)
|
||||
// if (~elStyle.position.indexOf('sticky')) {
|
||||
// elStyle.top = `${stickyTop}px`;
|
||||
// elStyle.zIndex = zIndex;
|
||||
// return
|
||||
// }
|
||||
const elHeight = el.getBoundingClientRect().height
|
||||
const elWidth = el.getBoundingClientRect().width
|
||||
elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}`
|
||||
|
||||
const parentElm = el.parentNode || document.documentElement
|
||||
const placeholder = document.createElement('div')
|
||||
placeholder.style.display = 'none'
|
||||
placeholder.style.width = `${elWidth}px`
|
||||
placeholder.style.height = `${elHeight}px`
|
||||
parentElm.insertBefore(placeholder, el)
|
||||
|
||||
let active = false
|
||||
|
||||
const getScroll = (target, top) => {
|
||||
const prop = top ? 'pageYOffset' : 'pageXOffset'
|
||||
const method = top ? 'scrollTop' : 'scrollLeft'
|
||||
let ret = target[prop]
|
||||
if (typeof ret !== 'number') {
|
||||
ret = window.document.documentElement[method]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
const sticky = () => {
|
||||
if (active) {
|
||||
return
|
||||
}
|
||||
if (!elStyle.height) {
|
||||
elStyle.height = `${el.offsetHeight}px`
|
||||
}
|
||||
|
||||
elStyle.position = 'fixed'
|
||||
elStyle.width = `${elWidth}px`
|
||||
placeholder.style.display = 'inline-block'
|
||||
active = true
|
||||
}
|
||||
|
||||
const reset = () => {
|
||||
if (!active) {
|
||||
return
|
||||
}
|
||||
|
||||
elStyle.position = ''
|
||||
placeholder.style.display = 'none'
|
||||
active = false
|
||||
}
|
||||
|
||||
const check = () => {
|
||||
const scrollTop = getScroll(window, true)
|
||||
const offsetTop = el.getBoundingClientRect().top
|
||||
if (offsetTop < stickyTop) {
|
||||
sticky()
|
||||
} else {
|
||||
if (scrollTop < elHeight + stickyTop) {
|
||||
reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
listenAction = () => {
|
||||
check()
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', listenAction)
|
||||
},
|
||||
|
||||
unbind() {
|
||||
window.removeEventListener('scroll', listenAction)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default vueSticky
|
||||
|
13
src/directive/waves/index.js
Normal file
13
src/directive/waves/index.js
Normal file
@ -0,0 +1,13 @@
|
||||
import waves from './waves'
|
||||
|
||||
const install = function(Vue) {
|
||||
Vue.directive('waves', waves)
|
||||
}
|
||||
|
||||
if (window.Vue) {
|
||||
window.waves = waves
|
||||
Vue.use(install); // eslint-disable-line
|
||||
}
|
||||
|
||||
waves.install = install
|
||||
export default waves
|
26
src/directive/waves/waves.css
Normal file
26
src/directive/waves/waves.css
Normal file
@ -0,0 +1,26 @@
|
||||
.waves-ripple {
|
||||
position: absolute;
|
||||
border-radius: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.15);
|
||||
background-clip: padding-box;
|
||||
pointer-events: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-transform: scale(0);
|
||||
-ms-transform: scale(0);
|
||||
transform: scale(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.waves-ripple.z-active {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(2);
|
||||
-ms-transform: scale(2);
|
||||
transform: scale(2);
|
||||
-webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
|
||||
transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
|
||||
transition: opacity 1.2s ease-out, transform 0.6s ease-out;
|
||||
transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
|
||||
}
|
42
src/directive/waves/waves.js
Normal file
42
src/directive/waves/waves.js
Normal file
@ -0,0 +1,42 @@
|
||||
import './waves.css'
|
||||
|
||||
export default{
|
||||
bind(el, binding) {
|
||||
el.addEventListener('click', e => {
|
||||
const customOpts = Object.assign({}, binding.value)
|
||||
const opts = Object.assign({
|
||||
ele: el, // 波纹作用元素
|
||||
type: 'hit', // hit点击位置扩散center中心点扩展
|
||||
color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
|
||||
}, customOpts)
|
||||
const target = opts.ele
|
||||
if (target) {
|
||||
target.style.position = 'relative'
|
||||
target.style.overflow = 'hidden'
|
||||
const rect = target.getBoundingClientRect()
|
||||
let ripple = target.querySelector('.waves-ripple')
|
||||
if (!ripple) {
|
||||
ripple = document.createElement('span')
|
||||
ripple.className = 'waves-ripple'
|
||||
ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px'
|
||||
target.appendChild(ripple)
|
||||
} else {
|
||||
ripple.className = 'waves-ripple'
|
||||
}
|
||||
switch (opts.type) {
|
||||
case 'center':
|
||||
ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px'
|
||||
ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px'
|
||||
break
|
||||
default:
|
||||
ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop) + 'px'
|
||||
ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft) + 'px'
|
||||
}
|
||||
ripple.style.backgroundColor = opts.color
|
||||
ripple.className = 'waves-ripple z-active'
|
||||
return false
|
||||
}
|
||||
}, false)
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import store from './store';
|
||||
import ELEMENT from 'element-ui';
|
||||
import { loadStyle } from './util/util'
|
||||
import * as urls from '@/config/env';
|
||||
import { iconfontUrl } from '@/config/env';
|
||||
import { iconfontUrl, iconfontVersion } from '@/config/env';
|
||||
import * as filters from './filters' // 全局filter
|
||||
import './styles/common.scss';
|
||||
Vue.use(ELEMENT)
|
||||
@ -22,8 +22,10 @@ Object.keys(urls).forEach(key => {
|
||||
Object.keys(filters).forEach(key => {
|
||||
Vue.filter(key, filters[key])
|
||||
})
|
||||
iconfontVersion.forEach(ele => {
|
||||
loadStyle(iconfontUrl.replace('$key', ele));
|
||||
})
|
||||
|
||||
loadStyle(iconfontUrl);
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
|
@ -1,123 +0,0 @@
|
||||
<template>
|
||||
<el-container class="menu-container pull-height">
|
||||
<el-header class="menu-header">
|
||||
<el-button-group>
|
||||
<el-button type="primary" icon="el-icon-plus" size="small" @click.native="handleAdd" v-if="permission.sys_menu_btn_add">新增</el-button>
|
||||
<el-button type="primary" icon="el-icon-edit" size="small" @click.native="handleEdit" v-if="permission.sys_menu_btn_edit">编辑</el-button>
|
||||
<el-button type="primary" icon="el-icon-delete" size="small" @click.native="handleDel" v-if="permission.sys_menu_btn_del">删除</el-button>
|
||||
</el-button-group>
|
||||
</el-header>
|
||||
<el-container>
|
||||
<el-aside width="300px">
|
||||
<el-tree
|
||||
:data="menuAll"
|
||||
node-key="id"
|
||||
highlight-current
|
||||
default-expand-all
|
||||
:expand-on-click-node="false"
|
||||
@node-click="handleNodeClick"></el-tree>
|
||||
</el-aside>
|
||||
<el-main>
|
||||
<el-form ref="form" :model="form" label-width="80px">
|
||||
<el-form-item label="父节点ID">
|
||||
<el-input v-model="parentForm.id" :disabled="true"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="父节点">
|
||||
<el-input v-model="parentForm.label" :disabled="true"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单名称">
|
||||
<el-input v-model="form.label" :disabled="formGrade"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单图标">
|
||||
<el-input v-model="form.icon" :disabled="formGrade"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单路径">
|
||||
<el-input v-model="form.href" :disabled="formGrade"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSubmit" :disabled="formGrade" v-if="formStatus=='add'">新增</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :disabled="formGrade" v-if="formStatus=='edit'">修改</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import { validatenull } from "@/util/validate";
|
||||
import { findParent } from "@/util/util";
|
||||
export default {
|
||||
name: "menu",
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
obj: {},
|
||||
parentForm: {},
|
||||
formGrade: true,
|
||||
formStatus: ""
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch("GetMenuAll").then(data => {});
|
||||
},
|
||||
mounted() {},
|
||||
computed: {
|
||||
...mapGetters(["permission", "menuAll"])
|
||||
},
|
||||
props: [],
|
||||
methods: {
|
||||
handleNodeClick(data, checked, indeterminate) {
|
||||
this.parentForm = Object.assign({}, findParent(this.menuAll, data.id));
|
||||
this.formGrade = true;
|
||||
this.formStatus = "";
|
||||
this.obj = data;
|
||||
this.form = data;
|
||||
},
|
||||
handleAdd() {
|
||||
this.formGrade = false;
|
||||
this.formStatus = "add";
|
||||
this.form = {};
|
||||
},
|
||||
handleEdit() {
|
||||
if (validatenull(this.obj)) {
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "请选择菜单",
|
||||
type: "warning"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
this.form = Object.assign({}, this.obj);
|
||||
this.formStatus = "edit";
|
||||
this.formGrade = false;
|
||||
},
|
||||
handleDel() {
|
||||
this.$confirm(`是否确认删除序号为${this.form.label}`, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "删除成功",
|
||||
type: "success"
|
||||
});
|
||||
})
|
||||
.catch(err => {});
|
||||
},
|
||||
handleSubmit() {}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.menu-container {
|
||||
padding: 0 20px;
|
||||
}
|
||||
.menu-header {
|
||||
padding: 8px 0;
|
||||
}
|
||||
</style>
|
@ -1,206 +0,0 @@
|
||||
<template>
|
||||
<div class="table-container pull-height">
|
||||
<div class="table-header">
|
||||
<el-button type="primary" @click="handleAdd" size="small" v-if="permission.sys_crud_btn_add">新 增</el-button>
|
||||
</div>
|
||||
<Crud
|
||||
:tableOption="tableOption"
|
||||
:tableData="tableData"
|
||||
:tableLoading="tableLoading"
|
||||
:page="page"
|
||||
ref="crud"
|
||||
width="290"
|
||||
@handleSave="handleSave"
|
||||
@handleUpdate="handleUpdate"
|
||||
@handleDel="handleDel"
|
||||
menu>
|
||||
<template slot-scope="scope">
|
||||
<el-button icon="el-icon-check" size="small" @click="handleGrade(scope.row,scope.$index)">权限</el-button>
|
||||
</template>
|
||||
</Crud>
|
||||
<el-dialog
|
||||
title="菜单"
|
||||
:visible.sync="grade.box"
|
||||
width="40%">
|
||||
<el-tree
|
||||
:data="menuAll"
|
||||
:default-checked-keys="grade.check"
|
||||
:default-expanded-keys="grade.check"
|
||||
show-checkbox
|
||||
node-key="id"
|
||||
@check-change="handleGradeCheckChange">
|
||||
</el-tree>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="handleGradeUpdate">更新</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import Crud from "@/components/crud/";
|
||||
import { roleOption } from "@/const/adminTabelOption.js";
|
||||
export default {
|
||||
name: "role",
|
||||
data() {
|
||||
return {
|
||||
tableOption: {}, //表格设置属性
|
||||
tableData: [], //表格的数据
|
||||
tablePage: 1,
|
||||
tableLoading: false,
|
||||
tabelObj: {},
|
||||
page: {
|
||||
total: 0, //总页数
|
||||
currentPage: 1, //当前页数
|
||||
pageSize: 10 //每页显示多少条
|
||||
},
|
||||
grade: {
|
||||
box: false,
|
||||
check: []
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
//初始化数据格式
|
||||
this.tableOption = roleOption;
|
||||
this.handleList();
|
||||
},
|
||||
watch: {},
|
||||
mounted() {},
|
||||
computed: {
|
||||
...mapGetters(["permission", "menuAll"])
|
||||
},
|
||||
props: [],
|
||||
methods: {
|
||||
/**
|
||||
* @title 权限更新
|
||||
*
|
||||
**/
|
||||
handleGradeUpdate() {
|
||||
this.tabelObj.check = [].concat(this.grade.check);
|
||||
this.tabelObj = {};
|
||||
this.grade.check = [];
|
||||
this.grade.box = false;
|
||||
},
|
||||
/**
|
||||
* @title 权限选择
|
||||
*
|
||||
**/
|
||||
handleGradeCheckChange(data, checked, indeterminate) {
|
||||
if (checked) {
|
||||
this.grade.check.push(data.id);
|
||||
} else {
|
||||
this.grade.check.splice(this.grade.check.indexOf(data.id), 1);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @title 打开权限
|
||||
*/
|
||||
handleGrade(row, index) {
|
||||
this.$store.dispatch("GetMenuAll").then(data => {
|
||||
this.grade.box = true;
|
||||
this.tabelObj = row;
|
||||
this.grade.check = this.tabelObj.check;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @title 打开新增窗口
|
||||
* @detail 调用crud的handleadd方法即可
|
||||
*
|
||||
**/
|
||||
handleAdd() {
|
||||
this.$refs.crud.handleAdd();
|
||||
},
|
||||
/**
|
||||
* @title 获取数据
|
||||
* @detail 赋值为tableData表格即可
|
||||
*
|
||||
**/
|
||||
handleList() {
|
||||
this.tableLoading = true;
|
||||
this.$store
|
||||
.dispatch("GetRoleData", { page: `${this.tablePage}` })
|
||||
.then(data => {
|
||||
setTimeout(() => {
|
||||
this.tableData = data.tableData;
|
||||
this.page = {
|
||||
total: data.total,
|
||||
pageSize: data.pageSize
|
||||
};
|
||||
this.tableLoading = false;
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @title 数据添加
|
||||
* @param row 为当前的数据
|
||||
* @param done 为表单关闭函数
|
||||
*
|
||||
**/
|
||||
handleSave(row, done) {
|
||||
this.tableData.push(row);
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "添加成功",
|
||||
type: "success"
|
||||
});
|
||||
done();
|
||||
},
|
||||
/**
|
||||
* @title 数据删除
|
||||
* @param row 为当前的数据
|
||||
* @param index 为当前更新数据的行数
|
||||
*
|
||||
**/
|
||||
handleDel(row, index) {
|
||||
this.$confirm(`是否确认删除序号为${row.name}`, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
this.tableData.splice(index, 1);
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "删除成功",
|
||||
type: "success"
|
||||
});
|
||||
})
|
||||
.catch(err => {});
|
||||
},
|
||||
/**
|
||||
* @title 数据更新
|
||||
* @param row 为当前的数据
|
||||
* @param index 为当前更新数据的行数
|
||||
* @param done 为表单关闭函数
|
||||
*
|
||||
**/
|
||||
handleUpdate(row, index, done) {
|
||||
this.tableData.splice(index, 1, row);
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "修改成功",
|
||||
type: "success"
|
||||
});
|
||||
done();
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Crud
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-container {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
.table-header {
|
||||
margin-bottom: 10px;
|
||||
& > .el-button {
|
||||
padding: 12px 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,157 +0,0 @@
|
||||
<template>
|
||||
<div class="table-container pull-height">
|
||||
<div class="table-header">
|
||||
<el-button type="primary" @click="handleAdd" size="small" v-if="permission.sys_crud_btn_add">新 增</el-button>
|
||||
</div>
|
||||
<Crud
|
||||
:tableOption="tableOption"
|
||||
:tableData="tableData"
|
||||
:tableLoading="tableLoading"
|
||||
:page="page"
|
||||
ref="crud"
|
||||
width="290"
|
||||
@handleSave="handleSave"
|
||||
@handleUpdate="handleUpdate"
|
||||
@handleDel="handleDel"
|
||||
menu>
|
||||
|
||||
</Crud>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import Crud from "@/components/crud/";
|
||||
import { userOption } from "@/const/adminTabelOption.js";
|
||||
export default {
|
||||
name: "user",
|
||||
data() {
|
||||
return {
|
||||
tableOption: {}, //表格设置属性
|
||||
tableData: [], //表格的数据
|
||||
tablePage: 1,
|
||||
tableLoading: false,
|
||||
tabelObj: {},
|
||||
page: {
|
||||
total: 0, //总页数
|
||||
currentPage: 1, //当前页数
|
||||
pageSize: 10 //每页显示多少条
|
||||
},
|
||||
grade: {
|
||||
box: false,
|
||||
check: []
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
//初始化数据格式
|
||||
this.tableOption = userOption;
|
||||
this.handleList();
|
||||
},
|
||||
watch: {},
|
||||
mounted() {},
|
||||
computed: {
|
||||
...mapGetters(["permission", "menuAll"])
|
||||
},
|
||||
props: [],
|
||||
methods: {
|
||||
/**
|
||||
* @title 打开新增窗口
|
||||
* @detail 调用crud的handleadd方法即可
|
||||
*
|
||||
**/
|
||||
handleAdd() {
|
||||
this.$refs.crud.handleAdd();
|
||||
},
|
||||
/**
|
||||
* @title 获取数据
|
||||
* @detail 赋值为tableData表格即可
|
||||
*
|
||||
**/
|
||||
handleList() {
|
||||
this.tableLoading = true;
|
||||
this.$store
|
||||
.dispatch("GetUserData", { page: `${this.tablePage}` })
|
||||
.then(data => {
|
||||
setTimeout(() => {
|
||||
this.tableData = data.tableData;
|
||||
this.page = {
|
||||
total: data.total,
|
||||
pageSize: data.pageSize
|
||||
};
|
||||
this.tableLoading = false;
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @title 数据添加
|
||||
* @param row 为当前的数据
|
||||
* @param done 为表单关闭函数
|
||||
*
|
||||
**/
|
||||
handleSave(row, done) {
|
||||
this.tableData.push(row);
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "添加成功",
|
||||
type: "success"
|
||||
});
|
||||
done();
|
||||
},
|
||||
/**
|
||||
* @title 数据删除
|
||||
* @param row 为当前的数据
|
||||
* @param index 为当前更新数据的行数
|
||||
*
|
||||
**/
|
||||
handleDel(row, index) {
|
||||
this.$confirm(`是否确认删除序号为${row.name}`, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
this.tableData.splice(index, 1);
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "删除成功",
|
||||
type: "success"
|
||||
});
|
||||
})
|
||||
.catch(err => {});
|
||||
},
|
||||
/**
|
||||
* @title 数据更新
|
||||
* @param row 为当前的数据
|
||||
* @param index 为当前更新数据的行数
|
||||
* @param done 为表单关闭函数
|
||||
*
|
||||
**/
|
||||
handleUpdate(row, index, done) {
|
||||
this.tableData.splice(index, 1, row);
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "修改成功",
|
||||
type: "success"
|
||||
});
|
||||
done();
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Crud
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-container {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
.table-header {
|
||||
margin-bottom: 10px;
|
||||
& > .el-button {
|
||||
padding: 12px 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,67 +0,0 @@
|
||||
<template>
|
||||
<div class="errpage-container pull-chheight">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>404错误页面</span>
|
||||
</div>
|
||||
<div class="error-box">
|
||||
<errorPage404 class="error-page"></errorPage404>
|
||||
<span class="error-text">/404当访问的页面不存在时会跳转到404页面,您可以在浏览器地址栏中修改url为一个不存在的路径,体验一下效果</span>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>403错误页面</span>
|
||||
</div>
|
||||
<div class="error-box">
|
||||
<errorPage403 class="error-page"></errorPage403>
|
||||
<span class="error-text">/403在当前登录用户不具有执行当前操作的权限时跳转到该页面,您可以在ajax请求方法中判断返回的状态码为403时跳转到该页面</span>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>500错误页面</span>
|
||||
</div>
|
||||
<div class="error-box">
|
||||
<errorPage500 class="error-page"></errorPage500>
|
||||
<span class="error-text">/500当请求之后出现服务端错误时跳转到该页面,您可以在ajax请求方法中判断返回的状态码为500时跳转到该页面</span>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import errorPage404 from "@/components/errorPage/404.vue";
|
||||
import errorPage403 from "@/components/errorPage/403.vue";
|
||||
import errorPage500 from "@/components/errorPage/500.vue";
|
||||
export default {
|
||||
name: "errPage",
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
computed: {},
|
||||
props: [],
|
||||
methods: {},
|
||||
components: { errorPage404, errorPage403, errorPage500 }
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.error-page {
|
||||
position: absolute;
|
||||
top: 90px;
|
||||
left: 150px;
|
||||
transform: scale(0.4);
|
||||
}
|
||||
.error-text {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 340px;
|
||||
}
|
||||
.error-box {
|
||||
position: relative;
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
@ -1,13 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--error code-->
|
||||
{{a.a}}
|
||||
<!--error code-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "errorTestA"
|
||||
};
|
||||
</script>
|
@ -1,67 +0,0 @@
|
||||
<template>
|
||||
<div class="errlog-container pull-chheight">
|
||||
<h5>
|
||||
<el-tag>tip:</el-tag> 错误是存储在本地,可以自己回掉方法上传服务器,调用vuex中的CLEAR_ALL_ERR方法清空本地记录
|
||||
</h5>
|
||||
<h5 v-if="errLog.length==0">
|
||||
还没有错误日志了!!!
|
||||
你可以放开 <el-tag type="danger">./src/page/errlog/index.vue中的errorA标签</el-tag> 的组件即可测试<br />
|
||||
</h5>
|
||||
<!-- <errorA></errorA> -->
|
||||
<div v-for="(err,index) in errLog" :key="index" class="errlog-list" v-else>
|
||||
<p class="errlog-item"><el-tag type="info">地址</el-tag><span>{{err.url}}</span></p>
|
||||
<p class="errlog-item"><el-tag type="danger">信息</el-tag><span>{{err.message}}</span></p>
|
||||
<div class="errlog-info">
|
||||
{{err.stack}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import errorA from "./errorTestA";
|
||||
export default {
|
||||
name: "errlog",
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
computed: {
|
||||
...mapGetters(["errLog"])
|
||||
},
|
||||
props: [],
|
||||
methods: {},
|
||||
components: { errorA }
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.errlog-container {
|
||||
padding: 15px;
|
||||
}
|
||||
.errlog-list {
|
||||
& > .errlog-item {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
& > span {
|
||||
font-size: 14px;
|
||||
}
|
||||
& > .el-tag {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
& > .errlog-info {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
padding: 8px 10px;
|
||||
background-color: #fff;
|
||||
font-size: 12px;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 5px;
|
||||
border-color: #ccc;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,85 +0,0 @@
|
||||
<template>
|
||||
<div class="from-container pull-chheight">
|
||||
<Form
|
||||
:formOption="formOption"
|
||||
:formSubmitText="formSubmitText"
|
||||
@handleSubmit="handleSubmit"
|
||||
></Form>
|
||||
<el-button @click.native="formate" style="margin: 8px 0">格式化</el-button>
|
||||
<el-input
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 2, maxRows: 15}"
|
||||
placeholder="请输入内容"
|
||||
v-model="formJson">
|
||||
</el-input>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import Form from "@/components/form/";
|
||||
import formOption from "@/const/formOption";
|
||||
export default {
|
||||
name: "from",
|
||||
data() {
|
||||
return {
|
||||
formJson: "",
|
||||
formOption: formOption,
|
||||
formSubmitText: "确定",
|
||||
form: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.formJson = JSON.stringify(formOption, null, 2);
|
||||
},
|
||||
watch: {},
|
||||
mounted() {},
|
||||
computed: {
|
||||
...mapGetters(["permission"])
|
||||
},
|
||||
props: [],
|
||||
methods: {
|
||||
formate() {
|
||||
let p = new Promise((resolve, reject) => {
|
||||
resolve(JSON.parse(this.formJson));
|
||||
});
|
||||
p
|
||||
.then(data => {
|
||||
this.formOption = data;
|
||||
this.formJson = JSON.stringify(data, null, 2);
|
||||
this.$message({
|
||||
message: "数据加载成功",
|
||||
type: "success"
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message({
|
||||
center: true,
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: `JSON格式错误<br \>\n${err}`,
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
},
|
||||
handleSubmit(form) {
|
||||
if (form) {
|
||||
this.form = form;
|
||||
this.$message({
|
||||
message: form,
|
||||
type: "success"
|
||||
});
|
||||
} else {
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Form
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.from-container {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
</style>
|
@ -1,97 +0,0 @@
|
||||
<template>
|
||||
<div class="iconfon-container pull-height">
|
||||
<h3 style="color:red;">修改./src/config/env.js中的iconfontVersion地址即可实时调用阿里云在线图标库</h3>
|
||||
<ul class="icon-list">
|
||||
<li><span><i class="icon-daohanglanmoshi02"></i><span class="icon-name">icon-daohanglanmoshi02</span></span></li>
|
||||
<li><span><i class="icon-changyonglogo27"></i><span class="icon-name">icon-changyonglogo27</span></span></li>
|
||||
<li><span><i class="icon-biaoge"></i><span class="icon-name">icon-biaoge</span></span></li>
|
||||
<li><span><i class="icon-baidu1"></i><span class="icon-name">icon-baidu1</span></span></li>
|
||||
<li><span><i class="icon-tubiao"></i><span class="icon-name">icon-tubiao</span></span></li>
|
||||
<li><span><i class="icon-souhu"></i><span class="icon-name">icon-souhu</span></span></li>
|
||||
<li><span><i class="icon-msnui-360"></i><span class="icon-name">icon-msnui-360</span></span></li>
|
||||
<li><span><i class="icon-iframe"></i><span class="icon-name">icon-iframe</span></span></li>
|
||||
<li><span><i class="icon-huanyingye"></i><span class="icon-name">icon-huanyingye</span></span></li>
|
||||
<li><span><i class="icon-weixin"></i><span class="icon-name">icon-weixin</span></span></li>
|
||||
<li><span><i class="icon-qq"></i><span class="icon-name">icon-qq</span></span></li>
|
||||
<li><span><i class="icon-tuichu"></i><span class="icon-name">icon-tuichu</span></span></li>
|
||||
<li><span><i class="icon-jiaoseguanli"></i><span class="icon-name">icon-jiaoseguanli</span></span></li>
|
||||
<li><span><i class="icon-yonghuguanli"></i><span class="icon-name">icon-yonghuguanli</span></span></li>
|
||||
<li><span><i class="icon-caidanguanli"></i><span class="icon-name">icon-caidanguanli</span></span></li>
|
||||
</ul>
|
||||
<img class="iconfon-explace" src="http://oetrwxnhv.bkt.clouddn.com/avue-iconfont.png" alt="">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "iconfont",
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
props: [],
|
||||
methods: {},
|
||||
components: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.iconfon-container {
|
||||
padding: 15px;
|
||||
}
|
||||
.iconfon-container > ul.icon-list {
|
||||
margin: 15px auto;
|
||||
overflow: hidden;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
border: 1px solid #eaeefb;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.iconfon-container .content > ul:not(.timeline) {
|
||||
margin: 10px 0;
|
||||
padding: 0 0 0 20px;
|
||||
font-size: 14px;
|
||||
color: #5e6d82;
|
||||
line-height: 2em;
|
||||
}
|
||||
.icon-list li {
|
||||
float: left;
|
||||
width: 16.66%;
|
||||
text-align: center;
|
||||
height: 120px;
|
||||
line-height: 120px;
|
||||
color: #666;
|
||||
font-size: 13px;
|
||||
transition: color 0.15s linear;
|
||||
border-right: 1px solid #eee;
|
||||
border-bottom: 1px solid #eee;
|
||||
margin-right: -1px;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
.icon-list li span {
|
||||
display: inline-block;
|
||||
line-height: normal;
|
||||
vertical-align: middle;
|
||||
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
|
||||
Microsoft YaHei, SimSun, sans-serif;
|
||||
color: #99a9bf;
|
||||
}
|
||||
.icon-list li i {
|
||||
display: block;
|
||||
font-size: 36px !important;
|
||||
margin-bottom: 15px;
|
||||
color: #606266;
|
||||
}
|
||||
.icon-list li .icon-name {
|
||||
display: inline-block;
|
||||
padding: 0 12px;
|
||||
font-size: 12px !important;
|
||||
height: 1em;
|
||||
color: #606266;
|
||||
}
|
||||
.iconfon-explace {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
@ -1,22 +1,27 @@
|
||||
<template>
|
||||
<div class="pull-height animated" :class="{'zoomOutUp': isLock}">
|
||||
<Top></Top>
|
||||
<div class="index">
|
||||
<Sidebar class="left pull-chheight"></Sidebar>
|
||||
<div class="right">
|
||||
<Tags ref="nav" class="nav"></Tags>
|
||||
<router-view class="main"></router-view>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pull-height animated" :class="{'zoomOutUp': isLock}">
|
||||
<top></top>
|
||||
<div class="index">
|
||||
<sidebar class="left pull-chheight"></sidebar>
|
||||
<div class="right">
|
||||
<tags ref="nav" class="nav"></tags>
|
||||
<router-view class="main pull-chheight"></router-view>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import Tags from "./tags";
|
||||
import Top from "./top/";
|
||||
import Sidebar from "./sidebar/";
|
||||
import tags from "./tags";
|
||||
import top from "./top/";
|
||||
import sidebar from "./sidebar/";
|
||||
export default {
|
||||
components: {
|
||||
top,
|
||||
tags,
|
||||
sidebar
|
||||
},
|
||||
name: "index",
|
||||
data() {
|
||||
return {};
|
||||
@ -25,12 +30,7 @@ export default {
|
||||
mounted() {},
|
||||
computed: mapGetters(["isLock"]),
|
||||
props: [],
|
||||
methods: {},
|
||||
components: {
|
||||
Top,
|
||||
Tags,
|
||||
Sidebar
|
||||
}
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -43,13 +43,14 @@ export default {
|
||||
min-height: 100%;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
.left {
|
||||
.left:not(.el-menu--collapse) {
|
||||
width: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.right {
|
||||
padding-top: 102px;
|
||||
padding-top: 90px;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.main {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-menu unique-opened :default-active="tag.value" class="el-menu-vertical-demo" background-color="#495060" text-color="#c9cbd0" active-text-color="#409EFF" :collapse="isCollapse">
|
||||
<el-menu unique-opened :default-active="nowTagValue" class="el-menu-vertical-demo" background-color="#495060" text-color="#c9cbd0" active-text-color="#fff" :collapse="isCollapse">
|
||||
<sidebar-item :menu="menu" :show="!isCollapse"></sidebar-item>
|
||||
</el-menu>
|
||||
</template>
|
||||
@ -7,6 +7,7 @@
|
||||
<script>
|
||||
import MENU from "@/mock/menu";
|
||||
import { mapGetters } from "vuex";
|
||||
import { setUrlPath } from "@/util/util";
|
||||
import SidebarItem from "./sidebarItem";
|
||||
|
||||
export default {
|
||||
@ -16,7 +17,12 @@ export default {
|
||||
created() {
|
||||
this.$store.dispatch("GetMenu").then(data => {});
|
||||
},
|
||||
computed: mapGetters(["menu", "tag", "isCollapse"]),
|
||||
computed: {
|
||||
...mapGetters(["menu", "tag", "isCollapse"]),
|
||||
nowTagValue: function() {
|
||||
return setUrlPath(this.$route);
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
methods: {},
|
||||
components: { SidebarItem }
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="menu-wrapper">
|
||||
<template v-for="item in menu">
|
||||
<el-menu-item v-if="item.children.length===0 " :index="item.component" @click="open(item)" :key="item.label">
|
||||
<el-menu-item v-if="item.children.length===0 " :index="item.path" @click="open(item)" :key="item.label">
|
||||
<i :class="item.icon"></i>
|
||||
<span slot="title">{{item.label}}</span>
|
||||
</el-menu-item>
|
||||
@ -11,7 +11,7 @@
|
||||
<span slot="title" :class="{display:!show}">{{item.label}}</span>
|
||||
</template>
|
||||
<template v-for="child in item.children">
|
||||
<el-menu-item v-if="child.children.length==0" :index="child.component" @click="open(child)">
|
||||
<el-menu-item v-if="child.children.length==0" :index="child.path" @click="open(child)">
|
||||
<i :class="child.icon"></i>
|
||||
<span slot="title">{{child.label}}</span>
|
||||
</el-menu-item>
|
||||
@ -40,10 +40,10 @@ export default {
|
||||
mounted() {},
|
||||
methods: {
|
||||
open(item) {
|
||||
this.$router.push({ path: resolveUrlPath(item.href) });
|
||||
this.$router.push({ path: resolveUrlPath(item.path) });
|
||||
this.$store.commit("ADD_TAG", {
|
||||
label: item.label,
|
||||
value: item.href
|
||||
value: item.path
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,8 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { resolveUrlPath } from "@/util/util";
|
||||
import { resolveUrlPath, setUrlPath } from "@/util/util";
|
||||
import { baseUrl } from "@/config/env";
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import Breadcrumb from "./breadcrumb";
|
||||
export default {
|
||||
@ -77,11 +78,7 @@ export default {
|
||||
computed: {
|
||||
...mapGetters(["tagWel", "tagList", "isCollapse", "tag"]),
|
||||
nowTagValue: function() {
|
||||
const value = this.$route.query.src
|
||||
? this.$route.query.src
|
||||
: this.$route.path;
|
||||
this.$store.commit("SET_TAG", value);
|
||||
return value;
|
||||
return setUrlPath(this.$route);
|
||||
},
|
||||
tagListNum: function() {
|
||||
return this.tagList.length != 0;
|
||||
@ -91,12 +88,14 @@ export default {
|
||||
init() {
|
||||
this.refsTag = this.$refs.tagsPageOpened;
|
||||
setTimeout(() => {
|
||||
this.refsTag.forEach((item, index) => {
|
||||
if (this.tag.value === item.attributes.name.value) {
|
||||
let tag = this.refsTag[index];
|
||||
this.moveToView(tag);
|
||||
}
|
||||
});
|
||||
if (this.refsTag) {
|
||||
this.refsTag.forEach((item, index) => {
|
||||
if (this.tag.value === item.attributes.name.value) {
|
||||
let tag = this.refsTag[index];
|
||||
this.moveToView(tag);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 1);
|
||||
},
|
||||
showCollapse() {
|
||||
|
@ -1,9 +1,11 @@
|
||||
<template>
|
||||
<div class="header">
|
||||
<div class="header-button is-left">
|
||||
<h3 style="letter-spacing: 1px;">Avue 通用管理系统快速开发框架</h3>
|
||||
<top-logo></top-logo>
|
||||
</div>
|
||||
<h1 class="header-title"></h1>
|
||||
<h1 class="header-title">
|
||||
<!-- <topMenu></topMenu> -->
|
||||
</h1>
|
||||
<div class="header-button is-right">
|
||||
<el-tooltip class="item" effect="dark" content="锁屏" placement="bottom">
|
||||
<span class="header-item">
|
||||
@ -43,9 +45,11 @@
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import { fullscreenToggel } from "@/util/util";
|
||||
import topLogo from "./top-logo";
|
||||
import topLock from "./top-lock";
|
||||
import topMenu from "./top-menu";
|
||||
export default {
|
||||
components: { topLock },
|
||||
components: { topLock, topLogo, topMenu },
|
||||
name: "top",
|
||||
data() {
|
||||
return {};
|
||||
|
40
src/page/index/top/top-logo.vue
Normal file
40
src/page/index/top/top-logo.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div class="pull-auto">
|
||||
<div class="logo">
|
||||
<span class="logo_title is-bold">Pig </span>
|
||||
<span class="logo_subtitle"> 微服务快速开发框架</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "top-logo",
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() {},
|
||||
computed: {},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped="scoped" lang="scss">
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.logo_title {
|
||||
padding: 0 8px 0 0;
|
||||
color: #409eff;
|
||||
line-height: 60px;
|
||||
font-size: 28px;
|
||||
font-style: italic;
|
||||
&.is-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
.logo_subtitle {
|
||||
padding-top: 5px;
|
||||
}
|
||||
</style>
|
65
src/page/index/top/top-menu.vue
Normal file
65
src/page/index/top/top-menu.vue
Normal file
@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<div class="pull-auto top-menu">
|
||||
<el-menu :default-active="activeIndex" mode="horizontal">
|
||||
<template v-for="item in items">
|
||||
<el-menu-item :index="item.parentId+''" @click.native="openMenu(item)">{{item.label}}</el-menu-item>
|
||||
</template>
|
||||
</el-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { resolveUrlPath } from "@/util/util";
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
export default {
|
||||
name: "top-menu",
|
||||
data() {
|
||||
return {
|
||||
activeIndex: "0",
|
||||
items: [
|
||||
{
|
||||
label: "首页",
|
||||
href: "/wel/index",
|
||||
parentId: 0
|
||||
},
|
||||
{
|
||||
label: "设置",
|
||||
parentId: 1
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
computed: {
|
||||
...mapGetters(["tagCurrent", "menu"])
|
||||
},
|
||||
methods: {
|
||||
openMenu(item) {
|
||||
this.$store.dispatch("GetMenu", item.parentId).then(data => {
|
||||
this.$store.commit("DEL_ALL_TAG");
|
||||
let tagCurrent = Object.assign([], this.tagCurrent);
|
||||
tagCurrent[0] = {
|
||||
label: item.label,
|
||||
value: item.href
|
||||
};
|
||||
this.$store.commit("SET_TAG_CURRENT", tagCurrent);
|
||||
this.$router.push({
|
||||
path: resolveUrlPath(item.href ? item.href : this.menu[0].href)
|
||||
});
|
||||
this.$store.commit("ADD_TAG", {
|
||||
label: item.label ? item.label : this.menu[0].label,
|
||||
value: item.href ? item.href : this.menu[0].href
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped="scoped" lang="scss">
|
||||
.top-menu {
|
||||
padding: 0 50px;
|
||||
margin-top: -4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
@ -14,6 +14,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters, mapState } from "vuex";
|
||||
import { resolveUrlPath } from "@/util/util";
|
||||
export default {
|
||||
name: "lock",
|
||||
data() {
|
||||
@ -60,7 +61,7 @@ export default {
|
||||
this.pass = true;
|
||||
setTimeout(() => {
|
||||
this.$store.commit("CLEAR_LOCK");
|
||||
this.$router.push({ path: this.tag.value || "/" });
|
||||
this.$router.push({ path: resolveUrlPath(this.tag.value || "/") });
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
|
@ -1,12 +1,16 @@
|
||||
<template>
|
||||
<div class="login-container pull-height pull-overflow" @keyup.enter.native="handleLogin">
|
||||
<div class="login-container pull-height" @keyup.enter.native="handleLogin">
|
||||
<div class="login-info text-white animated fadeInLeft">
|
||||
<h2>Pig 微服务快速开发框架</h2>
|
||||
<ul>
|
||||
<li><i class="el-icon-check"></i> 是一个基于Spring Cloud、oAuth2.0开发基于Vue前后分离的开发平台</li>
|
||||
<li><i class="el-icon-check"></i> 是一个基于vue+vuex+vue-router快速后台管理系统,采用token交互验证方式。</li>
|
||||
<li><i class="el-icon-check"></i> 最大程度上帮助企业节省时间成本和费用开支。 </li>
|
||||
<li><i class="el-icon-check"></i> QQ群:23754102 </li>
|
||||
<h2 class="login-info-title">Pig 微服务快速开发框架</h2>
|
||||
<ul class="login-info-list">
|
||||
<li class="login-info-item">
|
||||
<i class="el-icon-check"></i> 是一个基于Spring Cloud、oAuth2.0开发基于Vue前后分离的开发平台</li>
|
||||
<li class="login-info-item">
|
||||
<i class="el-icon-check"></i> 是一个基于vue+vuex+vue-router快速后台管理系统,采用token交互验证方式。</li>
|
||||
<li class="login-info-item">
|
||||
<i class="el-icon-check"></i> 最大程度上帮助企业节省时间成本和费用开支。 </li>
|
||||
<li class="login-info-item">
|
||||
<i class="el-icon-check"></i> QQ群:23754102 </li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="login-border pull-height">
|
||||
@ -18,7 +22,7 @@
|
||||
<userLogin></userLogin>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="短信验证码" name="code">
|
||||
<codeLogin></codeLogin>
|
||||
<codeLogin></codeLogin>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="第三方授权登录" name="third">
|
||||
<thirdLogin></thirdLogin>
|
||||
@ -27,7 +31,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import userLogin from "./userlogin";
|
||||
@ -77,10 +81,10 @@ export default {
|
||||
.login-info {
|
||||
padding-left: 60px;
|
||||
}
|
||||
.login-info > ul {
|
||||
padding: 20px 0;
|
||||
.login-info-title {
|
||||
line-height: 90px;
|
||||
}
|
||||
.login-info > ul > li {
|
||||
.login-info-item {
|
||||
font-size: 14px;
|
||||
}
|
||||
.login-border {
|
||||
|
@ -1,63 +0,0 @@
|
||||
<template>
|
||||
<div class="pull-chheight role-container">
|
||||
<el-card class="box-card">
|
||||
<p>当前用户的权限值是有权限时(admin) 时,才可以看到菜单有这个页面。</p>
|
||||
<el-switch
|
||||
v-model="roleSwitch"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
active-value="admin"
|
||||
active-text="有权限(admin)"
|
||||
inactive-value="user"
|
||||
inactive-text="无权限(user)" @change="handlechange">
|
||||
</el-switch>
|
||||
</el-card>
|
||||
<el-card class="box-card" style="margin-top:20px;">
|
||||
<p>当前用户的权限值是有权限时(admin) 时。才能看到全部按钮</p>
|
||||
<el-button v-if="permission.sys_role_btn1">默认按钮</el-button>
|
||||
<el-button type="primary" v-if="permission.sys_role_btn2">主要按钮</el-button>
|
||||
<el-button type="success" v-if="permission.sys_role_btn3">成功按钮</el-button>
|
||||
<el-button type="info" v-if="permission.sys_role_btn4">信息按钮</el-button>
|
||||
<el-button type="warning" v-if="permission.sys_role_btn5">警告按钮</el-button>
|
||||
<el-button type="danger" v-if="permission.sys_role_btn6">危险按钮</el-button>
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
export default {
|
||||
name: "role",
|
||||
data() {
|
||||
return {
|
||||
roleSwitch: ""
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.roleSwitch = this.roles[0];
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["roles", "permission"])
|
||||
},
|
||||
methods: {
|
||||
handlechange(val) {
|
||||
this.$store.commit("SET_ROLES", [val]);
|
||||
if (val == "user") {
|
||||
this.$store.commit("SET_PERMISSION", [
|
||||
"sys_role_btn1",
|
||||
"sys_role_btn2"
|
||||
]);
|
||||
} else if (val == "admin") {
|
||||
this.$store.dispatch("GetUserInfo");
|
||||
}
|
||||
|
||||
this.$store.dispatch("GetMenu");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped="scoped" lang="scss">
|
||||
|
||||
</style>
|
@ -1,315 +0,0 @@
|
||||
<template>
|
||||
<div class="table-container pull-chheight">
|
||||
<div class="table-header">
|
||||
<el-button type="primary" @click="handleAdd" size="small" v-if="permission.sys_crud_btn_add">新 增</el-button>
|
||||
<el-button type="success" @click="handleExport" size="small" v-if="permission.sys_crud_btn_export">导出excel</el-button>
|
||||
<el-button @click="toggleSelection([tableData[1]])" size="small">切换第二选中状态</el-button>
|
||||
<el-button @click="toggleSelection()" size="small">取消选择</el-button>
|
||||
</div>
|
||||
<Crud
|
||||
:tableOption="tableOption"
|
||||
:tableData="tableData"
|
||||
:tableLoading="tableLoading"
|
||||
:before-open="boxhandleOpen"
|
||||
:before-close="boxhandleClose"
|
||||
:page="page"
|
||||
ref="crud"
|
||||
width="290"
|
||||
@handleSave="handleSave"
|
||||
@handleUpdate="handleUpdate"
|
||||
@handleDel="handleDel"
|
||||
@handleCurrentChange="handleCurrentChange"
|
||||
@handleSelectionChange="handleSelectionChange"
|
||||
:menu="true">
|
||||
<template slot-scope="scope">
|
||||
<el-button icon="el-icon-check" size="small" @click="handleGrade(scope.row,scope.$index)">权限</el-button>
|
||||
</template>
|
||||
</Crud>
|
||||
<el-button @click.native="formate" style="margin: 8px 0">格式化</el-button>
|
||||
<el-input
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 2, maxRows: 15}"
|
||||
placeholder="请输入内容"
|
||||
v-model="formJson">
|
||||
</el-input>
|
||||
<el-dialog
|
||||
title="菜单"
|
||||
:visible.sync="grade.box"
|
||||
width="40%">
|
||||
<el-tree
|
||||
:data="menuAll"
|
||||
:default-checked-keys="grade.check"
|
||||
:default-expanded-keys="grade.check"
|
||||
show-checkbox
|
||||
node-key="id">
|
||||
</el-tree>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="handleGradeUpdate">更新</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import Crud from "@/components/crud/";
|
||||
import tableOption from "@/const/tableOption";
|
||||
export default {
|
||||
name: "table",
|
||||
data() {
|
||||
return {
|
||||
tableOption: tableOption, //表格设置属性
|
||||
tableData: [], //表格的数据
|
||||
tablePage: 1,
|
||||
tableLoading: false,
|
||||
tabelObj: {},
|
||||
formJson: "",
|
||||
page: {
|
||||
total: 0, //总页数
|
||||
currentPage: 1, //当前页数
|
||||
pageSize: 10 //每页显示多少条
|
||||
},
|
||||
grade: {
|
||||
box: false,
|
||||
check: []
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.formJson = JSON.stringify(tableOption, null, 2);
|
||||
this.handleList();
|
||||
},
|
||||
watch: {},
|
||||
mounted() {},
|
||||
computed: {
|
||||
...mapGetters(["permission", "menuAll"])
|
||||
},
|
||||
props: [],
|
||||
methods: {
|
||||
formate() {
|
||||
let p = new Promise((resolve, reject) => {
|
||||
resolve(JSON.parse(this.formJson));
|
||||
});
|
||||
p
|
||||
.then(data => {
|
||||
this.tableOption = data;
|
||||
this.formJson = JSON.stringify(data, null, 2);
|
||||
this.$message({
|
||||
message: "数据加载成功",
|
||||
type: "success"
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message({
|
||||
center: true,
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: `JSON格式错误<br \>\n${err}`,
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @title 权限更新
|
||||
*
|
||||
**/
|
||||
handleGradeUpdate() {
|
||||
this.tabelObj.check = [].concat(this.grade.check);
|
||||
this.tabelObj = {};
|
||||
this.grade.check = [];
|
||||
this.grade.box = false;
|
||||
},
|
||||
/**
|
||||
* @title 权限选择
|
||||
*
|
||||
**/
|
||||
handleGradeCheckChange(data, checked, indeterminate) {
|
||||
if (checked) {
|
||||
this.grade.check.push(data.id);
|
||||
} else {
|
||||
this.grade.check.splice(this.grade.check.indexOf(data.id), 1);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @title 打开权限
|
||||
*/
|
||||
handleGrade(row, index) {
|
||||
this.$store.dispatch("GetMenuAll").then(data => {
|
||||
this.grade.box = true;
|
||||
this.tabelObj = row;
|
||||
this.grade.check = this.tabelObj.check;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @title 导出excel
|
||||
*
|
||||
**/
|
||||
handleExport() {
|
||||
import("@/vendor/Export2Excel").then(excel => {
|
||||
const tHeader = ["username", "name"];
|
||||
const filterVal = ["username", "name"];
|
||||
const list = this.tableData;
|
||||
const data = this.formatJson(filterVal, list);
|
||||
excel.export_json_to_excel(tHeader, data, this.filename);
|
||||
});
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v =>
|
||||
filterVal.map(j => {
|
||||
if (j === "timestamp") {
|
||||
return parseTime(v[j]);
|
||||
} else {
|
||||
return v[j];
|
||||
}
|
||||
})
|
||||
);
|
||||
},
|
||||
/**
|
||||
* @title 页面改变值
|
||||
*
|
||||
**/
|
||||
handleCurrentChange(val) {
|
||||
this.tablePage = val;
|
||||
this.handleList();
|
||||
},
|
||||
/**
|
||||
* @title 打开新增窗口
|
||||
* @detail 调用crud的handleadd方法即可
|
||||
*
|
||||
**/
|
||||
handleAdd() {
|
||||
this.$refs.crud.handleAdd();
|
||||
},
|
||||
/**
|
||||
* @title 选中第几行
|
||||
* @param row 选中那几行数据
|
||||
* @detail 调用crud的toggleSelection方法即可
|
||||
*
|
||||
**/
|
||||
toggleSelection(row) {
|
||||
this.$refs.crud.toggleSelection(row);
|
||||
},
|
||||
/**
|
||||
* @title 获取数据
|
||||
* @detail 赋值为tableData表格即可
|
||||
*
|
||||
**/
|
||||
handleList() {
|
||||
this.tableLoading = true;
|
||||
this.$store
|
||||
.dispatch("GetTableData", { page: `${this.tablePage}` })
|
||||
.then(data => {
|
||||
setTimeout(() => {
|
||||
this.tableData = data.tableData;
|
||||
this.page = {
|
||||
total: data.total,
|
||||
pageSize: data.pageSize
|
||||
};
|
||||
this.tableLoading = false;
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @title 当前选中的数据
|
||||
* @param val 选中的值
|
||||
*
|
||||
**/
|
||||
handleSelectionChange(val) {
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: JSON.stringify(val),
|
||||
type: "success"
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @title 数据添加
|
||||
* @param row 为当前的数据
|
||||
* @param done 为表单关闭函数
|
||||
*
|
||||
**/
|
||||
handleSave(row, done) {
|
||||
this.tableData.push(row);
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "添加成功",
|
||||
type: "success"
|
||||
});
|
||||
done();
|
||||
},
|
||||
/**
|
||||
* @title 数据删除
|
||||
* @param row 为当前的数据
|
||||
* @param index 为当前更新数据的行数
|
||||
*
|
||||
**/
|
||||
handleDel(row, index) {
|
||||
this.$confirm(`是否确认删除序号为${row.name}`, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
this.tableData.splice(index, 1);
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "删除成功",
|
||||
type: "success"
|
||||
});
|
||||
})
|
||||
.catch(err => {});
|
||||
},
|
||||
/**
|
||||
* @title 数据更新
|
||||
* @param row 为当前的数据
|
||||
* @param index 为当前更新数据的行数
|
||||
* @param done 为表单关闭函数
|
||||
*
|
||||
**/
|
||||
handleUpdate(row, index, done) {
|
||||
this.tableData.splice(index, 1, row);
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "修改成功",
|
||||
type: "success"
|
||||
});
|
||||
done();
|
||||
},
|
||||
/**
|
||||
* @title 表单关闭前处理
|
||||
* @param done
|
||||
*
|
||||
**/
|
||||
boxhandleClose(done) {
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "表单关闭前处理事件",
|
||||
type: "success"
|
||||
});
|
||||
done();
|
||||
},
|
||||
boxhandleOpen(show) {
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: "表单打开前处理事件",
|
||||
type: "success"
|
||||
});
|
||||
show();
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Crud
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-container {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
.table-header {
|
||||
margin-bottom: 10px;
|
||||
& > .el-button {
|
||||
padding: 12px 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,14 +1,10 @@
|
||||
<template>
|
||||
<div class="app-main">
|
||||
<div class="yun-content">
|
||||
<div class="banner-sky"></div>
|
||||
<div class="banner-text">
|
||||
<h2>Pig 微服务快速开发框架</h2>
|
||||
<span :class="['actor',{typeing:isText}]">{{text}}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="pull-chheight wel-contailer">
|
||||
<div class="banner-text">
|
||||
<h2>Pig 微服务快速开发框架</h2>
|
||||
<span :class="['actor',{typeing:isText}]">{{text}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -84,27 +80,25 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped="scoped" lang="scss">
|
||||
.yun-content {
|
||||
background-color: #eee;
|
||||
.wel-contailer {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.banner-sky {
|
||||
position: absolute;
|
||||
top: -100px;
|
||||
bottom: -15px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transform: skewY(-4deg);
|
||||
transform-origin: center;
|
||||
background-color: #fcfcfc;
|
||||
}
|
||||
|
||||
.banner-text {
|
||||
position: relative;
|
||||
padding: 0 20px;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.banner-img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.8;
|
||||
display: none;
|
||||
}
|
||||
.actor {
|
||||
height: 250px;
|
||||
overflow: hidden;
|
||||
|
@ -58,13 +58,13 @@ function findMenuParent(tagCurrent, tag, tagWel) {
|
||||
} else {//其他操作
|
||||
let currentPathObj = store.getters.menu.filter(item => {
|
||||
if (item.children.length == 1) {
|
||||
return item.children[0].href === tag.value;
|
||||
return item.children[0].path === tag.value;
|
||||
} else {
|
||||
let i = 0;
|
||||
let childArr = item.children;
|
||||
let len = childArr.length;
|
||||
while (i < len) {
|
||||
if (childArr[i].href === tag.value) {
|
||||
if (childArr[i].path === tag.value) {
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
|
@ -1 +1 @@
|
||||
module.exports = file => require(`../page/${file}.vue`)
|
||||
module.exports = (path, file) => require(`../${path}/${file}.vue`)
|
@ -7,7 +7,7 @@ import { getStore, getSessionStore, vaildUtil } from '@/util/yun'
|
||||
|
||||
|
||||
import Myiframe from '@/components/iframe/iframe.vue'
|
||||
import INDEX from '@/page/index/'
|
||||
import Layout from '@/page/index/'
|
||||
import errorPage404 from '@/components/errorPage/404.vue';
|
||||
import errorPage403 from '@/components/errorPage/403.vue';
|
||||
import errorPage500 from '@/components/errorPage/500.vue';
|
||||
@ -31,8 +31,8 @@ export default new VueRouter({
|
||||
},
|
||||
});
|
||||
export const asyncRouterMap = [
|
||||
{ path: '/login', name: '登录页', component: _import('login/index') },
|
||||
{ path: '/lock', name: '锁屏页', component: _import('lock/index') },
|
||||
{ path: '/login', name: '登录页', component: _import('page', 'login/index') },
|
||||
{ path: '/lock', name: '锁屏页', component: _import('page', 'lock/index') },
|
||||
{ path: '*', redirect: '/404', hidden: true },
|
||||
{ path: '/404', component: errorPage404, name: '404' },
|
||||
{ path: '/403', component: errorPage403, name: '403' },
|
||||
@ -44,7 +44,7 @@ export const asyncRouterMap = [
|
||||
},
|
||||
{
|
||||
path: '/myiframe',
|
||||
component: INDEX,
|
||||
component: Layout,
|
||||
redirect: '/myiframe',
|
||||
children: [
|
||||
{
|
||||
@ -57,91 +57,32 @@ export const asyncRouterMap = [
|
||||
|
||||
}, {
|
||||
path: '/wel',
|
||||
component: INDEX,
|
||||
component: Layout,
|
||||
redirect: '/wel/index',
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: '首页',
|
||||
component: _import('wel')
|
||||
}
|
||||
]
|
||||
}, {
|
||||
path: '/role',
|
||||
component: INDEX,
|
||||
redirect: '/role/index',
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: '权限测试页',
|
||||
component: _import('role')
|
||||
}
|
||||
]
|
||||
}, {
|
||||
path: '/table',
|
||||
component: INDEX,
|
||||
redirect: '/table/index',
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: '表格CRUD',
|
||||
component: _import('table/index')
|
||||
}
|
||||
]
|
||||
}, {
|
||||
path: '/form',
|
||||
component: INDEX,
|
||||
redirect: '/form/index',
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: '表单CRUD',
|
||||
component: _import('form/index')
|
||||
}
|
||||
]
|
||||
}, {
|
||||
path: '/iconfont',
|
||||
component: INDEX,
|
||||
redirect: '/iconfont/index',
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: '阿里图标',
|
||||
component: _import('iconfont/index')
|
||||
}
|
||||
]
|
||||
}, {
|
||||
path: '/errlog',
|
||||
component: INDEX,
|
||||
redirect: '/errlog/index',
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: '错误日志',
|
||||
component: _import('errlog/index')
|
||||
}, {
|
||||
path: 'page',
|
||||
name: '错误页面',
|
||||
component: _import('errlog/errorPage')
|
||||
component: _import('page', 'wel')
|
||||
}
|
||||
]
|
||||
}, {
|
||||
menuId: 1,
|
||||
path: '/admin',
|
||||
component: INDEX,
|
||||
component: Layout,
|
||||
name: '系统管理',
|
||||
hidden: false,
|
||||
redirect: '/admin/user',
|
||||
meta: {
|
||||
title: '系统管理',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'user',
|
||||
name: '用户管理',
|
||||
component: _import('admin/user/index')
|
||||
}, {
|
||||
path: 'role',
|
||||
name: '角色管理',
|
||||
component: _import('admin/role/index')
|
||||
}, {
|
||||
path: 'menu',
|
||||
name: '菜单管理',
|
||||
component: _import('admin/menu/index')
|
||||
}
|
||||
{ menuId: 2, path: 'user', component: _import('views', 'admin/user/index'), name: '用户管理', meta: { title: '用户管理' } },
|
||||
{ menuId: 3, path: 'menu', component: _import('views', 'admin/menu/index'), name: '菜单管理', meta: { title: '菜单管理' } },
|
||||
{ menuId: 4, path: 'role', component: _import('views', 'admin/role/index'), name: '角色管理', meta: { title: '角色管理' } },
|
||||
{ menuId: 5, path: 'dept', component: _import('views', 'admin/dept/index'), name: '部门管理', meta: { title: '部门管理' } },
|
||||
{ menuId: 6, path: 'dict', component: _import('views', 'admin/dict/index'), name: '字典管理', meta: { title: '字典管理' } },
|
||||
{ menuId: 7, path: 'log', component: _import('views', 'admin/log/index'), name: '日志管理', meta: { title: '日志管理' } }
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
@ -3,7 +3,6 @@ import Vuex from 'vuex'
|
||||
import user from './modules/user'
|
||||
import common from './modules/common'
|
||||
import tags from './modules/tags'
|
||||
import admin from './modules/admin'
|
||||
import errLog from './modules/errLog'
|
||||
import getters from './getters'
|
||||
|
||||
@ -13,7 +12,6 @@ const store = new Vuex.Store({
|
||||
user,
|
||||
common,
|
||||
errLog,
|
||||
admin,
|
||||
tags
|
||||
},
|
||||
getters,
|
||||
|
@ -1,30 +0,0 @@
|
||||
import { getUserData, getRoleData } from '@/api/admin'
|
||||
const user = {
|
||||
state: {
|
||||
|
||||
},
|
||||
actions: {
|
||||
GetUserData({ commit, state, dispatch }, page) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getUserData(page).then(res => {
|
||||
const data = res.data;
|
||||
resolve(data);
|
||||
})
|
||||
})
|
||||
},
|
||||
GetRoleData({ commit, state, dispatch }, page) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getRoleData(page).then(res => {
|
||||
const data = res.data;
|
||||
resolve(data);
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
mutations: {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
export default user
|
@ -25,7 +25,7 @@ const navs = {
|
||||
label: "首页",
|
||||
value: "/wel/index"
|
||||
},
|
||||
tagCurrent: [{
|
||||
tagCurrent: getStore({ name: 'tagCurrent' }) || [{
|
||||
label: "首页",
|
||||
value: "/wel/index"
|
||||
}],
|
||||
@ -36,7 +36,7 @@ const navs = {
|
||||
mutations: {
|
||||
ADD_TAG: (state, action) => {
|
||||
state.tag = action;
|
||||
setStore({ name: 'tag', content: state.tag, type: 'session' })
|
||||
setStore({ name: 'tag', content: state.tag })
|
||||
if (state.tagList.some(a => a.value === action.value)) return
|
||||
state.tagList.push({
|
||||
label: action.label,
|
||||
@ -50,13 +50,12 @@ const navs = {
|
||||
setStore({ name: 'tagCurrent', content: state.tagCurrent })
|
||||
},
|
||||
SET_TAG: (state, value) => {
|
||||
for (const [i, v] of state.tagList.entries()) {
|
||||
if (v.value === value) {
|
||||
state.tag = state.tagList[i];
|
||||
state.tagList.forEach((ele, num) => {
|
||||
if (ele.value === value) {
|
||||
state.tag = state.tagList[num];
|
||||
setStore({ name: 'tag', content: state.tag })
|
||||
break
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
DEL_ALL_TAG: (state, action) => {
|
||||
state.tag = tagObj;
|
||||
@ -65,28 +64,26 @@ const navs = {
|
||||
removeStore({ name: 'tagList' });
|
||||
},
|
||||
DEL_TAG_OTHER: (state, action) => {
|
||||
for (const [i, v] of state.tagList.entries()) {
|
||||
if (v.value === state.tag.value) {
|
||||
state.tagList = state.tagList.slice(i, i + 1)
|
||||
state.tagList.forEach((ele, num) => {
|
||||
if (ele.value === state.tag.value) {
|
||||
state.tagList = state.tagList.slice(num, num + 1)
|
||||
state.tag = state.tagList[0];
|
||||
state.tagList[0].close = false;
|
||||
setStore({ name: 'tag', content: state.tag })
|
||||
setStore({ name: 'tagList', content: state.tagList })
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
DEL_TAG: (state, action) => {
|
||||
for (const [i, a] of state.tagList.entries()) {
|
||||
if (a.value === action.value) {
|
||||
state.tagList.splice(i, 1)
|
||||
state.tagList.forEach((ele, num) => {
|
||||
if (ele.value === action.value) {
|
||||
state.tagList.splice(num, 1)
|
||||
state.tagList = setFistTag(state.tagList);
|
||||
setStore({ name: 'tag', content: state.tagList, type: 'session' })
|
||||
setStore({ name: 'tagList', content: state.tagList, type: 'session' })
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -182,3 +182,34 @@ table {
|
||||
.text-white{
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
&:after {
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
content: " ";
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
//main-container全局样式
|
||||
.app-main{
|
||||
min-height: 100%
|
||||
}
|
||||
|
||||
.filter-container {
|
||||
padding-bottom: 10px;
|
||||
.filter-item {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,9 @@
|
||||
font-size: 12px;
|
||||
line-height: 28px;
|
||||
}
|
||||
.el-menu--popup{
|
||||
padding: 0;
|
||||
}
|
||||
.el-select,.el-date-editor.el-input, .el-date-editor.el-input__inner{
|
||||
width: 100%;
|
||||
}
|
@ -8,17 +8,16 @@
|
||||
|
||||
@mixin scrollBar {
|
||||
&::-webkit-scrollbar-track-piece {
|
||||
box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||
background-color: #fff;
|
||||
}
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: #999;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
background-color: #fff;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
box-shadow: inset 0 0 6px rgba(0,0,0,.3);
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 5px;
|
||||
background-color: #48576a;
|
||||
background-color: hsla(220,4%,58%,.3);
|
||||
}
|
||||
}
|
||||
@mixin radius($width,$size,$color){
|
||||
|
@ -1,14 +1,4 @@
|
||||
|
||||
.el-menu:not(.el-menu--collapse) {
|
||||
width: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.el-menu{
|
||||
border-right: 0;
|
||||
.is-active{
|
||||
color:#fff !important;
|
||||
}
|
||||
}
|
||||
.hideSidebar {
|
||||
.sidebar-container,.sidebar-container .el-menu {
|
||||
width: 36px!important;
|
||||
|
@ -6,18 +6,17 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16px;
|
||||
height: 60px;
|
||||
height: 50px;
|
||||
}
|
||||
.tags-breadcrumb-list{
|
||||
padding: 0 25px;
|
||||
}
|
||||
.tags-box{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
padding-right: 106px;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
overflow:hidden;
|
||||
background: #f0f0f0;
|
||||
|
||||
}
|
||||
@ -28,16 +27,15 @@
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
.tags-list{
|
||||
flex: 1;
|
||||
position: relative;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.tag-scroll{
|
||||
width: 200%;
|
||||
position: absolute;
|
||||
padding: 2px 10px;
|
||||
overflow: visible;
|
||||
white-space: nowrap;
|
||||
transition: left .3s ease;
|
||||
}
|
||||
.tag-item-icon{
|
||||
color: #eee;
|
||||
font-size: 10px !important;
|
||||
font-size: 11px !important;
|
||||
}
|
||||
.tag-item-icon.is-active{
|
||||
color: $mainBg;
|
||||
@ -69,8 +67,16 @@
|
||||
opacity: .85;
|
||||
}
|
||||
.tags-menu{
|
||||
margin-right: 5px;
|
||||
position: absolute;
|
||||
top:0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 15px;
|
||||
height: 96%;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
box-shadow: -3px 0 15px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
.contextmenu {
|
||||
|
@ -1,43 +1,43 @@
|
||||
.header {
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-bottom:2px solid $menuBg;
|
||||
color: #333;
|
||||
box-sizing: border-box;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
font-size: 18px;
|
||||
height: 60px;
|
||||
line-height: 1;
|
||||
padding: 0 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: inherit;
|
||||
font-weight: 400;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.header-userImg{
|
||||
margin: 0 3px 0 10px;
|
||||
padding: 2px;
|
||||
width: 35px;
|
||||
height:35px;
|
||||
border-radius: 100%;
|
||||
box-sizing: border-box;
|
||||
border:1px solid #eee;
|
||||
}
|
||||
.header-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.header-button>.header-item{
|
||||
margin-right: 12px;
|
||||
}
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-bottom:2px solid $menuBg;
|
||||
color: #333;
|
||||
box-sizing: border-box;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
font-size: 18px;
|
||||
height: 60px;
|
||||
line-height: 1;
|
||||
padding: 0 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: inherit;
|
||||
font-weight: 400;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.header-userImg{
|
||||
margin: 0 3px 0 10px;
|
||||
padding: 2px;
|
||||
width: 35px;
|
||||
height:35px;
|
||||
border-radius: 100%;
|
||||
box-sizing: border-box;
|
||||
border:1px solid #eee;
|
||||
}
|
||||
.header-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.header-button>.header-item{
|
||||
margin-right: 12px;
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
import { validatenull } from './validate'
|
||||
|
||||
|
||||
import { baseUrl } from '@/config/env'
|
||||
|
||||
|
||||
/**
|
||||
@ -80,14 +79,37 @@ export const findParent = (menu, id) => {
|
||||
* 总体路由处理器
|
||||
*/
|
||||
export const resolveUrlPath = (url) => {
|
||||
|
||||
let reqUrl = url;
|
||||
if (url.indexOf("http") != -1) {
|
||||
if (url.indexOf("#") != -1 && url.indexOf("http") == -1) {
|
||||
const port = reqUrl.substr(reqUrl.indexOf(':'));
|
||||
reqUrl = `/myiframe/urlPath?src=${baseUrl}${port}${reqUrl.replace('#', '').replace(port, '')}`;
|
||||
} else if (url.indexOf("http") != -1) {
|
||||
reqUrl = `/myiframe/urlPath?src=${reqUrl}`;
|
||||
} else {
|
||||
reqUrl = `${reqUrl}`;
|
||||
}
|
||||
return reqUrl;
|
||||
}
|
||||
/**
|
||||
* 总体路由设置器
|
||||
*/
|
||||
export const setUrlPath = ($route) => {
|
||||
let value = "";
|
||||
if ($route.query.src) {
|
||||
value = $route.query.src;
|
||||
if (value.indexOf(baseUrl) != -1) {
|
||||
const port = value
|
||||
.substr(value.lastIndexOf(":"))
|
||||
.replace(value.substr(value.lastIndexOf("/")), "");
|
||||
const path = value.replace(baseUrl + port, "");
|
||||
value = "#" + path + port;
|
||||
}
|
||||
} else {
|
||||
value = $route.path;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* 动态插入css
|
||||
*/
|
||||
|
205
src/views/admin/dept/index.vue
Normal file
205
src/views/admin/dept/index.vue
Normal file
@ -0,0 +1,205 @@
|
||||
`<template>
|
||||
<div class="app-container calendar-list-container">
|
||||
<div class="filter-container">
|
||||
<el-button-group>
|
||||
<el-button type="primary" v-if="deptManager_btn_add" icon="plus" @click="handlerAdd">添加</el-button>
|
||||
<el-button type="primary" v-if="deptManager_btn_edit" icon="edit" @click="handlerEdit">编辑</el-button>
|
||||
<el-button type="primary" v-if="deptManager_btn_del" icon="delete" @click="handleDelete">删除</el-button>
|
||||
</el-button-group>
|
||||
</div>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="8" style='margin-top:15px;'>
|
||||
<el-tree
|
||||
class="filter-tree"
|
||||
:data="treeData"
|
||||
node-key="id"
|
||||
highlight-current
|
||||
:props="defaultProps"
|
||||
:filter-node-method="filterNode"
|
||||
@node-click="getNodeData"
|
||||
default-expand-all
|
||||
>
|
||||
</el-tree>
|
||||
</el-col>
|
||||
<el-col :span="16" style='margin-top:15px;'>
|
||||
<el-card class="box-card">
|
||||
<el-form :label-position="labelPosition" label-width="80px" :model="form" ref="form">
|
||||
<el-form-item label="父级节点" prop="parentId">
|
||||
<el-input v-model="form.parentId" :disabled="formEdit" placeholder="请输入父级节点"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="节点编号" prop="parentId" v-if="formEdit">
|
||||
<el-input v-model="form.deptId" :disabled="formEdit" placeholder="节点编号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="部门名称" prop="name">
|
||||
<el-input v-model="form.name" :disabled="formEdit" placeholder="请输入名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="orderNum">
|
||||
<el-input v-model="form.orderNum" :disabled="formEdit" placeholder="请输入排序"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formStatus == 'update'">
|
||||
<el-button type="primary" @click="update">更新</el-button>
|
||||
<el-button @click="onCancel">取消</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formStatus == 'create'">
|
||||
<el-button type="primary" @click="create">保存</el-button>
|
||||
<el-button @click="onCancel">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchTree, getObj, addObj, delObj, putObj } from '@/api/dept'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'menu',
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
total: null,
|
||||
formEdit: true,
|
||||
formAdd: true,
|
||||
formStatus: '',
|
||||
showElement: false,
|
||||
typeOptions: ['0', '1'],
|
||||
methodOptions: ['GET', 'POST', 'PUT', 'DELETE'],
|
||||
listQuery: {
|
||||
name: undefined
|
||||
},
|
||||
treeData: [],
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'name'
|
||||
},
|
||||
labelPosition: 'right',
|
||||
form: {
|
||||
name: undefined,
|
||||
orderNum: undefined,
|
||||
parentId: undefined,
|
||||
deptId: undefined
|
||||
},
|
||||
currentId: 0,
|
||||
deptManager_btn_add: false,
|
||||
deptManager_btn_edit: false,
|
||||
deptManager_btn_del: false
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
typeFilter(type) {
|
||||
const typeMap = {
|
||||
0: '菜单',
|
||||
1: '按钮'
|
||||
}
|
||||
return typeMap[type]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
this.deptManager_btn_add = this.permissions['sys_dept_add']
|
||||
this.deptManager_btn_edit = this.permissions['sys_dept_edit']
|
||||
this.deptManager_btn_del = this.permissions['sys_dept_del']
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'elements',
|
||||
'permissions'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
fetchTree(this.listQuery).then(response => {
|
||||
this.treeData = response.data
|
||||
})
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
return data.label.indexOf(value) !== -1
|
||||
},
|
||||
getNodeData(data) {
|
||||
if (!this.formEdit) {
|
||||
this.formStatus = 'update'
|
||||
}
|
||||
getObj(data.id).then(response => {
|
||||
this.form = response.data
|
||||
})
|
||||
this.currentId = data.id
|
||||
this.showElement = true
|
||||
},
|
||||
handlerEdit() {
|
||||
if (this.form.deptId) {
|
||||
this.formEdit = false
|
||||
this.formStatus = 'update'
|
||||
}
|
||||
},
|
||||
handlerAdd() {
|
||||
this.resetForm()
|
||||
this.formEdit = false
|
||||
this.formStatus = 'create'
|
||||
},
|
||||
handleDelete() {
|
||||
this.$confirm('此操作将永久删除, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
delObj(this.currentId).then(() => {
|
||||
this.getList()
|
||||
this.resetForm()
|
||||
this.onCancel()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
update() {
|
||||
putObj(this.form).then(() => {
|
||||
this.getList()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
},
|
||||
create() {
|
||||
addObj(this.form).then(() => {
|
||||
this.getList()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
},
|
||||
onCancel() {
|
||||
this.formEdit = true
|
||||
this.formStatus = ''
|
||||
},
|
||||
resetForm() {
|
||||
this.form = {
|
||||
permission: undefined,
|
||||
name: undefined,
|
||||
menuId: undefined,
|
||||
parentId: this.currentId,
|
||||
url: undefined,
|
||||
icon: undefined,
|
||||
sort: undefined,
|
||||
component: undefined,
|
||||
type: undefined,
|
||||
method: undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
230
src/views/admin/dict/index.vue
Normal file
230
src/views/admin/dict/index.vue
Normal file
@ -0,0 +1,230 @@
|
||||
<template>
|
||||
<div class="app-container calendar-list-container">
|
||||
<div class="filter-container">
|
||||
<el-button v-if="sys_dict_add" class="filter-item" style="margin-left: 10px;" @click="handleCreate" type="primary" icon="edit">添加
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :key='tableKey' :data="list" v-loading="listLoading" element-loading-text="给我一点时间" border fit highlight-current-row style="width: 99%">
|
||||
<el-table-column align="center" label="编号">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.id }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="数据值">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.value }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="标签名">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.label }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="类型">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.type }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="描述">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.description }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="排序">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.sort }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="创建时间">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime | parseTime('{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="备注信息">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.remarks }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-if="sys_dict_upd" size="small" type="success" @click="handleUpdate(scope.row)">编辑
|
||||
</el-button>
|
||||
<el-button v-if="sys_dict_del" size="mini" type="danger" @click="handleDelete(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-show="!listLoading" class="pagination-container">
|
||||
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page.sync="listQuery.page" :page-sizes="[10,20,30, 50]" :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
||||
<el-form :model="form" :rules="rules" ref="form" label-width="100px">
|
||||
<el-form-item label="编号" prop="username">
|
||||
<el-input v-model="form.id" placeholder="编号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="数据值" prop="username">
|
||||
<el-input v-model="form.value" placeholder="数据值"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签名" prop="username">
|
||||
<el-input v-model="form.label" placeholder="标签名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="username">
|
||||
<el-input v-model="form.type" placeholder="类型"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="username">
|
||||
<el-input v-model="form.description" placeholder="描述"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序(升序)" prop="username">
|
||||
<el-input v-model="form.sort" placeholder="排序(升序)"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="username">
|
||||
<el-input v-model="form.createTime" placeholder="创建时间"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注信息" prop="username">
|
||||
<el-input v-model="form.remarks" placeholder="备注信息"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel('form')">取 消</el-button>
|
||||
<el-button v-if="dialogStatus=='create'" type="primary" @click="create('form')">确 定</el-button>
|
||||
<el-button v-else type="primary" @click="update('form')">修 改</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, addObj, putObj, delObj } from "@/api/dict";
|
||||
import waves from "@/directive/waves/index.js"; // 水波纹指令
|
||||
import { mapGetters } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "table_sys_dict",
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20
|
||||
},
|
||||
rules: {},
|
||||
form: {},
|
||||
dialogFormVisible: false,
|
||||
dialogStatus: "",
|
||||
sys_dict_add: false,
|
||||
sys_dict_upd: false,
|
||||
sys_dict_del: false,
|
||||
textMap: {
|
||||
update: "编辑",
|
||||
create: "创建"
|
||||
},
|
||||
tableKey: 0
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["permissions"])
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
0: "有效",
|
||||
1: "无效"
|
||||
};
|
||||
return statusMap[status];
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
this.sys_dict_add = this.permissions["sys_dict_add"];
|
||||
this.sys_dict_upd = this.permissions["sys_dict_upd"];
|
||||
this.sys_dict_del = this.permissions["sys_dict_del"];
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
this.listQuery.orderByField = "create_time";
|
||||
this.listQuery.isAsc = false;
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.records;
|
||||
this.total = response.data.total;
|
||||
this.listLoading = false;
|
||||
});
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val;
|
||||
this.getList();
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val;
|
||||
this.getList();
|
||||
},
|
||||
handleDelete(row) {
|
||||
delObj(row).then(response => {
|
||||
this.dialogFormVisible = false;
|
||||
this.getList();
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "删除成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
},
|
||||
handleCreate() {
|
||||
this.dialogStatus = "create";
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
create(formName) {
|
||||
const set = this.$refs;
|
||||
set[formName].validate(valid => {
|
||||
if (valid) {
|
||||
addObj(this.form).then(() => {
|
||||
this.dialogFormVisible = false;
|
||||
this.getList();
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "创建成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
cancel(formName) {
|
||||
this.dialogFormVisible = false;
|
||||
const set = this.$refs;
|
||||
set[formName].resetFields();
|
||||
},
|
||||
update(formName) {
|
||||
const set = this.$refs;
|
||||
set[formName].validate(valid => {
|
||||
if (valid) {
|
||||
this.dialogFormVisible = false;
|
||||
this.form.password = undefined;
|
||||
putObj(this.form).then(() => {
|
||||
this.dialogFormVisible = false;
|
||||
this.getList();
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "修改成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
160
src/views/admin/log/index.vue
Normal file
160
src/views/admin/log/index.vue
Normal file
@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div class="app-container calendar-list-container">
|
||||
<div class="filter-container">
|
||||
<el-select v-model="listQuery.type" filterable placeholder="请选择">
|
||||
<el-option v-for="item in dicts" :key="item.value" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-button class="filter-item" type="primary" v-waves icon="search" @click="handleFilter">搜索</el-button>
|
||||
</div>
|
||||
<el-table :key='tableKey' :data="list" v-loading="listLoading" element-loading-text="给我一点时间" border fit highlight-current-row style="width: 99%">
|
||||
|
||||
<el-table-column align="center" label="序号">
|
||||
<template slot-scope="scope">
|
||||
<span>{{Number(scope.row.id).toFixed()}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="类型" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>
|
||||
<el-button type="success" v-if="scope.row.type == 0">{{ scope.row.type | typeFilter }}</el-button>
|
||||
<el-button type="danger" v-if="scope.row.type ==9">{{ scope.row.type | typeFilter }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="请求接口" show-overflow-tooltip>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.requestUri}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="IP地址">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.remoteAddr}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="请求方式">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.method}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="传入参数" show-overflow-tooltip>
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.params}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="请求时间">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.time}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="创建时间">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.createTime | parseTime('{y}-{m}-{d} {h}:{i}')}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="danger" v-if="sys_log_del" @click="handleDelete(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-show="!listLoading" class="pagination-container">
|
||||
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page.sync="listQuery.page" :page-sizes="[10,20,30, 50]" :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { delObj, fetchList } from "@/api/log";
|
||||
import { remote } from "@/api/dict";
|
||||
import waves from "@/directive/waves/index.js"; // 水波纹指令
|
||||
import { mapGetters } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "table_log",
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
total: null,
|
||||
sys_dict_add: false,
|
||||
listLoading: true,
|
||||
dicts: [],
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
type: undefined
|
||||
},
|
||||
tableKey: 0
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["permissions"])
|
||||
},
|
||||
filters: {
|
||||
typeFilter(type) {
|
||||
const typeMap = {
|
||||
0: "正常",
|
||||
9: "异常"
|
||||
};
|
||||
return typeMap[type];
|
||||
}
|
||||
},
|
||||
created() {
|
||||
remote("log_type").then(response => {
|
||||
this.dicts = response.data;
|
||||
});
|
||||
console.log(this.dicts);
|
||||
this.getList();
|
||||
this.sys_log_del = this.permissions["sys_log_del"];
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
this.listQuery.orderByField = "create_time";
|
||||
this.listQuery.isAsc = false;
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.records;
|
||||
this.total = response.data.total;
|
||||
this.listLoading = false;
|
||||
});
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val;
|
||||
this.getList();
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val;
|
||||
this.getList();
|
||||
},
|
||||
handleDelete(row) {
|
||||
delObj(row.id).then(response => {
|
||||
this.dialogFormVisible = false;
|
||||
this.getList();
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "删除成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1;
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
233
src/views/admin/menu/index.vue
Normal file
233
src/views/admin/menu/index.vue
Normal file
@ -0,0 +1,233 @@
|
||||
<template>
|
||||
<div class="app-container calendar-list-container">
|
||||
<div class="filter-container">
|
||||
<el-button-group>
|
||||
<el-button type="primary" v-if="menuManager_btn_add" icon="plus" @click="handlerAdd">添加</el-button>
|
||||
<el-button type="primary" v-if="menuManager_btn_edit" icon="edit" @click="handlerEdit">编辑</el-button>
|
||||
<el-button type="primary" v-if="menuManager_btn_del" icon="delete" @click="handleDelete">删除</el-button>
|
||||
</el-button-group>
|
||||
</div>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="8" style='margin-top:15px;'>
|
||||
<el-tree
|
||||
class="filter-tree"
|
||||
:data="treeData"
|
||||
node-key="id"
|
||||
highlight-current
|
||||
:props="defaultProps"
|
||||
:filter-node-method="filterNode"
|
||||
@node-click="getNodeData"
|
||||
default-expand-all
|
||||
>
|
||||
</el-tree>
|
||||
</el-col>
|
||||
<el-col :span="16" style='margin-top:15px;'>
|
||||
<el-card class="box-card">
|
||||
<el-form :label-position="labelPosition" label-width="80px" :model="form" ref="form">
|
||||
<el-form-item label="父级节点" prop="parentId">
|
||||
<el-input v-model="form.parentId" :disabled="formEdit" placeholder="请输入父级节点"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="节点ID" prop="parentId">
|
||||
<el-input v-model="form.menuId" :disabled="formEdit" placeholder="请输入节点ID"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="标题" prop="name">
|
||||
<el-input v-model="form.name" :disabled="formEdit" placeholder="请输入标题"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="权限标识" prop="permission">
|
||||
<el-input v-model="form.permission" :disabled="formEdit" placeholder="请输入权限标识"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="图标" prop="icon">
|
||||
<el-input v-model="form.icon" :disabled="formEdit" placeholder="请输入图标"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="资源路径" prop="url">
|
||||
<el-input v-model="form.url" :disabled="formEdit" placeholder="请输入资源路径"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="请求方法" prop="method">
|
||||
<el-select class="filter-item" v-model="form.method" :disabled="formEdit" placeholder="请输入资源请求类型">
|
||||
<el-option v-for="item in methodOptions" :key="item" :label="item" :value="item"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select class="filter-item" v-model="form.type" :disabled="formEdit" placeholder="请输入资源请求类型">
|
||||
<el-option v-for="item in typeOptions" :key="item" :label="item | typeFilter" :value="item"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input v-model="form.sort" :disabled="formEdit" placeholder="请输入排序"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="前端组件" prop="component">
|
||||
<el-input v-model="form.component" :disabled="formEdit" placeholder="请输入描述"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formStatus == 'update'">
|
||||
<el-button type="primary" @click="update">更新</el-button>
|
||||
<el-button @click="onCancel">取消</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formStatus == 'create'">
|
||||
<el-button type="primary" @click="create">保存</el-button>
|
||||
<el-button @click="onCancel">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchTree, getObj, addObj, delObj, putObj } from '@/api/menu'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'menu',
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
total: null,
|
||||
formEdit: true,
|
||||
formAdd: true,
|
||||
formStatus: '',
|
||||
showElement: false,
|
||||
typeOptions: ['0', '1'],
|
||||
methodOptions: ['GET', 'POST', 'PUT', 'DELETE'],
|
||||
listQuery: {
|
||||
name: undefined
|
||||
},
|
||||
treeData: [],
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'name'
|
||||
},
|
||||
labelPosition: 'right',
|
||||
form: {
|
||||
permission: undefined,
|
||||
name: undefined,
|
||||
menuId: undefined,
|
||||
parentId: undefined,
|
||||
url: undefined,
|
||||
icon: undefined,
|
||||
sort: undefined,
|
||||
component: undefined,
|
||||
type: undefined,
|
||||
method: undefined
|
||||
},
|
||||
currentId: -1,
|
||||
menuManager_btn_add: false,
|
||||
menuManager_btn_edit: false,
|
||||
menuManager_btn_del: false
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
typeFilter(type) {
|
||||
const typeMap = {
|
||||
0: '菜单',
|
||||
1: '按钮'
|
||||
}
|
||||
return typeMap[type]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
this.menuManager_btn_add = this.permissions['sys_menu_add']
|
||||
this.menuManager_btn_edit = this.permissions['sys_menu_edit']
|
||||
this.menuManager_btn_del = this.permissions['sys_menu_del']
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'elements',
|
||||
'permissions'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
fetchTree(this.listQuery).then(response => {
|
||||
this.treeData = response.data
|
||||
})
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
return data.label.indexOf(value) !== -1
|
||||
},
|
||||
getNodeData(data) {
|
||||
if (!this.formEdit) {
|
||||
this.formStatus = 'update'
|
||||
}
|
||||
getObj(data.id).then(response => {
|
||||
this.form = response.data
|
||||
})
|
||||
this.currentId = data.id
|
||||
this.showElement = true
|
||||
},
|
||||
handlerEdit() {
|
||||
if (this.form.menuId) {
|
||||
this.formEdit = false
|
||||
this.formStatus = 'update'
|
||||
}
|
||||
},
|
||||
handlerAdd() {
|
||||
this.resetForm()
|
||||
this.formEdit = false
|
||||
this.formStatus = 'create'
|
||||
},
|
||||
handleDelete() {
|
||||
this.$confirm('此操作将永久删除, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
delObj(this.currentId).then(() => {
|
||||
this.getList()
|
||||
this.resetForm()
|
||||
this.onCancel()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
update() {
|
||||
putObj(this.form).then(() => {
|
||||
this.getList()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
},
|
||||
create() {
|
||||
addObj(this.form).then(() => {
|
||||
this.getList()
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
},
|
||||
onCancel() {
|
||||
this.formEdit = true
|
||||
this.formStatus = ''
|
||||
},
|
||||
resetForm() {
|
||||
this.form = {
|
||||
permission: undefined,
|
||||
name: undefined,
|
||||
menuId: undefined,
|
||||
parentId: this.currentId,
|
||||
url: undefined,
|
||||
icon: undefined,
|
||||
sort: undefined,
|
||||
component: undefined,
|
||||
type: undefined,
|
||||
method: undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
344
src/views/admin/role/index.vue
Normal file
344
src/views/admin/role/index.vue
Normal file
@ -0,0 +1,344 @@
|
||||
<template>
|
||||
<div class="app-container calendar-list-container">
|
||||
<div class="filter-container">
|
||||
<el-button class="filter-item" style="margin-left: 10px;" @click="handleCreate" type="primary" icon="edit">添加
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :key='tableKey' :data="list" v-loading="listLoading" element-loading-text="给我一点时间" border fit highlight-current-row style="width: 99%">
|
||||
|
||||
<el-table-column align="center" label="序号">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.roleId}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="角色名称">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.roleName}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="角色标识">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.roleCode}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="角色描述">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.roleDesc }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="所属部门">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.deptName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="创建时间">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.createTime | parseTime('{y}-{m}-{d} {h}:{i}')}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="220">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="success" @click="handleUpdate(scope.row)">编辑
|
||||
</el-button>
|
||||
<el-button size="mini" type="danger" @click="handleDelete(scope.row)">删除
|
||||
</el-button>
|
||||
<el-button size="mini" type="info" plain @click="handlePermission(scope.row)">权限
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
|
||||
<div v-show="!listLoading" class="pagination-container">
|
||||
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page.sync="listQuery.page" :page-sizes="[10,20,30, 50]" :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
||||
<el-form :model="form" :rules="rules" ref="form" label-width="100px">
|
||||
<el-form-item label="角色名称" prop="roleName">
|
||||
<el-input v-model="form.roleName" placeholder="角色名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色标识" prop="roleCode">
|
||||
<el-input v-model="form.roleCode" placeholder="角色标识"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="roleDesc">
|
||||
<el-input v-model="form.roleDesc" placeholder="描述"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属部门" prop="roleDept">
|
||||
<el-input v-model="form.deptName" placeholder="选择部门" @focus="handleDept()" readonly></el-input>
|
||||
<el-input type="hidden" v-model="form.roleDeptId"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel('form')">取 消</el-button>
|
||||
<el-button v-if="dialogStatus=='create'" type="primary" @click="create('form')">确 定</el-button>
|
||||
<el-button v-else type="primary" @click="update('form')">修 改</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogDeptVisible">
|
||||
<el-tree class="filter-tree" :data="treeDeptData" :default-checked-keys="checkedKeys" check-strictly node-key="id" highlight-current ref="deptTree" @node-click="getNodeData" :props="defaultProps" :filter-node-method="filterNode" default-expand-all>
|
||||
</el-tree>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogPermissionVisible">
|
||||
<el-tree class="filter-tree" :data="treeData" :default-checked-keys="checkedKeys" check-strictly node-key="id" highlight-current :props="defaultProps" show-checkbox ref="menuTree" :filter-node-method="filterNode" default-expand-all>
|
||||
</el-tree>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="updatePermession(roleId, roleCode)">更 新</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
fetchList,
|
||||
getObj,
|
||||
addObj,
|
||||
putObj,
|
||||
delObj,
|
||||
permissionUpd,
|
||||
fetchRoleTree,
|
||||
fetchDeptTree
|
||||
} from "@/api/role";
|
||||
import { fetchTree } from "@/api/menu";
|
||||
import waves from "@/directive/waves/index.js"; // 水波纹指令
|
||||
|
||||
export default {
|
||||
name: "table_role",
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
treeData: [],
|
||||
treeDeptData: [],
|
||||
checkedKeys: [],
|
||||
defaultProps: {
|
||||
children: "children",
|
||||
label: "name"
|
||||
},
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20
|
||||
},
|
||||
form: {
|
||||
roleName: undefined,
|
||||
roleCode: undefined,
|
||||
roleDesc: undefined,
|
||||
deptName: undefined,
|
||||
roleDeptId: undefined
|
||||
},
|
||||
roleId: undefined,
|
||||
roleCode: undefined,
|
||||
rules: {
|
||||
roleName: [
|
||||
{
|
||||
required: true,
|
||||
message: "角色名称",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 3,
|
||||
max: 20,
|
||||
message: "长度在 3 到 20 个字符",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
roleCode: [
|
||||
{
|
||||
required: true,
|
||||
message: "角色标识",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 3,
|
||||
max: 20,
|
||||
message: "长度在 3 到 20 个字符",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
roleDesc: [
|
||||
{
|
||||
required: true,
|
||||
message: "角色标识",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 3,
|
||||
max: 20,
|
||||
message: "长度在 3 到 20 个字符",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
},
|
||||
statusOptions: ["0", "1"],
|
||||
rolesOptions: undefined,
|
||||
dialogFormVisible: false,
|
||||
dialogDeptVisible: false,
|
||||
dialogPermissionVisible: false,
|
||||
dialogStatus: "",
|
||||
textMap: {
|
||||
update: "编辑",
|
||||
create: "创建",
|
||||
permission: "分配权限"
|
||||
},
|
||||
tableKey: 0
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.records;
|
||||
this.total = response.data.total;
|
||||
this.listLoading = false;
|
||||
});
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val;
|
||||
this.getList();
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val;
|
||||
this.getList();
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp();
|
||||
this.dialogStatus = "create";
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
handleUpdate(row) {
|
||||
getObj(row.roleId).then(response => {
|
||||
this.form = response.data;
|
||||
this.form.deptName = row.deptName;
|
||||
this.form.roleDeptId = row.roleDeptId;
|
||||
this.dialogFormVisible = true;
|
||||
this.dialogStatus = "update";
|
||||
});
|
||||
},
|
||||
handlePermission(row) {
|
||||
fetchRoleTree(row.roleCode).then(response => {
|
||||
this.checkedKeys = response.data;
|
||||
});
|
||||
fetchTree().then(response => {
|
||||
this.treeData = response.data;
|
||||
this.dialogStatus = "permission";
|
||||
this.dialogPermissionVisible = true;
|
||||
this.roleId = row.roleId;
|
||||
this.roleCode = row.roleCode;
|
||||
});
|
||||
},
|
||||
handleDept() {
|
||||
fetchDeptTree().then(response => {
|
||||
this.treeDeptData = response.data;
|
||||
this.dialogDeptVisible = true;
|
||||
});
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
return data.label.indexOf(value) !== -1;
|
||||
},
|
||||
getNodeData(data) {
|
||||
this.dialogDeptVisible = false;
|
||||
this.form.roleDeptId = data.id;
|
||||
this.form.deptName = data.name;
|
||||
console.log(data);
|
||||
},
|
||||
handleDelete(row) {
|
||||
delObj(row.roleId).then(response => {
|
||||
this.dialogFormVisible = false;
|
||||
this.getList();
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "删除成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
},
|
||||
create(formName) {
|
||||
const set = this.$refs;
|
||||
set[formName].validate(valid => {
|
||||
if (valid) {
|
||||
addObj(this.form).then(() => {
|
||||
this.dialogFormVisible = false;
|
||||
this.getList();
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "创建成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
cancel(formName) {
|
||||
this.dialogFormVisible = false;
|
||||
this.$refs[formName].resetFields();
|
||||
},
|
||||
update(formName) {
|
||||
const set = this.$refs;
|
||||
set[formName].validate(valid => {
|
||||
if (valid) {
|
||||
this.dialogFormVisible = false;
|
||||
putObj(this.form).then(() => {
|
||||
this.dialogFormVisible = false;
|
||||
this.getList();
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "修改成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
updatePermession(roleId, roleCode) {
|
||||
permissionUpd(roleId, this.$refs.menuTree.getCheckedKeys()).then(() => {
|
||||
this.dialogPermissionVisible = false;
|
||||
fetchTree().then(response => {
|
||||
this.treeData = response.data;
|
||||
});
|
||||
fetchRoleTree(roleCode).then(response => {
|
||||
this.checkedKeys = response.data;
|
||||
});
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "修改成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
},
|
||||
resetTemp() {
|
||||
this.form = {
|
||||
id: undefined,
|
||||
roleName: undefined,
|
||||
roleCode: undefined,
|
||||
roleDesc: undefined
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
369
src/views/admin/user/index.vue
Normal file
369
src/views/admin/user/index.vue
Normal file
@ -0,0 +1,369 @@
|
||||
<template>
|
||||
<div class="app-container calendar-list-container">
|
||||
<div class="filter-container">
|
||||
<el-input @keyup.enter.native="handleFilter" style="width: 200px;" class="filter-item" placeholder="用户名" v-model="listQuery.username">
|
||||
</el-input>
|
||||
<el-button class="filter-item" type="primary" v-waves icon="search" @click="handleFilter">搜索</el-button>
|
||||
<el-button v-if="sys_user_add" class="filter-item" style="margin-left: 10px;" @click="handleCreate" type="primary" icon="edit">添加</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :key='tableKey' :data="list" v-loading="listLoading" element-loading-text="给我一点时间" border fit highlight-current-row style="width: 99%">
|
||||
|
||||
<el-table-column align="center" label="序号">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.userId}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="用户名">
|
||||
<template slot-scope="scope">
|
||||
<span>
|
||||
<img v-if="scope.row.avatar" class="user-avatar" style="width: 20px; height: 20px; border-radius: 50%;" :src="scope.row.avatar+'?imageView2/1/w/20/h/20'"> {{scope.row.username}}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="所属部门" show-overflow-tooltip>
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.deptName}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="角色">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.roleList[0].roleDesc}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="创建时间">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.createTime | parseTime('{y}-{m}-{d} {h}:{i}')}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" class-name="status-col" label="状态">
|
||||
<template slot-scope="scope">
|
||||
<el-tag>{{scope.row.delFlag | statusFilter}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-if="sys_user_upd" size="small" type="success" @click="handleUpdate(scope.row)">编辑
|
||||
</el-button>
|
||||
<el-button v-if="sys_user_del" size="small" type="danger" @click="deletes(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
|
||||
<div v-show="!listLoading" class="pagination-container">
|
||||
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page.sync="listQuery.page" :page-sizes="[10,20,30, 50]" :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
|
||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogDeptVisible">
|
||||
<el-tree class="filter-tree" :data="treeDeptData" :default-checked-keys="checkedKeys" check-strictly node-key="id" highlight-current ref="deptTree" :props="defaultProps" @node-click="getNodeData" default-expand-all>
|
||||
</el-tree>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
||||
<el-form :model="form" :rules="rules" ref="form" label-width="100px">
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input v-model="form.username" placeholder="请输用户名"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="dialogStatus == 'create'" label="密码" placeholder="请输入密码" prop="password">
|
||||
<el-input type="password" v-model="form.password"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="所属部门" prop="deptName">
|
||||
<el-input v-model="form.deptName" placeholder="选择部门" @focus="handleDept()" readonly></el-input>
|
||||
<input type="hidden" v-model="form.deptId" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="角色" prop="role">
|
||||
<el-select class="filter-item" v-model="role" placeholder="请选择">
|
||||
<el-option v-for="item in rolesOptions" :key="item.roleId" :label="item.roleDesc" :value="item.roleId" :disabled="isDisabled[item.delFlag]">
|
||||
<span style="float: left">{{ item.roleDesc }}</span>
|
||||
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.roleCode }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="状态" v-if="dialogStatus == 'update' && sys_user_del " prop="delFlag">
|
||||
<el-select class="filter-item" v-model="form.delFlag" placeholder="请选择">
|
||||
<el-option v-for="item in statusOptions" :key="item" :label="item | statusFilter" :value="item"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel('form')">取 消</el-button>
|
||||
<el-button v-if="dialogStatus=='create'" type="primary" @click="create('form')">确 定</el-button>
|
||||
<el-button v-else type="primary" @click="update('form')">修 改</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, getObj, addObj, putObj, delObj } from "@/api/user";
|
||||
import { deptRoleList, fetchDeptTree } from "@/api/role";
|
||||
import waves from "@/directive/waves/index.js"; // 水波纹指令
|
||||
// import { parseTime } from '@/utils'
|
||||
import { mapGetters } from "vuex";
|
||||
import ElRadioGroup from "element-ui/packages/radio/src/radio-group";
|
||||
import ElOption from "element-ui/packages/select/src/option";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ElOption,
|
||||
ElRadioGroup
|
||||
},
|
||||
name: "table_user",
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
treeDeptData: [],
|
||||
checkedKeys: [],
|
||||
defaultProps: {
|
||||
children: "children",
|
||||
label: "name"
|
||||
},
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20
|
||||
},
|
||||
role: undefined,
|
||||
form: {
|
||||
username: undefined,
|
||||
password: undefined,
|
||||
delFlag: undefined,
|
||||
deptId: undefined
|
||||
},
|
||||
rules: {
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入账户",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 3,
|
||||
max: 20,
|
||||
message: "长度在 3 到 20 个字符",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
min: 5,
|
||||
max: 20,
|
||||
message: "长度在 5 到 20 个字符",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
deptId: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择部门",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
role: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择角色",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
},
|
||||
statusOptions: ["0", "1"],
|
||||
rolesOptions: [],
|
||||
dialogFormVisible: false,
|
||||
dialogDeptVisible: false,
|
||||
userAdd: false,
|
||||
userUpd: false,
|
||||
userDel: false,
|
||||
dialogStatus: "",
|
||||
textMap: {
|
||||
update: "编辑",
|
||||
create: "创建"
|
||||
},
|
||||
isDisabled: {
|
||||
0: false,
|
||||
1: true
|
||||
},
|
||||
tableKey: 0
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["permissions"])
|
||||
},
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
0: "有效",
|
||||
1: "无效",
|
||||
9: "锁定"
|
||||
};
|
||||
return statusMap[status];
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
this.sys_user_add = this.permissions["sys_user_add"];
|
||||
this.sys_user_upd = this.permissions["sys_user_upd"];
|
||||
this.sys_user_del = this.permissions["sys_user_del"];
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
this.listQuery.orderByField = "`user`.create_time";
|
||||
this.listQuery.isAsc = false;
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.records;
|
||||
this.total = response.data.total;
|
||||
this.listLoading = false;
|
||||
});
|
||||
},
|
||||
getNodeData(data) {
|
||||
this.dialogDeptVisible = false;
|
||||
this.form.deptId = data.id;
|
||||
this.form.deptName = data.name;
|
||||
deptRoleList(data.id).then(response => {
|
||||
this.rolesOptions = response.data;
|
||||
});
|
||||
},
|
||||
handleDept() {
|
||||
fetchDeptTree().then(response => {
|
||||
this.treeDeptData = response.data;
|
||||
this.dialogDeptVisible = true;
|
||||
});
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1;
|
||||
this.getList();
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val;
|
||||
this.getList();
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val;
|
||||
this.getList();
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp();
|
||||
this.dialogStatus = "create";
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
handleUpdate(row) {
|
||||
getObj(row.userId).then(response => {
|
||||
this.form = response.data;
|
||||
this.role = row.roleList[0].roleId;
|
||||
this.dialogFormVisible = true;
|
||||
this.dialogStatus = "update";
|
||||
deptRoleList(response.data.deptId).then(response => {
|
||||
this.rolesOptions = response.data;
|
||||
});
|
||||
});
|
||||
},
|
||||
create(formName) {
|
||||
const set = this.$refs;
|
||||
this.form.role = this.role;
|
||||
set[formName].validate(valid => {
|
||||
if (valid) {
|
||||
addObj(this.form).then(() => {
|
||||
this.dialogFormVisible = false;
|
||||
this.getList();
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "创建成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
cancel(formName) {
|
||||
this.dialogFormVisible = false;
|
||||
this.$refs[formName].resetFields();
|
||||
},
|
||||
update(formName) {
|
||||
const set = this.$refs;
|
||||
this.form.role = this.role;
|
||||
set[formName].validate(valid => {
|
||||
if (valid) {
|
||||
this.dialogFormVisible = false;
|
||||
this.form.password = undefined;
|
||||
putObj(this.form).then(() => {
|
||||
this.dialogFormVisible = false;
|
||||
this.getList();
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "修改成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
deletes(row) {
|
||||
this.$confirm(
|
||||
"此操作将永久删除该用户(用户名:" + row.username + "), 是否继续?",
|
||||
"提示",
|
||||
{
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}
|
||||
).then(() => {
|
||||
delObj(row.userId)
|
||||
.then(() => {
|
||||
this.getList();
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "删除成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
})
|
||||
.cache(() => {
|
||||
this.$notify({
|
||||
title: "失败",
|
||||
message: "删除失败",
|
||||
type: "error",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
resetTemp() {
|
||||
this.form = {
|
||||
id: undefined,
|
||||
username: "",
|
||||
password: "",
|
||||
role: undefined
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
160
src/views/admin/user/info.vue
Normal file
160
src/views/admin/user/info.vue
Normal file
@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div class="app-container calendar-list-container">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<div class="grid-content bg-purple">
|
||||
<el-form :model="ruleForm2" :rules="rules2" ref="ruleForm2" label-width="100px" class="demo-ruleForm">
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input type="text" :value="name" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="原密码" prop="pass">
|
||||
<el-input type="password" v-model="ruleForm2.password" auto-complete="off"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" prop="pass">
|
||||
<el-input type="password" v-model="ruleForm2.newpassword1" auto-complete="off"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="checkPass">
|
||||
<el-input type="password" v-model="ruleForm2.newpassword2" auto-complete="off"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="头像">
|
||||
<my-upload field="file" @crop-upload-success="cropUploadSuccess" v-model="show" :width="300" :height="300" url="/admin/user/upload" :headers="headers" img-format="png"></my-upload>
|
||||
<img :src="avatar">
|
||||
<el-button type="primary" @click="toggleShow" size="mini">选择
|
||||
<i class="el-icon-upload el-icon--right"></i>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm('ruleForm2')">提交</el-button>
|
||||
<el-button @click="resetForm('ruleForm2')">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import myUpload from "vue-image-crop-upload";
|
||||
import { getToken } from "@/util/auth";
|
||||
import ElFormItem from "element-ui/packages/form/src/form-item.vue";
|
||||
import request from "@/router/axios";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ElFormItem,
|
||||
"my-upload": myUpload
|
||||
},
|
||||
data() {
|
||||
var validatePass = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入密码"));
|
||||
} else if (value.length < 6) {
|
||||
callback(new Error("密码不能小于6位"));
|
||||
} else {
|
||||
if (this.ruleForm2.newpassword1 !== "") {
|
||||
this.$refs.ruleForm2.validateField("newpassword1");
|
||||
}
|
||||
callback();
|
||||
}
|
||||
};
|
||||
var validatePass2 = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请再次输入密码"));
|
||||
} else if (value !== this.ruleForm2.newpassword2) {
|
||||
callback(new Error("两次输入密码不一致!"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
return {
|
||||
fileList: [],
|
||||
show: false,
|
||||
headers: {
|
||||
Authorization: "Bearer " + getToken()
|
||||
},
|
||||
ruleForm2: {
|
||||
password: "",
|
||||
newpassword1: "",
|
||||
newpassword2: "",
|
||||
avatar: ""
|
||||
},
|
||||
rules2: {
|
||||
newpassword1: [{ validator: validatePass, trigger: "blur" }],
|
||||
newpassword2: [{ validator: validatePass2, trigger: "blur" }]
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["name", "avatar"])
|
||||
},
|
||||
methods: {
|
||||
submitForm(formName) {
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (valid) {
|
||||
this.ruleForm2.avatar = this.avatar;
|
||||
request({
|
||||
url: "/admin/user/editInfo",
|
||||
method: "put",
|
||||
data: this.ruleForm2
|
||||
})
|
||||
.then(response => {
|
||||
if (response) {
|
||||
this.$notify({
|
||||
title: "成功",
|
||||
message: "修改成功",
|
||||
type: "success",
|
||||
duration: 2000
|
||||
});
|
||||
// 修改密码之后强制重新登录
|
||||
if (this.ruleForm2.newpassword1 !== "") {
|
||||
this.$store.dispatch("LogOut").then(() => {
|
||||
location.reload(); // 为了重新实例化vue-router对象 避免bug
|
||||
});
|
||||
} else {
|
||||
this.$router.push({ path: "/" });
|
||||
}
|
||||
} else {
|
||||
this.$notify({
|
||||
title: "失败",
|
||||
message: response,
|
||||
type: "fail",
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.$notify({
|
||||
title: "失败",
|
||||
message: "修改失败",
|
||||
type: "fail",
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
},
|
||||
toggleShow() {
|
||||
this.show = !this.show;
|
||||
},
|
||||
/**
|
||||
* upload success
|
||||
*
|
||||
* [param] jsonData 服务器返回数据,已进行json转码
|
||||
* [param] field
|
||||
*/
|
||||
cropUploadSuccess(jsonData, field) {
|
||||
console.log("-------- upload success --------");
|
||||
this.$store.commit("SET_AVATAR", jsonData.filename);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
33
src/views/dashboard/index.vue
Normal file
33
src/views/dashboard/index.vue
Normal file
@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="dashboard-container">
|
||||
<div class="dashboard-text">欢迎登录</div>
|
||||
<div class="dashboard-text">用户名:{{name}}</div>
|
||||
<div class="dashboard-text">角色名:<span v-for='role in roles' :key='role'>{{role}}</span></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'dashboard',
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'name',
|
||||
'roles'
|
||||
])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.dashboard {
|
||||
&-container {
|
||||
margin: 30px;
|
||||
}
|
||||
&-text {
|
||||
font-size: 30px;
|
||||
line-height: 46px;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user