许愿墙的后台管理系统主要有4个模块:登录模块、首页模块、许愿管理模块和管理员管理模块。使用前后端分离方式,后端接口使用Express框架,前端使用Vue框架,页面使用Element组件。这节实现前端页面。
相关连接:3. 许愿墙后台管理系统(后端接口)
4.1 页面效果
4.1.1 登录页面
4.1.2 首页
4.1.3 许愿管理
4.1.4 管理员管理
4.2 创建前端项目
4.2.1 生成项目目录 wish-admin
4.2.2 安装依赖包
npm i element-ui -S
npm i jquery -S
npm i axios -S
安装好以后,在 main.js 中引入:
//main.js
...
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
...
import 'jquery'
...
Vue.use(ElementUI);
...
jquery引入后,还需要一些配置才能使用,在根目录下创建 vue.config.js:
//vue.config.js
const webpack = require('webpack')
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
})
]
}
}
然后在根目录的 eslintrc.js 中添加:
//eslintrc.js
...
env: {
...
jquery: true
},
...
4.2.3 添加公共方法和公共参数
//utils/commonData.js
export const commonData = {
rolesData: {
1: '超级管理员',
2: '普通管理员'
}
}
//utils/commonFunc.js
import { Loading, MessageBox} from 'element-ui';
//显示loading
export function setLoading(text){
return Loading.service({
lock: true,
text: text || '处理中...',
background: 'rgba(0, 0, 0, 0.7)'
});
}
//提示信息
export function showAlertMessage(text, title, type, func){
MessageBox.alert(text, title, {
type: type,
callback: func,
showClose: false,
confirmButtonText: '确定',
});
}
//提示信息
export function showConfirmMessage(text, title, type, func){
MessageBox.confirm(text, title,{
confirmButtonText:'确定',
cancelButtonText:'取消',
type: type
}).then(() => {
func && func();
}).catch(err => {
console.log(err);
})
}
//utils/outbound.js
import axios from 'axios'
import store from '@/store'
import {showAlertMessage} from '@/utils/commonFunc'
const urlData = {
LOGIN: '/login',//登录首页
WISH: '/wish',//操作许愿信息
ADMIN: '/admin',//操作管理员信息
};
/**
* 发送交易
*
**/
export function sendMSRequest(map, method, params, func) {
if(Object.prototype.hasOwnProperty.call(urlData, map)){
const comUrl = 'http://localhost:3002';
const token = store.getters.token;
let url = urlData[map];
let sendObj = {};
sendObj.method = method;
sendObj.url = comUrl + url;
if(map !== 'LOGIN'){
sendObj.headers = {
token: token
}
}
if(method === 'get'){
sendObj.params = params;
}else {
sendObj.data = params;
}
axios(sendObj).then(res => {
func(res.data);
}).catch(err => {
console.log(err);
})
}else{
let message = '发送的请求[ ' + map + ' ]出现错误,请查看!';
showAlertMessage(message, '提示信息', 'warning');
}
}
4.2.4 添加状态管理
//store/modules/login.js
const login = {
state: {
role: '',
name: '',
token: '',
username: '',
userInfo: null,
},
mutations: {
SET_ROLE(state, data){
state.role = data;
},
SET_NAME(state, data){
state.name = data;
},
SET_TOKEN(state, data){
state.token = data;
},
SET_USERNAME(state, data){
state.username = data;
},
SET_USERINFO(state, data){
state.userInfo = data;
}
},
actions: {
Set_Role({commit}, data){
commit('SET_ROLE', data);
},
Set_Name({commit}, data){
commit('SET_NAME', data);
},
Set_Token({ commit }, data){
commit('SET_TOKEN', data);
},
Set_Username({ commit }, data){
commit('SET_USERNAME', data);
},
Set_UserInfo({ commit }, data){
commit('SET_USERINFO', data);
}
},
getters: {
role: state => state.role,
name: state => state.name,
token: state => state.token,
username: state => state.username,
userInfo: state => state.userInfo
}
}
export default login
//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import login from './modules/login'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
login
}
})
export default store
4.2.5 添加公共样式
//styles/common.css
* {
margin: 0;
padding: 0;
}
.float-lf {
float: left;
}
.float-rt {
float: right;
}
.clearFloat:after {
content: "";
display: block;
clear: both;
}
.main-page {
margin: 10px;
padding: 20px;
background: #fff;
}
.el-select {
width: 100%;
}
.search-area {
margin-bottom: 20px;
}
.search-area .el-button {
margin-left: 5px;
}
.opt-btn {
text-align: center;
margin: 20px 0;
}
4.2.6 添加路由
//router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeContent from '@/views/home/homeContent'
import WishManage from '@/views/wishManage/wishManage'
import AdminManage from '@/views/adminManage/adminManage'
Vue.use(VueRouter)
const routes = [
{
name: '系统首页',
path: '/home',
component: HomeContent
}, {
name: '许愿管理',
path: '/wish',
component: WishManage
},{
name: '管理员管理',
path: '/admin',
component: AdminManage
},
]
const router = new VueRouter({
mode: 'history',
routes
});
export default router
4.2.7 添加公共组件
//components/comTable.vue
<template>
<!--单选表格-->
<div class="comTable">
<!--功能标签-->
<div class="label_list clearFloat">
<el-button type="primary" plain size="mini" v-for="(item,index) in funcData" :key="index" @click="item.clickFunc">{{item.text}}</el-button>
</div>
<el-table border size="small" :data="tableData" v-loading="isLoading" highlight-current-row @current-change="selectRow">
<el-table-column type="index" label="序号" width="50px" align="center">
<template slot-scope="scope">
{{(page - 1) * rows + scope.$index + 1}}
</template>
</el-table-column>
<el-table-column v-for="(item,index) in tableTitleData" :key="index" :label="item.text" align="center" :width="item.width" show-overflow-tooltip>
<template slot-scope="scope">
<span :class="item.clickFunc?'table_first_col':''" @click="clickFunc(item.clickFunc, scope.row)">{{scope.row[item.prop]}}</span>
</template>
</el-table-column>
<slot></slot>
</el-table>
<!--分页-->
<div class="page-break float-rt">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
prev-text="上一页"
next-text="下一页"
layout="total,sizes,prev,pager,next,jumper"
:current-page="page"
:page-sizes="[5,10,20,30]"
:page-size="rows"
:total="totalDataNum">
</el-pagination>
</div>
</div>
</template>
<script>
export default {
props: {
fixText: String,
funcData: Array,
tableData: Array,
tableTitleData: Array,
},
data(){
return {
rows: 10,
page: 1,
totalDataNum: 0,
isLoading: false,
selectRowData: null,
}
},
methods: {
//绑定事件
clickFunc(func, data){
if(func){
func(data);
}
},
//设置列显隐后刷新列表数据
refreshTableData(){
this.$emit('queryTableData', 'set');
},
//选中表格的某一行
selectRow(val){
this.selectRowData = val;
this.$emit('rowClick', this.selectRowData);
},
//每页显示条数变化取值
handleSizeChange(rows){
this.rows = rows;
this.$emit('queryTableData', '');
},
//当前页变化值
handleCurrentChange(page){
this.page = page;
this.$emit('queryTableData', '');
},
//查询后还原表格相关数据
resetTableData(){
this.isLoading = false;
this.selectRowData = null;
},
//初始化请求页数数据
initData(){
this.page = 1;
this.rows = 10;
this.totalDataNum = 0;
this.tableData.splice(0);
},
}
}
</script>
//components/comWindow.vue
<template>
<!--弹出窗口组件-->
<div ref="winFixed" class="com-win" @mousemove="mouseMove" @mouseup="mouseStop">
<div ref="winContainer"
class="win-container"
@mousedown="mouseStart"
:style="'left:' + position.x + 'px;top:' + position.y + 'px;'">
<div ref="winTitle" class="win-title">
{{winTitle}}
<i class="el-icon-close" style="float: right; cursor: pointer;" @click="closeWin"></i>
</div>
<div class="win-content">
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
winTitle: String,
},
data(){
return {
isMouse: false,//是否移动
startX: 0,//移动起始x
startY: 0,//移动起始y
endX: 0,//移动终点x
endY: 0,//移动终点y
position: {
x: 200,
y: 100
}
}
},
mounted(){
this.initWinPosition();
},
methods: {
//初始化弹框位置
initWinPosition(){
let winWidth = document.body.clientWidth;
this.position.x = winWidth/2 - 1100/2;
},
//开始移动
mouseStart(e){
if($(e.target).attr('class') === 'win-title'){
this.isMouse = true;
this.startX = e.clientX;
this.startY = e.clientY;
}else {
this.isMouse = false;
}
},
//移动中
mouseMove(e){
if(this.isMouse === true){
this.endX = e.clientX;
this.endY = e.clientY;
let mouseX = this.endX - this.startX;
let mouseY = this.endY - this.startY;
let winLeft = this.$refs.winFixed.clientLeft;
let winTop = this.$refs.winFixed.clientTop;
let winWidth = this.$refs.winFixed.clientWidth;
let winHeight = this.$refs.winFixed.clientHeight;
let contentWidth = this.$refs.winContainer.offsetWidth;
let contentHeight = this.$refs.winContainer.offsetHeight;
let contentLeft = this.$refs.winContainer.offsetLeft;
let contentTop = this.$refs.winContainer.offsetTop;
if(mouseX <= winLeft - contentLeft){
mouseX = winLeft - contentLeft;
}
if(mouseX >= winWidth - contentWidth - contentLeft){
mouseX = winWidth - contentWidth - contentLeft;
}
if(mouseY <= winTop - contentTop){
mouseY = winTop - contentTop;
}
if(mouseY >= winHeight - contentHeight - contentTop){
mouseY = winHeight - contentHeight - contentTop;
}
let left = contentLeft + mouseX;
let top = contentTop + mouseY;
this.position.x = left;
this.position.y = top;
this.startX = this.endX;
this.startY = this.endY;
}
},
//停止移动
mouseStop(){
this.isMouse = false;
},
//关闭
closeWin(){
this.$emit('closeWin');
},
}
}
</script>
<style scoped>
.com-win{
position: fixed;
top: 0; left: 0;
background: rgba(0,0,0,0.3);
width: 100%; height: 100vh;
z-index: 2000;
display: none;
}
.win-container {
width: 1100px;
background: #fff;
border-radius: 5px;
position: absolute;
top: 100px; left: 200px;
}
.win-title {
color: #fff;
cursor: move;
font-size: 14px;
line-height: 14px;
padding: 12px 15px;
background: #409eff;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.win-content {
padding: 20px 0;
min-height: 120px;
max-height: 420px;
overflow: auto;
}
</style>
//components/searchArea.vue
<template>
<!--表单组件-->
<div class="searchArea">
<el-form ref="searchData" :model="searchData?searchData:{}" :rules="searchRules?searchRules:{}" size="small" label-width="160px" class="search_list">
<slot></slot>
<div class="opt-btn">
<el-button type="primary" size="small" v-for="(item, index) in formBtnData" :key="index" :disabled="item.isDisabled" :icon="item.icon" @click="item.clickBtnFun">{{item.text}}</el-button>
</div>
</el-form>
</div>
</template>
<script>
export default {
props: {
searchRules: Object,
searchData: Object,
formBtnData: Array,
},
}
</script>
4.2.8 实现登录页面
//views/login/login.vue
<template>
<!--登录页面-->
<div class="login">
<div class="container">
<div class="title">许愿墙后台管理系统</div>
<el-form ref="loginData" :model="loginData" :rules="loginRules" class="content">
<el-form-item prop="username">
<el-input placeholder="请输入用户名" v-model="loginData.username">
<template slot="prepend"><i class="el-icon-user icon"></i></template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input show-password type="password" placeholder="请输入密码" v-model="loginData.password">
<template slot="prepend"><i class="el-icon-lock icon"></i></template>
</el-input>
</el-form-item>
<div class="login-btn">
<el-button type="primary" @click="login">登录</el-button>
</div>
</el-form>
</div>
</div>
</template>
<script>
import store from '@/store'
import {sendMSRequest} from '@/utils/outbound'
import {showAlertMessage, setLoading} from '@/utils/commonFunc'
export default {
data(){
return {
loginData: {
username: '',
password: ''
},
loginRules: {
username: [{required: true, message: '请输入用户名!', trigger: 'change'}],
password: [{required: true, message: '请输入密码!', trigger: 'change'}],
}
}
},
mounted(){
this.initData();//初始化数据
},
methods: {
//初始化数据
initData(){
if(store.getters.username){
this.loginData.username = store.getters.username;
}
},
//登录
login(){
this.$refs['loginData'].validate(valid => {
if(valid){
let params = {
username: this.loginData.username,
password: this.loginData.password
};
let showLoading = setLoading('登录中...');
sendMSRequest('LOGIN', 'post', params, res => {
showLoading.close();
if(res.code === '00'){
switch (res.data.role){
case 1:
res.data['role_desc'] = '超级管理员';
break;
case 2:
res.data['role_desc'] = '普通管理员';
break;
}
store.dispatch('Set_UserInfo', res.data);
store.dispatch('Set_Role', res.data.role);
store.dispatch('Set_Name', res.data.name);
store.dispatch('Set_Token', res.data.token);
store.dispatch('Set_Username', res.data.username);
this.$emit('modifyShowLogin', false);
if(this.$route.path !== '/home'){
this.$router.push('/home');
}
}else {
showLoading.close();
showAlertMessage(res.msg, '提示信息', 'warning');
}
})
}
})
},
}
}
</script>
<style scoped>
.login {
width: 100%;
height: 100vh;
background: #f4c6c6;
}
.container {
background: #1E66BF;
text-align: center;
position: absolute;
top: 50%; left: 50%;
transform: translateX(-50%) translateY(-50%);
}
.title {
color: #fff;
padding: 20px 0;
border-bottom: 1px solid #fff;
}
.content {
padding: 30px 40px;
}
.el-input, .el-button {
width: 300px;
}
.icon {
color: #1E66BF;
font-size: 18px;
}
</style>
4.2.9 实现首页
//views/home/home.vue
<template>
<!--首页-->
<div class="home">
<el-container>
<el-header>
<div class="header-lf float-lf">
<i class="el-icon-menu title-icon"></i>
<span class="title-text">许愿墙后台管理系统</span>
</div>
<div class="header-rt float-rt">
<div class="user-info">
<span class="user-name">{{username}}</span>
<i class="el-icon-caret-bottom"></i>
</div>
<div class="down-menu">
<div class="menu-item">{{name}}</div>
<div class="menu-item">{{role_desc}}</div>
<div class="menu-item log-out" @click="logOut">退出</div>
</div>
</div>
</el-header>
<el-container>
<el-aside>
<el-menu :default-active="activeId">
<el-menu-item v-for="item in menuData" :key="item.index" :index="item.index">
<router-link tag="div" :to="item.menuUrl">
<div @click="clickMenu(item.index)">
<i :class="item.icon"></i>
<span>{{item.text}}</span>
</div>
</router-link>
</el-menu-item>
</el-menu>
</el-aside>
<el-main>
<div class="main-tabs">
<div class="tab-item" :class="item.isTarget ? 'tab-target' : ''" v-for="item in tabsData" :key="item.index" @click="switchTab(item.index)">
<router-link tag="div" :to="item.menuUrl">
<span>{{item.text}}</span>
<i class="el-icon-close close-icon" v-if="item.index !== '1'" @click="handleTabsEdit(item.index)"></i>
</router-link>
</div>
</div>
<div class="main-content">
<router-view></router-view>
</div>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
import store from '@/store'
export default {
data(){
return {
role: '',
name: '',
activeId: '1',
username: '',
role_desc: '',
tabVal: '',
tabsData: [
{index: '1', text: '系统首页', icon: 'el-icon-s-home', isTarget: true, menuUrl: '/home'},
],
menuData: [
{index: '1', text: '系统首页', icon: 'el-icon-s-home', menuUrl: '/home'},
{index: '2', text: '许愿管理', icon: 'el-icon-s-opportunity', menuUrl: '/wish'},
{index: '3', text: '管理员管理', icon: 'el-icon-s-custom', menuUrl: '/admin'},
]
}
},
mounted(){
this.initData();// 初始化数据
},
methods: {
// 初始化数据
initData(){
this.role = store.getters.role;
this.name = store.getters.name;
this.username = store.getters.username;
switch(store.getters.role){
case 1:
this.role_desc = '超级管理员';
break;
case 2:
this.role_desc = '普通管理员';
break;
}
},
//退出登录
logOut(){
this.$emit('modifyShowLogin', true);
},
//点击左侧菜单
clickMenu(index){
let flag = true;
this.tabsData.forEach(val => {
val.isTarget = false;
if(val.index === index){
flag = false;
}
});
if(flag){
let inx = Number(index) - 1;
this.tabsData.push(this.menuData[inx]);
}
this.tabsData.forEach(val => {
if(val.index === index){
val.isTarget = true;
}
});
this.tabsData = this.tabsData.slice(0);
},
//点击tab
switchTab(index){
this.activeId = index;
this.tabsData.forEach(val => {
val.isTarget = false;
});
this.tabsData.forEach(val => {
if(val.index === index){
val.isTarget = true;
}
});
this.tabsData = this.tabsData.slice(0);
},
//关闭tab
handleTabsEdit(index){
this.tabsData.forEach((val, inx) => {
if(val.index === index){
this.tabsData.splice(inx, 1);
}
});
let length = this.tabsData.length;
let menuUrl = this.tabsData[length - 1].menuUrl;
setTimeout(() => {
if(this.$route.path !== menuUrl){
this.$router.push(menuUrl);
}
this.tabsData[length - 1].isTarget = true;
this.tabsData = this.tabsData.slice(0);
}, 10);
},
}
}
</script>
<style scoped>
.home {
width: 100%;
height: 100vh;
}
.el-header{
color: #fff;
height: 60px;
line-height: 60px;
background: #1E66BF;
}
.el-aside {
height: calc(100vh - 60px);
background: #eff1f5;
}
.el-main {
height: calc(100vh - 60px);
padding: 0;
overflow: hidden;
}
.title-icon {
cursor: pointer;
}
.title-text {
margin-left: 5px;
}
.header-rt {
position: relative;
}
.user-info {
cursor: pointer;
}
.user-name {
margin-right: 5px;
}
.down-menu {
width: 160%;
text-align: center;
line-height: 16px;
background: #3f70e8;
padding: 5px 0;
border-radius: 5px;
position: absolute;
top: 45px; left: -30px;
display: none;
}
.header-rt:hover .down-menu {
display: block;
}
.menu-item {
padding: 10px;
border-radius: 5px;
}
.menu-item:hover {
background: #3993e8;
}
.log-out {
cursor: pointer;
}
.main-tabs {
padding: 8px 10px;
background: #f5f5f5;
}
.tab-item {
color: #333;
cursor: pointer;
font-size: 12px;
margin-right: 5px;
padding: 8px 10px;
border: 1px solid #ccc;
border-radius: 5px;
display: inline-block;
}
.tab-target {
color: #fff;
background: #409EFF;
}
.close-icon {
color: #fff;
margin-left: 5px;
border-radius: 50%;
background: #f4c6c6;
padding: 2px;
}
.main-content {
height: calc(100vh - 110px);
overflow-y: auto;
background: #F5E5F5;
}
</style>
//views/home/homeContent.vue
<template>
<!--首页内容-->
<div class="home-content main-page">
<div class="user-info">
<div class="name">{{userInfo.name}}</div>
<div class="role">{{userInfo.role_desc}}</div>
</div>
<div class="login-info">
<span>上次登录时间:</span>
<span class="time">{{userInfo.lastLoginAt}}</span>
</div>
</div>
</template>
<script>
import store from '@/store'
export default {
data(){
return {
userInfo: store.getters.userInfo
}
}
}
</script>
<style scoped>
.home-content {
min-height: 200px;
}
.user-info {
padding-bottom: 20px;
margin-bottom: 20px;
border-bottom: 1px solid #ccc;
}
.name {
font-size: 20px;
}
.role, .login-info {
color: #333;
font-size: 14px;
margin-top: 5px;
}
.time {
margin-left: 50px;
}
</style>
4.2.10 实现许愿管理页面
//views/wishManage/wishManage.vue
<template>
<!--许愿管理-->
<div class="wish-manage main-page">
<div class="search-area">
<el-row>
<el-col :span="8">
<el-input clearable type="text" size="small" v-model="name" placeholder="请输入搜索的姓名"></el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" size="small" @click="queryTableData(true)">搜索</el-button>
<el-button type="primary" size="small" @click="openMainWishWin('添加许愿信息')">添加</el-button>
</el-col>
</el-row>
</div>
<div class="clearFloat">
<com-table ref="comTable" :funcData="[]" :tableTitleData="tableTitleData" :tableData="tableData" @queryTableData="queryTableData">
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="primary" size="mini" icon="el-icon-edit" @click="openMainWishWin('修改许愿信息', scope.row)">修改</el-button>
<el-button type="primary" size="mini" icon="el-icon-delete" @click="deleteWish(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</com-table>
</div>
<!--维护许愿窗口-->
<main-wish-win ref="mainWishWin" @queryTableData="queryTableData"></main-wish-win>
</div>
</template>
<script>
import {sendMSRequest} from '@/utils/outbound'
import {setLoading, showAlertMessage} from '@/utils/commonFunc'
import ComTable from '@/components/comTable'
import MainWishWin from '@/views/wishManage/mainWishWin'
export default {
components: {
ComTable,
MainWishWin
},
data(){
return {
name: '',
tableData: [],
tableTitleData: [
{text: '姓名', prop: 'name'},
{text: '内容', prop: 'content'},
{text: '创建时间', prop: 'createdAt'},
],
}
},
mounted(){
this.queryTableData(true);
},
methods: {
//查询许愿列表数据
queryTableData(type){
if(type){
this.$refs.comTable.initData();
}
this.$refs.comTable.isLoading = true;
let params = {
name: this.name,
page: this.$refs.comTable.page,
rows: this.$refs.comTable.rows
};
sendMSRequest('WISH', 'get', params, res => {
if(res.code === '00'){
this.tableData = res.data;
this.$refs.comTable.totalDataNum = res.count;
}else {
showAlertMessage(res.msg, '提示信息', 'warning');
}
this.$refs.comTable.resetTableData();
})
},
//打开维护许愿窗口
openMainWishWin(title, row){
$('.main_wish_win').show();
this.$refs.mainWishWin.title = title;
if(row && row.id){
this.$refs.mainWishWin.mainWish.name = row.name;
this.$refs.mainWishWin.mainWish.wishId = row.id;
this.$refs.mainWishWin.mainWish.content = row.content;
}else {
this.$refs.mainWishWin.mainWish.wishId = '';
}
},
//删除许愿
deleteWish(wishId){
let params = {
id: wishId
};
let showLoading = setLoading();
sendMSRequest('WISH', 'delete', params, res => {
showLoading.close();
if(res.code === '00'){
showAlertMessage('成功删除许愿信息!', '成功信息', 'success', () => {
this.queryTableData(false);
});
}else {
showAlertMessage(res.msg, '提示信息', 'warning');
}
})
}
}
}
</script>
//views/wishManage/mainWishWin.vue
<template>
<!--维护许愿窗口-->
<com-window class="main_wish_win" ref="comWindow" :winTitle="title" @closeWin="closeWin">
<search-area ref="searchArea" :searchData="mainWish" :searchRules="mainRules" :formBtnData="formBtnData">
<el-row>
<el-col :span="22">
<el-form-item label="许愿人:" prop="name">
<el-input v-model="mainWish.name"></el-input>
</el-form-item>
</el-col>
<el-col :span="22">
<el-form-item label="许愿内容:" prop="content">
<el-input v-model="mainWish.content"></el-input>
</el-form-item>
</el-col>
</el-row>
</search-area>
</com-window>
</template>
<script>
import {sendMSRequest} from '@/utils/outbound'
import {setLoading, showAlertMessage} from '@/utils/commonFunc'
import ComWindow from '@/components/comWindow'
import SearchArea from '@/components/searchArea'
export default {
components: {
ComWindow,
SearchArea
},
data(){
return {
title: '',
mainWish: {
name: '',
content: '',
wishId: '',
},
mainRules: {
name: [{
required: true, message: '请填写许愿人!', trigger: 'blur'
}],
content: [{
required: true, message: '请填写许愿内容!', trigger: 'blur'
}],
},
formBtnData: [
{text: '确定', icon: 'el-icon-check', clickBtnFun: () => {this.submitForm()}},
{text: '关闭', icon: 'el-icon-close', clickBtnFun: () => {this.closeWin()}},
]
}
},
methods: {
//提交
submitForm(){
this.$refs.searchArea.$refs['searchData'].validate(valid => {
if(valid){
let params = {
id: this.mainWish.wishId,
name: this.mainWish.name,
content: this.mainWish.content
};
let showLoading = setLoading();
let method = this.mainWish.wishId ? 'put' : 'post';
sendMSRequest('WISH', method, params, res => {
showLoading.close();
if(res.code === '00'){
let message = this.mainWish.wishId ? '修改' : '添加';
showAlertMessage('成功' + message + '添加许愿信息!', '成功信息', 'success', () => {
this.closeWin();
if(this.mainWish.wishId ){
this.$emit('queryTableData', false);
}else {
this.$emit('queryTableData', true);
}
});
}else {
showAlertMessage(res.msg, '提示信息', 'warning');
}
})
}
})
},
// 关闭
closeWin(){
$('.main_wish_win').hide();
this.$refs.searchArea.$refs['searchData'].resetFields();
}
}
}
4.2.11 实现管理员管理页面
//views/adminManage/adminManage.vue
<template>
<!--管理员管理-->
<div class="admin-manage main-page">
<div class="search-area">
<el-row>
<el-col :span="8">
<el-input clearable type="text" size="small" v-model="username" placeholder="请输入搜索的用户名"></el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" size="small" @click="queryTableData(true)">搜索</el-button>
<el-button type="primary" size="small" @click="openMainAdminWin('添加管理员信息')">添加</el-button>
</el-col>
</el-row>
</div>
<div class="clearFloat">
<com-table ref="comTable" :funcData="[]" :tableTitleData="tableTitleData" :tableData="tableData" @queryTableData="queryTableData">
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="primary" size="mini" icon="el-icon-edit" @click="openMainAdminWin('修改管理员信息', scope.row)">修改</el-button>
<el-button type="primary" size="mini" icon="el-icon-delete" @click="deleteAdmin(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</com-table>
</div>
<!--维护许愿窗口-->
<main-admin-win ref="mainAdminWin" @queryTableData="queryTableData"></main-admin-win>
</div>
</template>
<script>
import {sendMSRequest} from '@/utils/outbound'
import {setLoading, showAlertMessage} from '@/utils/commonFunc'
import ComTable from '@/components/comTable'
import MainAdminWin from '@/views/adminManage/mainAdminWin'
export default {
components: {
ComTable,
MainAdminWin
},
data(){
return {
username: '',
tableData: [],
tableTitleData: [
{text: '用户名', prop: 'username'},
{text: '姓名', prop: 'name'},
{text: '角色', prop: 'role_desc'},
{text: '创建时间', prop: 'createdAt'},
],
}
},
mounted(){
this.queryTableData(true);
},
methods: {
//查询管理员列表数据
queryTableData(type){
if(type){
this.$refs.comTable.initData();
}
this.$refs.comTable.isLoading = true;
let params = {
username: this.username,
page: this.$refs.comTable.page,
rows: this.$refs.comTable.rows
};
sendMSRequest('ADMIN', 'get', params, res => {
if(res.code === '00'){
res.data.forEach(val => {
switch (val.role){
case 1:
val['role_desc'] = '超级管理员';
break;
case 2:
val['role_desc'] = '普通管理员';
break;
}
});
this.tableData = res.data;
this.$refs.comTable.totalDataNum = res.count;
}else {
showAlertMessage(res.msg, '提示信息', 'warning');
}
this.$refs.comTable.resetTableData();
})
},
//打开维护许愿窗口
openMainAdminWin(title, row){
$('.main_admin_win').show();
this.$refs.mainAdminWin.title = title;
if(row && row.id){
this.$refs.mainAdminWin.mainAdmin.name = row.name;
this.$refs.mainAdminWin.mainAdmin.userId = row.id;
this.$refs.mainAdminWin.mainAdmin.role = row.role + '';
this.$refs.mainAdminWin.mainAdmin.username = row.username;
this.$refs.mainAdminWin.mainAdmin.password = row.password;
}else {
this.$refs.mainAdminWin.mainAdmin.userId = '';
}
},
//删除许愿
deleteAdmin(userId){
let params = {
id: userId
};
let showLoading = setLoading();
sendMSRequest('ADMIN', 'delete', params, res => {
showLoading.close();
if(res.code === '00'){
showAlertMessage('成功删除管理员信息!', '成功信息', 'success', () => {
this.queryTableData(false);
});
}else {
showAlertMessage(res.msg, '提示信息', 'warning');
}
})
}
}
}
</script>
//views/adminManage/mainAdminWin.vue
<template>
<!--维护管理员窗口-->
<com-window class="main_admin_win" ref="comWindow" :winTitle="title" @closeWin="closeWin">
<search-area ref="searchArea" :searchData="mainAdmin" :searchRules="mainRules" :formBtnData="formBtnData">
<el-row>
<el-col :span="11">
<el-form-item label="用户名:" prop="username">
<el-input v-model="mainAdmin.username"></el-input>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="姓名:" prop="name">
<el-input v-model="mainAdmin.name"></el-input>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="密码:" prop="password">
<el-input v-model="mainAdmin.password"></el-input>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="角色:" prop="role">
<el-select clearable v-model="mainAdmin.role">
<el-option v-for="(value, key) in rolesData" :key="key" :label="value" :value="key"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</search-area>
</com-window>
</template>
<script>
import {sendMSRequest} from '@/utils/outbound'
import {commonData} from '@/utils/commonData'
import {setLoading, showAlertMessage} from '@/utils/commonFunc'
import ComWindow from '@/components/comWindow'
import SearchArea from '@/components/searchArea'
export default {
components: {
ComWindow,
SearchArea
},
data(){
return {
title: '',
mainAdmin: {
userId: '',
username: '',
name: '',
password: '',
role: '',
},
rolesData: {},
mainRules: {
username: [{
required: true, message: '请填写用户名!', trigger: 'blur'
}],
name: [{
required: true, message: '请填写姓名!', trigger: 'blur'
}],
password: [{
required: true, message: '请填写密码!', trigger: 'blur'
}],
role: [{
required: true, message: '请选择角色!', trigger: 'blur'
}],
},
formBtnData: [
{text: '确定', icon: 'el-icon-check', clickBtnFun: () => {this.submitForm()}},
{text: '关闭', icon: 'el-icon-close', clickBtnFun: () => {this.closeWin()}},
]
}
},
mounted(){
this.initData();//初始化数据
},
methods: {
//初始化数据
initData(){
this.rolesData = commonData.rolesData;
},
//提交
submitForm(){
this.$refs.searchArea.$refs['searchData'].validate(valid => {
if(valid){
let params = {
id: this.mainAdmin.userId,
username: this.mainAdmin.username,
name: this.mainAdmin.name,
password: this.mainAdmin.password,
role: Number(this.mainAdmin.role)
};
let showLoading = setLoading();
let method = this.mainAdmin.userId ? 'put' : 'post';
sendMSRequest('ADMIN', method, params, res => {
showLoading.close();
if(res.code === '00'){
let message = this.mainAdmin.userId ? '修改' : '添加';
showAlertMessage('成功' + message + '管理员信息!', '成功信息', 'success', () => {
this.closeWin();
if(this.mainAdmin.userId){
this.$emit('queryTableData', false);
}else {
this.$emit('queryTableData', true);
}
});
}else {
showAlertMessage(res.msg, '提示信息', 'warning');
}
})
}
})
},
// 关闭
closeWin(){
$('.main_admin_win').hide();
this.$refs.searchArea.$refs['searchData'].resetFields();
}
}
}
</script>
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有