Commit ce162cbb authored by liuyang's avatar liuyang

init project

parents
> 1%
last 2 versions
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'eslint:recommended'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
},
parserOptions: {
parser: 'babel-eslint'
}
}
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
{
"name": "online-edu-admin",
"version": "1.0.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@jiaminghi/data-view": "^2.7.3",
"ant-design-vue": "^1.7.5",
"axios": "^0.19.0",
"core-js": "^3.4.3",
"nprogress": "^0.2.0",
"vue": "^2.6.10",
"vue-router": "^3.1.3",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.1.0",
"@vue/cli-plugin-eslint": "^4.1.0",
"@vue/cli-plugin-router": "^4.1.0",
"@vue/cli-plugin-vuex": "^4.1.0",
"@vue/cli-service": "^4.1.0",
"babel-eslint": "^10.0.3",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"vue-template-compiler": "^2.6.10"
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>管理云平台</title>
<style>
html,
body {
width: 100%;
height: 100%;
box-sizing: border-box;
margin: 0px;
padding: 0px;
overflow: hidden;
}
[class^="icon"] {
font-family: "iconfont" !important;
font-size: 18px !important;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</style>
</head>
<body>
<div id="app"></div>
</body>
</html>
\ No newline at end of file
/**
* app
*/
<template>
<a-config-provider :locale="locale">
<div id="app">
<router-view />
</div>
</a-config-provider>
</template>
<script>
import zh_CN from 'ant-design-vue/lib/locale-provider/zh_CN';
export default {
name: "app",
data() {
return {
locale: zh_CN,
};
},
// 创建完毕状态
created() {
},
// 挂载结束状态
mounted() {},
methods: {}
};
</script>
<style scoped>
#app {
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
\ No newline at end of file
/******************
* 终端管理
*****************/
// 导入请求公用方法
import {
request
} from '../../utils/axiosFun';
export const fetchList = (query) => {
return request('get', '/admin/client/page', query, "Y")
}
export const delObj = (id) => {
return request('delete', '/admin/client/' + id, {})
}
export const addObj = (obj) => {
return request('post', '/admin/client', obj)
}
export const getObj = (id) => {
return request('get', '/admin/client/' + id, {})
}
export const putObj = (obj) => {
return request('put', '/admin/client', obj)
}
\ No newline at end of file
/******************
* 部门管理
*****************/
// 导入请求公用方法
import {
request
} from '../../utils/axiosFun';
export function fetchDeptTree(query) {
return request('get', '/admin/dept/user-tree', query, "Y")
}
export function fetchTree(query) {
return request('get', '/admin/dept/tree', query, "Y")
}
export function addObj(obj) {
return request('post', '/admin/dept', obj)
}
export function getdept(id) {
return request('get', '/admin/dept/' + id, {})
}
export function delObj(id) {
return request('delete', '/admin/dept/' + id, {})
}
export function putObj(obj) {
return request('put', '/admin/dept', obj)
}
// 保存角色与部门对应关系
export function saveRoledept(obj) {
return request('post', '/admin/roledept', obj)
}
// 通过角色ID查询部门ID列表
export function getRoledept(roleId) {
return request('get', '/admin/roledept/' + roleId, {})
}
\ No newline at end of file
/******************
* 字典管理
*****************/
// 导入请求公用方法
import {
request
} from '../../utils/axiosFun';
export const fetchList = (query) => {
return request('post', '/api/sys/config/list', query)
}
export const addObj = (obj) => {
return request('post', '/api/sys/config/save', obj)
}
export const getObj = (id) => {
return request('get', '/api/sys/config/info/' + id)
}
export const delObj = (ids) => {
return request('post', '/api/sys/config/delete', ids)
}
export const putObj = (obj) => {
return request('post', '/api/sys/config/update', obj)
}
/******************
* 代码生成
*****************/
// 导入请求公用方法
import {
request
} from '../../utils/axiosFun';
// 针对文件下载引入axios
import axios from 'axios';
export const fetchList = (query) => {
return request('get', '/gen/generator/page', query, "Y")
}
export const handleDown = (table) => {
return axios({
url: '/gen/generator/code',
method: 'post',
data: table,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem("token")
},
responseType: 'arraybuffer'
}).then((response) => { // 处理返回的文件流
let blob = new Blob([response.data], {
type: 'application/zip'
})
let filename = table.tableName + '.zip'
let link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = filename
document.body.appendChild(link)
link.click()
window.setTimeout(function () {
URL.revokeObjectURL(blob)
document.body.removeChild(link)
}, 0)
})
}
\ No newline at end of file
/******************
* 日志管理
*****************/
// 导入请求公用方法
import {
request
} from '../../utils/axiosFun';
export const fetchList = (query) => {
return request('post', '/api/sys/log/list', query)
}
/******************
* 菜单管理
*****************/
// 导入请求公用方法
import {
request
} from '../../utils/axiosFun';
export function GetMenu() {
return request('get', '/admin/menu', {})
}
export function fetchList(query) {
return request('post', '/api/sys/menu/list', query)
}
export function fetchMenuTree(){
return request('get','/api/sys/menu/tree')
}
export function addObj(obj) {
return request('post', '/api/sys/menu/save', obj)
}
export function getObj(id) {
return request('get', '/api/sys/menu/info/' + id)
}
export function delObj(id) {
return request('get', '/api/sys/menu/delete/' + id)
}
export function putObj(obj) {
return request('post', '/api/sys/menu/update', obj)
}
/******************
* 角色管理
*****************/
// 导入请求公用方法
import {
request
} from '../../utils/axiosFun';
export function fetchList(query) {
return request('post', '/api/sys/role/list', query)
}
export function getRoleList() {
return request('get', '/api/sys/role/select', {})
}
export function getObj(id) {
return request('get', '/admin/role/' + id, {})
}
export function addObj(obj) {
return request('post', '/api/sys/role/save', obj)
}
export function putObj(obj) {
return request('post', '/api/sys/role/update', obj)
}
export function delObj(ids) {
return request('post', '/api/sys/role/delete', ids)
}
export function permissionUpd(roleId, menuIds) {
return request('post', '/api/sys/role/menu/save', {
roleId: roleId,
menuIds: menuIds
})
}
export function fetchRoleMenuIds(roleId) {
return request('get', '/api/sys/role/menuIds/' + roleId)
}
\ No newline at end of file
/******************
* 获取token
*****************/
// 导入请求公用方法
import {
loginRequest,
request
} from '../../utils/axiosFun';
/**
* 获取token
* @params:{json}
* @returns:{json}
*/
export const loginByUserToken = (params) => {
return loginRequest("post", "/api/sys/login", params, "F")
};
/**
* 获取用户
* @params:{json}
* @returns:{json}
*/
export const getUserInfo = () => {
return request("get", "/admin/user/info", {})
};
/**
* 获取用户菜单
* @params:{json}
* @returns:{json}
*/
export const GetMenu = () => {
return request("get", "/api/sys/menu/nav", {})
};
export const fetchList = (query) => {
return request('get', '/admin/token/page', query, "Y")
}
export const delObj = (token) => {
return request('delete', '/admin/token/' + token, {})
}
\ No newline at end of file
/******************
* 用户管理
*****************/
// 导入请求公用方法
import {
request
} from '../../utils/axiosFun';
export const fetchList = (query) => {
return request('post', '/api/sys/user/list', query, "F")
}
export const addObj = (obj) => {
return request('post', '/api/sys/user/save', obj)
}
export const delObj = (ids) => {
return request('post', '/api/sys/user/delete', ids)
}
export const putObj = (obj) => {
return request('post', '/api/sys/user/update', obj)
}
export const getObj = (id) => {
return request('get','/api/sys/user/info/' + id)
}
export const getCurrentInfo = () => {
return request('get','/api/sys/user/info',{})
}
export const changePassword = (obj) => {
return request('post','/api/sys/user/password',obj)
}
\ No newline at end of file
/**
* 登录页轮播
**/
<template>
<a-carousel autoplay class="a-body">
<img :src="data[0]" alt />
<img :src="data[1]" alt />
<img :src="data[2]" alt />
<img :src="data[3]" alt />
</a-carousel>
</template>
<script>
export default {
data() {
return {
data: [
require("../assets/img/1.png"),
require("../assets/img/2.png"),
require("../assets/img/3.png"),
require("../assets/img/4.png")
]
};
},
methods: {}
};
</script>
<style scoped>
/* For demo */
.a-body {
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
}
.a-body img {
width: 100%;
height: 100vh;
}
.ant-carousel .slick-slider {
width: 100% !important;
height: 100% !important;
}
.ant-carousel >>> .slick-slide {
height: 100%;
line-height: 100vh;
overflow: hidden;
}
</style>
\ No newline at end of file
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// 引入Antd
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
Vue.config.productionTip = false;
Vue.use(Antd);
// 增加混入
import shareUtils from "@/mixins/utils";
Vue.mixin(shareUtils);
// 过滤器
import * as filters from './utils/util'
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
})
// 将自动注册所有组件为全局组件
import dataV from '@jiaminghi/data-view'
Vue.use(dataV)
//导入
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// 路由拦截器
router.beforeEach((to, from, next) => {
NProgress.start()
if (to.matched.length != 0) {
if (to.meta.requireAuth) { // 判断该路由是否需要登录权限
if (Boolean(localStorage.getItem("token"))) { // 通过vuex state获取当前的user是否存在
if (to.path == '/' && from.path == '/') {
next({
path: '/index'
})
} else {
next();
}
} else {
next({
path: '/login',
query: {
redirect: to.fullPath
} // 将跳转的路由path作为参数,登录成功后跳转到该路由
})
}
} else {
if (Boolean(localStorage.getItem("token"))) { // 判断是否登录
if (to.path != "/" && to.path != "/login") { //判断是否要跳到登录界面
next();
} else {
/**
* 防刷新,如果登录,修改路由跳转到登录页面,修改路由为登录后的首页
*/
next({
path: '/index'
})
}
} else {
next();
}
}
} else {
next({
path: '/login',
query: {
redirect: to.fullPath
} // 将跳转的路由path作为参数,登录成功后跳转到该路由
})
}
})
router.afterEach(() => {
NProgress.done()
})
import {
iconfontUrl
} from '@/utils/config'
import {
loadStyle
} from './utils/util'
loadStyle(iconfontUrl)
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App),
data: {
// 空的实例放到根组件下,所有的子组件都能调用
Bus: new Vue()
}
}).$mount('#app')
\ No newline at end of file
/**
* vue 混入
* 主要功能是获取实时时间
**/
import {
Icon
} from 'ant-design-vue';
const IconFont = Icon.createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/font_2546107_birr9zqbggv.js',
});
export default {
data() {
return {
// 实时时间
NewTime: ""
};
},
components: {
IconFont,
},
created() {},
computed: {},
methods: {
}
};
\ No newline at end of file
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [{
path: '/login',
name: '登录页',
component: () =>
import( /* webpackChunkName: "page" */ '@/views/login'),
meta: {
requireAuth: false,
},
}, {
path: '/',
name: '布局页',
component: () =>
import( /* webpackChunkName: "page" */ '@/views/index'),
meta: {
requireAuth: true,
},
children: [{
path: 'index',
name: '首页',
component: () =>
import( /* webpackChunkName: "page" */ '@/views/wel'),
meta: {
requireAuth: true,
}
},
{
path: "/userinfo",
name: "用户信息",
component: () =>
import('@/views/admin/user/info.vue'),
meta: {
requireAuth: true,
}
},
]
},
]
const router = new VueRouter({
// 页面刷新白屏问题
// mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
\ No newline at end of file
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})
.wel-con {
width: 100%;
height: 100%;
box-sizing: border-box;
background-image: url("./../assets/bg.png");
background-repeat: no-repeat;
background-size: 100% 100%;
position: relative;
}
.Full {
width: 30px;
height: 30px;
position: absolute;
top: 10px;
right: 10px;
z-index: 1000;
box-sizing: border-box;
padding: 5px;
border-radius: 5px;
}
.Full:hover {
background-color: #fff;
}
.Full > img {
width: 100%;
height: 100%;
}
.map {
width: 100%;
height: 100%;
box-sizing: border-box;
overflow: hidden;
position: relative;
}
.map-FullScreen {
z-index: 9000;
object-fit: contain;
position: fixed !important;
top: 0px !important;
right: 0px !important;
bottom: 0px !important;
left: 0px !important;
box-sizing: border-box !important;
min-width: 0px !important;
max-width: none !important;
min-height: 0px !important;
max-height: none !important;
width: 100% !important;
height: 100% !important;
transform: none !important;
margin: 0px !important;
}
.head-title {
width: 100%;
height: 100px;
text-align: center;
display: flex;
justify-content: space-between;
}
.title-con {
width: 50%;
display: flex;
flex-direction: column;
justify-content: center;
}
.title {
display: inline-block;
font-size: 30px;
color: #f9fbff;
position: relative;
height: 30px;
}
.title > span {
width: 100%;
text-align: center;
position: absolute;
left: 0px;
top: 10px;
}
.smcon {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
box-sizing: border-box;
padding-top: 100px;
}
.border-con {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 20px;
}
.border-smcon {
width: 100%;
height: 100%;
box-sizing: border-box;
position: relative;
}
.con-left {
width: 25%;
height: 100%;
box-sizing: border-box;
position: absolute;
left: 0px;
top: 0px;
}
.con-cen {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 0px 25%;
}
.con-right {
width: 25%;
height: 100%;
box-sizing: border-box;
position: absolute;
right: 0px;
top: 0px;
}
.left-bp {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 20px;
}
.left-top {
width: 100%;
height: 49%;
display: flex;
justify-content: center;
align-items: center;
}
.left-bottom {
width: 100%;
height: 49%;
display: flex;
justify-content: center;
align-items: center;
}
.cen-box {
width: 100%;
height: 100%;
box-sizing: border-box;
position: relative;
}
.cen-top {
width: 100%;
height: calc(100% - 40%);
box-sizing: border-box;
display: flex;
justify-content: space-between;
}
.cent-box {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 5px;
}
.cen-bottom {
width: 100%;
height: 40%;
box-sizing: border-box;
}
.tab-box {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 20px;
display: flex;
justify-content: center;
}
.left-item {
width: 100%;
height: 33%;
box-sizing: border-box;
position: relative;
}
.po-ab {
position: absolute;
top: 0px;
left: 0px;
color: #f9fbff;
}
.po-n {
width: 100%;
height: 100%;
box-sizing: border-box;
padding-top: 20px;
}
.tab-item {
width: 33%;
height: 100%;
box-sizing: border-box;
position: relative;
}
.rotate {
transform: rotate(180deg);
}
.po-tab {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
text-align: center;
color: #f9fbff;
}
.po-tn {
width: 100%;
height: 100%;
box-sizing: border-box;
padding-top: 30px;
}
.pad-b {
padding-top: 8px;
}
.po-bn {
padding-top: 38px;
}
.cen-t {
font-size: 12px;
color: #f9fbff;
text-align: left;
}
.cent {
width: 50%;
box-sizing: border-box;
text-align: center;
}
.dv-smbox {
width: 100%;
height: 100%;
/* padding: 10px; */
box-sizing: border-box;
display: flex;
justify-items: space-between;
}
.title-box {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 10px;
}
.time {
position: absolute;
top: -35px;
right: 5%;
font-size: 25px;
color: #f9fbff;
}
.Decoration {
position: absolute;
top: -35px;
left: 5%;
}
.tbox-top {
width: 100%;
height: 130px;
box-sizing: border-box;
position: relative;
}
.tbox-bottom {
width: 100%;
height: calc(100% - 130px);
box-sizing: border-box;
}
.zs-box {
position: absolute;
top: 0px;
right: 0px;
width: 180px;
height: 50px;
}
.Coupons {
widows: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
justify-content: space-between;
}
.Half {
width: 50%;
height: 100%;
}
\ No newline at end of file
/**
* axios 请求方法封转
*/
import axios from 'axios';
/**
* axios 登录请求方法
* @param:{string} method 请求类型,必填
* @param:{string} url 请求地址,必填
* @param:{string} params 请求参数,必填
* @param:{string} variation 是否变异,非必填
**/
const loginRequest = (method, url, params, variation = "F") => {
if (variation == "F") {
return axios({
method: method,
url: url,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic cGlnOnBpZw=='
},
data: params
}).then(res => res.data);
} else {
return axios({
method: method,
url: url,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic cGlnOnBpZw=='
},
params: params
}).then(res => res.data);
}
};
/**
* axios 通用公用方法
* @param:{string} method 请求类型,必填
* @param:{string} url 请求地址,必填
* @param:{string} params 请求参数,必填
* @param:{string} variation 是否变异,非必填
**/
const request = (method, url, params, variation = "F") => {
if (variation == "F") {
return axios({
method: method,
url: url,
headers: {
'Content-Type': 'application/json',
'Authorization': localStorage.getItem("token")
},
data: params,
}).then(res => res.data);
} else {
return axios({
method: method,
url: url,
headers: {
'Content-Type': 'application/json',
'Authorization': localStorage.getItem("token")
},
params: params,
}).then(res => res.data);
}
};
// 导出方法
export {
loginRequest,
request
}
\ No newline at end of file
let iconfontUrl = `//at.alicdn.com/t/font_2546107_birr9zqbggv.css`
export {
iconfontUrl
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* 时间戳
* @param:{string} timestamp 时间戳,必填
* @returns:{string}
*/
const timestampToTime = (timestamp) => {
if (timestamp == "" || timestamp == null || timestamp == "null") {
return ""
}
let date = new Date(timestamp) //时间戳为10位需*1000,时间戳为13位的话不需乘1000
let Y = date.getFullYear() + '-'
let M =
(date.getMonth() + 1 < 10 ?
'0' + (date.getMonth() + 1) :
date.getMonth() + 1) + '-'
let D =
(date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' '
let h =
(date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'
let m =
(date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) +
':'
let s =
date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
return Y + M + D + h + m + s
};
/**
* 时间戳转yyyy-mm-dd
* @param:{string} timestamp 时间戳,必填
* @returns:{string}
*/
const timestampToymd = (timestamp) => {
if (timestamp == "" || timestamp == null || timestamp == "null") {
return ""
}
let date = new Date(timestamp) //时间戳为10位需*1000,时间戳为13位的话不需乘1000
let Y = date.getFullYear() + '-'
let M =
(date.getMonth() + 1 < 10 ?
'0' + (date.getMonth() + 1) :
date.getMonth() + 1) + '-'
let D =
(date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' '
return Y + M + D
};
const datetinmeToTimestamp = (dateStr) => {
if (dateStr == "" || dateStr == null || dateStr == "null") {
return ""
}
let timestamp = Date.parse(new Date(dateStr));
return timestamp;
}
/**
* 浏览器判断是否全屏
*/
export const fullscreenToggel = () => {
if (fullscreenEnable()) {
exitFullScreen();
} else {
reqFullScreen();
}
};
/**
* esc监听全屏
*/
export const listenfullscreen = (callback) => {
function listen() {
callback()
}
document.addEventListener("fullscreenchange", function () {
listen();
});
document.addEventListener("mozfullscreenchange", function () {
listen();
});
document.addEventListener("webkitfullscreenchange", function () {
listen();
});
document.addEventListener("msfullscreenchange", function () {
listen();
});
};
/**
* 浏览器判断是否全屏
*/
export const fullscreenEnable = () => {
return document.isFullScreen || document.mozIsFullScreen || document.webkitIsFullScreen
}
/**
* 浏览器全屏
*/
export const reqFullScreen = () => {
if (document.documentElement.requestFullScreen) {
document.documentElement.requestFullScreen();
} else if (document.documentElement.webkitRequestFullScreen) {
document.documentElement.webkitRequestFullScreen();
} else if (document.documentElement.mozRequestFullScreen) {
document.documentElement.mozRequestFullScreen();
}
};
/**
* 浏览器退出全屏
*/
export const exitFullScreen = () => {
if (document.documentElement.requestFullScreen) {
document.exitFullScreen();
} else if (document.documentElement.webkitRequestFullScreen) {
document.webkitCancelFullScreen();
} else if (document.documentElement.mozRequestFullScreen) {
document.mozCancelFullScreen();
}
};
/**
* 动态插入css
*/
export const loadStyle = url => {
const link = document.createElement('link')
link.type = 'text/css'
link.rel = 'stylesheet'
link.href = url
const head = document.getElementsByTagName('head')[0]
head.appendChild(link)
}
/**
* 处理请求返回
* @param:{string} self 当前操作,必填
* @param:{string} data 状态值,必填
**/
function disposereq(self, data) {
console.log(data)
if (data.message.indexOf('401') != -1) {
self.$message.info("token过期,请重新登录!");
localStorage.removeItem("token");
localStorage.removeItem('UserInfo')
setTimeout(() => {
self.$router.push({
path: '/login'
})
}, 1000)
}
};
export {
timestampToTime,
timestampToymd,
datetinmeToTimestamp,
disposereq
}
\ No newline at end of file
import CryptoJS from './crypto-js'
/**
*加密处理
*/
export const encryption = (params) => {
let {
data,
type,
param,
key
} = params
const result = JSON.parse(JSON.stringify(data))
if (type === 'Base64') {
param.forEach(ele => {
result[ele] = btoa(result[ele])
})
} else {
param.forEach(ele => {
var data = result[ele]
key = CryptoJS.enc.Latin1.parse(key)
var iv = key
// 加密
var encrypted = CryptoJS.AES.encrypt(
data,
key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
})
result[ele] = encrypted.toString()
})
}
return result
}
<template>
<div class="template_content">
<!-- 搜索 -->
<div class="search_box">
<a-form layout="inline">
<a-form-item label="类型">
<a-input v-model="searchPage.type" placeholder="请输入类型" allowClear></a-input>
</a-form-item>
<a-form-item label="关键字">
<a-input v-model="searchPage.key" placeholder="请输入关键字" allowClear></a-input>
</a-form-item>
<a-form-item>
<a-button icon="search" type="primary" @click="handleSubmit">查询</a-button>
</a-form-item>
</a-form>
</div>
<!-- 主体内容 -->
<div class="content_box">
<!-- 表格操作 -->
<div class="table_top">
<a-button
icon="plus"
type="primary"
class="btn_right_margin"
@click="showModal('')"
>添加</a-button>
</div>
<a-table
:columns="columns"
:dataSource="data"
:loading="loading"
:pagination="pagination"
bordered
size="small"
@change="handleTableChange"
>
<template slot="action" slot-scope="text, record">
<a-button
icon="edit"
type="primary"
class="btn_margin"
@click="showModal(record)"
>编辑</a-button>
<a-button
icon="delete"
type="danger"
class="btn_margin"
@click="deleteRow({record})"
>删除</a-button>
</template>
</a-table>
</div>
<!-- 弹窗 -->
<a-modal :title="modalTitle" v-model="modalVisible" :footer="null">
<a-form :form="modalForm" @submit="modalHandleSubmit">
<a-form-item label="关键字" :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
<a-input
v-decorator="['key', { rules: [{ required: true, message: '关键字不能为空' }] }]"
placeholder="请输入关键字"
/>
</a-form-item>
<a-form-item label="值" :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
<a-input
v-decorator="['value', { rules: [{ required: true, message: '值不能为空' }] }]"
placeholder="请输入值"
/>
</a-form-item>
<a-form-item label="类型" :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
<a-input
v-decorator="['type', { rules: [{ required: true, message: '类型不能为空' }] }]"
placeholder="请输入类型"
/>
</a-form-item>
<a-form-item
label="备注"
:label-col="{ span: 5 }"
:wrapper-col="{ span: 19 }"
>
<a-input
v-decorator="['remark']"
placeholder="请输入备注"
/>
</a-form-item>
<a-form-item :wrapper-col="{ span: 19, offset: 5 }">
<a-button type="primary" html-type="submit">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
// 导入接口
import { addObj, delObj, fetchList, getObj, putObj } from "@/api/admin/dict";
import { disposereq } from "@/utils/util";
let columns = [
{
title: "关键字",
dataIndex: "key",
align: "center"
},
{
title: "值",
dataIndex: "value",
align: "center"
},
{
title: "类型",
dataIndex: "type",
align: "center"
},
{
title: "备注",
dataIndex: "remark",
align: "center"
},
{
title: "操作",
key: "action",
scopedSlots: { customRender: "action" },
align: "center"
}
];
export default {
data() {
return {
loading: true,
searchPage: {
type: "",
key: "",
pageIndex: 1,
pageSize: 10
},
columns: columns,
data: [],
pagination: {
showQuickJumper: true,
showSizeChanger: true
},
modalVisible: false,
modalTitle: '添加',
modalForm: this.$form.createForm(this, { name: "coordinated" }),
rowData: {}
};
},
// 创建完毕
created() {
this.getList(this.searchPage);
},
// 即将更新渲染
beforeUpdate() {
},
methods: {
// 获取字典列表
getList(pageData) {
fetchList(pageData)
.then(res => {
this.loading = false;
if (res.code == 200) {
this.data = res.data;
const pager = { ...this.pagination };
pager.current = pageData.pageIndex;
pager.total = res.count;
this.pagination = pager;
} else {
this.$message.info(res.res_msg);
}
})
.catch(err => {
disposereq(this, err);
});
},
// 表格数据变化触发事件
handleTableChange(pagination, filters, sorter) {
const searchPage = { ...this.searchPage };
searchPage.pageIndex = pagination.current;
searchPage.pageSize = pagination.pageSize;
this.loading = true;
this.getList(searchPage);
},
// 搜索事件
handleSubmit() {
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
},
// 显示对话框
showModal(row) {
this.modalVisible = true;
// 判断添加或者编辑
if (row == "") {
this.modalTitle = '添加';
this.modalType = "add";
this.$nextTick(() => {
this.modalForm.setFieldsValue({
key: "",
value: "",
type: "",
remark: ""
});
});
} else {
this.modalTitle = '编辑';
this.modalType = "edit";
this.rowData = row;
this.$nextTick(() => {
this.modalForm.setFieldsValue({
key: row.key,
value: row.value,
type: row.type,
remark: row.remark
});
});
}
},
// 删除行数据
deleteRow(row) {
delObj([row.record.id])
.then(res => {
this.loading = false;
if (res.resp_code == 200) {
this.$message.success('删除成功');
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
disposereq(this, err);
});
},
// 对话框
modalHandleSubmit(e) {
e.preventDefault();
this.modalForm.validateFields((err, values) => {
if (!err && this.modalType == "add") {
addObj(values)
.then(res => {
if (res.resp_code == 200) {
this.modalVisible = false;
this.$message.success('保存成功');
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
} else if (!err && this.modalType == "edit") {
values.id = this.rowData.id
putObj(values)
.then(res => {
if (res.resp_code == 200) {
this.modalVisible = false;
this.$message.success('保存成功');
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
}
});
}
}
};
</script>
<style>
.search_box {
width: 100%;
box-sizing: border-box;
padding: 14px;
background-color: #fff;
}
.template_content {
background-color: #f0f2f5;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.content_box {
width: 100%;
background-color: #fff;
margin-top: 10px;
padding: 14px;
}
.table_top {
padding-bottom: 14px;
}
.btn_margin {
margin: 0px 5px;
}
.btn_right_margin {
margin-right: 10px;
}
</style>
\ No newline at end of file
<template>
<div class="template_content">
<!-- 搜索 -->
<div class="search_box">
<a-form layout="inline">
<a-form-item label="查询条件">
<a-select
v-model="searchPage.type"
style="width: 120px"
>
<a-select-option
v-for="item in logType"
:key="item.label"
:value="item.value"
>{{item.label}}</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<a-input v-if="searchPage.type != 'dayRange'" v-model="searchPage.condition" placeholder="请输入查询条件" allowClear></a-input>
<a-range-picker v-if="searchPage.type == 'dayRange'" @change="onDayRangeChange" />
</a-form-item>
<a-form-item>
<a-button icon="search" type="primary" @click="handleSubmit">查询</a-button>
</a-form-item>
</a-form>
</div>
<!-- 主体内容 -->
<div class="content_box">
<a-table
:columns="columns"
:dataSource="data"
:loading="loading"
:pagination="pagination"
bordered
size="small"
@change="handleTableChange"
rowKey="id"
>
</a-table>
</div>
</div>
</template>
<script>
// 导入接口
import { fetchList } from "@/api/admin/log";
import { disposereq ,timestampToTime,datetinmeToTimestamp} from "@/utils/util";
let columns= [
{
title: "用户名",
dataIndex: "username",
align: "center"
},
{
title: "操作名称",
dataIndex: "operation",
align: "center"
},
{
title: "方法名称",
dataIndex: "method",
align: "center",
ellipsis: true,
},
{
title: "参数",
dataIndex: "params",
align: "center",
ellipsis: true,
},
{
title: "执行时间",
dataIndex: "time",
align: "center"
},
{
title: "IP地址",
dataIndex: "ip",
align: "center"
},
{
title: "创建时间",
dataIndex: "createTime",
align: "center",
customRender: (text,record) => {
return timestampToTime(text);
}
},
];
export default {
data() {
return {
logType: [
{
label: '用户名称',
value: 'username'
},
{
label: '操作名称',
value: 'operation'
},
{
label: '方法名称',
value: 'method'
},
{
label: '时间范围',
value: 'dayRange'
}
],
loading: true,
searchPage: {
type: "username",
pageIndex: 1,
pageSize: 10,
condition: "",
start: "",
end: ""
},
columns: columns,
data: [],
pagination: {
showQuickJumper: true,
showSizeChanger: true
},
modalForm: this.$form.createForm(this, { name: "coordinated" })
};
},
// 创建完毕
created() {
this.getList(this.searchPage);
},
// 即将更新渲染
beforeUpdate() {
},
methods: {
onDayRangeChange(date, dateString){
console.log(datetinmeToTimestamp(dateString[0]+' 00:00:00'));
console.log(datetinmeToTimestamp(dateString[1]+' 23:59:59'));
this.searchPage.start = datetinmeToTimestamp(dateString[0]+' 00:00:00');
this.searchPage.end = datetinmeToTimestamp(dateString[1]+' 23:59:59');
},
// 获取日志
getList(pageData) {
fetchList(pageData)
.then(res => {
this.loading = false;
if (res.code == 200) {
this.data = res.data;
const pager = { ...this.pagination };
pager.current = pageData.pageIndex;
pager.total = res.count;
this.pagination = pager;
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
disposereq(this, err);
});
},
// 表格数据变化触发事件
handleTableChange(pagination, filters, sorter) {
const searchPage = { ...this.searchPage };
searchPage.pageIndex = pagination.current;
searchPage.pageSize = pagination.pageSize;
this.loading = true;
this.getList(searchPage);
},
// 搜索事件
handleSubmit() {
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
},
}
};
</script>
<style>
.search_box {
width: 100%;
box-sizing: border-box;
padding: 14px;
background-color: #fff;
}
.template_content {
background-color: #f0f2f5;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.content_box {
width: 100%;
background-color: #fff;
margin-top: 10px;
padding: 14px;
}
.table_top {
padding-bottom: 14px;
}
.btn_margin {
margin: 0px 5px;
}
.btn_right_margin {
margin-right: 10px;
}
</style>
\ No newline at end of file
<template>
<div class="template_content">
<div class="content_box">
<!-- 操作 -->
<div class="table_top">
<a-button-group>
<a-button icon="plus" type="primary" @click="addMenu('add')">添加</a-button>
<a-button icon="edit" type="primary" @click="editMenu('edit')">修改</a-button>
<a-button icon="delete" type="primary" @click="delMenu('del')">删除</a-button>
</a-button-group>
</div>
<div>
<a-row>
<a-col :span="4" class="col-h">
<a-tree
:treeData="menuTreeData"
:replaceFields="menuReplaceFields"
defaultExpandAll
@select="onMenuCheck"
checkStrictly
showLine
/>
</a-col>
<a-col :span="10">
<a-form :form="modalForm" @submit="modalHandleSubmit">
<a-form-item
label="父级名称"
:label-col="{ span: 3 }"
:wrapper-col="{ span: 21 }"
>
<a-input disabled v-decorator="['parentName']" placeholder="空" />
</a-form-item>
<a-form-item label="菜单名称" :label-col="{ span: 3 }" :wrapper-col="{ span: 21 }">
<a-input
v-decorator="['name', { rules: [{ required: true, message: '菜单名称不能为空' }] }]"
placeholder="请输入菜单名称"
/>
</a-form-item>
<a-form-item
label="权限"
:label-col="{ span: 3 }"
:wrapper-col="{ span: 21 }"
>
<a-input v-decorator="['perms']" placeholder="请输入权限" />
</a-form-item>
<a-form-item label="菜单图标" :label-col="{ span: 3 }" :wrapper-col="{ span: 21 }">
<a-input v-decorator="['icon']" placeholder="请输入图标名称" />
</a-form-item>
<a-form-item label="菜单类型" :label-col="{ span: 3 }" :wrapper-col="{ span: 21 }">
<a-select
v-decorator="[
'type',
{ rules: [{ required: true, message: '类型不能为空' }] },
]"
placeholder="请选择类型"
>
<a-select-option value="FOLDER">目录</a-select-option>
<a-select-option value="MENU">菜单</a-select-option>
<a-select-option value="BUTTON">按扭</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="序号" :label-col="{ span: 3 }" :wrapper-col="{ span: 21 }">
<a-input v-decorator="['orderNum']" placeholder="请输入序号" />
</a-form-item>
</a-form-item>
<a-form-item label="路径" :label-col="{ span: 3 }" :wrapper-col="{ span: 21 }">
<a-input v-decorator="['url']" placeholder="请输入路径" />
</a-form-item>
<a-form-item v-show="btnShowType" :wrapper-col="{ span: 21, offset: 3 }">
<a-button
type="primary"
html-type="submit"
class="btn_right_margin"
>保存</a-button>
<a-button @click="onCancel">取消</a-button>
</a-form-item>
</a-form>
</a-col>
</a-row>
</div>
</div>
</div>
</template>
<script>
// 导入接口
import {
addObj,
delObj,
fetchMenuTree,
getObj,
putObj
} from "@/api/admin/menu";
import { disposereq } from "@/utils/util";
export default {
data() {
return {
modalForm: this.$form.createForm(this, { name: "coordinated" }),
menuTreeData: [],
menuReplaceFields: {
children: "children",
title: "name",
key: "id"
},
checkData: "",
btnType: "",
btnShowType: false
};
},
// 创建完毕
created() {
this.GetAllMenu();
},
// 即将更新渲染
beforeUpdate() {
},
methods: {
// 获取所有菜单
GetAllMenu() {
fetchMenuTree()
.then(res => {
if (res.resp_code == 200) {
this.menuTreeData = res.datas.roots;
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
disposereq(this, err);
});
},
getMenuInfo(menuId){
getObj(menuId).then(res => {
if(res.resp_code == 200){
this.btnShowType = false;
this.checkData = res.datas;
this.$nextTick(()=>{
this.modalForm.setFieldsValue({
parentName: this.checkData.parentName,
name: this.checkData.name,
perms: this.checkData.perms,
icon: this.checkData.icon,
type: this.checkData.type,
orderNum: this.checkData.orderNum,
url: this.checkData.url
});
});
}else{
this.$message.info(res.resp_msg);
}
}).catch(err => {
disposereq(this, err);
});
},
// 菜单选中事件
onMenuCheck(checkedKeys, info) {
if(checkedKeys && checkedKeys.length > 0){
this.getMenuInfo(checkedKeys);
}else{
this.checkData = "";
this.$nextTick(() => {
this.modalForm.setFieldsValue({
parentName: "",
name: "",
perms: "",
icon: "",
type: "",
orderNum: "",
url: ""
});
});
}
},
// 添加菜单
addMenu(type) {
this.btnType = type;
this.btnShowType = true;
if (this.checkData == "") {
} else {
this.$nextTick(() => {
this.modalForm.setFieldsValue({
parentName: this.checkData.name,
name: "",
perms: "",
icon: "",
type: "",
orderNum: "",
url: ""
});
});
}
},
// 编辑菜单
editMenu(type) {
this.btnType = type;
if (this.checkData == "") {
this.$message.info('请先选择菜单');
} else {
this.btnShowType = true;
}
},
// 删除菜单
delMenu(type) {
this.btnType = type;
this.btnShowType = false;
if (this.checkData == "") {
this.$message.info('请先选择菜单');
} else {
delObj(this.checkData.id)
.then(res => {
if (res.resp_code == 200) {
this.GetAllMenu();
this.$message.success('删除成功');
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
}
},
// 提交事件
modalHandleSubmit(e) {
e.preventDefault();
this.modalForm.validateFields((err, values) => {
if (!err && this.btnType == "add") {
let menuObj = {};
menuObj.parentId = this.checkData == "" ? 0 : this.checkData.id;
menuObj.name = values.name;
menuObj.perms = values.perms ? values.perms : "";
menuObj.icon = values.icon ? values.icon : "";
menuObj.type = values.type;
menuObj.orderNum = values.orderNum ? values.orderNum : this.checkData == "" ? 0 : this.checkData.orderNum + 1
menuObj.url = values.url ? values.url : ""
// console.log(menuObj)
addObj(menuObj)
.then(res => {
if (res.resp_code == 200) {
this.GetAllMenu();
this.$message.success('添加成功');
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
} else if (!err && this.btnType == "edit") {
values.id = this.checkData.id;
values.parentId = this.checkData.parentId;
// console.log(values)
putObj(values)
.then(res => {
if (res.resp_code == 200) {
this.GetAllMenu();
this.$message.success('编辑成功');
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
}
});
},
onCancel(e){
// console.log("cancel")
this.btnShowType = false;
if(this.checkData != ""){
this.getMenuInfo(this.checkData.id);
}
}
}
};
</script>
<style>
.template_content {
background-color: #f0f2f5;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.content_box {
width: 100%;
background-color: #fff;
padding: 14px;
}
.table_top {
padding-bottom: 14px;
}
.btn_margin {
margin: 0px 5px;
}
.btn_right_margin {
margin-right: 10px;
}
.col-h{
min-height: 400px;
box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 5px 1px;
}
</style>
\ No newline at end of file
<template>
<div class="template_content">
<!-- 主体内容 -->
<div class="content_box">
<!-- 表格操作 -->
<div class="table_top">
<a-button
icon="plus"
type="primary"
class="btn_right_margin"
@click="showModal('')"
>添加</a-button>
</div>
<a-table
:columns="columns"
:dataSource="data"
:loading="loading"
:pagination="pagination"
bordered
size="small"
rowKey="id"
@change="handleTableChange"
>
<template slot="action" slot-scope="text, record">
<a-button
icon="edit"
type="primary"
class="btn_margin"
@click="showModal(record)"
>编辑</a-button>
<a-button
icon="delete"
type="danger"
class="btn_margin"
@click="deleteRow(record)"
>删除</a-button>
<a-button
icon="cluster"
type="link"
class="btn_margin"
@click="menuAuthModal(record)"
>菜单权限</a-button>
</template>
</a-table>
</div>
<!-- 添加及编辑弹窗 -->
<a-modal :title="modalTitle" v-model="modalVisible" :footer="null">
<a-form :form="modalForm" @submit="modalHandleSubmit">
<a-form-item label="角色名称" :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
<a-input
v-decorator="[
'name',{rules: [{required: true, message: '角色名称不能为空'}]}
]"
placeholder="请输入角色名称"
/>
</a-form-item>
<a-form-item label="角色代码" :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
<a-input
v-decorator="[
'code',{rules: [{required: true, message: '角色代码不能为空'}]}
]"
placeholder="请输入角色代码"
/>
</a-form-item>
<a-form-item :wrapper-col="{ span: 19, offset: 5 }">
<a-button type="primary" html-type="submit">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
<!-- 菜单权限弹窗 -->
<a-modal
title="菜单权限"
v-model="menumodalVisible"
:footer="null"
destroyOnClose
>
<a-tree
checkable
:treeData="menuTreeData"
:defaultCheckedKeys="menuDefaultCheckedKeys"
:replaceFields="menuReplaceFields"
defaultExpandAll
@check="this.onMenuCheck"
/>
<div class="btn-box">
<a-button type="primary" @click="saveMenu">保存</a-button>
</div>
</a-modal>
</div>
</template>
<script>
// 导入接口
import {
addObj,
delObj,
fetchList,
putObj,
fetchRoleMenuIds,
permissionUpd
} from "@/api/admin/role";
import { fetchMenuTree } from "@/api/admin/menu";
import { disposereq } from "@/utils/util";
let columns = [
{
title: "角色名称",
dataIndex: "name",
align: "center"
},
{
title: "角色代码",
dataIndex: "code",
align: "center"
},
{
title: "创建时间",
dataIndex: "createTime",
align: "center"
},
{
title: "操作",
key: "action",
scopedSlots: { customRender: "action" },
align: "center"
}
];
export default {
data() {
return {
name: "",
loading: true,
searchPage: {
pageIndex: 1,
pageSize: 10,
name: ""
},
columns: columns,
data: [],
pagination: {
showQuickJumper: true,
showSizeChanger: true
},
modalVisible: false,
modalTitle: '添加',
modalForm: this.$form.createForm(this, { name: "coordinated" }),
rowData: {},
menumodalVisible: false,
menuTreeData: [],
menuDefaultCheckedKeys: [],
allMenuCheckedKeys: [],
menuReplaceFields: {
children: "children",
title: "name",
key: "id"
},
tmpMenuIds: []
};
},
// 创建完毕
created() {
this.getList(this.searchPage);
this.GetAllMenu();
},
// 即将更新渲染
beforeUpdate() {
},
methods: {
// 获取角色
getList(pageData) {
fetchList(pageData)
.then(res => {
this.loading = false;
if (res.code == 200) {
this.data = res.data;
const pager = { ...this.pagination };
pager.current = pageData.pageIndex;
pager.total = res.count;
this.pagination = pager;
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
},
// 获取所有菜单
GetAllMenu() {
fetchMenuTree()
.then(res => {
if (res.resp_code == 200) {
// console.log(res.datas)
this.menuTreeData = res.datas.roots;
this.deepList(res.datas.roots);
// console.log(this.menuTreeData)
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
},
// 获取选中菜单
GetCheckMenu(roleId) {
fetchRoleMenuIds(roleId)
.then(res => {
// console.log(this.tmpMenuIds)
this.allMenuCheckedKeys = res.datas
let result = [...new Set(this.tmpMenuIds)].filter((item) => new Set(eval(res.datas)).has(item));
// console.log(result)
this.menuDefaultCheckedKeys = result
this.menumodalVisible = true;
})
.catch(err => {
this.$message.info(err);
});
},
deepList(data){
data.map((item) => {
if (item.children && item.children.length > 0) {
this.deepList(item.children);
} else {
//test数组存放
this.tmpMenuIds.push(item.id);
}
});
},
// 表格数据变化触发事件
handleTableChange(pagination, filters, sorter) {
const searchPage = { ...this.searchPage };
searchPage.current = pagination.current;
searchPage.size = pagination.pageSize;
this.loading = true;
this.getList(searchPage);
},
// 搜索事件
handleSubmit() {
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
},
// 显示对话框
showModal(row) {
this.modalVisible = true;
// 判断添加或者编辑
if (row == "") {
this.modalTitle = '添加';
this.modalType = "add";
this.$nextTick(() => {
this.modalForm.setFieldsValue({
name: "",
code: ""
});
});
} else {
this.modalTitle = '编辑';
this.modalType = "edit";
this.$nextTick(() => {
this.modalForm.setFieldsValue({
name: row.name,
code: row.code
});
this.rowData = row;
});
}
},
// 删除行数据
deleteRow(row) {
console.log(row)
delObj([row.id])
.then(res => {
this.loading = false;
if (res.resp_code == 200) {
this.$message.success('删除成功');
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
},
// 对话框
modalHandleSubmit(e) {
e.preventDefault();
this.modalForm.validateFields((err, values) => {
if (!err && this.modalType == "add") {
// console.log(values)
addObj(values)
.then(res => {
if (res.resp_code == 200) {
this.modalVisible = false;
this.$message.success('保存成功');
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
} else if (!err && this.modalType == "edit") {
this.rowData.name = values.name;
this.rowData.code = values.code;
putObj(this.rowData)
.then(res => {
if (res.resp_code == 200) {
this.modalVisible = false;
this.$message.success('保存成功');
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
}
});
},
// 显示菜单权限
menuAuthModal(row) {
this.GetCheckMenu(row.id);
this.roleId = row.id;
},
onMenuCheck(selectedKeys, info) {
this.menuDefaultCheckedKeys = selectedKeys;
this.allMenuCheckedKeys = selectedKeys.concat(info.halfCheckedKeys);
},
// 保存菜单
saveMenu() {
// console.log(this.allMenuCheckedKeys)
permissionUpd(this.roleId, this.allMenuCheckedKeys)
.then(res => {
if (res.resp_code == 200) {
this.menumodalVisible = false;
this.$message.success('保存成功');
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
},
}
};
</script>
<style>
.search_box {
width: 100%;
box-sizing: border-box;
padding: 14px;
background-color: #fff;
}
.template_content {
background-color: #f0f2f5;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.content_box {
width: 100%;
background-color: #fff;
margin-top: 10px;
padding: 14px;
}
.table_top {
padding-bottom: 14px;
}
.btn_margin {
margin: 0px 5px;
}
.btn_right_margin {
margin-right: 10px;
}
.btn-box {
margin-top: 20px;
}
</style>
\ No newline at end of file
<template>
<div class="template_content">
<!-- 搜索 -->
<div class="search_box">
<a-form layout="inline">
<a-form-item label="查询条件:">
<a-input v-model="searchPage.username" placeholder="用户名" allowClear></a-input>
</a-form-item>
<a-form-item>
<a-button icon="search" type="primary" @click="handleSubmit">查询</a-button>
</a-form-item>
</a-form>
</div>
<!-- 主体内容 -->
<div class="content_box">
<!-- 表格操作 -->
<div class="table_top">
<a-button
icon="plus"
type="primary"
class="btn_right_margin"
@click="showModal('')"
>添加</a-button>
</div>
<a-table
:columns="columns"
:dataSource="data"
:loading="loading"
:pagination="pagination"
bordered
size="small"
@change="handleTableChange"
rowKey="id"
>
<!-- 角色 -->
<span slot="roleList" slot-scope="roleList">
<a-tag v-for="role in roleList" :key="role.roleId" color="purple">{{role.name}}</a-tag>
</span>
<!-- 状态 -->
<span slot="statusFlag" slot-scope="status">
<a-tag
:key="status"
:color="status == 'ENABLE'?'#108ee9':'#f50'"
>{{status == 'ENABLE'?"启用":"禁用"}}</a-tag>
</span>
<!-- 操作 -->
<template slot="action" slot-scope="text, record">
<a-button
icon="edit"
type="primary"
class="btn_margin"
@click="showModal(record)"
>修改</a-button>
<a-button
icon="delete"
type="danger"
class="btn_margin"
@click="deleteRow({record})"
>删除</a-button>
</template>
</a-table>
</div>
<!-- 弹窗 -->
<a-modal :title="modalTitle" v-model="modalVisible" :footer="null">
<a-form :form="modalForm" @submit="modalHandleSubmit">
<a-form-item label="用户名" :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
<a-input
v-decorator="['username', { rules: [{ required: true, message: '用户名不能为空' }] }]"
placeholder="请输入用户名"
:disabled="modalType == 'edit'"
/>
</a-form-item>
<a-form-item v-if="modalType == 'add'" label="密码" :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
<a-input-password
v-decorator="['password', { rules: [{ required: true, message: '密码不能为空' }] }]"
placeholder="请输入密码"
/>
</a-form-item>
<a-form-item label="昵称" :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
<a-input
v-decorator="['nickName']"
placeholder="请输入昵称"
/>
</a-form-item>
<a-form-item label="角色" :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
<a-select
v-decorator="[
'roleIdList',
{ rules: [{ required: true, message: '角色不能为空'}] },
]"
placeholder="请选择角色"
mode="multiple"
>
<a-select-option
v-for="item in roleList"
:key="item.id"
:value="item.id"
>{{item.name}}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="状态" :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
<a-select
v-decorator="['status']"
>
<a-select-option value="ENABLE">启用</a-select-option>
<a-select-option value="DISABLE">禁用</a-select-option>
</a-select>
</a-form-item>
<a-form-item :wrapper-col="{ span: 19, offset: 5 }">
<a-button type="primary" html-type="submit">保存</a-button>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
// 导入接口
import { addObj, delObj, fetchList, getObj, putObj } from "@/api/admin/user";
import { getRoleList } from "@/api/admin/role";
import { fetchTree } from "@/api/admin/dept";
import { disposereq,timestampToTime } from "@/utils/util";
let columns = [
{
title: "用户名",
dataIndex: "username",
align: "center"
},
{
title: "昵称",
dataIndex: "nickName",
align: "center"
},
{
title: "状态",
dataIndex: "status",
align: "center",
scopedSlots: { customRender: "statusFlag" }
},
{
title: "角色",
dataIndex: "roleIdList",
align: "center",
scopedSlots: { customRender: "roleList" }
},
{
title: "创建时间",
dataIndex: "createTime",
align: "center",
customRender: (text,record) => {
return timestampToTime(text);
}
},
{
title: "操作",
key: "action",
scopedSlots: { customRender: "action" },
align: "center"
}
];
export default {
data() {
return {
username: "",
loading: true,
searchPage: {
pageIndex: 1,
pageSize: 10,
username: ""
},
columns: columns,
data: [],
pagination: {
showQuickJumper: true,
showSizeChanger: true
},
modalVisible: false,
modalTitle: '添加',
modalType: '',
modalForm: this.$form.createForm(this, { name: "coordinated" }),
parameters: {
username: "",
password: "",
role: [],
status: "ENABLE"
},
roleList: "",
rowData: {},
fieldNames: { label: "name", value: "id", children: "children" }
};
},
// 创建完毕
created() {
this.getList(this.searchPage);
this.getRoleList();
},
// 即将更新渲染
beforeUpdate() {
},
methods: {
// 获取用户
getList(pageData) {
fetchList(pageData)
.then(res => {
// console.log(res);
this.loading = false;
if (res.code === 200) {
this.data = res.data;
const pager = { ...this.pagination };
pager.current = pageData.pageIndex;
pager.total = res.count;
this.pagination = pager;
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
// console.log(err);
disposereq(this, err);
});
},
// 获取角色
getRoleList() {
getRoleList()
.then(res => {
// console.log(res);
this.loading = false;
if (res.resp_code == 200) {
this.roleList = res.datas;
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
disposereq(this, err);
});
},
// 表格数据变化触发事件
handleTableChange(pagination, filters, sorter) {
const searchPage = { ...this.searchPage };
searchPage.pageIndex = pagination.current;
searchPage.pageSize = pagination.pageSize;
this.loading = true;
this.getList(searchPage);
},
// 搜索事件
handleSubmit() {
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
},
// 显示对话框
showModal(row) {
this.modalVisible = true;
// 判断添加或者编辑
if (row == "") {
this.modalTitle = '添加';
this.modalType = "add";
this.$nextTick(() => {
this.modalForm.setFieldsValue({
username: "",
password: "",
nickName: "",
roleIdList: [],
status: "ENABLE"
});
});
} else {
console.log(row);
this.modalTitle = '编辑';
this.modalType = "edit";
// 获取角色liebiao
let role = [];
for (let i = 0; i < row.roleIdList.length; i++) {
role.push(row.roleIdList[i].id);
}
this.$nextTick(() => {
this.modalForm.setFieldsValue({
username: row.username,
nickName: row.nickName,
roleIdList: role,
status: row.status
});
this.rowData = row;
});
}
},
// 删除行数据
deleteRow(row) {
delObj([row.record.id])
.then(res => {
this.loading = false;
if (res.resp_code == 200) {
this.$message.success('删除成功');
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
disposereq(this, err);
});
},
// 对话框
modalHandleSubmit(e) {
e.preventDefault();
this.modalForm.validateFields((err, values) => {
if (!err && this.modalType == "add") {
// console.log(values);
addObj(values)
.then(res => {
if (res.resp_code == 200) {
this.modalVisible = false;
this.$message.success('保存成功');
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
} else if (!err && this.modalType == "edit") {
this.rowData.username = values.username;
this.rowData.nickName = values.nickName;
this.rowData.roleIdList = values.roleIdList;
this.rowData.status = values.status;
// console.log(this.rowData);
putObj(this.rowData)
.then(res => {
if (res.resp_code == 200) {
this.modalVisible = false;
this.$message.success('保存成功');
const searchPage = { ...this.searchPage };
this.loading = true;
this.getList(searchPage);
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
this.$message.info(err);
});
}
});
}
}
};
</script>
<style>
.search_box {
width: 100%;
box-sizing: border-box;
padding: 14px;
background-color: #fff;
}
.template_content {
background-color: #f0f2f5;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.content_box {
width: 100%;
background-color: #fff;
margin-top: 10px;
padding: 14px;
}
.table_top {
padding-bottom: 14px;
}
.btn_margin {
margin: 0px 5px;
}
.btn_right_margin {
margin-right: 10px;
}
</style>
\ No newline at end of file
<template>
<div>
<a-form-model
:model="form"
:label-col="labelCol"
:wrapper-col="wrapperCol"
:rules="rules"
ref="ruleForm"
>
<a-form-model-item label="用户名">
<a-input v-model="form.username" disabled/>
</a-form-model-item>
<a-form-model-item label="昵称" prop="nickName">
<a-input v-model="form.nickName"/>
</a-form-model-item>
<a-form-model-item label="角色">
<a-tag v-for="role in form.roles" :key="role.id" color="blue">
{{role.name}}
</a-tag>
</a-form-model-item>
<a-form-model-item :wrapper-col="{span: 4,offset: 4}">
<a-space size="middle">
<a-button type="primary" @click="onSubmit">
保存
</a-button>
<a-button type="primary" @click="showModel">
修改密码
</a-button>
</a-space>
</a-form-model-item>
</a-form-model>
<!-- 修改密码Modal -->
<a-modal title="修改密码"
:confirm-loading="comfirmLoading"
:visible="modalVisible"
@ok="changePwd"
@cancel="handleCancel"
>
<a-form-model
:model="modalForm"
:rules="modalRules"
ref="modalForm"
:label-col="{span:4}"
:wrapper-col="{span:8}"
>
<a-form-model-item ref="oldPwd" label="原始密码" prop="password">
<a-input-password v-model="modalForm.password"
@blur="() => {
$refs.oldPwd.onFieldBlur()
}"
/>
</a-form-model-item>
<a-form-model-item ref="newPwd" label="新密码" prop="newPassword">
<a-input-password v-model="modalForm.newPassword"
@blur="() => {
$refs.newPwd.onFieldBlur()
}
"
/>
</a-form-model-item>
</a-form-model>
</a-modal>
</div>
</template>
<script>
import {getCurrentInfo,putObj,changePassword} from '@/api/admin/user';
import { disposereq } from "@/utils/util";
export default {
data(){
return {
labelCol: {span: 4},
wrapperCol: {span: 4},
form: {
id: 0,
username: '',
nickName: '',
status: '',
roles: [],
status: ''
},
modalForm: {
password: '',
newPassword: '',
},
rules: {
nickName: [
{required: true,message: '昵称不能为空',trigger: 'blur'}
]
},
modalRules: {
oldPwd: [
{required: true ,message: '原始密码不能为空',trigger: 'blur'}
],
newPwd: [
{required: true ,message: '新密码不能为空',trigger: 'blur'}
]
},
comfirmLoading: false,
modalVisible: false,
}
},
// 创建完毕
created() {
this.getUserInfo()
},
// 即将更新渲染
beforeUpdate() {
},
methods:{
getUserInfo(){
let userInfoStr = localStorage.getItem("UserInfo")
let userInfo = JSON.parse(userInfoStr)
getCurrentInfo().then(res => {
if(res.resp_code == 200){
this.form.id = res.datas.id
this.form.username = res.datas.username
this.form.nickName = res.datas.nickName
this.form.roles = userInfo.roles
this.form.status = res.datas.status
}else{
this.$message.info(res.resp_msg)
}
}).catch(err => {
disposereq(err);
})
// console.log(userInfoStr)
},
onSubmit(){
this.$refs.ruleForm.validate(valid => {
if(valid){
putObj(this.form).then(res => {
if(res.resp_code == 200){
this.$message.info('保存成功')
}else{
this.$message.info('保存失败')
}
}).catch(err => {
disposereq(err)
})
}
});
},
showModel(){
this.modalVisible = true;
},
changePwd(e){
this.comfirmLoading = true;
this.$refs.modalForm.validate(valid => {
if(valid){
changePassword(this.modalForm).then(res => {
if(res.resp_code == 200){
this.modalVisible = false;
this.comfirmLoading = false;
this.$refs.modalForm.resetFields()
}else{
this.$message.info(res.resp_msg);
this.comfirmLoading = false;
}
}).catch(err => {
disposereq(err);
})
}else{
this.comfirmLoading = false;
return false;
}
})
},
handleCancel(e){
this.modalVisible = false;
this.$refs.modalForm.resetFields()
}
}
}
</script>
<style>
</style>
<template>
<a-layout class="layoutbox" id="components-layout-demo-custom-trigger">
<!-- 左侧菜单 -->
<a-layout-sider :trigger="null" collapsible v-model="collapsed">
<div class="logo">{{ collapsed ? "菜单" : "后台管理系统" }}</div>
<a-menu
theme="dark"
mode="inline"
:defaultSelectedKeys="['1']"
@click="selectItem"
:selectedKeys="[$route.path]"
>
<a-sub-menu v-for="item in menu" :key="item.key">
<span slot="title">
<a-icon :type="item.icon" />
<span v-show="!collapsed">{{ item.name }}</span>
</span>
<a-menu-item
v-for="childrenitem in item.children"
:key="childrenitem.key"
>
<a-icon :type="childrenitem.icon" />
<span>{{ childrenitem.name }}</span>
</a-menu-item>
</a-sub-menu>
</a-menu>
</a-layout-sider>
<a-layout>
<!-- 页面整体头部导航 -->
<a-layout-header class="headbox" style="padding: 0">
<!-- 左侧展示与隐藏 -->
<a-icon
class="trigger"
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
@click="() => (collapsed = !collapsed)"
/>
<div class="user-head">
<!-- 用户信息 -->
<a-dropdown>
<span>
<a-avatar icon="user" />
<a class="ant-dropdown-link" href="#">
{{ UserInfo.username }}
<a-icon type="down" />
</a></span>
<a-menu slot="overlay">
<a-menu-item @click="headClick('home')">
<i class="iconfont iconicon_huabanfuben"></i>
<span>首页</span>
</a-menu-item>
<a-menu-item @click="headClick('userInfo')">
<i class="iconfont icongerenzhongxin"></i>
<span>个人信息</span>
</a-menu-item>
<a-menu-item @click="headClick('quit')">
<i class="iconfont icontuichu2"></i>
<span>退出登录</span>
</a-menu-item>
</a-menu>
</a-dropdown>
</div>
</a-layout-header>
<!-- 中间主体部分 -->
<a-layout-content
:style="{
margin: '10px 10px',
padding: '0px',
background: '#fff',
minHeight: '280px'
}"
>
<router-view class="avue-view" />
</a-layout-content>
</a-layout>
</a-layout>
</template>
<script>
import { GetMenu } from "../api/admin/token";
import { disposereq } from "@/utils/util";
import router from "@/router";
import Layout from "@/views/index/";
export default {
data() {
return {
collapsed: false,
menu: [],
UserInfo: {},
};
},
created() {
this.getMenu();
// 获取用户信息
this.UserInfo = JSON.parse(localStorage.getItem("UserInfo"));
},
methods: {
// 获取菜单
getMenu() {
GetMenu()
.then(res => {
if (res.resp_code === 200) {
this.menu = this.formatData(
res.datas.menuList
);
let asyncRouters = this.routerPackag(
res.datas.menuList
);
// console.log(asyncRouters);
// asyncRouters.push({ path: "*", redirect: "/index" });
router.addRoutes(asyncRouters);
} else {
this.$message.info(res.resp_msg);
}
})
.catch(err => {
disposereq(this, err);
});
},
// 路由数据重新封装
routerPackag(menuList) {
let accessedRouters = [];
if(menuList){
for(let i = 0;i<menuList.length;i++){
let router = {};
router.name = menuList[i].name;
router.path = menuList[i].url;
if(menuList[i].type == 'FOLDER'){
router.component = Layout;
}else{
router.component = this.loadView(menuList[i].url);
}
if(menuList[i].children && menuList[i].children.length){
router.children = this.routerPackag(menuList[i].children);
}
accessedRouters.push(router);
}
}
return accessedRouters;
},
loadView(view) {
// 路由懒加载
return () => import(`@/views/${view}`);
},
// 菜单点击事件
selectItem(item) {
console.log(item);
this.$router.push({
path: item.key
});
},
// 由于数据格式不符合,需要对数据进行处理
formatData(data,parentKey = null) {
var menuList = [];
if(data){
for (let i = 0; i < data.length; i++) {
var menuItem = {};
menuItem.name = data[i].name;
menuItem.key = parentKey == null ? data[i].url : parentKey + '/' + data[i].url;
menuItem.icon = data[i].icon;
menuItem.children = this.formatData(data[i].children,menuItem.key);
menuList.push(menuItem);
}
}
return menuList;
},
headClick(type) {
if (type == "home") {
this.$router.push({
path: "/index"
});
} else if (type == "userInfo") {
this.$router.push({
path: "/userinfo"
})
} else {
localStorage.removeItem("token");
this.$router.push({
path: "/login"
});
}
},
}
};
</script>
<style>
.layoutbox {
height: 100%;
}
#components-layout-demo-custom-trigger .trigger {
font-size: 18px;
line-height: 64px;
padding: 0 24px;
cursor: pointer;
transition: color 0.3s;
color: #fff;
}
#components-layout-demo-custom-trigger .trigger:hover {
color: #1890ff;
}
#components-layout-demo-custom-trigger .logo {
height: 32px;
margin: 16px;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
font-weight: bold;
}
.headbox {
display: flex;
justify-content: space-between;
align-items: center;
}
.iconfont {
font-size: 14px !important;
margin-right: 5px;
}
.toggle {
display: inline-block;
box-sizing: border-box;
padding-right: 20px;
}
.user-head {
display: inline-block;
box-sizing: border-box;
padding-right: 20px;
}
</style>
<template>
<div class="body">
<TSCarousel />
<div class="conbox">
<div class="logo">
<img src="../assets/img/logo.png" alt />
<div>后台管理平台</div>
</div>
<div class="smbox">
<div class="a-form-itembox">
<a-form :form="form" @submit="handleSubmit">
<a-form-item class="Item">
<div class="title">系统登录</div>
</a-form-item>
<a-form-item class="Item inputbox">
<a-input
placeholder="请输入用户名"
size="large"
v-decorator="['username', { rules: [{ required: true, message: '用户名不能为空' }] }]"
>
<icon-font
slot="prefix"
type="icon-yonghu"
:style="{ fontSize: '16px', color: '#0088cc' }"
/>
</a-input>
</a-form-item>
<a-form-item class="Item inputbox">
<a-input
placeholder="请输入密码"
size="large"
type="password"
v-decorator="['password', { rules: [{ required: true, message: '密码不能为空' }] }]"
>
<icon-font
slot="prefix"
type="icon-mima"
:style="{ fontSize: '16px', color: '#0088cc' }"
/>
</a-input>
</a-form-item>
<a-form-item class="Item inputbox">
<a-button
type="primary"
:loading="btnloading"
html-type="submit"
class="btn"
size="large"
>登录</a-button>
</a-form-item>
</a-form>
</div>
</div>
<div class="foot">
<a class="copyright-a" href="http://www.beian.miit.gov.cn">蒙ICP备XXXXXXXXX号</a> Copyright ©2017-2021 版权所有 : www.qiankundata.com
</div>
</div>
</div>
</template>
<script>
import TSCarousel from "../components/TSCarousel";
import { encryption } from "../utils/utils";
import { loginByUserToken, getUserInfo } from "../api/admin/token";
export default {
data() {
return {
login: {
username: "",
password: "",
},
btnloading: false,
form: this.$form.createForm(this, { name: "coordinated" })
};
},
// 注册组件
components: {
TSCarousel
},
created() {
},
beforeUpdate() {
},
methods: {
// 提交
handleSubmit(e) {
e.preventDefault();
this.form.validateFields((err, values) => {
if (!err) {
this.btnloading = true;
this.login.username = values.username;
this.login.password = values.password;
// 请求token
loginByUserToken(this.login).then(response => {
// 判断是否成功
if(response.resp_code === 200){
localStorage.setItem('token',response.datas.authorization);
localStorage.setItem('UserInfo',JSON.stringify(response.datas));
this.$router.push({
path: '/index'
});
}else{
this.$message.info(response.resp_msg);
this.btnloading = false;
}
});
}
});
}
}
};
</script>
<style scoped>
.body {
width: 100%;
height: 100vh;
box-sizing: border-box;
}
.conbox {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.logo {
font-size: 30px;
color: #fff;
width: 60vw;
display: flex;
align-items: center;
}
.logo img {
height: 80px;
margin-right: 20px;
}
.smbox {
width: 60vw;
height: 60vh;
background-color: #fff;
margin: 40px 0px;
box-shadow: 0px 0px 10px #000;
background-image: url("../assets/img/bg.png");
background-repeat: no-repeat;
background-position: left;
background-size: 100%;
position: relative;
}
.a-form-itembox {
position: absolute;
top: 0px;
right: 0px;
box-sizing: border-box;
padding: 60px 80px;
}
.title {
font-size: 20px;
}
.inputbox {
width: 300px;
box-sizing: border-box;
}
.inputsmbox {
width: 300px;
box-sizing: border-box;
display: flex;
flex-direction: row;
}
.btn {
width: 300px;
}
.foot {
color: #fff;
}
.copyright-a {
text-decoration: none;
color: #fff;
}
.copyright-a:hover {
color: #fff;
}
.toggle {
position: absolute;
top: 20px;
right: 20px;
z-index: 1000;
}
</style>
/**
* 欢迎界面
*/
<template >
<div class="container">
<h1>欢迎使用后台管理系统</h1>
<img src="../assets/img/welcome.png" alt />
</div>
</template>
<script>
export default {
// 创建完毕状态(里面是操作)
created() {
},
// 挂载结束状态(里面是操作)
mounted() {},
// 里面的函数只有调用才会执行
methods: {
}
};
</script>
<style>
h1 {
font-size: xx-large;
}
.container{
width: 100%;
height: 100%;
display: flex;
display: -webkit-flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
align-content: center;
}
</style>
\ No newline at end of file
/**
* 配置该文件可以参考:
* https://cli.vuejs.org/zh/config/#%E7%9B%AE%E6%A0%87%E6%B5%8F%E8%A7%88%E5%99%A8
*
*/
const url = 'http://localhost:9090'
// 基础路径,发布前修改这里,当前配置打包出来的资源都是相对路径
let publicPath = '/'
module.exports = {
configureWebpack: {
externals: {
"BMap": "BMap"
}
},
publicPath: publicPath,
// eslint校验
lintOnSave: false,
productionSourceMap: false,
// 配置转发代理
devServer: {
port: 8081,
proxy: {
'/api': {
target: url,
changeOrigin: true,
ws: true,
pathRewrite: {
'^/api': '/online-edu-backend/api'
}
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment