yujialong 4 years ago
parent 834fb22228
commit 4a172c4890
  1. 10
      src/App.vue
  2. 3
      src/api/index.js
  3. BIN
      src/assets/img/remove-gray.png
  4. BIN
      src/assets/img/search-gray.png
  5. 17
      src/layouts/header/index.vue
  6. 3
      src/libs/util.db.js
  7. 8
      src/pages/account/login/index.vue
  8. 97
      src/pages/index/list/index.vue
  9. 7
      src/pages/setting/person/download.vue
  10. 204
      src/pages/setting/person/info.vue
  11. 2
      src/plugins/auth/index.js
  12. 2
      src/plugins/requests/index.js
  13. 28
      src/router/modules/wrongBook.js
  14. 2
      src/router/permission.js
  15. 9
      src/setting.js
  16. 0
      src/store/modules/data.js
  17. 97
      src/store/modules/exam.js
  18. 0
      src/store/modules/role.js
  19. 0
      src/store/modules/stat.js
  20. 35
      src/store/modules/user.js
  21. 24
      src/store/modules/wrongBook.js
  22. 2
      src/styles/layout/index.scss

@ -10,14 +10,14 @@
export default {
name: 'App',
created () {
//sessionStorage
if (util.session.get(Setting.storeKey) ) {
this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(util.session.get(Setting.storeKey))))
//localStorage
if (util.local.get(Setting.storeKey) ) {
this.$store.replaceState(Object.assign({}, this.$store.state,util.local.get(Setting.storeKey)))
}
//vuexsessionStorage
//vuexlocalStorage
window.addEventListener("beforeunload",()=>{
util.session.get(Setting.usernameKey) && util.session.set(Setting.storeKey,JSON.stringify(this.$store.state))
util.local.get(Setting.usernameKey) && util.local.set(Setting.storeKey,this.$store.state)
})
}
}

