提交 1d423b30 编写于 作者: qq_18203925's avatar qq_18203925

前端整合

上级 5d8c61ba
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# dormitory-for-admin
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}
此差异已折叠。
{
"name": "dormitory-for-admin",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"core-js": "^3.8.3",
"echarts": "^4.9.0",
"element-ui": "^2.4.5",
"node-sass": "^7.0.1",
"sass-loader": "^12.6.0",
"vue": "^2.6.14",
"vue-baidu-map": "^0.21.22",
"vue-router": "^3.5.1",
"vuex": "^3.6.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"axios": "^0.18.0",
"vue-cli-plugin-axios": "^0.0.4",
"vue-cli-plugin-element": "^1.0.1",
"vue-template-compiler": "^2.6.14"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
<!DOCTYPE html>
<html lang="">
<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><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
<style>
*{
margin: 0;
padding: 0;
}
html,body{
width: 100%;
height: 100%;
}
</style>
<template>
<el-container>
<!-- header部分 -->
<el-header>
<NavTop></NavTop>
</el-header>
<el-container>
<!-- aside部分 -->
<Nav style="overflow-x: hidden;overflow-y: hidden"></Nav>
<el-main>
<!-- main部分 -->
<router-view />
</el-main>
</el-container>
</el-container>
</template>
<script>
import NavTop from "@/components/nav-top.vue";
import Nav from "@/components/Nav.vue";
export default {
components: {
NavTop,
Nav
},
data() {
return {};
},
methods: {}
};
</script>
<style>
.el-main {
background-color: #f5f7f9;
}
.el-header,
.el-footer {
background-color: white;
box-sizing: border-box;
border-bottom: 1px solid #f5f1f1;
}
.el-container {
height: 100%;
}
</style>
<template>
<el-aside width="200px">
<el-row class="tac">
<el-col>
<el-menu
router
default-active="/layout/home"
class="el-menu-vertical-demo"
>
<el-menu-item index="/layout/home">
<i class="el-icon-s-home"></i>
<span slot="title">主页</span>
</el-menu-item>
<el-menu-item index="/layout/dormMgt">
<i class="el-icon-office-building"></i>
<span slot="title">宿舍管理</span>
</el-menu-item>
<el-submenu index="1">
<template slot="title">
<i class="el-icon-document"></i>
<span>人员信息</span>
</template>
<el-menu-item-group>
<el-menu-item index="/layout/stuInfo">学生信息</el-menu-item>
<el-menu-item index="/layout/houseKeepingInfo">楼管信息</el-menu-item>
<el-menu-item index="/layout/maintainerInfo">维修人员信息</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="2">
<template slot="title">
<i class="el-icon-location"></i>
<span>签到管理</span>
</template>
<el-menu-item-group>
<el-menu-item index="/layout/checkins">签到情况</el-menu-item>
<el-menu-item index="/layout/publishTask">发布任务</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="3">
<template slot="title">
<i class="el-icon-user-solid"></i>
<span>服务管理</span>
</template>
<el-menu-item-group>
<el-menu-item index="/layout/repairMgt">报修管理</el-menu-item>
<el-menu-item index="/layout/complainMgt">投诉管理</el-menu-item>
<el-menu-item index="/layout/communalFaciRepInfo">公共设施检修情况</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="4">
<template slot="title">
<i class="el-icon-notebook-2"></i>
<span>收费管理</span>
</template>
<el-menu-item-group>
<el-menu-item index="/layout/chargeItems">收费项目</el-menu-item>
<el-menu-item index="/layout/chargeDetailsMgt">收费管理明细</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-menu-item index="/layout/adminList">
<i class="el-icon-s-custom"></i>
<span>管理员列表</span>
</el-menu-item>
<!-- <el-submenu index="5">-->
<!-- <template slot="title">-->
<!-- </template>-->
<!-- <el-menu-item-group>-->
<!-- <el-menu-item index="/layout/userGroupMgt">用户组管理</el-menu-item>-->
<!-- </el-menu-item-group>-->
<!-- </el-submenu>-->
<el-menu-item index="/layout/personalInfoSetting">
<i class="el-icon-setting"></i>
<span slot="title">个人信息设置</span>
</el-menu-item>
</el-menu>
</el-col>
</el-row>
</el-aside>
</template>
<script>
var $this = {};
export default {
data() {
return {};
},
beforeCreate() {
$this = this;
},
methods: {
}
};
</script>
<style scoped>
.el-row{
height: 100%;
}
.el-menu{
border-right:none;
}
.el-aside{
border-right: 1px solid #f5f1f1;
}
</style>
<template>
<el-container>
<el-aside width="auto" class="header-logo tap" >
<img class="logo" src="@/assets/imgs/logo.png" alt="Logo" />
</el-aside>
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper">
<img src="@/assets/imgs/head.jpg" class="user-avatar" height="50px" width="100px">
<i class="el-icon-caret-bottom" />
</div>
<el-dropdown-menu slot="dropdown">
<router-link to="/layout/personalInfoSetting">
<el-dropdown-item>Settings</el-dropdown-item>
</router-link>
<el-dropdown-item divided @click.native="logout">
<span style="display:block;">Log Out</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-container>
</template>
<script>
export default {
data() {
return {
activeIndex: "1",
};
},
methods: {
handleSelect(key, keyPath) {
console.log(key, keyPath);
},
async logout() {
localStorage.removeItem('tempUser');
await this.$router.push('/');
}
}
};
</script>
<style lang="scss" scoped>
.avatar-container {
margin-right: 30px;
.avatar-wrapper {
margin-top: 5px;
position: relative;
.user-avatar {
cursor: pointer;
width: 45px;
height: 45px;
border: 1px solid lightblue;
border-radius: 50%;
}
.el-icon-caret-bottom {
cursor: pointer;
position: absolute;
right: -20px;
top: 25px;
font-size: 12px;
}
}
}
.el-aside {
display: flex;
justify-content: center;
align-items: center;
}
section{
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
}
.logo {
width: 200px;
}
.headerLogo,.logo{
cursor: pointer;
}
</style>
import Vue from 'vue'
import './plugins/axios'
import App from './App.vue'
import router from './router'
import store from './store'
import './plugins/element.js'
import axios from 'axios'
import echarts from 'echarts'
import BaiduMap from 'vue-baidu-map'
Vue.prototype.$echarts = echarts
Vue.use(echarts)
Vue.use( BaiduMap, { ak : 'M4aQ9Na4sRKXqZr5qA8SE9lhS1g6u50A' } )
axios.defaults.withCredentials = true;
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
"use strict";
import Vue from 'vue';
import axios from "axios";
// Full config: https://github.com/axios/axios#request-config
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
let config = {
// baseURL: process.env.baseURL || process.env.apiUrl || ""
// timeout: 60 * 1000, // Timeout
// withCredentials: true, // Check cross-site Access-Control
};
const _axios = axios.create(config);
_axios.interceptors.request.use(
function(config) {
// Do something before request is sent
return config;
},
function(error) {
// Do something with request error
return Promise.reject(error);
}
);
// Add a response interceptor
_axios.interceptors.response.use(
function(response) {
// Do something with response data
return response;
},
function(error) {
// Do something with response error
return Promise.reject(error);
}
);
Plugin.install = function(Vue, options) {
Vue.axios = _axios;
window.axios = _axios;
Object.defineProperties(Vue.prototype, {
axios: {
get() {
return _axios;
}
},
$axios: {
get() {
return _axios;
}
},
});
};
Vue.use(Plugin)
export default Plugin;
import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(Element)
// import Vue from 'vue'
// import VueRouter from 'vue-router'
//
//
// Vue.use(VueRouter)
//
// const routes = [
// {
// path: '/',
// name: 'login',
// component: () => import('../views/LoginRegister.vue')
// },
// {
// path: '/home',
// name: 'home',
// component: () => import('../views/HomeView.vue')
// },
// {
// path: '/dormMgt',
// name: 'dormMgt',
// component: () => import('../views/DormitoryManagement.vue')
// },{
// path: '/stuInfo',
// name: 'stuInfo',
// component: () => import('../views/personnelInformation/StudentInformation')
// },
// {
// path: '/houseKeepingInfo',
// name: 'houseKeepInfo',
// component: () => import('../views/personnelInformation/HousekeepingInformation')
// },
// {
// path: '/maintainerInfo',
// name: 'maintainerInfo',
// component: () => import('../views/personnelInformation/MaintainerInformation')
// },{
// path: '/checkins',
// name: 'checkins',
// component: () => import('../views/registrationManagement/CheckIns')
// },
// {
// path: '/publishTask',
// name: 'publishTask',
// component: () => import('../views/registrationManagement/PublishTask')
// },
// {
// path: '/repairMgt',
// name: 'repairMgt',
// component: () => import('../views/ServiceManagement/RepairManagement')
// },{
// path: '/complainMgt',
// name: 'complainMgt',
// component: () => import('../views/ServiceManagement/ComplaintManagement')
// },
// {
// path: '/communalFaciRepInfo',
// name: 'communalFaciRepInfo',
// component: () => import('../views/ServiceManagement/CommunalFacilitiesRepairInfo')
// },{
// path: '/chargeItems',
// name: 'chargeItems',
// component: () => import('../views/chargeManagement/ChargeItems')
// },
// {
// path: '/chargeDetailsMgt',
// name: 'chargeDetailsMgt',
// component: () => import('../views/chargeManagement/ChargeDetailsManagement')
// },{
// path: '/adminList',
// name: 'adminList',
// component: () => import('../views/AdministratorManagement/AdministratorList')
// },
// {
// path: '/userGroupMgt',
// name: 'userGroupMgt',
// component: () => import('../views/AdministratorManagement/UserGroupManagement')
// },{
// path: '/personalInfoSetting',
// name: 'personalInfoSetting',
// component: () => import('../views/PersonalInformationSettings')
// }
// ]
//
// const router = new VueRouter({
// mode: 'history',
// base: process.env.BASE_URL,
// routes
// })
//
// export default router
import Vue from 'vue'
import Router from 'vue-router'
import Layout from '@/components/Layout'
Vue.use(Router)
const router= new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'login',
component:()=>import('../views/LoginRegister')
},
{
path: '/layout',
name: 'Layout',
component: Layout,
children: [{
path: 'home',
name: 'home',
component: () => import('../views/HomeView.vue')
},
{
path: 'dormMgt',
name: 'dormMgt',
component: () => import('../views/DormitoryManagement.vue')
},{
path: 'stuInfo',
name: 'stuInfo',
component: () => import('../views/personnelInformation/StudentInformation')
},
{
path: 'houseKeepingInfo',
name: 'houseKeepInfo',
component: () => import('../views/personnelInformation/HousekeepingInformation')
},
{
path: 'maintainerInfo',
name: 'maintainerInfo',
component: () => import('../views/personnelInformation/MaintainerInformation')
},{
path: 'checkins',
name: 'checkins',
component: () => import('../views/registrationManagement/CheckIns')
},
{
path: 'publishTask',
name: 'publishTask',
component: () => import('../views/registrationManagement/PublishTask')
},
{
path: 'repairMgt',
name: 'repairMgt',
component: () => import('../views/ServiceManagement/RepairManagement')
},{
path: 'complainMgt',
name: 'complainMgt',
component: () => import('../views/ServiceManagement/ComplaintManagement')
},
{
path: 'communalFaciRepInfo',
name: 'communalFaciRepInfo',
component: () => import('../views/ServiceManagement/CommunalFacilitiesRepairInfo')
},{
path: 'chargeItems',
name: 'chargeItems',
component: () => import('../views/chargeManagement/ChargeItems')
},
{
path: 'chargeDetailsMgt',
name: 'chargeDetailsMgt',
component: () => import('../views/chargeManagement/ChargeDetailsManagement')
},{
path: 'adminList',
name: 'adminList',
component: () => import('../views/AdministratorManagement/AdministratorList')
},
{
path: 'userGroupMgt',
name: 'userGroupMgt',
component: () => import('../views/AdministratorManagement/UserGroupManagement')
},{
path: 'personalInfoSetting',
name: 'personalInfoSetting',
component: () => import('../views/PersonalInformationSettings')
}
]
},
]
})
router.beforeEach((to,from,next)=>{
let tempUser=JSON.parse(localStorage.getItem('tempUser'));
if (!tempUser && to.path !=='/'){
next({path:'/'});
}
next();
})
export default router;
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
}
})
<template>
<div>
<el-dialog title="添加管理员" :visible.sync="dialogFormVisible" >
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="用户名" :label-width="formLabelWidth" prop="username">
<el-input v-model="form.username" autocomplete="off" ></el-input>
</el-form-item>
<el-form-item label="密码" :label-width='formLabelWidth' prop="password">
<el-input :type="passw" v-model="form.password" autocomplete="off">
<i slot="suffix" :class="icon" @click="showPass"></i>
</el-input>
</el-form-item>
<el-form-item label="确认密码" :label-width='formLabelWidth' prop="repassword">
<el-input :type="passw" v-model="form.repassword" autocomplete="off">
<i slot="suffix" :class="icon" @click="showPass"></i>
</el-input>
</el-form-item>
<el-form-item label="电话号码" :label-width="formLabelWidth" prop="tel">
<el-input v-model="form.tel" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="姓名" :label-width="formLabelWidth" prop="name">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="resetForm('form')">重置</el-button>
<el-button @click="closeForm">取 消</el-button>
<el-button type="primary" @click="addUser">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "AddAdministrator",
props:['dfn'],
data(){
var validatePass2 = (rule, value, callback) => {
if (value === ''||value.length===0) {
callback(new Error('请再次输入密码'))
} else if (value !== this.form.password) {
callback(new Error('两次输入密码不一致!'))
} else {
callback()
}
}
return {
dialogFormVisible: false,
form: {
username:'',
password:'',
tel:'',
name:'',
repassword:''
},
formLabelWidth: '120px',
passw:"password",
icon:"el-input__icon el-icon-view",
rules:{
username:[{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{4,20}$/, message: '密码必须是由4-20位字母+数字组合' }
],
repassword: [
{ required: true, validator: validatePass2, trigger: 'blur' }
],
tel: [{ required: true, message: '请输入手机号' ,trigger: 'blur' },
{pattern: /^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$/, message: '手机号格式错误'}
],
name:[{ required: true, message: '请输入姓名', trigger: 'blur' },
{ min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur' }
],
}
}
},
methods:{
closeForm() {
this.dialogFormVisible= false;
this.$refs['form'].clearValidate();
this.resetForm();
},
resetForm() {
this.form={
username:'',
password:'',
tel:'',
name:'',
repassword:''
};
},
showPass(){
if (this.passw === 'text'){
this.passw = 'password';
this.icon="el-input__icon el-icon-view";
}
else{
this.passw = 'text';
this.icon="el-input__icon el-icon-loading";
}
},
addUser(){
this.$refs.form.validate((validate)=>{
if (validate){
this.dialogFormVisible= false;
axios.post("http://124.223.194.15:19260/admin/add",this.form).then(response=>{
// console.log(response);
if (response.data.status === 1000){
this.$message.success("添加成功");
this.$emit('refreshTable');
}
}).catch(function (error) {
console.log(error);
});
}
})
}
},
watch:{
dfn(){
this.dialogFormVisible= true;
this.resetForm();
//等待form加载出来再执行
this.$nextTick(()=>{
this.$refs['form'].clearValidate();
})
}
}
}
</script>
<style scoped>
</style>
<template>
<div style="width: 80%;margin-left: 10%">
<h1>管理员列表</h1>
<el-button type="primary" icon="el-icon-plus el-icon-user-solid" @click="add">添加</el-button>
<el-table
:data="tableData"
border
style="width: 100%">
<el-table-column
prop="id"
label="ID"
width="180"
align="center">
</el-table-column>
<el-table-column
prop="username"
label="用户名"
width="180"
align="center">
</el-table-column>
<el-table-column
prop="tel"
label="电话号码"
width="180"
align="center">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180"
align="center">
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<!-- <el-button-->
<!-- size="mini"-->
<!-- @click="handleEdit(scope.$index, scope.row)">编辑</el-button>-->
<!-- <el-button type="primary" icon="el-icon-edit" circle @click=transfer(scope.row)></el-button>-->
<el-button type="danger" icon="el-icon-delete" circle @click="handleDelete(scope.$index, scope.row)"></el-button>
<!-- <el-button-->
<!-- v-if="scope.row.permession===1"-->
<!-- size="mini"-->
<!-- type="danger"-->
<!-- @click="handleDelete(scope.$index, scope.row)">删除-->
<!-- </el-button>-->
<!-- <el-button-->
<!-- v-else-->
<!-- size="mini"-->
<!-- disabled-->
<!-- type="danger">删除-->
<!-- </el-button>-->
</template>
</el-table-column>
</el-table>
<AddAdministrator :dfn="dfn_add" @refreshTable="getData($event)"></AddAdministrator>
<!-- <UpdateAdministrator :user="user" :dfn="dfn_update" @refreshTable="getData($event)"></UpdateAdministrator>-->
</div>
</template>
<script>
import AddAdministrator from "@/views/AdministratorManagement/AddAdministrator";
import UpdateAdministrator from "@/views/AdministratorManagement/UpdateAdministrator";
export default {
name: "AdministratorList",
components: {UpdateAdministrator, AddAdministrator},
data() {
return {
tableData: [],
user: {},
dfn_update: 0,
dfn_add: 0
}
},
mounted() {
axios.post('http://124.223.194.15:19260/admin/search', {})
.then(response => {
// console.log(response.data.data);
this.tableData = response.data.data;
})
.catch(function (error) {
this.$message.error("获取数据失败");
console.log(error);
});
},
methods: {
handleDelete(index, row) {
this.$confirm('确定要删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
type: 'warning',
center: true
}).then(async () => {
axios.get('http://124.223.194.15:19260/admin/delete',{params:{id:row.id}})
.then(response=>{
if (response.data.status ===1000){
this.$message.success('删除成功');
this.getData();
}
else{
this.$message.error('删除失败');
}
}).catch(function (error) {
console.log(error);
});
}).catch(()=>{})
console.log(index, row);
},
transfer(row) {
this.dfn_update++;
this.user = {id: row.id, username: row.username, password: row.password, name: row.name, tel: row.tel};
},
add() {
this.dfn_add++;
},
getData() {
axios.post('http://124.223.194.15:19260/admin/search', {})
.then(response => {
this.tableData = response.data.data;
})
.catch(function (error) {
this.$message.error("获取数据失败");
console.log(error);
});
}
}
}
</script>
<style scoped>
</style>
<template>
<div>
<el-dialog title="修改管理员信息" :visible.sync="dialogFormVisible">
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="ID" :label-width="formLabelWidth" >
<el-input v-model="form.id" autocomplete="off" disabled></el-input>
</el-form-item>
<el-form-item label="用户名" :label-width="formLabelWidth" prop="username">
<el-input v-model="form.username" autocomplete="off" ></el-input>
</el-form-item>
<el-form-item label="密码" :label-width='formLabelWidth' prop="password">
<el-input :type="passw" v-model="form.password" autocomplete="off">
<i slot="suffix" :class="icon" @click="showPass"></i>
</el-input>
</el-form-item>
<el-form-item label="确认密码" :label-width='formLabelWidth' prop="repassword">
<el-input :type="passw" v-model="form.repassword" autocomplete="off">
<i slot="suffix" :class="icon" @click="showPass"></i>
</el-input>
</el-form-item>
<el-form-item label="电话号码" :label-width="formLabelWidth" prop="tel">
<el-input v-model="form.tel" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="姓名" :label-width="formLabelWidth" prop="name">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="closeForm">取 消</el-button>
<el-button type="primary" @click=updateAdmin>确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "UpdateAdministrator",
props:['user','dfn'],
data(){
var validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== this.form.password) {
callback(new Error('两次输入密码不一致!'))
} else {
callback()
}
}
return {
dialogFormVisible: false,
form: {
id:'',
username:'',
password:'',
tel:'',
name:'',
repassword:''
},
passw:"password",
icon:"el-input__icon el-icon-view",
formLabelWidth: '120px',
rules:{
username:[{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur' }
],
password: [
{ required: false, message: '请输入密码', trigger: 'blur' },
{ pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{4,20}$/, message: '密码必须是由4-20位字母+数字组合' }
],
repassword: [
{ required: false, validator: validatePass2, trigger: 'blur' }
],
tel: [{ required: true, message: '请输入手机号' ,trigger: 'blur' },
{pattern: /^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$/, message: '手机号格式错误'}
],
name:[{ required: true, message: '请输入姓名', trigger: 'blur' },
{ min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur' }
],
}
}
},
methods:{
closeForm(){
this.dialogFormVisible= false;
this.$refs['form'].clearValidate();
},
showPass(){
if (this.passw === 'text'){
this.passw = 'password';
this.icon="el-input__icon el-icon-view";
}
else{
this.passw = 'text';
this.icon="el-input__icon el-icon-loading";
}
},
updateAdmin(){
this.$refs.form.validate((validate)=>{
if (validate){
this.dialogFormVisible = false;
axios.post("http://124.223.194.15:19260/admin/update",this.form).then(response=>{
console.log(response);
if (response.data.status === 1000){
this.$message.success("修改成功");
this.$emit('refreshTable');
}
}).catch(function (error) {
console.log(error);
});
}
})
}
},
watch:{
user:{
handler(newVal){
if (newVal){
// console.log(newVal);
this.form=newVal;
}
},
deep:true
},
dfn(){
this.dialogFormVisible=true;
}
}
}
</script>
<style scoped>
</style>
<template>
<div>
<h1>用户组管理</h1>
</div>
</template>
<script>
export default {
name: "UserGroupManagement"
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<div>
<h1>宿舍管理</h1>
<br/>
<el-row>
<el-col :span="2">
<el-button style="font-size: 20px" type="primary" plain @click="getDialog">添加</el-button>
</el-col>
<el-col :span="3">
<el-button style="font-size: 20px" type="success" plain @click="handleUpload">文件上传</el-button>
</el-col>
</el-row>
<br/>
<el-row>
<el-table
ref="multipleTable"
:data="tableData"
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
prop="bid"
label="楼号"
width="120">
</el-table-column>
<el-table-column
prop="rcount"
label="总房间数"
width="120">
</el-table-column>
<el-table-column
prop="area"
label="所属区域"
width="120">
<template slot-scope="scope">{{ scope.row.area+''}}</template>
</el-table-column>
<el-table-column
prop="manager"
label="负责人"
width="120">
</el-table-column>
<el-table-column
prop="tel"
label="联系方式"
width="200">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" circle @click="handleEdit(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-dialog :title="title" :visible.sync="dialogVisible" height="80%" width="30%">
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="楼号" prop="bid">
<el-input v-model="form.bid" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="所属区域" prop="area">
<el-input v-model="form.area" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="负责人" prop="cno">
<el-select v-model="form.cno" clearablell placeholder="请选择负责人">
<el-option
v-for="item in caretakerOptions"
:key="item.cno"
:label="item.name"
:value="item.cno">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="resetForm('form')">重置</el-button>
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="文件上传" :visible.sync="uploadDialogVisible" width="30%">
<el-upload
class="upload-demo"
ref="upload"
action="customize"
:http-request="uploadFile"
:on-preview="handlePreview"
:before-remove="beforeRemove"
:before-upload="beforeUpload"
accept=".txt"
:auto-upload="false"
:limit="1"
:on-exceed="handleExceed"
:file-list="fileList">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传txt文件,且不超过20MB</div>
</el-upload>
<span slot="footer" class="dialog-footer">
<el-button @click="uploadDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmUpload">确定上传</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name: "DormitoryManagement",
data() {
return {
uploadDialogVisible:false,
file_Url:'',
fileList:[],
title:'',
tableData: [],
caretakerOptions:[],
sexOptions:[
{
id: '0',
name: ''
},
{
id: '1',
name: ''
},
],
rules: {
bid: [
{ required: true, message: '请输入楼号', trigger: 'blur' }
],
area: [
{ required: true, message: '请输入区域', trigger: 'blur' }
],
cno: [
{ required: true, message: '请选择负责人', trigger: 'change' }
],
},
multipleSelection: [],
value: "",
options:[],
deleteOptions:[],
dialogVisible:false,
form:{
bid:1,
area:1,
cno:1,
},
}},
created() {
axios.post('http://124.223.194.15:19260/admin/building/search',{})
.then(response => {
this.tableData=response.data.data;
console.log('请求成功');
})
.catch(function (error) {
console.log(error);
});
axios.post('http://124.223.194.15:19260/admin/caretaker/search',{})
.then(response => {
this.caretakerOptions=response.data.data;
console.log('请求成功');
})
.catch(function (error) {
console.log(error);
});
},
methods: {
handlePreview(file) {
console.log(file);
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${ file.name }?`);
},
beforeUpload(file){
const extension = file.name.split(".")[1] === "txt";
if (!extension) {
this.$message({
message: '上传文件只能是 txt 格式!',
type: 'error'
});
}
return extension;
},
uploadFile(params){
const _file = params.file;
const isLt20M = _file.size / 1024 / 1024 < 20;
let formData = new FormData();
formData.append("file", _file);
let config = {
headers:{
'Content-Type':'multipart/form-data',
}
}; //添加请求头
if (!isLt20M) {
this.$message.error("请上传20M以下的.xlsx文件");
return false;
}
//获取文件url
axios.post('http://124.223.194.15:19260/upload',formData,config)
.then(response=>{
if (response.data.status ===1000){
// this.$message.success('请求成功');
console.log(response)
this.file_Url = response.data.url;
axios.post('http://124.223.194.15:19260/admin/building/addList',{
fileUrl:this.file_Url
}).then(response=>{
if (response.data.status ===1000){
this.$message.success('文件上传成功');
}
else{
this.$message.error('文件上传失败');
}
}).catch(function (error) {
console.log(error);
});
}
else{
this.$message.error('请求失败');
}
}).catch(function (error) {
console.log(error);
});
},
confirmUpload(){
this.$refs.upload.submit();
},
handleUpload(){
this.uploadDialogVisible = true;
},
refleshTable(){
axios.post('http://124.223.194.15:19260/admin/building/search',{})
.then(response => {
this.tableData=response.data.data;
console.log('请求成功');
})
.catch(function (error) {
console.log(error);
});
},
toggleSelection(rows) {
if (rows) {
rows.forEach(row => {
this.$refs.multipleTable.toggleRowSelection(row);
});
} else {
this.$refs.multipleTable.clearSelection();
}
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
getDialog()
{
this.form={}
this.title="添加宿舍楼信息"
this.dialogVisible = true;
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
save(){
if(this.form.bid==null||this.form.area==null||this.form.cno==null)
this.$message.error("请填写完整的数据!");
else {
this.dialogVisible = false;
if(this.title=="修改宿舍楼信息")
{
this.form.bid=this.form.bid-0
this.form.area=this.form.area-0
axios.post("http://124.223.194.15:19260/admin/building/update", this.form).then(response => {
if (response.data.status === 1000) {
this.$message.success("修改成功");
this.refleshTable();
}else{
this.$message.error("修改失败");
}
}).catch(function (error) {
console.log(error);
});
}else{
this.form.bid=this.form.bid-0
this.form.area=this.form.area-0
axios.post("http://124.223.194.15:19260/admin/building/add", this.form).then(response => {
if (response.data.status === 1000) {
this.$message.success("添加成功");
this.refleshTable();
}else{
this.$message.error("添加失败");
}
}).catch(function (error) {
console.log(error);
});
}
}
},
handleEdit(data){
data=data ||{}
this.title="修改宿舍楼信息"
this.dialogVisible=true
this.form =data
},
},
}
</script>
<style scoped>
</style>
<template>
<div>
<br/>
<el-row :gutter="20">
<el-col><h1>宿舍概况</h1></el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="5" offset="2">
<el-card>
<i class="el-icon-office-building" style="font-size: 150px;color: aquamarine "></i>
<div>
<h1>总栋数</h1>
<h1>{{homeData.bcount}}</h1>
</div>
</el-card>
</el-col>
<el-col :span="5" offset="2">
<el-card>
<i class="el-icon-s-home" style="font-size: 150px;color: crimson "></i>
<div>
<h1>房间数</h1>
<h1>{{homeData.rcount}}</h1>
</div>
</el-card>
</el-col>
<el-col :span="5" offset="2">
<el-card>
<i class="el-icon-user-solid" style="font-size: 150px;color: cornflowerblue "></i>
<div>
<h1>总人数</h1>
<h1>{{homeData.pcount}}</h1>
</div>
</el-card>
</el-col>
</el-row>
<br/><br/>
<el-row :gutter="20">
<el-col><h1>信息统计</h1></el-col>
</el-row>
<br/><br/>
<el-row :gutter="20">
<el-col :span="5" offset=1>
<div id="myChart" style="width: 300px;height: 300px;"></div>
</el-col>
<el-col :span="5" offset=1>
<div id="myChart2" style="width: 300px;height: 300px;"></div>
</el-col>
<el-col :span="8" offset=1>
<el-table
:data="tableData"
height="300"
border
style="width: 400px;">
<el-table-column
prop="type"
label="报修类型"
width="80px"
height="50px"
>
</el-table-column>
<el-table-column
prop="describe"
label="报修描述"
width="120px"
height="50px"
>
</el-table-column>
<el-table-column
prop="time"
label="报修时间"
width="100px"
height="50px"
>
<template slot-scope="scope">{{scope.row.time.slice(0, 19).replace("T", " ")}}</template>
</el-table-column>
<el-table-column
prop="status"
label="状态"
width="99px"
height="50px"
>
<template slot-scope="scope">
<span v-if="scope.row.status == 0">未完成</span>
<span v-if="scope.row.status == 1">已完成</span>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
// import * as echarts from 'echarts';
export default {
name: 'HomeView',
data() {
return {
homeData: {
"area": [
3
],
"rcount": 28888,
"month": [
5
],
"rate": [
2
],
"pcount": 4,
"people": [
488
],
"bcount": 7
}
,
tableData: [ {
"id": 1,
"username": "fdj", //报修人姓名
"repairer": "fdjsb",
"tel": "123456789",
"type": "电类",
"bid": 34,
"rid": 209,
"describe": "test",
"imageUrl": "null",
"other": "null",
"time": "2022-04-12 12:00:00",
"status": 1
}, {
"id": 1,
"username": "fdj", //报修人姓名
"repairer": "fdjsb",
"tel": "123456789",
"type": "电类",
"bid": 34,
"rid": 209,
"describe": "test",
"imageUrl": "null",
"other": "null",
"time": "2022-04-12 12:00:00",
"status": 1
} ,{
"id": 1,
"username": "fdj", //报修人姓名
"repairer": "fdjsb",
"tel": "123456789",
"type": "电类",
"bid": 34,
"rid": 209,
"describe": "test",
"imageUrl": "null",
"other": "null",
"time": "2022-04-12 12:00:00",
"status": 1
},{
"id": 1,
"username": "fdj", //报修人姓名
"repairer": "fdjsb",
"tel": "123456789",
"type": "电类",
"bid": 34,
"rid": 209,
"describe": "test",
"imageUrl": "null",
"other": "null",
"time": "2022-04-12 12:00:00",
"status": 1
}, {
"id": 1,
"username": "fdj", //报修人姓名
"repairer": "fdjsb",
"tel": "123456789",
"type": "电类",
"bid": 34,
"rid": 209,
"describe": "test",
"imageUrl": "null",
"other": "null",
"time": "2022-04-12 12:00:00",
"status": 1
} ,{
"id": 1,
"username": "fdj", //报修人姓名
"repairer": "fdjsb",
"tel": "123456789",
"type": "电类",
"bid": 34,
"rid": 209,
"describe": "test",
"imageUrl": "null",
"other": "null",
"time": "2022-04-12 12:00:00",
"status": 1
}]
};
},
created() {
axios.post('http://124.223.194.15:19260/admin/repair/search',{}).then(response => {
this.tableData = response.data.data;
})
},
mounted() {
axios.get('http://124.223.194.15:19260/admin/mainPageData').then(response => {
this.homeData = response.data.data;
})
},
watch:{
homeData:{
handler(newValue){
this.drawLine();
this.drawLine2();
}
}
},
methods: {
drawLine() {
// 基于准备好的dom,初始化echarts实例
let myChart = this.$echarts.init(document.getElementById("myChart"));
// 绘制图表
myChart.setOption({
title: { text: "人数统计" },
tooltip: {},
xAxis: {
name: "",
data: this.homeData.area,
},
yAxis: {name: "",},
series: [
{
name: "人数",
type: "bar",
data: this.homeData.people,
},
],
});
},
drawLine2() {
// 基于准备好的dom,初始化echarts实例
let myChart = this.$echarts.init(document.getElementById("myChart2"));
// 绘制图表
myChart.setOption({
title: { text: "投诉数量" },
xAxis: {
name: "",
type: 'category',
data: this.homeData.month
},
yAxis: {
name: "",
type: 'value'
},
series: [
{
data: this.homeData.rate,
type: 'line'
}
]
});
},
},
};
</script>
<style>
.div1{
float:left;
width:300px;
background: #8d97dc;
}
/*同行靠左*/
.div2{
float:left;
width:300px;
background: #92e4ba;
}
</style>
\ No newline at end of file
<template>
<div class="big">
<br /><br /><br /><br /><br /><br />
<el-container>
<el-aside width="500px"></el-aside>
<!--
<el-header width="40px"></el-header width="40px"> -->
<div class="main">
<el-main width="">
<h1 style="text-align: center">智慧宿舍管理系统登陆</h1>
<br /><br /><br />
<div class="tablee">
<table>
<tr>
<td>
<h1>账号:</h1>
</td>
<td>
<el-input
type="text"
v-model="id"
placeholder="请输入账号"
style="width: 400px"
></el-input>
</td>
</tr>
<tr>
<td>
<h1>密码:</h1>
</td>
<td>
<el-input
v-model="psw"
placeholder="请输入密码"
show-password
style="width: 400px"
></el-input>
</td>
</tr>
</table>
</div>
<br /><br /><br />
<el-button type="primary" @click="login" style="align: center"
>登录</el-button
>
</el-main>
</div>
<el-aside width="500px"></el-aside>
</el-container>
</div>
</template>
<script>
export default {
name: "LoginRegister.vue",
data() {
return {
id: "",
psw: "",
status: 1000,
};
},
methods: {
login: function () {
console.log("点击登录");
//后端接口
axios
.post("http://124.223.194.15:19260/admin/login", {
username: this.id,
password: this.psw,
})
.then(
(response) => {
console.log(response);
this.status = response.data.status;
if (this.status === 1000) {
console.log("登录成功");
localStorage.setItem('tempUser',JSON.stringify(response.data));
this.$router.push({ path: "/layout/home" }); //跳转
} else if (this.status == "1001") alert("账号/密码错误");
},
(error) => {
console.log("请求失败", error.message);
}
);
},
},
};
</script>
<style scoped>
.big {
vertical-align: middle;
text-align: center;
width: 100%;
margin: 0 auto;
}
.tablee {
width: 600px;
height: 100px;
margin-right: auto;
margin-left: auto;
}
/* .main {
position: relative;
}*/
</style>
<template>
<div>
<el-row :gutter="20" style="margin-top:10px;">
<el-col :span="8">
<div class="grid-content bg-purple">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>个人中心</span>
</div>
<div style="text-align: center">
<h1>头像</h1>
<el-upload
disabled
class="avatar-uploader"
action="https://jsonplaceholder.typicode.com/posts/"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
<div class="registe-info">
</div>
<el-divider></el-divider>
<div class="personal-relation">
<div class="relation-item">姓名: <div style="float: right; padding-right:20px;">{{ dataForm.name }}</div></div>
</div>
<div class="personal-relation">
<div class="relation-item">用户名: <div style="float: right; padding-right:20px;">{{ dataForm.username }}</div></div>
</div>
<div class="personal-relation">
<div class="relation-item">电话: <div style="float: right; padding-right:20px;">{{ dataForm.tel }}</div></div>
</div>
</el-card>
</div>
</el-col>
<el-col :span="16">
<div>
<el-button type="text" style="font-size:15px;color:#4D4D4D;" @click="informationClick()">个人信息<span style="color:#B0E0E6;" v-if="informationShow" class="el-icon-s-promotion"></span></el-button>
<el-button type="text" style="font-size:15px;color:#4D4D4D;" @click="passwordClick()">修改密码<span style="color:#B0E0E6;" v-if="passwordShow" class="el-icon-s-promotion"></span></el-button>
</div>
<div class="grid-content bg-purple">
<el-card class="box-card" v-if="informationShow">
<div slot="header" class="clearfix">
<span>个人信息</span>
</div>
<div>
<el-form :model="dataForm" ref="dataForm" :rules="rules1" label-width="80px" size="small" label-position="right">
<el-form-item label="用户昵称" prop="name">
<el-input auto-complete="off" v-model="dataForm.name"></el-input>
</el-form-item>
<el-form-item label="手机号" prop="tel">
<el-input auto-complete="off" v-model="dataForm.tel"></el-input>
</el-form-item>
<el-form-item label="用户名" prop="username">
<el-input disabled maxlength="18" v-model="dataForm.username"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="changeInfo">修改</el-button>
<el-button size="mini" type="warning" @click="closeInfo">关闭</el-button>
</div>
</div>
</el-card>
<el-card class="box-card" v-if="passwordShow">
<div slot="header" class="clearfix">
<span>修改密码</span>
</div>
<div>
<el-form :model="dataPsw" ref="dataPsw" :rules="rules2" label-width="80px" size="small" label-position="right">
<!-- <el-form-item label="原密码" prop="name">-->
<!-- <el-input type="password" auto-complete="off" v-model="dataPsw.oldPassword"></el-input>-->
<!-- </el-form-item>-->
<el-form-item label="新密码" prop="newPassword">
<el-input type="password" auto-complete="off" v-model="dataPsw.newPassword"></el-input>
</el-form-item>
<el-form-item label="重复密码" prop="repeatPassword">
<el-input type="password" maxlength="18" v-model="dataPsw.repeatPassword"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="changePassword">修改</el-button>
<el-button size="mini" type="warning" @click="closePsw" >关闭</el-button>
</div>
</div>
</el-card>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name:"PersonalInformationSettings",
data(){
var validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== this.dataPsw.newPassword) {
callback(new Error('两次输入密码不一致!'))
} else {
callback()
}
}
return{
tempUser:{},
imageUrl: require("@/assets/imgs/head.jpg"),
dataForm:{
name: '伞兵',
tel: '173567777777',
username: 'fdjsb'
},
informationShow:true,
passwordShow:false,
dataPsw:{
// oldPassword:'',
newPassword:'',
repeatPassword:'',
},
rules1:{
// username:[{ required: true, message: '请输入用户名', trigger: 'blur' },
// { min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur' }
// ],
tel: [{ required: true, message: '请输入手机号' ,trigger: 'blur' },
{pattern: /^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$/, message: '手机号格式错误'}
],
name:[{ required: true, message: '请输入姓名', trigger: 'blur' },
{ min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur' }
],
},
rules2:{
newPassword: [
{ required: false, message: '请输入密码', trigger: 'blur' },
{ pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{4,20}$/, message: '密码必须是由4-20位字母+数字组合' }
],
repeatPassword: [
{ required: false, validator: validatePass2, trigger: 'blur' }
]
}
}
},
mounted() {
this.tempUser=JSON.parse(localStorage.getItem('tempUser'));
this.dataForm.name=this.tempUser.name;
this.dataForm.tel=this.tempUser.tel;
this.dataForm.username=this.tempUser.username;
},
methods:{
changeInfo(){
this.$refs['dataForm'].validate(validate=>{
if (validate){
axios.post("http://124.223.194.15:19260/admin/update",{"name":this.dataForm.name,"tel":this.dataForm.tel})
.then(response=>{
console.log(response);
if (response.data.status === 1000){
this.$message.success('修改成功')
this.tempUser.name=this.dataForm.name;
this.tempUser.tel=this.dataForm.tel;
// this.tempUser.username=this.dataForm.username;
localStorage.setItem('tempUser',JSON.stringify(this.tempUser));
}
else{
this.$message.error('修改失败')
}
})
.catch(function (error) {
console.log(error);
});
}
})
},
changePassword(){
this.$refs['dataPsw'].validate(validate=>{
if (validate){
axios.post("http://124.223.194.15:19260/admin/update",{"password":this.dataPsw.newPassword})
.then(response=>{
console.log(response);
if (response.data.status === 1000){
this.$message.success('密码已修改,请重新登录');
this.$router.push("/");
}
else{
this.$message.error('修改失败')
}
})
.catch(function (error) {
console.log(error);
});
}
})
},
closeInfo(){
this.informationShow=false;
},
closePsw(){
this.passwordShow=false;
},
handleAvatarSuccess(res, file) {
this.imageUrl = URL.createObjectURL(file.raw);
},
beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
return isJPG && isLt2M;
},
informationClick(){ //个人信息事件
this.informationShow = true
this.passwordShow = false
},
passwordClick(){ //密码事件
this.informationShow = false
this.passwordShow = true
}
}
}
</script>
<style lang="scss" scoped>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
border:1px solid gray;
border-radius:50%;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
.text {
font-size: 14px;
}
.item {
margin-bottom: 18px;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both
}
.box-card {
width: 100%;
}
//文本样式区
.name-role {
font-size: 16px;
padding: 5px;
text-align:center;
}
.sender{
text-align:center;
}
.registe-info{
text-align: center;
padding-top:10px;
}
.personal-relation {
font-size: 16px;
padding: 0px 5px 15px;
margin-right: 1px;
width: 100%
}
.relation-item {
padding: 12px;
}
.dialog-footer{
padding-top:10px ;
padding-left: 10%;
}
//布局样式区
.el-row {
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
}
}
.el-col {
border-radius: 4px;
}
.bg-purple-dark {
background: #99a9bf;
}
.bg-purple {
background: #d3dce6;
}
.bg-purple-light {
background: #e5e9f2;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
}
.row-bg {
padding: 10px 0;
background-color: #f9fafc;
}
</style>
<template>
<div >
<h1>公共设施检修情况</h1>
<div id="select" style="margin: 10px 10px">
<span>请选择楼号:</span>
<el-autocomplete
class="inline-input"
v-model="buildingID"
:fetch-suggestions="querySearch"
placeholder="请输入楼号"
@select="handleSelect"
style="margin-left: 10px"
></el-autocomplete>
<span style="margin-left: 10px">请选择类别:</span>
<el-select v-model="repairType" clearable placeholder="请选择" style="margin-left: 10px">
<el-option
v-for="item in options"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-button type="primary" @click="search" icon="el-icon-search" round style="margin-left: 10px"></el-button>
</div>
<el-table
:data="tableData"
border
style="width:100%"
:row-class-name="tableRowClassName">
<el-table-column
prop="id"
label="序号"
width="50"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="cname"
label="报修人姓名"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="tel"
label="报修人联系方式"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="type"
label="报修类型"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="bid"
label="报修宿舍楼号"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="describe"
label="问题描述"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="image"
label="故障图片"
align = center
header-align = center>
<template slot-scope="scope" >
<el-popover placement="top-start" title="" trigger="hover">
<el-image :src="scope.row.image" alt="" style="width: 200px;height: 200px"></el-image>
<el-image slot="reference" :src="scope.row.image" style="width: 100px;height: 100px"></el-image>
</el-popover>
</template>
</el-table-column>
<el-table-column
prop="time"
label="报修时间"
align = center
header-align = center>
<template slot-scope="scope">{{scope.row.time.slice(0, 19).replace("T", " ")}}</template>
</el-table-column>
<el-table-column
prop="repairer"
label="维修人员"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="other"
label="备注"
align = center
header-align = center>
</el-table-column>
</el-table>
</div>
</template>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
<script>
export default {
name: "CommunalFacilitiesRepairInfo",
methods: {
search(){
let bID, rType;
if(this.buildingID == '全部' || this.buildingID == null || this.buildingID == ''){
bID = null;
}
else{
bID = this.buildingID-0;
}
if(this.repairType == '全部' || this.repairType == ''){
rType = null
}else{
rType = this.repairType
}
axios.post('http://124.223.194.15:19260/admin/publicFacilitiesRepair/search',{
bid: bID,
type: rType
}).then(
res => {
console.log(res)
if(res.data.status=="1000"){
this.tableData = res.data.data
}
else
alert("查询请求失败!");
},
error => {
console.log('请求失败',error.message)
}
)
},
tableRowClassName({rowIndex}) {
if (this.tableData[rowIndex].status === 1) {
return 'success-row';
} else{
return 'warning-row';
}
},
querySearch(queryString, cb) {
var buildings = this.buildings;
var results = queryString ? buildings.filter(this.createFilter(queryString)) : buildings;
// 调用 callback 返回建议列表的数据
cb(results);
},
createFilter(queryString) {
return (building) => {
return (building.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ "value": "全部" },{ "value": 1 },{ "value": 5 },{ "value": 10 },
{ "value": 15 },{ "value": 20 },{ "value": 25 },
{ "value": 30 },{ "value": 35 },{ "value": 40 },
{ "value": 45 },{ "value": 50 },{ "value": 55 },
];
},
handleSelect(item) {
console.log(item);
}
},
mounted() {
this.buildings = this.loadAll();
axios.get('http://124.223.194.15:19260/admin/publicFacilitiesRepair/type',{params:{}})
.then(response=>{
if (response.data.status ===1000){
this.options=response.data.data;
console.log(response)
console.log('请求成功');
}
else{
this.$message.error('请求失败');
}
}).catch(function (error) {
console.log(error);
});
axios.post('http://124.223.194.15:19260/admin/publicFacilitiesRepair/search',{
bid: null,
type: null
}).then(
res => {
console.log(res)
if(res.data.status=="1000"){
this.tableData = res.data.data
}
else
alert("查询请求失败!");
},
error => {
console.log('请求失败',error.message)
}
)
},
data() {
return {
buildings: [],
buildingID: null,
options: [],
repairType: null,
tableData: [
// {
// "id": 1,
// "username": "fdj",
// "repairer": "fdjsb",
// "tel": "123456789",
// "type": "门禁",
// "bid": "34",
// "describe": "test",
// "imageUrl": "null",
// "other": "null",
// "time": "2022-04-12 12:00:00",
// "status": 1
// },
// {
// "id": 2,
// "username": "fdj",
// "repairer": "fdjsb",
// "tel": "123456789",
// "type": "门禁",
// "bid": "37",
// "describe": "test",
// "imageUrl": "null",
// "other": "null",
// "time": "2022-04-12 12:00:00",
// "status": 1
// },
// {
// "id": 3,
// "username": "fdj",
// "repairer": "fdjsb",
// "tel": "123456789",
// "type": "门禁",
// "bid": "31",
// "describe": "test",
// "imageUrl": "null",
// "other": "null",
// "time": "2022-04-12 12:00:00",
// "status": 0
// }
]
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<div>
<h1>投诉管理</h1>
<div id="select" style="margin: 10px 10px">
<span>请输入投诉人学号:</span>
<el-input
placeholder="投诉人学号"
v-model="complaintSID"
clearable
style="width: 15%; margin-left: 10px">
</el-input>
<span style="margin-left: 10px">请选择处理状态:</span>
<el-select v-model="complaintStatus" clearable placeholder="请选择" style="margin-left: 10px">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-button type="primary" @click="search" icon="el-icon-search" round style="margin-left: 10px"></el-button>
</div>
<el-table
:data="tableData"
border
style="width:100%"
:row-class-name="tableRowClassName">
<el-table-column
prop="id"
label="序号"
width="50"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="sname"
label="投诉人姓名"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="tel"
label="联系方式"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="describe"
label="问题描述"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="image"
label="投诉图片"
align = center
header-align = center>
<template slot-scope="scope" >
<el-popover placement="top-start" title="" trigger="hover">
<el-image :src="scope.row.image" alt="" style="width: 200px;height: 200px"></el-image>
<el-image slot="reference" :src="scope.row.image" style="width: 100px;height: 100px"></el-image>
</el-popover>
</template>
</el-table-column>
<el-table-column
prop="time"
label="投诉时间"
align = center
header-align = center>
<template slot-scope="scope">{{scope.row.time.slice(0, 19).replace("T", " ")}}</template>
</el-table-column>
<el-table-column
prop="response"
label="答复"
align = center
header-align = center>
</el-table-column>
<el-table-column
fixed="right"
label="操作"
width="120"
align = center
header-align = center>
<template slot-scope="scope">
<el-button type="text" @click="subResponse(scope.row)" :disabled="scope.row.status === 1">答复</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog title="投诉回复" :visible.sync="dialogVisible" width="30%">
<el-input type="textarea"
:rows="5"
placeholder="请输入内容"
v-model="textarea">" style="width: 80%">
</el-input>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
<script>
export default {
name: "ComplaintManagement",
methods: {
subResponse(row){
this.dialogVisible = true;
this.rowNum = row.id;
},
save(){
if(this.rowNum!=-1){
axios.post('http://124.223.194.15:19260/admin/complaint/response',{
id:this.rowNum,
response:this.textarea
}).then(
res => {
console.log(res)
console.log(this.textarea)
if(res.data.status=="1000"){
alert("回复提交成功!");
}
else
alert("请求失败!");
},
error => {
console.log('请求失败',error.message)
}
)
}
},
search(){
let c_SID,c_status;
if(this.complaintSID!=null && this.complaintSID!=''){
c_SID = this.complaintSID-0;
}
else{
c_SID = null;
}
if(this.complaintStatus == null || this.complaintStatus == ''){
c_status = null;
}
else{
c_status = this.complaintStatus-0;
}
axios.post('http://124.223.194.15:19260/admin/complaint/search',{
sno: c_SID,
status: c_status
}).then(
res => {
console.log(res)
if(res.data.status=="1000"){
this.tableData = res.data.data
}
else
alert("查询请求失败!");
},
error => {
console.log('请求失败',error.message)
}
)
},
tableRowClassName({rowIndex}) {
if (this.tableData[rowIndex].status === 1) {
return 'success-row';
} else{
return 'warning-row';
}
},
},
mounted(){
axios.post('http://124.223.194.15:19260/admin/complaint/search',{
sno: null,
status: null
}).then(
res => {
console.log(res)
if(res.data.status=="1000"){
this.tableData = res.data.data
}
else
alert("查询请求失败!");
},
error => {
console.log('请求失败',error.message)
}
);
},
data() {
return {
rowNum: -1,
textarea:'',
dialogVisible:false,
complaintStatus:null,
complaintSID: null,
options: [{
value: null,
label: '全部'
},{
value: '0',
label: '未处理'
},{
value: '1',
label: '已处理'
}],
tableData: [
// {
// "id": 1,
// "username": "fdj", //投诉人姓名
// "tel": "123456789",
// "describe": "test",
// "time": "2022-04-12 12:00:00",
// "response": "test",
// "imageUrl": null,
// "status": 1
// },
// {
// "id": 2,
// "username": "fdj", //投诉人姓名
// "tel": "123456789",
// "describe": "test",
// "time": "2022-04-12 12:00:00",
// "response": "test",
// "imageUrl": null,
// "status": 0
// }
]
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<div>
<h1>报修管理</h1>
<div id="select" style="margin: 10px 10px">
<span>请选择楼号:</span>
<el-autocomplete
class="inline-input"
v-model="buildingID"
:fetch-suggestions="querySearch"
placeholder="请输入楼号"
@select="handleSelect"
style="margin-left: 10px"
></el-autocomplete>
<span style="margin-left: 10px">请选择类别:</span>
<el-select v-model="repairType" clearable placeholder="请选择" style="margin-left: 10px">
<el-option
v-for="item in options"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-button type="primary" @click="search" icon="el-icon-search" round style="margin-left: 10px"></el-button>
</div>
<el-table
:data="tableData"
border
style="width:100%"
:row-class-name="tableRowClassName">
<el-table-column
prop="id"
label="序号"
width="50"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="sname"
label="报修人姓名"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="tel"
label="报修人联系方式"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="type"
label="报修类型"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="bid"
label="报修宿舍楼号"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="rid"
label="报修房间号"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="describe"
label="问题描述"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="image"
label="故障图片"
align = center
header-align = center>
<template slot-scope="scope" >
<el-popover placement="top-start" title="" trigger="hover">
<el-image :src="scope.row.image" alt="" style="width: 200px;height: 200px"></el-image>
<el-image slot="reference" :src="scope.row.image" style="width: 100px;height: 100px"></el-image>
</el-popover>
</template>
</el-table-column>
<el-table-column
prop="time"
label="报修时间"
align = center
header-align = center>
<template slot-scope="scope">{{scope.row.time.slice(0, 19).replace("T", " ")}}</template>
</el-table-column>
<el-table-column
prop="repairer"
label="维修人员"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="other"
label="备注"
align = center
header-align = center>
</el-table-column>
</el-table>
</div>
</template>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
<script>
export default {
name: "RepairManagement",
methods: {
search(){
let bID, rType;
if(this.buildingID == '全部' || this.buildingID == null || this.buildingID == ''){
bID = null;
}
else{
bID = this.buildingID-0;
}
if(this.repairType == '全部' || this.repairType == ''){
rType = null
}else{
rType = this.repairType
}
axios.post('http://124.223.194.15:19260/admin/repair/search',{
bid: bID,
type: rType
}).then(
res => {
console.log(res)
if(res.data.status=="1000"){
this.tableData = res.data.data
}
else
alert("查询请求失败!");
},
error => {
console.log('请求失败',error.message)
}
)
},
tableRowClassName({rowIndex}) {
if (this.tableData[rowIndex].status === 1) {
return 'success-row';
} else{
return 'warning-row';
}
},
querySearch(queryString, cb) {
const buildings = this.buildings;
const results = queryString ? buildings.filter(this.createFilter(queryString)) : buildings;
// 调用 callback 返回建议列表的数据
cb(results);
},
createFilter(queryString) {
return (building) => {
return (building.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ "value": "全部" },{ "value": 1 },{ "value": 5 },{ "value": 10 },
{ "value": 15 },{ "value": 20 },{ "value": 25 },
{ "value": 30 },{ "value": 35 },{ "value": 40 },
{ "value": 45 },{ "value": 50 },{ "value": 55 },
];
},
handleSelect(item) {
console.log(item);
}
},
mounted() {
this.buildings = this.loadAll();
axios.get('http://124.223.194.15:19260/admin/repair/type',{params:{}})
.then(response=>{
if (response.data.status ===1000){
this.options=response.data.data;
console.log(response)
console.log('请求成功');
}
else{
this.$message.error('请求失败');
}
}).catch(function (error) {
console.log(error);
});
axios.post('http://124.223.194.15:19260/admin/repair/search',{
bid: null,
type: null
}).then(
res => {
console.log(res)
if(res.data.status=="1000"){
this.tableData = res.data.data
}
else
alert("查询请求失败!");
},
error => {
console.log('请求失败',error.message)
}
)
},
data() {
return {
buildings: [],
buildingID: null,
options: [],
repairType: null,
tableData: [
// {
// "id": 1,
// "username": "fdj", //报修人姓名
// "repairer": "fdjsb",
// "tel": "123456789",
// "type": "电类",
// "bid": 34,
// "rid": 209,
// "describe": "test",
// "imageUrl": "https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
// "other": "null",
// "time": "2022-04-12 12:00:00",
// "status": 1
// },
// {
// "id": 2,
// "username": "fdj", //报修人姓名
// "repairer": "fdjsb",
// "tel": "123456789",
// "type": "电类",
// "bid": 34,
// "rid": 209,
// "describe": "test",
// "imageUrl": "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.puchedu.cn%2Fuploads%2F3%2F26%2F1194960887%2F1105860307.jpg&refer=http%3A%2F%2Fimg.puchedu.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1654158973&t=d88991484ce8b5232f41e1967b81fa45",
// "other": "null",
// "time": "2022-04-12 12:00:00",
// "status": 0
// },
// {
// "id": 3,
// "username": "fdj", //报修人姓名
// "repairer": "fdjsb",
// "tel": "123456789",
// "type": "电类",
// "bid": 34,
// "rid": 209,
// "describe": "test",
// "imageUrl": "",
// "other": "null",
// "time": "2022-04-12 12:00:00",
// "status": 0
// },
// {
// "id": 4,
// "username": "fdj", //报修人姓名
// "repairer": "fdjsb",
// "tel": "123456789",
// "type": "电类",
// "bid": 34,
// "rid": 209,
// "describe": "test",
// "imageUrl":"",
// "other": "null",
// "time": "2022-04-12 12:00:00",
// "status": 0
// },
// {
// "id": 5,
// "username": "fdj", //报修人姓名
// "repairer": "fdjsb",
// "tel": "123456789",
// "type": "电类",
// "bid": 34,
// "rid": 209,
// "describe": "test",
// "imageUrl":"",
// "other": "null",
// "time": "2022-04-12 12:00:00",
// "status": 1
// },
// {
// "id": 6,
// "username": "fdj", //报修人姓名
// "repairer": "fdjsb",
// "tel": "123456789",
// "type": "电类",
// "bid": 34,
// "rid": 209,
// "describe": "test",
// "imageUrl":"",
// "other": "null",
// "time": "2022-04-12 12:00:00",
// "status": 0
// }
]
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<div>
<el-dialog title="添加收费项目" :visible.sync="dialogFormVisible">
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="项目名称" :label-width="formLabelWidth" prop="name">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="开始时间" :label-width="formLabelWidth" prop="startTime">
<el-date-picker
style="float: left"
v-model="form.startTime"
type="datetime"
placeholder="选择开始日期"
value-format="yyyy-MM-ddTHH:mm:ss"
>
</el-date-picker>
</el-form-item>
<el-form-item label="结束时间" :label-width="formLabelWidth" prop="endTime">
<el-date-picker
style="float: left"
v-model="form.endTime"
type="datetime"
placeholder="选择结束日期"
value-format="yyyy-MM-ddTHH:mm:ss">
</el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="resetForm('form')">重置</el-button>
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="addCharge">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "AddCharge",
props:['dfn'],
data(){
return {
dialogFormVisible: false,
form:{
name:'',
startTime:'',
endTime:''
},
formLabelWidth: '120px',
rules:{
name:[{ required: true, message: '请输入项目名称', trigger:'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
],
startTime: [{required:true,message:'请输入开始日期'}],
endTime: [{required:true,message:'请输入截止日期'}]
}
}
},
methods:{
resetForm(formName) {
this.$refs[formName].resetFields();
},
addCharge(){
this.$refs['form'].validate((validate)=>{
if (validate){
// console.log(this.form);
this.dialogFormVisible= false;
axios.post("http://124.223.194.15:19260/admin/charge/add",this.form).then(response=>{
// console.log(response);
if (response.data.status === 1000){
this.$message.success("添加成功");
this.$emit('refreshTable');
}
}).catch(function (error) {
console.log(error);
});
}
})
}
},
watch:{
dfn(){
this.dialogFormVisible= true;
}
}
}
</script>
<style scoped>
</style>
<template>
<div>
<h1>收费明细管理</h1>
<el-row>
<el-col :span="12">
<el-select v-model="value" placeholder="根据收费项目查找" style="float: right;margin-bottom: 5px">
<el-option
v-for="item in options"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="bid"
label="楼号"
>
</el-table-column>
<el-table-column
prop="rid"
label="宿舍号"
>
</el-table-column>
<el-table-column
prop="money"
label="金额">
</el-table-column>
<el-table-column
prop="status"
label="缴费状态">
<template slot-scope="scope">{{scope.row.status===0?'未缴费':'已缴费'}}</template>
</el-table-column>
<el-table-column
prop="submittime"
label="缴费时间">
<template slot-scope="scope">{{scope.row.status===0?'':scope.row.submittime.slice(0, 19).replace("T", " ")}}</template>
</el-table-column>
</el-table>
</el-col>
<el-col :span="12">
<ChargeEcharts :all-data="graphData" v-if="hasData"></ChargeEcharts>
</el-col>
</el-row>
</div>
</template>
<script>
import ChargeEcharts from "@/views/chargeManagement/ChargeEcharts";
export default {
name: "ChargeDetailsManagement",
components: {ChargeEcharts},
data(){
return {
hasData:false,
options:[],
value:'',
tableData:[],
graphData:{}
}
},
mounted() {
axios.post('http://124.223.194.15:19260/admin/charge/search',{})
.then(response=>{
if (response.data.status ===1000){
this.options=response.data.data;
console.log(response)
console.log('请求成功');
this.hasData=true;
}
else{
this.$message.error('请求失败');
}
}).catch(function (error) {
console.log(error);
});
},
watch:{
value:{
handler(newValue){
console.log(newValue);
axios.get('http://124.223.194.15:19260/admin/charge/detail',{params:{
pid:newValue
}}).then(response=>{
if (response.data.status ===1000){
this.tableData = response.data.data;
// console.log('获取成功',response);
}
else this.$message.error('数据获取失败');
}).catch(function (error) {
console.log(error);
});
axios.get('http://124.223.194.15:19260/admin/charge/status',{params:{
id:newValue
}}).then((response=>{
if (response.data.status ===1000){
this.graphData = response.data.data;
console.log('获取成功',response);
}
else this.$message.error('数据获取失败');
})).catch(function (error) {
console.log(error);
});
}
}
}
}
</script>
<style scoped>
</style>
<template>
<div>
<div style="width: auto;height: 400px" id="main">
</div>
</div>
</template>
<script>
//通过this.$echarts来使用
export default {
name: "ChargeEcharts",
props:['allData'],
methods: {
//初始化echarts
echartsInit(yData,sData) {
//柱形图
//因为初始化echarts 的时候,需要指定的容器 id='main'
this.$echarts.init(document.getElementById('main')).setOption({
title:{
show:'true',
text:'收费情况统计'
},
xAxis: {
type: 'value'
},
yAxis: {
type: 'category',
data: yData
},
series: [{
data: sData,
type: 'bar',
showBackground: true,
backgroundStyle: {
color: 'rgba(220, 220, 220, 0.8)'
}
}]
})
}
},
watch:{
allData(newVal){
this.echartsInit(newVal.bid,newVal.data);
console.log("data",newVal.data);
console.log('bid',newVal.bid)
}
}
}
</script>
<template>
<div style="width: 80%;margin-left: 10%">
<h1> 收费项目</h1>
<el-button @click="add" style="float: left;background-color: cornflowerblue">添加</el-button>
<el-date-picker
v-model="stTime"
type="datetime"
placeholder="选择开始日期">
</el-date-picker>
<el-date-picker
style="float: right;"
v-model="edTime"
type="datetime"
placeholder="选择结束日期">
</el-date-picker>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="id"
label="ID"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="admin"
label="管理员"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="name"
label="项目名"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="starttime"
label="开始时间"
align = center
header-align = center>
<template slot-scope="scope">{{scope.row.starttime.slice(0, 19).replace("T", " ")}}</template>
</el-table-column>
<el-table-column
prop="endtime"
label="截止时间"
align = center
header-align = center>
<template slot-scope="scope">{{scope.row.endtime.slice(0, 19).replace("T", " ")}}</template>
</el-table-column>
<el-table-column label="操作" style="width: 120px" align = center header-align = center>
<template slot-scope="scope">
<el-row>
<el-col :span="9" offset="1">
<el-button
size="mini"
@click="handleUpload(scope.$index, scope.row)">上传文件</el-button>
</el-col>
<el-col :span="6" offset="1">
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除</el-button>
</el-col>
</el-row>
</template>
</el-table-column>
</el-table>
<AddCharge :dfn="dfn_add" @refreshTable="getData($event)"></AddCharge>
<el-dialog title="文件上传" :visible.sync="dialogVisible" width="30%">
<el-upload
class="upload-demo"
ref="upload"
action="customize"
:http-request="uploadFile"
:on-preview="handlePreview"
:before-remove="beforeRemove"
:before-upload="beforeUpload"
accept=".txt"
:auto-upload="false"
:limit="1"
:on-exceed="handleExceed"
:file-list="fileList">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传txt文件,且不超过20MB</div>
</el-upload>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmUpload">确定上传</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import AddCharge from "@/views/chargeManagement/AddCharge";
export default {
name: "ChargeItems",
components: {AddCharge},
data(){
return{
tableData:[],
duplicate:[],
dfn_update:0,
dfn_add:0,
stTime:'',
edTime:'',
dialogVisible:false,
file_Url:'',
chargeID:0,
fileList:[]
}
},
watch:{
stTime(newVal){
this.doTheFilter(newVal,this.edTime);
},
edTime(newVal){
this.doTheFilter(this.stTime,newVal);
}
},
mounted() {
axios.post('http://124.223.194.15:19260/admin/charge/search',{})
.then(response=>{
if (response.data.status ===1000){
this.tableData=response.data.data;
this.duplicate=response.data.data.concat();
console.log(response)
console.log('请求成功');
}
else{
this.$message.error('请求失败');
}
}).catch(function (error) {
console.log(error);
});
},
methods:{
doTheFilter(a,b){
let st=a===''||a===null?undefined:new Date(this.stTime);
let ed=b===''||b===null?undefined:new Date(this.edTime);
this.tableData = this.duplicate.filter(item=>{
let starttime = new Date(item.starttime);
let endtime = new Date(item.endtime);
return (st?starttime>=st:true)&&(ed?endtime<=ed:true);
})
},
handlePreview(file) {
console.log(file);
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${ file.name }?`);
},
beforeUpload(file){
const extension = file.name.split(".")[1] === "txt";
if (!extension) {
this.$message({
message: '上传文件只能是 txt 格式!',
type: 'error'
});
}
return extension;
},
uploadFile(params){
const _file = params.file;
const isLt20M = _file.size / 1024 / 1024 < 20;
let formData = new FormData();
formData.append("file", _file);
let config = {
headers:{
'Content-Type':'multipart/form-data',
}
}; //添加请求头
if (!isLt20M) {
this.$message.error("请上传20M以下的.xlsx文件");
return false;
}
//获取文件url
axios.post('http://124.223.194.15:19260/upload',formData,config)
.then(response=>{
if (response.data.status ===1000){
// this.$message.success('请求成功');
console.log(response)
this.file_Url = response.data.url;
axios.post('http://124.223.194.15:19260/admin/charge/addDetail',{
id:1,
fileUrl:this.file_Url
}).then(response=>{
if (response.data.status ===1000){
this.$message.success('文件上传成功');
}
else{
this.$message.error('文件上传失败');
}
}).catch(function (error) {
console.log(error);
});
}
else{
this.$message.error('请求失败');
}
}).catch(function (error) {
console.log(error);
});
},
confirmUpload(){
this.$refs.upload.submit();
},
handleUpload(index, row){
this.dialogVisible = true;
this.chargeID = row.id;
},
handleDelete(index, row) {
this.$confirm('确定要删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
type: 'warning',
center: true
}).then(async () => {
axios.post('http://124.223.194.15:19260/admin/charge/delete',{id:row.id})
.then(response=>{
if (response.data.status ===1000){
this.$message.success('删除成功');
this.getData();
}
else{
this.$message.error('删除失败');
}
}).catch(function (error) {
console.log(error);
});
}).catch(()=>{})
console.log(index, row);
},
transfer(row){
this.dfn_update++;
this.user={id:row.id,username:row.username,password:row.password,name:row.name,tel:row.tel};
},
add(){
this.dfn_add++;
},
getData(){
axios.post('http://124.223.194.15:19260/admin/charge/search',{})
.then(response=>{
if (response.data.status ===1000){
console.log(this);
this.tableData=response.data.data;
this.duplicate=response.data.data.concat();
this.$message.success('请求成功');
}
else{
this.$message.error('请求失败');
}
}).catch(function (error) {
console.log(error);
});
}
}
}
</script>
<style scoped>
</style>
<template>
</template>
<script>
export default {
name: "UpdateCharge"
}
</script>
<style scoped>
</style>
<template>
<div>
<h1>签到情况</h1>
<div id="select" style="margin: 10px 10px">
<span>请选择签到任务:</span>
<el-select v-model="task" placeholder="签到任务" style="margin-left: 10px">
<el-option
v-for="item in options"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
<el-button type="primary" @click="refresh" icon="el-icon-search" round style="margin-left: 10px"></el-button>
</div>
<div id="tables" style="margin-top: 30px">
<div class="echart" id="mychart" :style="myChartStyle"></div>
<div style="width: 50%;float: right">
<div id="selectBuildAndStatus" style="margin: 10px 10px" >
<span>请输入楼号:</span>
<el-autocomplete
class="inline-input"
v-model="buildingID"
:fetch-suggestions="querySearch"
placeholder="签到任务不能为空"
@select="handleSelect"
style="margin-left: 10px;width: 25%"
:disabled="this.task === null"
></el-autocomplete>
<span style="margin-left: 10px">请选择状态:</span>
<el-select v-model="checkInStatus"
clearable placeholder="签到任务不能为空"
style="margin-left: 10px;width: 25%"
:disabled="this.task === null">
<el-option
v-for="item in statusOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-button type="primary" @click="search" icon="el-icon-search" round style="margin-left: 10px" :disabled="this.task === null"></el-button>
</div>
<el-table
:data="tableData"
style="width: 100%"
:row-class-name="tableRowClassName">
<el-table-column
prop="bid"
label="楼号"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="rid"
label="宿舍号"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="bed"
label="床号"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="sno"
label="学号"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="name"
label="姓名"
align = center
header-align = center>
</el-table-column>
<el-table-column
prop="status"
label="签到状态"
align = center
header-align = center>
<template slot-scope="scope">
<span>{{ statusMap[scope.row.status] }}</span>
</template>
</el-table-column>
<el-table-column
prop="submittime"
label="签到时间"
align = center
header-align = center>
<template slot-scope="scope">
<div v-if="scope.row.submittime!=null">
{{scope.row.submittime.slice(0, 19).replace("T", " ")}}
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
<script>
import * as echarts from "echarts";
export default {
name: "CheckIns",
data(){
return{
statusMap:{
0:"未签到",
1:"已签到"
},
options:[],
statusOptions: [{
value: null,
label: '全部'
},{
value: '0',
label: '未签到'
},{
value: '1',
label: '已签到'
}],
tableData:[
// { "bid": "34",
// "rid": "209",
// "bed": "4",
// "sno": "221900306",
// "name": "万择匀",
// "status": 1,
// "submittime": "null"}
],
task:null,
checkInStatus:null,
buildingID: null,
// xData: [0.9,0.8,0.9,0.9,0.8,0.9,0.9,0.8,0.9,0.9,0.8,0.9,1], //横坐标
// yData: [1,2,3,4,5,6,7,8,9,10,11,12,13], //数据
xData: [],
yData: [],
myChartStyle: { float: "left", width: "50%", height: "400px" } //图表样式
}
},
mounted() {
this.initEcharts();
this.buildings = this.loadAll();
axios.post('http://124.223.194.15:19260/admin/signIn/search',{params:{}})
.then(response=>{
if (response.data.status ===1000){
this.options=response.data.data;
console.log(response)
console.log('请求成功');
}
else{
this.$message.error('请求失败');
}
}).catch(function (error) {
console.log(error);
});
},
methods: {
refresh(){
console.log(this.task);
//添加表格数据
axios.post('http://124.223.194.15:19260/admin/signIn/detail',{
tid:this.task
}).then(response=>{
if (response.data.status ===1000){
this.tableData = response.data.data;
// console.log('获取成功',response);
}
else this.$message.error('数据获取失败');
}).catch(function (error) {
console.log(error);
});
//添加柱状图数据
axios.get('http://124.223.194.15:19260/admin/signIn/status',{params:{
id:this.task
}}).then(response=>{
if (response.data.status ===1000){
this.xData = response.data.data.data;
this.yData = response.data.data.bid;
this.initEcharts();
// console.log('获取成功',response);
}
else this.$message.error('数据获取失败');
}).catch(function (error) {
console.log(error);
});
},
search(){
let t_id,b_id,_status;
if(this.task == ''){
t_id = null;
}else{
t_id = this.task;
}
if(this.buildingID != null && this.buildingID != ''){
b_id = this.buildingID - 0;
}
else{
b_id = null;
}
if(this.checkInStatus == '' || this.checkInStatus == null){
_status = null;
}
else{
_status = this.checkInStatus-0;
}
//添加表格数据
axios.post('http://124.223.194.15:19260/admin/signIn/detail',{
tid:t_id,
bid:b_id,
status:_status
}).then(response=>{
if (response.data.status ===1000){
this.tableData = response.data.data;
// console.log('获取成功',response);
}
else this.$message.error('数据获取失败');
}).catch(function (error) {
console.log(error);
});
},
initEcharts() {
// 基本柱状图
const option = {
xAxis: {
type: 'value'
},
yAxis: {
type: 'category',
data: this.yData
},
legend:{
data: ["签到率"],
top: "0%"
},
series: [
{
name:'签到率',
type: "bar", //形状为柱状图
data: this.xData
}
],
dataZoom:[
{
type: "inside",
startValue: 0,
endValue: 9,
minValueSpan: 9,
maxValueSpan: 9,
yAxisIndex: [0],
zoomOnMouseWheel: false, // 关闭滚轮缩放
moveOnMouseWheel: true, // 开启滚轮平移
moveOnMouseMove: true // 鼠标移动能触发数据窗口平移
},
{
type: 'slider',
realtime: true,
startValue: 0,
endValue: 2,
width: '3.5',
height: '75%',
yAxisIndex: [0], // 控制y轴滚动
fillerColor: "rgba(154, 181, 215, 1)", // 滚动条颜色
borderColor: "rgba(17, 100, 210, 0.12)",
backgroundColor: '#cfcfcf',//两边未选中的滑动条区域的颜色
handleSize:0, // 两边手柄尺寸
showDataShadow: false,//是否显示数据阴影 默认auto
showDetail: false, // 拖拽时是否展示滚动条两侧的文字
top:'10%',
right:'50',
}
]
};
const myChart = echarts.init(document.getElementById("mychart"));
myChart.setOption(option);
//随着屏幕大小调节图表
window.addEventListener("resize", () => {
myChart.resize();
});
},
tableRowClassName({rowIndex}) {
if (this.tableData[rowIndex].status === 1) {
return 'success-row';
} else{
return 'warning-row';
}
},
querySearch(queryString, cb) {
const buildings = this.buildings;
const results = queryString ? buildings.filter(this.createFilter(queryString)) : buildings;
// 调用 callback 返回建议列表的数据
cb(results);
},
createFilter(queryString) {
return (building) => {
return (building.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
};
},
loadAll() {
return [
{ "value": "1" },{ "value": "5" },{ "value": "10" },
{ "value": "15" },{ "value": "20" },{ "value": "25" },
{ "value": "30" },{ "value": "35" },{ "value": "40" },
{ "value": "45" },{ "value": "50" },{ "value": "55" },
];
},
handleSelect(item) {
console.log(item);
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
})
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# dormitory-for-users
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册