@ -3,8 +3,7 @@ let uploadURL = Setting.upload.apiURL
export default {
// 登录注册
logins: `management/userInfo/login`,
save: `management/userInfo/add`,
logins: `liuwanr/userInfo/adminLogins`,
uploadUserAvatars: `liuwanr/userInfo/uploadUserAvatars`,
queryProvince: `liuwanr/province/queryProvince`,

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

@ -1,9 +1,11 @@
<template>
<div class="header">
<div class="inner">
<img class="logo" src="../../assets/img/logo.png" alt="">
<a class="logo" @click="toIndex">
<img src="../../assets/img/logo.png" alt="">
</a>
<div style="height: 80px;"></div>
<navbar></navbar>
<navbar ref="nav"></navbar>
<div class="action">
<img class="search" src="../../assets/img/search.png" alt="">
<el-dropdown class="user-wrap" @command="userCommand">
@ -48,8 +50,13 @@ export default {
...mapActions('user', [
'logout'
]),
toIndex(){
this.$refs.nav.jump({
index: '/index/list',
title: '首页'
})
},
userCommand(command){
console.log(command)
if(command == 'person'){
this.$router.push('/setting/person')
}else{
@ -73,6 +80,10 @@ export default {
}
.logo{
width: 180px;
cursor: pointer;
img{
width: 100%;
}
}
.action{

@ -35,9 +35,10 @@ var _local = {
// 如果有startTime的值,说明设置了失效时间
if (item && item.startTime) {
let date = new Date().getTime();
// 如果大于就是过期了,如果小于或等于就还没过期
if (date - item.startTime > item.expires) {
localStorage.removeItem(name);
localStorage.removeItem(key);
return false;
} else {
return item.value;

@ -30,12 +30,13 @@
<script>
import { mapActions } from 'vuex'
import vHead from '@/layouts/header'
import util from '@/libs/util'
export default {
data: function() {
return {
loginForm: {
username: '20204400194',
password: '111aaa',
username: 'admin',
password: 'admin',
},
loginRules: {
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
@ -54,7 +55,8 @@ export default {
if (valid) {
let data = {
username: this.loginForm.username,
password: this.loginForm.password
password: this.loginForm.password,
remember: this.remember
}
this.login(data).then(() => {
let redirect = this.$route.query.redirect ? decodeURIComponent(this.$route.query.redirect) : '/index'

@ -1,13 +1,37 @@
<template>
<div>
<div class="title">欢迎来到<br>或然数据网</div>
<div class="wrap" :class="{result: keyword}">
<div class="title" v-if="!keyword">欢迎来到<br>或然数据网</div>
<div class="search">
<div class="input">
<img src="../../../assets/img/search-white.png" alt="">
<input type="text" placeholder="请输入关键词">
<img v-if="keyword" src="../../../assets/img/search-gray.png" alt="">
<img v-else src="../../../assets/img/search-white.png" alt="">
<input v-model="keyword" type="text" placeholder="请输入关键词">
</div>
<img src="../../../assets/img/remove.png" alt="" class="remove">
<img v-if="keyword" src="../../../assets/img/remove-gray.png" alt="" class="remove" @click="keyword = ''">
</div>
<template v-if="keyword">
<div class="tips">
<p class="result">搜索结果</p>
<p class="num">搜索完成共有4个结果匹配</p>
</div>
<el-table :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="roleName" label="数据表名称" align="center"></el-table-column>
<el-table-column prop="roleName" label="数据总量" align="center"></el-table-column>
<el-table-column prop="roleName" label="数据大小" align="center"></el-table-column>
<el-table-column prop="roleName" label="更新时间" align="center"></el-table-column>
<el-table-column label="操作" width="180" align="center">
<template slot-scope="scope">
<el-button type="text" @click="download(scope.row)">下载</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination>
</div>
</template>
</div>
</template>
@ -16,19 +40,43 @@ export default {
name: 'index',
data() {
return {
keyword: '',
searchTimer: null,
listData:[],
page: 1,
pageSize: 10,
total: 0,
}
},
watch: {
keyword: function(val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.getData()
},500)
}
},
mounted() {
},
methods: {
getData(){
},
handleCurrentChange(val) {
this.page = val
this.$refs.table.clearSelection()
this.getData()
},
download(row){
}
}
};
</script>
<style lang="scss" scoped>
.wrap{
.title{
margin: 70px 0 130px;
font-size: 50px;
@ -44,10 +92,13 @@ export default {
margin: 0 auto;
border-bottom: 2px solid #fff;
.input{
flex: 1;
display: inline-flex;
align-items: center;
margin-right: 20px;
}
input{
flex: 1;
padding-left: 20px;
margin-left: 30px;
font-size: 24px;
@ -55,9 +106,9 @@ export default {
background-color: transparent;
border: 0;
border-left: 2px solid #fff;
&::-webkit-input-placeholder{color: #fff}
&::-moz-placeholder{color: #fff}
&:-moz-placeholder{color: #fff}
&::-webkit-input-placeholder{color: #f5f5f5}
&::-moz-placeholder{color: #f5f5f5}
&:-moz-placeholder{color: #f5f5f5}
&:focus{
outline: none;
}
@ -66,5 +117,31 @@ export default {
cursor: pointer;
}
}
&.result{
padding: 70px 90px 50px;
background-color: #fff;
.search{
border-bottom-color: #cdcdcd;
input{
color: #999;
border-left-color: #cdcdcd;
&::-webkit-input-placeholder{color: #999}
&::-moz-placeholder{color: #999}
&:-moz-placeholder{color: #999}
}
}
.tips{
margin-bottom: 50px;
.result{
margin: 30px 0 10px;
font-size: 17px;
color: $main-color;
}
.num{
font-size: 14px;
color: #515151;
}
}
}
}
</style>

@ -23,7 +23,7 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination>
</div>
</div>
</div>
@ -86,6 +86,11 @@ export default {
handleSelectionChange(val) {
this.multipleSelection = val
},
handleCurrentChange(val) {
this.page = val
this.$refs.table.clearSelection()
this.getData()
},
}
};
</script>

@ -35,12 +35,7 @@
<span>国家</span>
<div>
<el-select v-model="personalInformation.countries" placeholder>
<el-option
v-for="item in countryList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
<el-option v-for="item in countryList" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</div>
</div>
@ -48,12 +43,7 @@
<span>省份</span>
<div>
<el-select v-model="personalInformation.provinceId" placeholder @change="id => getCity(id,1)">
<el-option
v-for="item in provinceList"
:key="item.provinceId"
:label="item.provinceName"
:value="item.provinceId"
></el-option>
<el-option v-for="item in provinceList" :key="item.provinceId" :label="item.provinceName" :value="item.provinceId"></el-option>
</el-select>
</div>
</div>
@ -61,12 +51,7 @@
<span>城市</span>
<div>
<el-select v-model="personalInformation.cityId" placeholder :disabled="personalInformation.provinceId ? false : true">
<el-option
v-for="item in cityList"
:key="item.cityId"
:label="item.cityName"
:value="item.cityId"
></el-option>
<el-option v-for="item in cityList" :key="item.cityId" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</div>
</div>
@ -82,12 +67,7 @@
<label>教育程度</label>
<div>
<el-select v-model="personalInformation.educationDegree" placeholder="请选择教育程度">
<el-option
v-for="(item,index) in educationDegreeList"
:key="index"
:label="item.name"
:value="item.value"
></el-option>
<el-option v-for="(item,index) in educationDegreeList" :key="index" :label="item.name" :value="item.value"></el-option>
</el-select>
</div>
</li>
@ -174,13 +154,15 @@
<li>
<label>手机号</label>
<div>
<el-input v-model="personalInformation.phone" clearable></el-input>
<span class="val" v-if="personalInformation.phone">{{personalInformation.phone}}</span>
<el-button size="small" @click="bindPhone">更换</el-button>
</div>
</li>
<li>
<label>邮箱</label>
<div>
<el-input v-model="personalInformation.email" clearable></el-input>
<span class="val" v-if="personalInformation.email">{{personalInformation.email}}</span>
<el-button size="small" @click="bindEmail">更换</el-button>
</div>
</li>
<li>
@ -195,6 +177,41 @@
</div>
</div>
<el-dialog :title="personalInformation.email ? '更换邮箱' : '绑定邮箱'" :visible.sync="emailVisible" :close-on-click-modal="false" @close="closeEmail" width="30%">
<el-form ref="form" :model="form" label-width="60px">
<el-form-item label="邮箱">
<el-input placeholder="请输入邮箱" v-model="email"></el-input>
</el-form-item>
<el-form-item label="验证码">
<div class="flex">
<el-input v-model="emailCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left: 10px" type="text" @click="sendEmailCode" :disabled="emailDisabled">{{emailBtnText}}</el-button>
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="emailVisible = false"> </el-button>
<el-button type="primary" @click="emailSubmit"> </el-button>
</span>
</el-dialog>
<el-dialog :title="personalInformation.phone ? '更换手机号' : '绑定手机号'" :visible.sync="phoneVisible" :close-on-click-modal="false" @close="closePhone" width="30%">
<el-form ref="form" :model="form" label-width="60px">
<el-form-item label="手机号">
<el-input placeholder="请输入手机号" v-model="phone" maxlength="11"></el-input>
</el-form-item>
<el-form-item label="验证码">
<div class="flex">
<el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left: 10px" type="text" @click="sendPhoneCode" :disabled="phoneDisabled">{{phoneBtnText}}</el-button>
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="phoneVisible = false"> </el-button>
<el-button type="primary" @click="phoneSubmit"> </el-button>
</span>
</el-dialog>
<el-dialog title="更换密码" :visible.sync="passwordVisible" :close-on-click-modal="false" @close="closePassword" width="30%">
<el-form ref="passwordForm" :model="form" label-width="60px">
@ -442,11 +459,11 @@ export default {
}
},
addArch() {
let isEmpty = false
this.archivesList.forEach((n,k) => {
if(!n.personalCareerId) isEmpty = true
})
if(isEmpty) return this.$message.warning('请选择职业')
// let isEmpty = false
// this.archivesList.forEach((n,k) => {
// if(!n.personalCareerId) isEmpty = true
// })
// if(isEmpty) return this.$message.warning('')
this.showArch = true
this.concatArch()
},
@ -496,6 +513,120 @@ export default {
document.documentElement.scrollTop = document.querySelector('.content-box').scrollHeight
})
},
emailCountdown(){
let count = 60
if(!this.emailTimer){
this.emailDisabled = true
this.emailTimer = setInterval(() => {
console.log('倒计时中')
if(count > 0){
count--
this.emailBtnText = `${count}秒后重试`
}else{
this.emailDisabled = false
clearInterval(this.emailTimer)
this.emailTimer = null
this.emailBtnText = `发送验证码`
}
},1000)
}
},
phoneCountdown(){
let count = 60
if(!this.phoneTimer){
this.phoneDisabled = true
this.phoneTimer = setInterval(() => {
console.log('倒计时中')
if(count > 0){
count--
this.phoneBtnText = `${count}秒后重试`
}else{
this.phoneDisabled = false
clearInterval(this.phoneTimer)
this.phoneTimer = null
this.phoneBtnText = `发送验证码`
}
},1000)
}
},
closeEmail(){
if(!this.emailDisabled){
this.emailCode = ''
}
},
sendEmailCode(){
if(!this.email) return this.$message.warning('请输入邮箱')
if(!/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(this.email)) return this.$message.warning('请输入正确的邮箱')
let data = {
userId: this.userId,
email: this.email,
types: 1
}
this.$post(this.api.sendEmailCode,data).then(res => {
if(res.errmessage == 'success'){
this.emailCountdown()
this.emailOpener = res.data
}
}).catch(res => {});
},
emailSubmit(){
if(!this.email) return this.$message.warning('请输入邮箱')
if(!/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(this.email)) return this.$message.warning('请输入正确的邮箱')
if(!this.emailCode) return this.$message.warning('请输入验证码')
let data = {
userId: this.userId,
email: this.email,
types: 1,
code: this.emailCode,
opener: this.emailOpener
}
this.$put(this.api.bingEmail,data).then(res => {
if(res.errmessage == 'success'){
this.$message.success('绑定成功')
this.personalInformation.email = this.email
this.emailVisible = false
}
}).catch(res => {});
},
closePhone(){
if(!this.emailDisabled){
this.emailCode = ''
}
},
sendPhoneCode(){
if(!this.phone) return this.$message.warning('请输入手机号')
if(!/^1[3456789]\d{9}$/.test(this.phone)) return this.$message.warning('请输入正确的手机号')
let data = {
userId: this.userId,
phone: this.phone,
types: 2
}
this.$post(this.api.sendPhoneCode,data).then(res => {
if(res.errmessage == 'success'){
this.phoneCountdown()
this.phoneOpener = res.data
}
}).catch(res => {});
},
phoneSubmit(){
if(!this.phone) return this.$message.warning('请输入手机号')
if(!/^1[3456789]\d{9}$/.test(this.phone)) return this.$message.warning('请输入正确的手机号')
if(!this.phoneCode) return this.$message.warning('请输入验证码')
let data = {
userId: this.userId,
phone: this.phone,
types: 2,
code: this.phoneCode,
opener: this.phoneOpener
}
this.$put(this.api.bindPhone,data).then(res => {
if(res.errmessage == 'success'){
this.$message.success('绑定成功')
this.personalInformation.phone = this.phone
this.phoneVisible = false
}
}).catch(res => {});
},
}
};
</script>
@ -530,6 +661,11 @@ export default {
border-color: #999;
}
}
.val{
margin-right: 15px;
color: #606266;
font-size: 14px;
}
.mul{
display: inline-flex;
margin-top: 10px;
@ -547,5 +683,11 @@ export default {
}
}
.archives{
padding: 30px;
margin-bottom: 30px;
border-radius: 8px;
border: 1px dashed #C0C4CC;
}
}
</style>

@ -1,7 +1,7 @@
/**
* @description 鉴权指令
* 当传入的权限当前用户没有时会移除该组件
* 用例<Tag v-auth">text</Tag> 或者:<Tag v-auth="'user:编辑'">text</Tag>
* 用例<Tag v-auth>text</Tag> <Tag v-auth="'user:'">text</Tag>
* */
import store from '@/store';

@ -32,7 +32,7 @@ service.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
service.interceptors.response.use(
response => {
const res = response.data
if (res.success) {
if (res.status == 200) {
return Promise.resolve(res).catch(e => {})
} else {
switch (res.code) {

@ -1,28 +0,0 @@
import BasicLayout from '@/layouts/home';
const meta = {};
const pre = 'wrongBook-';
export default {
path: '/wrongBook',
name: 'wrongBook',
redirect: {
name: `${pre}list`
},
meta,
component: BasicLayout,
children: [
{
name: `${pre}list`,
path: `list`,
component: () => import('@/pages/wrongBook/list'),
meta: { title: '我的错题本' }
},{
name: `${pre}do`,
path: `do`,
component: () => import('@/pages/wrongBook/do'),
meta: { title: '错题练习' }
},
]
};

@ -4,7 +4,7 @@ import util from '@/libs/util'
router.beforeEach((to, from, next) => {
document.title = Setting.titleSuffix;
const role = util.session.get(Setting.usernameKey);
const role = util.local.get(Setting.usernameKey);
if (!role && to.path !== '/login') {
next('/login')
} else if(role && to.path == '/login') {

@ -16,13 +16,17 @@ const Setting = {
showProgressBar: true,
// 接口请求地址
// apiBaseURL: env === 'development' ? 'http://192.168.31.151:8001' : 'http://39.108.250.202:8000',
apiBaseURL: env === 'development' ? 'http://39.108.250.202:9000' : 'http://39.108.250.202:9000',
apiBaseURL: env === 'development' ? 'http://www.occupationlab.com' : 'http://www.liuwanr.cn',
// 接口请求返回错误时,弹窗的持续时间,单位:秒
modalDuration: 3,
// 接口请求返回错误时,弹窗的类型,可选值为 Message 或 Notice
errorModalType: 'Message',
// Cookies 默认保存时间,单位:天
cookiesExpires: 1,
/**
* 免登录保存的token的key
*/
tokenKey: 'data_token',
/**
* sessionStorage里state的key
*/
@ -48,8 +52,7 @@ const Setting = {
* 布局配置
* */
layout: {
// 需要隐藏顶栏的页面路径
hideNavList: ['practice-do','practice-randomDo','setting-person','achievement-assessment','achievement-practice','exam-do','exam-detail','wrongBook-do'],
},
/**
* 功能配置

@ -1,97 +0,0 @@
/**
* 试卷管理
* */
export default {
namespaced: true,
state: {
typeList: [
{
id: 1,
name: '期中考试'
},{
id: 2,
name: '期末考试'
},{
id: 3,
name: '模拟考'
}
],
stateList: [
{
id: 0,
name: '待开始'
},{
id: 1,
name: '进行中'
},{
id: 2,
name: '已提交'
}
],
assessmentStateList: [
{
id: 1,
name: '待开始'
},{
id: 2,
name: '进行中'
},{
id: 3,
name: '已结束'
}
],
degreeList: [
{
id: 0,
label: '简单'
},{
id: 1,
label: '一般'
},{
id: 2,
label: '较难'
},{
id: 3,
label: '很难'
},
],
assessmentName: '',
testPaperId: '',
assessmentId: '',
teacherId: '',
classId: '',
paperName: '',
countdown: '',
assessmentName: ''
},
getters: {
getDegreeName: state => id => {
return id != null ? state.degreeList.find(n => n.id == id).label : ''
},
getTypeName: state => id => {
return id != null ? state.typeList.find(n => n.id == id).name : ''
},
getStateName: state => id => {
return id != null ? state.stateList.find(n => n.id == id).name : ''
},
getAssessmentStateName: state => id => {
return id != null ? state.assessmentStateList.find(n => n.id == id).name : ''
},
},
mutations: {
SET_INFO: (state, info) => {
state.assessmentName = info.assessmentName
state.assessmentId = info.assessmentId
state.teacherId = info.teacherId
state.classId = info.classId
state.testPaperId = info.testPaperId
state.countdown = info.countdown
state.assessmentName = info.assessmentName
},
},
actions: {
setInfo({ commit },info) {
commit('SET_INFO',info)
},
}
}

@ -1,9 +1,9 @@
import addRoutes from '@/libs/route/addRoutes';
import Setting from '@/setting';
import util from '@/libs/util';
import { Message } from 'element-ui';
import addRoutes from '@/libs/route/addRoutes'
import Setting from '@/setting'
import util from '@/libs/util'
import { Message } from 'element-ui'
import {post,get,del,put} from '@/plugins/requests/index.js'
import api from '@/api';
import api from '@/api'
/**
* 用户信息
@ -53,13 +53,16 @@ export default {
},
actions: {
login({ state,commit }, userInfo) {
// util.local.set('data-token','testfffff',1296000000)
const { username, password } = userInfo
return new Promise((resolve, reject) => {
get(api.logins,{ account: username.trim(), password: password }).then(res => {
if(res.success){
let user = res.data.userInfo
if(user.roleId == 4){
let routes = res.data.permissions[0].children
get(api.logins,{ account: username.trim(), password: password, source: 0 }).then(res => {
console.log(333,res)
if(res.status == 200){
let user = res.message.retvalue
console.log(user)
if(user.roleId == 1){
let routes = res.message.listValue
commit('SET_INFO',{
avatar: user.userAvatars,
userId: user.userId,
@ -70,9 +73,12 @@ export default {
clientId: user.clientId,
clientName: user.clientName,
})
if(userInfo.remember) util.local.set(Setting.tokenKey,user.token,1296000000)
Setting.dynamicRoute && addRoutes(routes)
util.session.set(Setting.usernameKey, user.userName)
util.successMsg('登录成功');
util.local.set(Setting.usernameKey, user.userName)
util.successMsg('登录成功')
resolve()
}else{
util.errorMsg('该用户没有权限')
@ -87,8 +93,9 @@ export default {
},
logout({ commit, state, dispatch }) {
return new Promise((resolve, reject) => {
util.session.remove(Setting.usernameKey);
util.session.remove(Setting.storeKey);
util.local.remove(Setting.usernameKey)
util.local.remove(Setting.storeKey)
util.local.remove(Setting.tokenKey)
location.reload()
resolve()
})

@ -1,24 +0,0 @@
/**
* 我的错题本
* */
export default {
namespaced: true,
state: {
qid: '',
type: 1
},
getters: {
},
mutations: {
SET_INFO: (state, info) => {
state.qid = info.qid
state.type = info.type
},
},
actions: {
setInfo({ commit },info) {
commit('SET_INFO',info)
},
}
}

@ -9,7 +9,7 @@ body,
}
body {
min-width: $inner-width;
min-width: 1500px;
font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif;
font-size: 14px;
background: rgba(0, 0, 0, 0.02);

Loading…
Cancel
Save