@ -0,0 +1,3 @@ |
|||||||
|
> 1% |
||||||
|
last 2 versions |
||||||
|
not ie <= 8 |
@ -0,0 +1,22 @@ |
|||||||
|
.DS_Store |
||||||
|
node_modules |
||||||
|
/dist |
||||||
|
example.html |
||||||
|
favicon.ico |
||||||
|
# local env files |
||||||
|
.env.local |
||||||
|
.env.*.local |
||||||
|
|
||||||
|
# Log files |
||||||
|
npm-debug.log* |
||||||
|
yarn-debug.log* |
||||||
|
yarn-error.log* |
||||||
|
|
||||||
|
# Editor directories and files |
||||||
|
.idea |
||||||
|
.vscode |
||||||
|
*.suo |
||||||
|
*.ntvs* |
||||||
|
*.njsproj |
||||||
|
*.sln |
||||||
|
*.sw* |
@ -0,0 +1,6 @@ |
|||||||
|
{ |
||||||
|
"tabWidth": 4, |
||||||
|
"singleQuote": true, |
||||||
|
"trailingComma": "none", |
||||||
|
"printWidth": 140 |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
MIT License |
||||||
|
|
||||||
|
Copyright (c) 2016-2019 vue-manage-system |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
SOFTWARE. |
@ -0,0 +1,197 @@ |
|||||||
|
# vue-manage-system |
||||||
|
|
||||||
|
<a href="https://github.com/vuejs/vue"> |
||||||
|
<img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue"> |
||||||
|
</a> |
||||||
|
<a href="https://github.com/ElemeFE/element"> |
||||||
|
<img src="https://img.shields.io/badge/element--ui-2.8.2-brightgreen.svg" alt="element-ui"> |
||||||
|
</a> |
||||||
|
<a href="https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE"> |
||||||
|
<img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license"> |
||||||
|
</a> |
||||||
|
<a href="https://github.com/lin-xin/vue-manage-system/releases"> |
||||||
|
<img src="https://img.shields.io/github/release/lin-xin/vue-manage-system.svg" alt="GitHub release"> |
||||||
|
</a> |
||||||
|
<a href="https://lin-xin.gitee.io/example/work/#/donate"> |
||||||
|
<img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="donate"> |
||||||
|
</a> |
||||||
|
|
||||||
|
基于 Vue + Element UI 的后台管理系统解决方案。[线上地址](https://lin-xin.gitee.io/example/work/) |
||||||
|
|
||||||
|
> React + Ant Design 的版本正在开发中,仓库地址:[react-manage-system](https://github.com/lin-xin/react-manage-system) |
||||||
|
|
||||||
|
[English document](https://github.com/lin-xin/manage-system/blob/master/README_EN.md) |
||||||
|
|
||||||
|
## 项目截图 |
||||||
|
|
||||||
|
### 登录 |
||||||
|
|
||||||
|
![Image text](https://github.com/lin-xin/manage-system/raw/master/screenshots/wms3.png) |
||||||
|
|
||||||
|
### 默认皮肤 |
||||||
|
|
||||||
|
![Image text](https://github.com/lin-xin/manage-system/raw/master/screenshots/wms1.png) |
||||||
|
|
||||||
|
### 浅绿色皮肤 |
||||||
|
|
||||||
|
![Image text](https://github.com/lin-xin/manage-system/raw/master/screenshots/wms2.png) |
||||||
|
|
||||||
|
## 赞赏 |
||||||
|
|
||||||
|
请作者喝杯咖啡吧!(微信号:linxin_20) |
||||||
|
|
||||||
|
![微信扫一扫](https://lin-xin.gitee.io/images/weixin.jpg) |
||||||
|
|
||||||
|
## 特别鸣谢 |
||||||
|
|
||||||
|
- [实验楼](https://www.shiyanlou.com?source=vue-manage-system) |
||||||
|
|
||||||
|
## 前言 |
||||||
|
|
||||||
|
该方案作为一套多功能的后台框架模板,适用于绝大部分的后台管理系统(Web Management System)开发。基于 vue.js,使用 vue-cli3 脚手架,引用 Element UI 组件库,方便开发快速简洁好看的组件。分离颜色样式,支持手动切换主题色,而且很方便使用自定义主题色。 |
||||||
|
|
||||||
|
## 功能 |
||||||
|
|
||||||
|
- [x] Element UI |
||||||
|
- [x] 登录/注销 |
||||||
|
- [x] Dashboard |
||||||
|
- [x] 表格 |
||||||
|
- [x] Tab 选项卡 |
||||||
|
- [x] 表单 |
||||||
|
- [x] 图表 :bar_chart: |
||||||
|
- [x] 富文本编辑器 |
||||||
|
- [x] markdown 编辑器 |
||||||
|
- [x] 图片拖拽/裁剪上传 |
||||||
|
- [x] 支持切换主题色 :sparkles: |
||||||
|
- [x] 列表拖拽排序 |
||||||
|
- [x] 权限测试 |
||||||
|
- [x] 404 / 403 |
||||||
|
- [x] 三级菜单 |
||||||
|
- [x] 自定义图标 |
||||||
|
- [x] 可拖拽弹窗 |
||||||
|
- [x] 国际化 |
||||||
|
|
||||||
|
## 安装步骤 |
||||||
|
|
||||||
|
``` |
||||||
|
git clone https://github.com/lin-xin/vue-manage-system.git // 把模板下载到本地 |
||||||
|
cd vue-manage-system // 进入模板目录 |
||||||
|
npm install // 安装项目依赖,等待安装完成之后,安装失败可用 cnpm 或 yarn |
||||||
|
|
||||||
|
// 开启服务器,浏览器访问 http://localhost:8080 |
||||||
|
npm run serve |
||||||
|
|
||||||
|
// 执行构建命令,生成的dist文件夹放在服务器下即可访问 |
||||||
|
npm run build |
||||||
|
``` |
||||||
|
|
||||||
|
## 组件使用说明与演示 |
||||||
|
|
||||||
|
### vue-schart |
||||||
|
|
||||||
|
vue.js 封装 sChart.js 的图表组件。访问地址:[vue-schart](https://github.com/linxin/vue-schart) |
||||||
|
|
||||||
|
<p><a href="https://www.npmjs.com/package/vue-schart"><img src="https://img.shields.io/npm/dm/vue-schart.svg" alt="Downloads"></a></p> |
||||||
|
|
||||||
|
```html |
||||||
|
<template> |
||||||
|
<div> |
||||||
|
<schart class="wrapper" canvasId="myCanvas" :options="options"></schart> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Schart from 'vue-schart'; // 导入Schart组件 |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
options: { |
||||||
|
type: 'bar', |
||||||
|
title: { |
||||||
|
text: '最近一周各品类销售图' |
||||||
|
}, |
||||||
|
labels: ['周一', '周二', '周三', '周四', '周五'], |
||||||
|
datasets: [ |
||||||
|
{ |
||||||
|
label: '家电', |
||||||
|
data: [234, 278, 270, 190, 230] |
||||||
|
}, |
||||||
|
{ |
||||||
|
label: '百货', |
||||||
|
data: [164, 178, 190, 135, 160] |
||||||
|
}, |
||||||
|
{ |
||||||
|
label: '食品', |
||||||
|
data: [144, 198, 150, 235, 120] |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
Schart |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
<style> |
||||||
|
.wrapper { |
||||||
|
width: 7rem; |
||||||
|
height: 5rem; |
||||||
|
} |
||||||
|
</style> |
||||||
|
``` |
||||||
|
|
||||||
|
## 其他注意事项 |
||||||
|
|
||||||
|
### 一、如果我不想用到上面的某些组件呢,那我怎么在模板中删除掉不影响到其他功能呢? |
||||||
|
|
||||||
|
举个栗子,我不想用 Vue-Quill-Editor 这个组件,那我需要分四步走。 |
||||||
|
|
||||||
|
第一步:删除该组件的路由,在目录 src/router/index.js 中,找到引入改组件的路由,删除下面这段代码。 |
||||||
|
|
||||||
|
```JavaScript |
||||||
|
{ |
||||||
|
// 富文本编辑器组件 |
||||||
|
path: '/editor', |
||||||
|
component: resolve => require(['../components/page/VueEditor.vue'], resolve) |
||||||
|
}, |
||||||
|
``` |
||||||
|
|
||||||
|
第二步:删除引入该组件的文件。在目录 src/components/page/ 删除 VueEditor.vue 文件。 |
||||||
|
|
||||||
|
第三步:删除该页面的入口。在目录 src/components/common/Sidebar.vue 中,找到该入口,删除下面这段代码。 |
||||||
|
|
||||||
|
```js |
||||||
|
{ |
||||||
|
index: 'editor', |
||||||
|
title: '富文本编辑器' |
||||||
|
}, |
||||||
|
``` |
||||||
|
|
||||||
|
第四步:卸载该组件。执行以下命令: |
||||||
|
npm un vue-quill-editor -S |
||||||
|
|
||||||
|
完成。 |
||||||
|
|
||||||
|
### 二、如何切换主题色呢? |
||||||
|
|
||||||
|
第一步:打开 src/main.js 文件,找到引入 element 样式的地方,换成浅绿色主题。 |
||||||
|
|
||||||
|
```javascript |
||||||
|
import 'element-ui/lib/theme-default/index.css'; // 默认主题 |
||||||
|
// import './assets/css/theme-green/index.css'; // 浅绿色主题 |
||||||
|
``` |
||||||
|
|
||||||
|
第二步:打开 src/App.vue 文件,找到 style 标签引入样式的地方,切换成浅绿色主题。 |
||||||
|
|
||||||
|
```javascript |
||||||
|
@import "./assets/css/main.css"; |
||||||
|
@import "./assets/css/color-dark.css"; /*深色主题*/ |
||||||
|
/*@import "./assets/css/theme-green/color-green.css"; !*浅绿色主题*!*/ |
||||||
|
``` |
||||||
|
|
||||||
|
第三步:打开 src/components/common/Sidebar.vue 文件,找到 el-menu 标签,把 background-color/text-color/active-text-color 属性去掉即可。 |
||||||
|
|
||||||
|
## License |
||||||
|
|
||||||
|
[MIT](https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE) |
@ -0,0 +1,196 @@ |
|||||||
|
# vue-manage-system |
||||||
|
|
||||||
|
<a href="https://github.com/vuejs/vue"> |
||||||
|
<img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue"> |
||||||
|
</a> |
||||||
|
<a href="https://github.com/ElemeFE/element"> |
||||||
|
<img src="https://img.shields.io/badge/element--ui-2.8.2-brightgreen.svg" alt="element-ui"> |
||||||
|
</a> |
||||||
|
<a href="https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE"> |
||||||
|
<img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license"> |
||||||
|
</a> |
||||||
|
<a href="https://github.com/lin-xin/vue-manage-system/releases"> |
||||||
|
<img src="https://img.shields.io/github/release/lin-xin/vue-manage-system.svg" alt="GitHub release"> |
||||||
|
</a> |
||||||
|
<a href="https://lin-xin.gitee.io/example/work/#/donate"> |
||||||
|
<img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="donate"> |
||||||
|
</a> |
||||||
|
|
||||||
|
The web management system solution based on Vue2 and Element-UI。[live demo](https://lin-xin.gitee.io/example/work/) |
||||||
|
|
||||||
|
## Donation |
||||||
|
|
||||||
|
![WeChat](https://lin-xin.gitee.io/images/weixin.jpg) |
||||||
|
|
||||||
|
## Preface |
||||||
|
|
||||||
|
The scheme as a set of multi-function background frame templates, suitable for most of the WEB management system development. Convenient development fast simple good components based on Vue2 and Element-UI. Color separation of color style, support manual switch themes, and it is convenient to use a custom theme color. |
||||||
|
|
||||||
|
## Function |
||||||
|
|
||||||
|
- [x] Element-UI |
||||||
|
- [x] Login/Logout |
||||||
|
- [x] Dashboard |
||||||
|
- [x] Table |
||||||
|
- [x] Tabs |
||||||
|
- [x] From |
||||||
|
- [x] Chart :bar_chart: |
||||||
|
- [x] Editor |
||||||
|
- [x] Markdown |
||||||
|
- [x] Upload pictures by clipping or dragging |
||||||
|
- [x] Support manual switch themes :sparkles: |
||||||
|
- [x] List drag sort |
||||||
|
- [x] Permission |
||||||
|
- [x] 404 / 403 |
||||||
|
- [x] Three level menu |
||||||
|
- [x] Custom icon |
||||||
|
|
||||||
|
## Installation steps |
||||||
|
|
||||||
|
git clone https://github.com/lin-xin/vue-manage-system.git // Clone templates |
||||||
|
cd vue-manage-system // Enter template directory |
||||||
|
npm install // Installation dependency |
||||||
|
|
||||||
|
## Local development |
||||||
|
|
||||||
|
// Open server and access http://localhost:8080 in browser |
||||||
|
npm run serve |
||||||
|
|
||||||
|
## Constructing production |
||||||
|
|
||||||
|
// Constructing project |
||||||
|
npm run build |
||||||
|
|
||||||
|
## Component description and presentation |
||||||
|
|
||||||
|
### vue-schart |
||||||
|
|
||||||
|
Vue.js wrapper for sChart.js. Github : [vue-schart](https://github.com/linxin/vue-schart) |
||||||
|
|
||||||
|
```html |
||||||
|
<template> |
||||||
|
<div> |
||||||
|
<schart class="wrapper" canvasId="myCanvas" :options="options"></schart> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Schart from 'vue-schart'; // 导入Schart组件 |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
options: { |
||||||
|
type: 'bar', |
||||||
|
title: { |
||||||
|
text: '最近一周各品类销售图' |
||||||
|
}, |
||||||
|
labels: ['周一', '周二', '周三', '周四', '周五'], |
||||||
|
datasets: [ |
||||||
|
{ |
||||||
|
label: '家电', |
||||||
|
data: [234, 278, 270, 190, 230] |
||||||
|
}, |
||||||
|
{ |
||||||
|
label: '百货', |
||||||
|
data: [164, 178, 190, 135, 160] |
||||||
|
}, |
||||||
|
{ |
||||||
|
label: '食品', |
||||||
|
data: [144, 198, 150, 235, 120] |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
Schart |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
<style> |
||||||
|
.wrapper { |
||||||
|
width: 7rem; |
||||||
|
height: 5rem; |
||||||
|
} |
||||||
|
</style> |
||||||
|
``` |
||||||
|
|
||||||
|
### element-ui |
||||||
|
|
||||||
|
A desktop component library based on vue.js2.0 . Github : [element](http://element.eleme.io/#/zh-CN/component/layout) |
||||||
|
|
||||||
|
### Vue-Quill-Editor |
||||||
|
|
||||||
|
Quill editor component for Vue2. Github : [vue-quill-editor](https://github.com/surmon-china/vue-quill-editor) |
||||||
|
|
||||||
|
### mavonEditor |
||||||
|
|
||||||
|
A markdown editor based on Vue that supports a variety of personalized features. Github: [mavonEditor](https://github.com/hinesboy/mavonEditor) |
||||||
|
|
||||||
|
### vue-cropperjs |
||||||
|
|
||||||
|
A Vue wrapper component for cropperjs. Github: [vue-cropperjs](https://github.com/Agontuk/vue-cropperjs) |
||||||
|
|
||||||
|
## Notice |
||||||
|
|
||||||
|
### 一、If I don't want to use some components, how can I delete it? |
||||||
|
|
||||||
|
For example, I don't want to use the Vue-Quill-Editor component, I need to take four steps. |
||||||
|
|
||||||
|
The first step to remove the component of the routing. Enter 'src/router/index.js' and delete the code below. |
||||||
|
|
||||||
|
```JavaScript |
||||||
|
{ |
||||||
|
path: '/editor', |
||||||
|
component: resolve => require(['../components/page/VueEditor.vue'], resolve) |
||||||
|
}, |
||||||
|
``` |
||||||
|
|
||||||
|
Second,delete the component files. Enter 'src/components/page/' and delete 'VueEditor.vue' file. |
||||||
|
|
||||||
|
The third step is to delete the entry. Enter 'src/components/common/Sidebar.vue' and delete the code below. |
||||||
|
|
||||||
|
```js |
||||||
|
{ |
||||||
|
index: 'editor', |
||||||
|
title: '富文本编辑器' |
||||||
|
}, |
||||||
|
``` |
||||||
|
|
||||||
|
Finally, uninstall this component. |
||||||
|
npm un vue-quill-editor -S |
||||||
|
|
||||||
|
Complete! |
||||||
|
|
||||||
|
### 二、How to switch themes? |
||||||
|
|
||||||
|
The first step to enter 'src/main.js' and change into green theme. |
||||||
|
|
||||||
|
```javascript |
||||||
|
import 'element-ui/lib/theme-default/index.css'; // default theme |
||||||
|
// import '../static/css/theme-green/index.css'; // green theme |
||||||
|
``` |
||||||
|
|
||||||
|
The second step to enter 'src/App.vue' and change into green theme. |
||||||
|
|
||||||
|
```javascript |
||||||
|
@import "../static/css/main.css"; |
||||||
|
@import "../static/css/color-dark.css"; /*深色主题*/ |
||||||
|
/*@import "../static/css/theme-green/color-green.css"; !*浅绿色主题*!*/ |
||||||
|
``` |
||||||
|
|
||||||
|
Finally,enter 'src/components/common/Sidebar.vue' and find el-menu Tags,delete 'background-color/text-color/active-text-color'。 |
||||||
|
|
||||||
|
## Screenshot |
||||||
|
|
||||||
|
### Default theme |
||||||
|
|
||||||
|
![Image text](https://github.com/lin-xin/manage-system/raw/master/screenshots/wms1.png) |
||||||
|
|
||||||
|
### Green theme |
||||||
|
|
||||||
|
![Image text](https://github.com/lin-xin/manage-system/raw/master/screenshots/wms2.png) |
||||||
|
|
||||||
|
## License |
||||||
|
|
||||||
|
[MIT](https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE) |
@ -0,0 +1,5 @@ |
|||||||
|
module.exports = { |
||||||
|
presets: [ |
||||||
|
'@vue/app' |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
{ |
||||||
|
"name": "vue-manage-system", |
||||||
|
"version": "4.2.0", |
||||||
|
"private": true, |
||||||
|
"scripts": { |
||||||
|
"dev": "npm run serve", |
||||||
|
"serve": "vue-cli-service serve", |
||||||
|
"build": "vue-cli-service build" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"axios": "^0.18.0", |
||||||
|
"babel-polyfill": "^6.26.0", |
||||||
|
"echarts": "^4.9.0", |
||||||
|
"element-theme": "^2.0.1", |
||||||
|
"element-ui": "^2.13.0", |
||||||
|
"js-cookie": "^2.2.1", |
||||||
|
"lodash": "^4.17.20", |
||||||
|
"mavon-editor": "^2.6.17", |
||||||
|
"postcss-px2rem": "^0.3.0", |
||||||
|
"px2rem-loader": "^0.1.9", |
||||||
|
"vue": "^2.6.10", |
||||||
|
"vue-cropperjs": "^3.0.0", |
||||||
|
"vue-i18n": "^8.10.0", |
||||||
|
"vue-quill-editor": "^3.0.6", |
||||||
|
"vue-router": "^3.0.3", |
||||||
|
"vue-schart": "^2.0.0", |
||||||
|
"vuedraggable": "^2.17.0", |
||||||
|
"vuex": "^3.1.2" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@vue/cli-plugin-babel": "^3.9.0", |
||||||
|
"@vue/cli-service": "^3.9.0", |
||||||
|
"element-theme-chalk": "^2.13.0", |
||||||
|
"node-sass": "^4.14.1", |
||||||
|
"sass-loader": "^8.0.0", |
||||||
|
"vue-template-compiler": "^2.6.10" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
module.exports = { |
||||||
|
plugins: { |
||||||
|
autoprefixer: {} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"> |
||||||
|
<link rel="stylesheet" href="//at.alicdn.com/t/font_830376_qzecyukz0s.css"> |
||||||
|
<title>电子竞技在线教学资源管理平台</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<noscript> |
||||||
|
<strong>We're sorry but vms 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> |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 112 KiB |
@ -0,0 +1,32 @@ |
|||||||
|
<template> |
||||||
|
<div id="app"> |
||||||
|
<router-view></router-view> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Setting from '@/setting'; |
||||||
|
import util from '@/libs/util'; |
||||||
|
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)))) |
||||||
|
} |
||||||
|
|
||||||
|
//在页面刷新时将vuex里的信息保存到sessionStorage里 |
||||||
|
window.addEventListener("beforeunload",()=>{ |
||||||
|
util.session.get(Setting.usernameKey) && util.session.set(Setting.storeKey,JSON.stringify(this.$store.state)) |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style> |
||||||
|
@import "./assets/css/main.css"; |
||||||
|
/* @import "./assets/css/color-dark.css"; */ |
||||||
|
/*深色主题*/ |
||||||
|
@import "./assets/css/theme-green/color-green.css"; |
||||||
|
/* 浅绿色主题 */ |
||||||
|
</style> |
@ -0,0 +1,28 @@ |
|||||||
|
.header{ |
||||||
|
background-color: #242f42; |
||||||
|
} |
||||||
|
.login-wrap{ |
||||||
|
background: #324157; |
||||||
|
} |
||||||
|
.plugins-tips{ |
||||||
|
background: #eef1f6; |
||||||
|
} |
||||||
|
.plugins-tips a{ |
||||||
|
color: #20a0ff; |
||||||
|
} |
||||||
|
.el-upload--text em { |
||||||
|
color: #20a0ff; |
||||||
|
} |
||||||
|
.pure-button{ |
||||||
|
background: #20a0ff; |
||||||
|
} |
||||||
|
.tags-li.active { |
||||||
|
border: 1px solid #409EFF; |
||||||
|
background-color: #409EFF; |
||||||
|
} |
||||||
|
.message-title{ |
||||||
|
color: #20a0ff; |
||||||
|
} |
||||||
|
.collapse-btn:hover{ |
||||||
|
background: rgb(40,52,70); |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
|
||||||
|
[class*=" icon-"], [class^=icon-] { |
||||||
|
font-family: iconfont!important; |
||||||
|
} |
@ -0,0 +1,384 @@ |
|||||||
|
* { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
html, |
||||||
|
body, |
||||||
|
#app, |
||||||
|
.wrapper { |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
body { |
||||||
|
font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif; |
||||||
|
font-size: 14px; |
||||||
|
background: #f0f0f0; |
||||||
|
} |
||||||
|
|
||||||
|
a { |
||||||
|
text-decoration: none |
||||||
|
} |
||||||
|
i{ |
||||||
|
font-style: normal; |
||||||
|
} |
||||||
|
li { |
||||||
|
list-style-type:none; |
||||||
|
} |
||||||
|
|
||||||
|
.required{ |
||||||
|
margin-right: 5px; |
||||||
|
color: #F56C6C; |
||||||
|
} |
||||||
|
.content-box { |
||||||
|
-webkit-transition: left .3s ease-in-out; |
||||||
|
transition: left .3s ease-in-out; |
||||||
|
} |
||||||
|
|
||||||
|
.content { |
||||||
|
width: auto; |
||||||
|
height: 100%; |
||||||
|
padding: 20px; |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
|
||||||
|
.content-collapse { |
||||||
|
left: 65px; |
||||||
|
} |
||||||
|
|
||||||
|
.container { |
||||||
|
padding: 30px; |
||||||
|
background: #fff; |
||||||
|
border: 1px solid #ddd; |
||||||
|
border-radius: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.crumbs { |
||||||
|
margin: 10px 0; |
||||||
|
} |
||||||
|
|
||||||
|
.el-table th { |
||||||
|
background-color: #f5f7fa !important; |
||||||
|
} |
||||||
|
|
||||||
|
.pagination { |
||||||
|
margin: 20px 0; |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
.plugins-tips { |
||||||
|
padding: 20px 10px; |
||||||
|
margin-bottom: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.el-button+.el-tooltip { |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.el-table tr:hover { |
||||||
|
background: #f6faff; |
||||||
|
} |
||||||
|
|
||||||
|
.orderTable td .el-input{ |
||||||
|
width: 60%; |
||||||
|
} |
||||||
|
|
||||||
|
.orderTable .el-select>.el-input{ |
||||||
|
display: inline-block; |
||||||
|
} |
||||||
|
|
||||||
|
.mgb20 { |
||||||
|
margin-bottom: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.move-enter-active, |
||||||
|
.move-leave-active { |
||||||
|
transition: opacity .5s; |
||||||
|
} |
||||||
|
|
||||||
|
.move-enter, |
||||||
|
.move-leave { |
||||||
|
opacity: 0; |
||||||
|
} |
||||||
|
|
||||||
|
/*BaseForm*/ |
||||||
|
|
||||||
|
.form-box { |
||||||
|
width: 600px; |
||||||
|
} |
||||||
|
|
||||||
|
.form-box .line { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.el-time-panel__content::after, |
||||||
|
.el-time-panel__content::before { |
||||||
|
margin-top: -7px; |
||||||
|
} |
||||||
|
|
||||||
|
.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) { |
||||||
|
padding-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
/*Upload*/ |
||||||
|
|
||||||
|
.pure-button { |
||||||
|
width: 150px; |
||||||
|
height: 40px; |
||||||
|
line-height: 40px; |
||||||
|
text-align: center; |
||||||
|
color: #fff; |
||||||
|
border-radius: 3px; |
||||||
|
} |
||||||
|
|
||||||
|
.g-core-image-corp-container .info-aside { |
||||||
|
height: 45px; |
||||||
|
} |
||||||
|
|
||||||
|
.avatar-uploader .el-upload--text { |
||||||
|
background-color: #fff; |
||||||
|
border: 1px dashed #d9d9d9; |
||||||
|
border-radius: 6px; |
||||||
|
box-sizing: border-box; |
||||||
|
width: 360px; |
||||||
|
height: 180px; |
||||||
|
text-align: center; |
||||||
|
cursor: pointer; |
||||||
|
position: relative; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.avatar-uploader .el-upload--text .el-icon-upload { |
||||||
|
font-size: 67px; |
||||||
|
color: #97a8be; |
||||||
|
margin: 40px 0 16px; |
||||||
|
line-height: 50px; |
||||||
|
} |
||||||
|
|
||||||
|
.avatar-uploader .el-upload--text { |
||||||
|
color: #97a8be; |
||||||
|
font-size: 14px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.avatar-uploader .el-upload--text em { |
||||||
|
font-style: normal; |
||||||
|
} |
||||||
|
|
||||||
|
/* .link_upload .el-upload-list{ |
||||||
|
width: 30%; |
||||||
|
} */ |
||||||
|
|
||||||
|
/*VueEditor*/ |
||||||
|
|
||||||
|
.ql-container { |
||||||
|
min-height: 400px; |
||||||
|
} |
||||||
|
|
||||||
|
.ql-snow .ql-tooltip { |
||||||
|
transform: translateX(117.5px) translateY(10px) !important; |
||||||
|
} |
||||||
|
|
||||||
|
.editor-btn { |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
/*markdown*/ |
||||||
|
|
||||||
|
.v-note-wrapper .v-note-panel { |
||||||
|
min-height: 500px; |
||||||
|
} |
||||||
|
|
||||||
|
.ms-login .el-tabs__nav-wrap::after{ |
||||||
|
background-color: #fff; |
||||||
|
opacity: 0; |
||||||
|
} |
||||||
|
.ms-login .el-tabs__item{ |
||||||
|
padding: 0 90px; |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
.ms-login .el-tabs__item:hover{ |
||||||
|
color: #000; |
||||||
|
} |
||||||
|
.ms-login .el-tabs__item.is-active{ |
||||||
|
color: #333; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
.ms-login .el-tabs__active-bar{ |
||||||
|
background-color: #000; |
||||||
|
border-radius:2px; |
||||||
|
} |
||||||
|
.ms-login .el-tabs__nav-scroll{ |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
|
||||||
|
.ms-login .el-input__inner{ |
||||||
|
height: 80px; |
||||||
|
line-height: 80px; |
||||||
|
border:1px solid rgba(220,220,220,1); |
||||||
|
border-radius:2px; |
||||||
|
} |
||||||
|
|
||||||
|
.el-row { |
||||||
|
margin-bottom: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.mgb20 { |
||||||
|
margin-bottom: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
#app .el-table thead{ |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
#app .el-table th{ |
||||||
|
background-color: #cb221c!important; |
||||||
|
font-size: 16px; |
||||||
|
font-weight: normal; |
||||||
|
} |
||||||
|
#app .el-select{ |
||||||
|
display: unset; |
||||||
|
} |
||||||
|
|
||||||
|
/*flex*/ |
||||||
|
.flex-center{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
.flex-between{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
} |
||||||
|
.flex-around{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-around; |
||||||
|
} |
||||||
|
.flex-start-around{ |
||||||
|
display: flex; |
||||||
|
align-items: flex-start; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
.flex-end-around{ |
||||||
|
display: flex; |
||||||
|
align-items: flex-end; |
||||||
|
justify-content: center; |
||||||
|
} |
||||||
|
.flex-column{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
.flex-start{ |
||||||
|
display: flex; |
||||||
|
align-items: flex-start; |
||||||
|
} |
||||||
|
.flex-end{ |
||||||
|
display: flex; |
||||||
|
align-items: flex-end; |
||||||
|
} |
||||||
|
.flex-justify-end{ |
||||||
|
display: flex; |
||||||
|
justify-content: flex-end; |
||||||
|
} |
||||||
|
|
||||||
|
.hr_tag{ |
||||||
|
background-color: #cb221c; |
||||||
|
width: 3px; |
||||||
|
height: 15px; |
||||||
|
margin-right: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.user_header{ |
||||||
|
padding: 20px 0; |
||||||
|
border-bottom: 1px dashed #eee; |
||||||
|
} |
||||||
|
.addhr_tag{ |
||||||
|
background-color: #666; |
||||||
|
width: 6px; |
||||||
|
height: 17px; |
||||||
|
margin-right: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.per_title span{ |
||||||
|
font-size: 16px; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
.per_back{ |
||||||
|
margin-left: 5px; |
||||||
|
} |
||||||
|
.per_school{ |
||||||
|
margin-left: 30px; |
||||||
|
} |
||||||
|
.per_title:hover{ |
||||||
|
cursor:pointer; |
||||||
|
} |
||||||
|
|
||||||
|
/* 溢出省略号 */ |
||||||
|
.ellipsis{ |
||||||
|
overflow: hidden; |
||||||
|
text-overflow: ellipsis; |
||||||
|
white-space: nowrap; |
||||||
|
} |
||||||
|
|
||||||
|
.tabs{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 20px 1.5% 20px; |
||||||
|
margin-bottom: 20px; |
||||||
|
z-index: 999; |
||||||
|
background-color: #fff; |
||||||
|
} |
||||||
|
.tabs .item{ |
||||||
|
padding: 12px 20px; |
||||||
|
margin-right: 10px; |
||||||
|
color:#606266; |
||||||
|
line-height: 1; |
||||||
|
border-radius: 4px; |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #dcdfe6; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.tabs .active{ |
||||||
|
color: #fff; |
||||||
|
background-color: #cb221c; |
||||||
|
border-color: #cb221c; |
||||||
|
} |
||||||
|
|
||||||
|
.btns{ |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
.btns button{ |
||||||
|
height: 30px; |
||||||
|
padding: 0 30px; |
||||||
|
margin: 0 15px; |
||||||
|
font-size: 14px; |
||||||
|
color: #333; |
||||||
|
line-height: 30px; |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #ededed; |
||||||
|
border-radius: 4px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.btns .submit{ |
||||||
|
color: #fff; |
||||||
|
background-color: #e80909; |
||||||
|
border-color: #e80909; |
||||||
|
} |
||||||
|
.btns button:hover{ |
||||||
|
opacity: .8; |
||||||
|
} |
||||||
|
.btns button:focus{ |
||||||
|
outline: none; |
||||||
|
} |
||||||
|
|
||||||
|
.userRadio .el-radio{ |
||||||
|
margin-right: 10px!important; |
||||||
|
} |
||||||
|
.userRadio .el-radio__input{ |
||||||
|
display: none!important; |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
.header{ |
||||||
|
background-color: #fff; |
||||||
|
} |
||||||
|
.login-wrap{ |
||||||
|
background: rgba(56, 157, 170, 0.82);; |
||||||
|
} |
||||||
|
.plugins-tips{ |
||||||
|
background: #f2f2f2; |
||||||
|
} |
||||||
|
.plugins-tips a{ |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
.el-upload--text em { |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
.pure-button{ |
||||||
|
background: #cb221c; |
||||||
|
} |
||||||
|
.pagination > .active > a, .pagination > .active > a:hover, .pagination > .active > a:focus, .pagination > .active > span, .pagination > .active > span:hover, .pagination > .active > span:focus { |
||||||
|
background-color: #cb221c !important; |
||||||
|
border-color: #cb221c !important; |
||||||
|
} |
||||||
|
.tags-li.active { |
||||||
|
border: 1px solid #cb221c; |
||||||
|
background-color: #cb221c; |
||||||
|
} |
||||||
|
.collapse-btn:hover{ |
||||||
|
background: #cb221c; |
||||||
|
} |
@ -0,0 +1,539 @@ |
|||||||
|
/* Logo 字体 */ |
||||||
|
@font-face { |
||||||
|
font-family: "iconfont logo"; |
||||||
|
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); |
||||||
|
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), |
||||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), |
||||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), |
||||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); |
||||||
|
} |
||||||
|
|
||||||
|
.logo { |
||||||
|
font-family: "iconfont logo"; |
||||||
|
font-size: 160px; |
||||||
|
font-style: normal; |
||||||
|
-webkit-font-smoothing: antialiased; |
||||||
|
-moz-osx-font-smoothing: grayscale; |
||||||
|
} |
||||||
|
|
||||||
|
/* tabs */ |
||||||
|
.nav-tabs { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.nav-tabs .nav-more { |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
bottom: 0; |
||||||
|
height: 42px; |
||||||
|
line-height: 42px; |
||||||
|
color: #666; |
||||||
|
} |
||||||
|
|
||||||
|
#tabs { |
||||||
|
border-bottom: 1px solid #eee; |
||||||
|
} |
||||||
|
|
||||||
|
#tabs li { |
||||||
|
cursor: pointer; |
||||||
|
width: 100px; |
||||||
|
height: 40px; |
||||||
|
line-height: 40px; |
||||||
|
text-align: center; |
||||||
|
font-size: 16px; |
||||||
|
border-bottom: 2px solid transparent; |
||||||
|
position: relative; |
||||||
|
z-index: 1; |
||||||
|
margin-bottom: -1px; |
||||||
|
color: #666; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
#tabs .active { |
||||||
|
border-bottom-color: #f00; |
||||||
|
color: #222; |
||||||
|
} |
||||||
|
|
||||||
|
.tab-container .content { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
/* 页面布局 */ |
||||||
|
.main { |
||||||
|
padding: 30px 100px; |
||||||
|
width: 960px; |
||||||
|
margin: 0 auto; |
||||||
|
} |
||||||
|
|
||||||
|
.main .logo { |
||||||
|
color: #333; |
||||||
|
text-align: left; |
||||||
|
margin-bottom: 30px; |
||||||
|
line-height: 1; |
||||||
|
height: 110px; |
||||||
|
margin-top: -50px; |
||||||
|
overflow: hidden; |
||||||
|
*zoom: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.main .logo a { |
||||||
|
font-size: 160px; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
.helps { |
||||||
|
margin-top: 40px; |
||||||
|
} |
||||||
|
|
||||||
|
.helps pre { |
||||||
|
padding: 20px; |
||||||
|
margin: 10px 0; |
||||||
|
border: solid 1px #e7e1cd; |
||||||
|
background-color: #fffdef; |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.icon_lists { |
||||||
|
width: 100% !important; |
||||||
|
overflow: hidden; |
||||||
|
*zoom: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.icon_lists li { |
||||||
|
width: 100px; |
||||||
|
margin-bottom: 10px; |
||||||
|
margin-right: 20px; |
||||||
|
text-align: center; |
||||||
|
list-style: none !important; |
||||||
|
cursor: default; |
||||||
|
} |
||||||
|
|
||||||
|
.icon_lists li .code-name { |
||||||
|
line-height: 1.2; |
||||||
|
} |
||||||
|
|
||||||
|
.icon_lists .icon { |
||||||
|
display: block; |
||||||
|
height: 100px; |
||||||
|
line-height: 100px; |
||||||
|
font-size: 42px; |
||||||
|
margin: 10px auto; |
||||||
|
color: #333; |
||||||
|
-webkit-transition: font-size 0.25s linear, width 0.25s linear; |
||||||
|
-moz-transition: font-size 0.25s linear, width 0.25s linear; |
||||||
|
transition: font-size 0.25s linear, width 0.25s linear; |
||||||
|
} |
||||||
|
|
||||||
|
.icon_lists .icon:hover { |
||||||
|
font-size: 100px; |
||||||
|
} |
||||||
|
|
||||||
|
.icon_lists .svg-icon { |
||||||
|
/* 通过设置 font-size 来改变图标大小 */ |
||||||
|
width: 1em; |
||||||
|
/* 图标和文字相邻时,垂直对齐 */ |
||||||
|
vertical-align: -0.15em; |
||||||
|
/* 通过设置 color 来改变 SVG 的颜色/fill */ |
||||||
|
fill: currentColor; |
||||||
|
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 |
||||||
|
normalize.css 中也包含这行 */ |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.icon_lists li .name, |
||||||
|
.icon_lists li .code-name { |
||||||
|
color: #666; |
||||||
|
} |
||||||
|
|
||||||
|
/* markdown 样式 */ |
||||||
|
.markdown { |
||||||
|
color: #666; |
||||||
|
font-size: 14px; |
||||||
|
line-height: 1.8; |
||||||
|
} |
||||||
|
|
||||||
|
.highlight { |
||||||
|
line-height: 1.5; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown img { |
||||||
|
vertical-align: middle; |
||||||
|
max-width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown h1 { |
||||||
|
color: #404040; |
||||||
|
font-weight: 500; |
||||||
|
line-height: 40px; |
||||||
|
margin-bottom: 24px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown h2, |
||||||
|
.markdown h3, |
||||||
|
.markdown h4, |
||||||
|
.markdown h5, |
||||||
|
.markdown h6 { |
||||||
|
color: #404040; |
||||||
|
margin: 1.6em 0 0.6em 0; |
||||||
|
font-weight: 500; |
||||||
|
clear: both; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown h1 { |
||||||
|
font-size: 28px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown h2 { |
||||||
|
font-size: 22px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown h3 { |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown h4 { |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown h5 { |
||||||
|
font-size: 12px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown h6 { |
||||||
|
font-size: 12px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown hr { |
||||||
|
height: 1px; |
||||||
|
border: 0; |
||||||
|
background: #e9e9e9; |
||||||
|
margin: 16px 0; |
||||||
|
clear: both; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown p { |
||||||
|
margin: 1em 0; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown>p, |
||||||
|
.markdown>blockquote, |
||||||
|
.markdown>.highlight, |
||||||
|
.markdown>ol, |
||||||
|
.markdown>ul { |
||||||
|
width: 80%; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown ul>li { |
||||||
|
list-style: circle; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown>ul li, |
||||||
|
.markdown blockquote ul>li { |
||||||
|
margin-left: 20px; |
||||||
|
padding-left: 4px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown>ul li p, |
||||||
|
.markdown>ol li p { |
||||||
|
margin: 0.6em 0; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown ol>li { |
||||||
|
list-style: decimal; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown>ol li, |
||||||
|
.markdown blockquote ol>li { |
||||||
|
margin-left: 20px; |
||||||
|
padding-left: 4px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown code { |
||||||
|
margin: 0 3px; |
||||||
|
padding: 0 5px; |
||||||
|
background: #eee; |
||||||
|
border-radius: 3px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown strong, |
||||||
|
.markdown b { |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown>table { |
||||||
|
border-collapse: collapse; |
||||||
|
border-spacing: 0px; |
||||||
|
empty-cells: show; |
||||||
|
border: 1px solid #e9e9e9; |
||||||
|
width: 95%; |
||||||
|
margin-bottom: 24px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown>table th { |
||||||
|
white-space: nowrap; |
||||||
|
color: #333; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown>table th, |
||||||
|
.markdown>table td { |
||||||
|
border: 1px solid #e9e9e9; |
||||||
|
padding: 8px 16px; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown>table th { |
||||||
|
background: #F7F7F7; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown blockquote { |
||||||
|
font-size: 90%; |
||||||
|
color: #999; |
||||||
|
border-left: 4px solid #e9e9e9; |
||||||
|
padding-left: 0.8em; |
||||||
|
margin: 1em 0; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown blockquote p { |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown .anchor { |
||||||
|
opacity: 0; |
||||||
|
transition: opacity 0.3s ease; |
||||||
|
margin-left: 8px; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown .waiting { |
||||||
|
color: #ccc; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown h1:hover .anchor, |
||||||
|
.markdown h2:hover .anchor, |
||||||
|
.markdown h3:hover .anchor, |
||||||
|
.markdown h4:hover .anchor, |
||||||
|
.markdown h5:hover .anchor, |
||||||
|
.markdown h6:hover .anchor { |
||||||
|
opacity: 1; |
||||||
|
display: inline-block; |
||||||
|
} |
||||||
|
|
||||||
|
.markdown>br, |
||||||
|
.markdown>p>br { |
||||||
|
clear: both; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
.hljs { |
||||||
|
display: block; |
||||||
|
background: white; |
||||||
|
padding: 0.5em; |
||||||
|
color: #333333; |
||||||
|
overflow-x: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.hljs-comment, |
||||||
|
.hljs-meta { |
||||||
|
color: #969896; |
||||||
|
} |
||||||
|
|
||||||
|
.hljs-string, |
||||||
|
.hljs-variable, |
||||||
|
.hljs-template-variable, |
||||||
|
.hljs-strong, |
||||||
|
.hljs-emphasis, |
||||||
|
.hljs-quote { |
||||||
|
color: #df5000; |
||||||
|
} |
||||||
|
|
||||||
|
.hljs-keyword, |
||||||
|
.hljs-selector-tag, |
||||||
|
.hljs-type { |
||||||
|
color: #a71d5d; |
||||||
|
} |
||||||
|
|
||||||
|
.hljs-literal, |
||||||
|
.hljs-symbol, |
||||||
|
.hljs-bullet, |
||||||
|
.hljs-attribute { |
||||||
|
color: #0086b3; |
||||||
|
} |
||||||
|
|
||||||
|
.hljs-section, |
||||||
|
.hljs-name { |
||||||
|
color: #63a35c; |
||||||
|
} |
||||||
|
|
||||||
|
.hljs-tag { |
||||||
|
color: #333333; |
||||||
|
} |
||||||
|
|
||||||
|
.hljs-title, |
||||||
|
.hljs-attr, |
||||||
|
.hljs-selector-id, |
||||||
|
.hljs-selector-class, |
||||||
|
.hljs-selector-attr, |
||||||
|
.hljs-selector-pseudo { |
||||||
|
color: #795da3; |
||||||
|
} |
||||||
|
|
||||||
|
.hljs-addition { |
||||||
|
color: #55a532; |
||||||
|
background-color: #eaffea; |
||||||
|
} |
||||||
|
|
||||||
|
.hljs-deletion { |
||||||
|
color: #bd2c00; |
||||||
|
background-color: #ffecec; |
||||||
|
} |
||||||
|
|
||||||
|
.hljs-link { |
||||||
|
text-decoration: underline; |
||||||
|
} |
||||||
|
|
||||||
|
/* 代码高亮 */ |
||||||
|
/* PrismJS 1.15.0 |
||||||
|
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ |
||||||
|
/** |
||||||
|
* prism.js default theme for JavaScript, CSS and HTML |
||||||
|
* Based on dabblet (http://dabblet.com) |
||||||
|
* @author Lea Verou |
||||||
|
*/ |
||||||
|
code[class*="language-"], |
||||||
|
pre[class*="language-"] { |
||||||
|
color: black; |
||||||
|
background: none; |
||||||
|
text-shadow: 0 1px white; |
||||||
|
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; |
||||||
|
text-align: left; |
||||||
|
white-space: pre; |
||||||
|
word-spacing: normal; |
||||||
|
word-break: normal; |
||||||
|
word-wrap: normal; |
||||||
|
line-height: 1.5; |
||||||
|
|
||||||
|
-moz-tab-size: 4; |
||||||
|
-o-tab-size: 4; |
||||||
|
tab-size: 4; |
||||||
|
|
||||||
|
-webkit-hyphens: none; |
||||||
|
-moz-hyphens: none; |
||||||
|
-ms-hyphens: none; |
||||||
|
hyphens: none; |
||||||
|
} |
||||||
|
|
||||||
|
pre[class*="language-"]::-moz-selection, |
||||||
|
pre[class*="language-"] ::-moz-selection, |
||||||
|
code[class*="language-"]::-moz-selection, |
||||||
|
code[class*="language-"] ::-moz-selection { |
||||||
|
text-shadow: none; |
||||||
|
background: #b3d4fc; |
||||||
|
} |
||||||
|
|
||||||
|
pre[class*="language-"]::selection, |
||||||
|
pre[class*="language-"] ::selection, |
||||||
|
code[class*="language-"]::selection, |
||||||
|
code[class*="language-"] ::selection { |
||||||
|
text-shadow: none; |
||||||
|
background: #b3d4fc; |
||||||
|
} |
||||||
|
|
||||||
|
@media print { |
||||||
|
|
||||||
|
code[class*="language-"], |
||||||
|
pre[class*="language-"] { |
||||||
|
text-shadow: none; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* Code blocks */ |
||||||
|
pre[class*="language-"] { |
||||||
|
padding: 1em; |
||||||
|
margin: .5em 0; |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
|
||||||
|
:not(pre)>code[class*="language-"], |
||||||
|
pre[class*="language-"] { |
||||||
|
background: #f5f2f0; |
||||||
|
} |
||||||
|
|
||||||
|
/* Inline code */ |
||||||
|
:not(pre)>code[class*="language-"] { |
||||||
|
padding: .1em; |
||||||
|
border-radius: .3em; |
||||||
|
white-space: normal; |
||||||
|
} |
||||||
|
|
||||||
|
.token.comment, |
||||||
|
.token.prolog, |
||||||
|
.token.doctype, |
||||||
|
.token.cdata { |
||||||
|
color: slategray; |
||||||
|
} |
||||||
|
|
||||||
|
.token.punctuation { |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
|
||||||
|
.namespace { |
||||||
|
opacity: .7; |
||||||
|
} |
||||||
|
|
||||||
|
.token.property, |
||||||
|
.token.tag, |
||||||
|
.token.boolean, |
||||||
|
.token.number, |
||||||
|
.token.constant, |
||||||
|
.token.symbol, |
||||||
|
.token.deleted { |
||||||
|
color: #905; |
||||||
|
} |
||||||
|
|
||||||
|
.token.selector, |
||||||
|
.token.attr-name, |
||||||
|
.token.string, |
||||||
|
.token.char, |
||||||
|
.token.builtin, |
||||||
|
.token.inserted { |
||||||
|
color: #690; |
||||||
|
} |
||||||
|
|
||||||
|
.token.operator, |
||||||
|
.token.entity, |
||||||
|
.token.url, |
||||||
|
.language-css .token.string, |
||||||
|
.style .token.string { |
||||||
|
color: #9a6e3a; |
||||||
|
background: hsla(0, 0%, 100%, .5); |
||||||
|
} |
||||||
|
|
||||||
|
.token.atrule, |
||||||
|
.token.attr-value, |
||||||
|
.token.keyword { |
||||||
|
color: #07a; |
||||||
|
} |
||||||
|
|
||||||
|
.token.function, |
||||||
|
.token.class-name { |
||||||
|
color: #DD4A68; |
||||||
|
} |
||||||
|
|
||||||
|
.token.regex, |
||||||
|
.token.important, |
||||||
|
.token.variable { |
||||||
|
color: #e90; |
||||||
|
} |
||||||
|
|
||||||
|
.token.important, |
||||||
|
.token.bold { |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
.token.italic { |
||||||
|
font-style: italic; |
||||||
|
} |
||||||
|
|
||||||
|
.token.entity { |
||||||
|
cursor: help; |
||||||
|
} |
@ -0,0 +1,446 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"/> |
||||||
|
<title>IconFont Demo</title> |
||||||
|
<link rel="shortcut icon" href="https://img.alicdn.com/tps/i4/TB1_oz6GVXXXXaFXpXXJDFnIXXX-64-64.ico" type="image/x-icon"/> |
||||||
|
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css"> |
||||||
|
<link rel="stylesheet" href="demo.css"> |
||||||
|
<link rel="stylesheet" href="iconfont.css"> |
||||||
|
<script src="iconfont.js"></script> |
||||||
|
<!-- jQuery --> |
||||||
|
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script> |
||||||
|
<!-- 代码高亮 --> |
||||||
|
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div class="main"> |
||||||
|
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank"></a></h1> |
||||||
|
<div class="nav-tabs"> |
||||||
|
<ul id="tabs" class="dib-box"> |
||||||
|
<li class="dib active"><span>Unicode</span></li> |
||||||
|
<li class="dib"><span>Font class</span></li> |
||||||
|
<li class="dib"><span>Symbol</span></li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=1540265" target="_blank" class="nav-more">查看项目</a> |
||||||
|
|
||||||
|
</div> |
||||||
|
<div class="tab-container"> |
||||||
|
<div class="content unicode" style="display: block;"> |
||||||
|
<ul class="icon_lists dib-box"> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">已勾选32</div> |
||||||
|
<div class="code-name">&#xe63d;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">未勾选32</div> |
||||||
|
<div class="code-name">&#xe63e;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">未勾选40</div> |
||||||
|
<div class="code-name">&#xe64a;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">已勾选40</div> |
||||||
|
<div class="code-name">&#xe64b;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">实 向右箭头-01</div> |
||||||
|
<div class="code-name">&#xe626;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">实 向下箭头-01</div> |
||||||
|
<div class="code-name">&#xe625;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">加号-填充</div> |
||||||
|
<div class="code-name">&#xe72d;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">42指向上、上箭头</div> |
||||||
|
<div class="code-name">&#xe769;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">44指向下、下箭头</div> |
||||||
|
<div class="code-name">&#xe76b;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">群蜂删除-充</div> |
||||||
|
<div class="code-name">&#xe6e9;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">qq</div> |
||||||
|
<div class="code-name">&#xe614;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont"></span> |
||||||
|
<div class="name">微信-36</div> |
||||||
|
<div class="code-name">&#xe68a;</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
</ul> |
||||||
|
<div class="article markdown"> |
||||||
|
<h2 id="unicode-">Unicode 引用</h2> |
||||||
|
<hr> |
||||||
|
|
||||||
|
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p> |
||||||
|
<ul> |
||||||
|
<li>兼容性最好,支持 IE6+,及所有现代浏览器。</li> |
||||||
|
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li> |
||||||
|
<li>但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。</li> |
||||||
|
</ul> |
||||||
|
<blockquote> |
||||||
|
<p>注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式</p> |
||||||
|
</blockquote> |
||||||
|
<p>Unicode 使用步骤如下:</p> |
||||||
|
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3> |
||||||
|
<pre><code class="language-css" |
||||||
|
>@font-face { |
||||||
|
font-family: 'iconfont'; |
||||||
|
src: url('iconfont.eot'); |
||||||
|
src: url('iconfont.eot?#iefix') format('embedded-opentype'), |
||||||
|
url('iconfont.woff2') format('woff2'), |
||||||
|
url('iconfont.woff') format('woff'), |
||||||
|
url('iconfont.ttf') format('truetype'), |
||||||
|
url('iconfont.svg#iconfont') format('svg'); |
||||||
|
} |
||||||
|
</code></pre> |
||||||
|
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3> |
||||||
|
<pre><code class="language-css" |
||||||
|
>.iconfont { |
||||||
|
font-family: "iconfont" !important; |
||||||
|
font-size: 16px; |
||||||
|
font-style: normal; |
||||||
|
-webkit-font-smoothing: antialiased; |
||||||
|
-moz-osx-font-smoothing: grayscale; |
||||||
|
} |
||||||
|
</code></pre> |
||||||
|
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3> |
||||||
|
<pre> |
||||||
|
<code class="language-html" |
||||||
|
><span class="iconfont">&#x33;</span> |
||||||
|
</code></pre> |
||||||
|
<blockquote> |
||||||
|
<p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p> |
||||||
|
</blockquote> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="content font-class"> |
||||||
|
<ul class="icon_lists dib-box"> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-yigouxuan"></span> |
||||||
|
<div class="name"> |
||||||
|
已勾选32 |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-yigouxuan |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-weigouxuan"></span> |
||||||
|
<div class="name"> |
||||||
|
未勾选32 |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-weigouxuan |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-weigouxuan1"></span> |
||||||
|
<div class="name"> |
||||||
|
未勾选40 |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-weigouxuan1 |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-yigouxuan1"></span> |
||||||
|
<div class="name"> |
||||||
|
已勾选40 |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-yigouxuan1 |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-shixiangyoujiantou-"></span> |
||||||
|
<div class="name"> |
||||||
|
实 向右箭头-01 |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-shixiangyoujiantou- |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-shixiangxiajiantou-"></span> |
||||||
|
<div class="name"> |
||||||
|
实 向下箭头-01 |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-shixiangxiajiantou- |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-jiahao"></span> |
||||||
|
<div class="name"> |
||||||
|
加号-填充 |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-jiahao |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-up"></span> |
||||||
|
<div class="name"> |
||||||
|
42指向上、上箭头 |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-up |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-down"></span> |
||||||
|
<div class="name"> |
||||||
|
44指向下、下箭头 |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-down |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-delete"></span> |
||||||
|
<div class="name"> |
||||||
|
群蜂删除-充 |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-delete |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-qq"></span> |
||||||
|
<div class="name"> |
||||||
|
qq |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-qq |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<span class="icon iconfont icon-weixin"></span> |
||||||
|
<div class="name"> |
||||||
|
微信-36 |
||||||
|
</div> |
||||||
|
<div class="code-name">.icon-weixin |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
</ul> |
||||||
|
<div class="article markdown"> |
||||||
|
<h2 id="font-class-">font-class 引用</h2> |
||||||
|
<hr> |
||||||
|
|
||||||
|
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p> |
||||||
|
<p>与 Unicode 使用方式相比,具有如下特点:</p> |
||||||
|
<ul> |
||||||
|
<li>兼容性良好,支持 IE8+,及所有现代浏览器。</li> |
||||||
|
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li> |
||||||
|
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li> |
||||||
|
<li>不过因为本质上还是使用的字体,所以多色图标还是不支持的。</li> |
||||||
|
</ul> |
||||||
|
<p>使用步骤如下:</p> |
||||||
|
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3> |
||||||
|
<pre><code class="language-html"><link rel="stylesheet" href="./iconfont.css"> |
||||||
|
</code></pre> |
||||||
|
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3> |
||||||
|
<pre><code class="language-html"><span class="iconfont icon-xxx"></span> |
||||||
|
</code></pre> |
||||||
|
<blockquote> |
||||||
|
<p>" |
||||||
|
iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p> |
||||||
|
</blockquote> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="content symbol"> |
||||||
|
<ul class="icon_lists dib-box"> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-yigouxuan"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">已勾选32</div> |
||||||
|
<div class="code-name">#icon-yigouxuan</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-weigouxuan"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">未勾选32</div> |
||||||
|
<div class="code-name">#icon-weigouxuan</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-weigouxuan1"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">未勾选40</div> |
||||||
|
<div class="code-name">#icon-weigouxuan1</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-yigouxuan1"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">已勾选40</div> |
||||||
|
<div class="code-name">#icon-yigouxuan1</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-shixiangyoujiantou-"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">实 向右箭头-01</div> |
||||||
|
<div class="code-name">#icon-shixiangyoujiantou-</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-shixiangxiajiantou-"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">实 向下箭头-01</div> |
||||||
|
<div class="code-name">#icon-shixiangxiajiantou-</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-jiahao"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">加号-填充</div> |
||||||
|
<div class="code-name">#icon-jiahao</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-up"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">42指向上、上箭头</div> |
||||||
|
<div class="code-name">#icon-up</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-down"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">44指向下、下箭头</div> |
||||||
|
<div class="code-name">#icon-down</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-delete"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">群蜂删除-充</div> |
||||||
|
<div class="code-name">#icon-delete</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-qq"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">qq</div> |
||||||
|
<div class="code-name">#icon-qq</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
<li class="dib"> |
||||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-weixin"></use> |
||||||
|
</svg> |
||||||
|
<div class="name">微信-36</div> |
||||||
|
<div class="code-name">#icon-weixin</div> |
||||||
|
</li> |
||||||
|
|
||||||
|
</ul> |
||||||
|
<div class="article markdown"> |
||||||
|
<h2 id="symbol-">Symbol 引用</h2> |
||||||
|
<hr> |
||||||
|
|
||||||
|
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a> |
||||||
|
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p> |
||||||
|
<ul> |
||||||
|
<li>支持多色图标了,不再受单色限制。</li> |
||||||
|
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li> |
||||||
|
<li>兼容性较差,支持 IE9+,及现代浏览器。</li> |
||||||
|
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li> |
||||||
|
</ul> |
||||||
|
<p>使用步骤如下:</p> |
||||||
|
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3> |
||||||
|
<pre><code class="language-html"><script src="./iconfont.js"></script> |
||||||
|
</code></pre> |
||||||
|
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3> |
||||||
|
<pre><code class="language-html"><style> |
||||||
|
.icon { |
||||||
|
width: 1em; |
||||||
|
height: 1em; |
||||||
|
vertical-align: -0.15em; |
||||||
|
fill: currentColor; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
</style> |
||||||
|
</code></pre> |
||||||
|
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3> |
||||||
|
<pre><code class="language-html"><svg class="icon" aria-hidden="true"> |
||||||
|
<use xlink:href="#icon-xxx"></use> |
||||||
|
</svg> |
||||||
|
</code></pre> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<script> |
||||||
|
$(document).ready(function () { |
||||||
|
$('.tab-container .content:first').show() |
||||||
|
|
||||||
|
$('#tabs li').click(function (e) { |
||||||
|
var tabContent = $('.tab-container .content') |
||||||
|
var index = $(this).index() |
||||||
|
|
||||||
|
if ($(this).hasClass('active')) { |
||||||
|
return |
||||||
|
} else { |
||||||
|
$('#tabs li').removeClass('active') |
||||||
|
$(this).addClass('active') |
||||||
|
|
||||||
|
tabContent.hide().eq(index).fadeIn() |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
</script> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,71 @@ |
|||||||
|
@font-face {font-family: "iconfont"; |
||||||
|
src: url('iconfont.eot?t=1589437921018'); /* IE9 */ |
||||||
|
src: url('iconfont.eot?t=1589437921018#iefix') format('embedded-opentype'), /* IE6-IE8 */ |
||||||
|
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAdgAAsAAAAADwwAAAcTAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCESgqOeIt2ATYCJAM0CxwABCAFhG0HgTMbpQxRlHBSFNlX2JThXqSJ4cz0aLyxzNkVgYOP2N97wQhUeQbPDZA1QByDeHha+9+5M7PrD1FpdI8mCSqJLulDJPFDxCQTvUQS6Qtka3ukU0/kuK8wfBBwMr1kmeTIb8hUohVh6lTeCHDCrRPPf5v6f+sQfS+QqgmpiZLNw+ZI6zMXZGL3nXY47elJFnjALaE4zjzyjJN773yuzM/7H4oZ9NV+v/q1g1ddvP1QmE5JlPRM7uAv5klMk0vWTBWTLpoJEUIja6hWSkNhOklN/ds4n0BvhyLMuZ6hKdArLC1Q4a4iG0Gfi1JaHEMbXtfsW8S8SpsepzuAJ+HLx28hoSepMmvby3e6LdC2EN2eV0ykW36MR/MlQFiJjGNAEej7WvtLgB6aM6evXtwH1glnTloW1snRYnBhky+LxyuL9glaGNmaDbRsJYR1tl+seImrgUGtEtLc//GMeo1WR9QYfUSrp7nohWgXDRrJBqpBcoAqkGagAGkBSiADQBlkEKiAbAI/N/mCYHoWi1HDEgWoBbGjlg7M/OpbgEMgnUf0fxab8kjK0tvq8cZ6/dpKwk4bNsXFx4bHR4RHcty4LVnR4xp/2TFxDN42tgefhUpEMeeqppXCU50JyT/gkVCD+EiEgl56LOkMN+6cAfyKs3dvomHU7fvnq96Uc/duIXMMqWmhNRoax1m8jNWfPorp2jlqumvHrolfe/2TcuIPCt3K589dhUNiT5OSEh4KoM9Jp1vK2GMnFjDdyaeFMrd06ki1gn9CmEz3OErpebmp+GzyAN+lMLw6dwkKh6Ve5dOnzp4W0+Y25TTfhHB10isXpxIB5GHDKcggnof+NCpCD+okAFyTPNGuRVgahmhLjZo1rnqnMlpD0ORJSluuY6jT+gPWHtaIeDKOaoradNDPruOQzulPGcBtz0C2YdbLrSFPIMGTrcNRDGC3YnJOm1JLceYK2sCWY5lqxICXIEU0gki2nkPFUteBwoqLMyTdKE7ZlOzE3yHfdSyOU2shl8RoxPJlx1bQ6C0Li3DLg+Sdi+c5evEkhtF3rBdfXpe0IiNcfW27+x6u5U4vs8zZZdu1R7Gblyc6AV9OB4Xp65HRDqcvw0Pi1DGbddntOKzYgkbhXJq+Y4bRVqszl746KdRPFV5FxSUb6XmKomd1yCb0nJbpz+aOIZskx0phXx8sHfNKyRjPsM8LGU/xJ9Qrv2JugdVBkBg/ZpUIDvpN0jfHD550XPKNDgkKEZ46l4dwq0sOxIecJlX2pxxA8GTwkCGMFqxVFf5PRZplCky9uCIQL/s/RFabTYZNkhtkQXFR28vKXwKUP5rZbFg+s3VAFTu5dBZG4G07t5tHuM2cFirh2BisrHKYoE8lzO1h/LkwjSD+VZF0qs1hQVK+d0xHOLN80q4B/P9utxQDmGt4DaEKE6Lc5lnI6VxDf/35owQHCAuKw95VG6l1bvXPY3J1slpepPBXdCx8EM+ubbd2tV48b2UtWLtYb89PZhvg2jsq5+zkBdIVVTFHfhEwNv0CxNiT02LKVxGSus1dt9VsXDZulogOJB1AkGQVg4e833uzaWatx7bPrLKyhBeBqlC3xGqNoe3MVQHmDmBs4jm+xFjW/sjcAgOiPOFawwe3bUeTa20vGNZgbV6tCtL/qEL/fmiFLjqCCDpZdQpkdKgx6tSuzlCdqnrMFsLMhWn9sKH4ezmjmvpp9Selw9oCS0Vtcbox4f967yYpc1lNwUzPAUT3N0R32yz0bof5Wblw2jzkuw4VkWFptzoKckHRUwszvHJS8IgkAfys2IvKr/LtZBa1LzvfHBmFD6/V9enLD7LLJD2tz7n3E8BkFcwVyA/DL8P0fCpXAdLntBfy9tQCpuUP2QBAWkwyYccYGYFWWc/HS8Of6pVNf1r8p8n48bn+wPLzm5gyWoneAh3ivzATiiRKljoz8hQTN3S0itSojpnbgvjFod7uBf2Rtsa7dej63gKVRdenkDS2Q9baZyzWY1AZnIBa6yT0juo9eLCWhhOlwxFrCYRVjkKywhfIVrlrLNa3UNngB9RWBQe9mxF1zMGBUFCnRoyUWLBpCStm1SU5sRRFFSeI7HUYtawUeswQzaNk4PKSsmJBL3ERbY4dPD65glIJS5rqxD3kYsThULFbU23ETEuslLobSkuluh1LzKoTkLM0hBH1A1pgJku2CjOVizQ+hUrPP4GQeTkYaS0tarYzCI2HMnusXImyHsZe3dWrxb1U9/CRVaBMggS79TUqJ6yHSSAcdq4Kc9evZUOYUSWsI7LdGpQy7Ul99ZL1qfObT4CedX+zSJGjRBV1NNFGF30MMcYsVugeKLLqDXiNLuQnSQjRvRwtrRzlsSoBxeiSl1SvLVQoF1FcZj0Jqi46odWosl43b1H9Lp2FOAgl7OKibs6cgOICAA==') format('woff2'), |
||||||
|
url('iconfont.woff?t=1589437921018') format('woff'), |
||||||
|
url('iconfont.ttf?t=1589437921018') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ |
||||||
|
url('iconfont.svg?t=1589437921018#iconfont') format('svg'); /* iOS 4.1- */ |
||||||
|
} |
||||||
|
|
||||||
|
.iconfont { |
||||||
|
font-family: "iconfont" !important; |
||||||
|
font-size: 16px; |
||||||
|
font-style: normal; |
||||||
|
-webkit-font-smoothing: antialiased; |
||||||
|
-moz-osx-font-smoothing: grayscale; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-yigouxuan:before { |
||||||
|
content: "\e63d"; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-weigouxuan:before { |
||||||
|
content: "\e63e"; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-weigouxuan1:before { |
||||||
|
content: "\e64a"; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-yigouxuan1:before { |
||||||
|
content: "\e64b"; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-shixiangyoujiantou-:before { |
||||||
|
content: "\e626"; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-shixiangxiajiantou-:before { |
||||||
|
content: "\e625"; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-jiahao:before { |
||||||
|
content: "\e72d"; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-up:before { |
||||||
|
content: "\e769"; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-down:before { |
||||||
|
content: "\e76b"; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-delete:before { |
||||||
|
content: "\e6e9"; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-qq:before { |
||||||
|
content: "\e614"; |
||||||
|
font-size: 60px; |
||||||
|
color: #22aaf8; |
||||||
|
margin-left: 32px; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-weixin:before { |
||||||
|
content: "\e68a"; |
||||||
|
font-size: 60px; |
||||||
|
color: #10b747; |
||||||
|
margin-right: 32px; |
||||||
|
} |
||||||
|
|
@ -0,0 +1,93 @@ |
|||||||
|
{ |
||||||
|
"id": "1540265", |
||||||
|
"name": "education", |
||||||
|
"font_family": "iconfont", |
||||||
|
"css_prefix_text": "icon-", |
||||||
|
"description": "", |
||||||
|
"glyphs": [ |
||||||
|
{ |
||||||
|
"icon_id": "2716513", |
||||||
|
"name": "已勾选32", |
||||||
|
"font_class": "yigouxuan", |
||||||
|
"unicode": "e63d", |
||||||
|
"unicode_decimal": 58941 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"icon_id": "2716516", |
||||||
|
"name": "未勾选32", |
||||||
|
"font_class": "weigouxuan", |
||||||
|
"unicode": "e63e", |
||||||
|
"unicode_decimal": 58942 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"icon_id": "2892929", |
||||||
|
"name": "未勾选40", |
||||||
|
"font_class": "weigouxuan1", |
||||||
|
"unicode": "e64a", |
||||||
|
"unicode_decimal": 58954 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"icon_id": "2892954", |
||||||
|
"name": "已勾选40", |
||||||
|
"font_class": "yigouxuan1", |
||||||
|
"unicode": "e64b", |
||||||
|
"unicode_decimal": 58955 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"icon_id": "5979965", |
||||||
|
"name": "实 向右箭头-01", |
||||||
|
"font_class": "shixiangyoujiantou-", |
||||||
|
"unicode": "e626", |
||||||
|
"unicode_decimal": 58918 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"icon_id": "5979966", |
||||||
|
"name": "实 向下箭头-01", |
||||||
|
"font_class": "shixiangxiajiantou-", |
||||||
|
"unicode": "e625", |
||||||
|
"unicode_decimal": 58917 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"icon_id": "8349103", |
||||||
|
"name": "加号-填充", |
||||||
|
"font_class": "jiahao", |
||||||
|
"unicode": "e72d", |
||||||
|
"unicode_decimal": 59181 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"icon_id": "6129078", |
||||||
|
"name": "42指向上、上箭头", |
||||||
|
"font_class": "up", |
||||||
|
"unicode": "e769", |
||||||
|
"unicode_decimal": 59241 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"icon_id": "6129081", |
||||||
|
"name": "44指向下、下箭头", |
||||||
|
"font_class": "down", |
||||||
|
"unicode": "e76b", |
||||||
|
"unicode_decimal": 59243 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"icon_id": "410692", |
||||||
|
"name": "群蜂删除-充", |
||||||
|
"font_class": "delete", |
||||||
|
"unicode": "e6e9", |
||||||
|
"unicode_decimal": 59113 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"icon_id": "468193", |
||||||
|
"name": "qq", |
||||||
|
"font_class": "qq", |
||||||
|
"unicode": "e614", |
||||||
|
"unicode_decimal": 58900 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"icon_id": "7009153", |
||||||
|
"name": "微信-36", |
||||||
|
"font_class": "weixin", |
||||||
|
"unicode": "e68a", |
||||||
|
"unicode_decimal": 59018 |
||||||
|
} |
||||||
|
] |
||||||
|
} |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 875 B |
After Width: | Height: | Size: 918 B |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 829 B |
After Width: | Height: | Size: 683 B |
After Width: | Height: | Size: 1.0 MiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 1.5 MiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 2.0 MiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 659 B |
@ -0,0 +1,159 @@ |
|||||||
|
<template> |
||||||
|
<div class="box"> |
||||||
|
<div class="left"> |
||||||
|
<div class="title">基本信息</div> |
||||||
|
<div class="info"> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">考试名称:</p> |
||||||
|
<p class="val">期末考</p> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">开始时间:</p> |
||||||
|
<p class="val">2020.10.12</p> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">总分:</p> |
||||||
|
<p class="val">100分</p> |
||||||
|
</div> |
||||||
|
<div class="items"> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">最高分:</p> |
||||||
|
<p class="val">期末考</p> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">应考人数:</p> |
||||||
|
<p class="val">10人</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="items"> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">最低分:</p> |
||||||
|
<p class="val">期末考</p> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">实考人数:</p> |
||||||
|
<p class="val">10人</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">平均分:</p> |
||||||
|
<p class="val">20分</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="right"> |
||||||
|
<div class="title">成绩分布图</div> |
||||||
|
<div class="info"> |
||||||
|
<div class="chart" id="chart"></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import mixins from '@/mixins/setBackground'; |
||||||
|
import echarts from 'echarts' |
||||||
|
export default { |
||||||
|
mixins: [ mixins ], |
||||||
|
data() { |
||||||
|
return { |
||||||
|
|
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
this.getChart() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
this.$get(`${this.api.getCourse}/${this.id}`) |
||||||
|
.then(res => { |
||||||
|
let data = res.data.course |
||||||
|
this.name = data.name |
||||||
|
this.classificationId = data.classificationId |
||||||
|
this.description = data.description |
||||||
|
this.coverUrl = data.coverUrl |
||||||
|
this.uploadList.push({ |
||||||
|
name: 'cover.jpg', |
||||||
|
url: this.coverUrl |
||||||
|
}) |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
getChart(){ |
||||||
|
let myChart = echarts.init(document.getElementById('chart')) |
||||||
|
myChart.setOption({ |
||||||
|
title: { text: '成绩分布图' }, |
||||||
|
tooltip: {}, |
||||||
|
xAxis: { |
||||||
|
type: 'category', |
||||||
|
boundaryGap: false, |
||||||
|
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] |
||||||
|
}, |
||||||
|
yAxis: { |
||||||
|
type: 'value' |
||||||
|
}, |
||||||
|
series: [{ |
||||||
|
data: [820, 932, 901, 934, 1290, 1330, 1320], |
||||||
|
type: 'line', |
||||||
|
areaStyle: {} |
||||||
|
}] |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.box{ |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
width: 90%; |
||||||
|
margin: 0 auto; |
||||||
|
.title{ |
||||||
|
padding-left: 5px; |
||||||
|
border-left: 5px solid #cb221c; |
||||||
|
margin: 20px 0 40px; |
||||||
|
line-height: 1; |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
.left,.right{ |
||||||
|
width: 48%; |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
.info{ |
||||||
|
height: 450px; |
||||||
|
padding: 30px 30px; |
||||||
|
background-color: #efefef; |
||||||
|
box-sizing: border-box; |
||||||
|
.item,.items{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin: 20px 0; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
.key{ |
||||||
|
color: #333; |
||||||
|
font-weight: bold; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
.val{ |
||||||
|
font-size: #757575; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
.items{ |
||||||
|
.item{ |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
.item:first-child{ |
||||||
|
margin-right: 20px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.chart{ |
||||||
|
height: 400px; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,264 @@ |
|||||||
|
<template> |
||||||
|
<div class="box"> |
||||||
|
<h1 class="title">期中测评</h1> |
||||||
|
<div class="metas"> |
||||||
|
<div> |
||||||
|
<span class="name">学生姓名:</span> |
||||||
|
<span class="val">张裕</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<span class="name">学生得分:</span> |
||||||
|
<span class="val">112</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<span class="name">试卷总分:</span> |
||||||
|
<span class="val">212</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<span class="name">练习时长:</span> |
||||||
|
<span class="val">60min</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="wrap"> |
||||||
|
<div class="select"> |
||||||
|
<el-radio v-model="look" label="1">查看全部</el-radio> |
||||||
|
<el-radio v-model="look" label="2">只看错题</el-radio> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="item"> |
||||||
|
<div class="status">简答题:待阅</div> |
||||||
|
<p class="name">1、测试测试测试测试测试测试测试</p> |
||||||
|
<div class="answer"> |
||||||
|
<p class="key">学生答案:</p> |
||||||
|
<p class="val">测试测试测试测试测试测试测试</p> |
||||||
|
</div> |
||||||
|
<div class="meta"> |
||||||
|
<span class="key">知识点:</span> |
||||||
|
<span class="val">测试测试</span> |
||||||
|
</div> |
||||||
|
<div class="meta"> |
||||||
|
<span class="key">答案解析:</span> |
||||||
|
<span class="val">测试测试</span> |
||||||
|
</div> |
||||||
|
<div class="meta"> |
||||||
|
<span class="key">考试得分:</span> |
||||||
|
<div class="val"> |
||||||
|
<input type="text"> 分 |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="item"> |
||||||
|
<div class="status done">客观题:已阅</div> |
||||||
|
<p class="name">1、测试测试测试测试测试测试测试</p> |
||||||
|
<div class="answer"> |
||||||
|
<p class="key">学生答案:</p> |
||||||
|
<p class="val">测试测试测试测试测试测试测试</p> |
||||||
|
</div> |
||||||
|
<div class="meta"> |
||||||
|
<span class="key">知识点:</span> |
||||||
|
<span class="val">测试测试</span> |
||||||
|
</div> |
||||||
|
<div class="meta"> |
||||||
|
<span class="key">答案解析:</span> |
||||||
|
<span class="val">测试测试</span> |
||||||
|
</div> |
||||||
|
<div class="meta"> |
||||||
|
<span class="key">考试得分:</span> |
||||||
|
<div class="val"> |
||||||
|
<input type="text"> 分 |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="btns"> |
||||||
|
<button type="button" class="submit">提交</button> |
||||||
|
<button type="button">保存</button> |
||||||
|
<button type="button">返回</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import mixins from '@/mixins/setBackground'; |
||||||
|
export default { |
||||||
|
mixins: [ mixins ], |
||||||
|
data() { |
||||||
|
return { |
||||||
|
schoolId: this.$store.state.schoolId, |
||||||
|
id: '', |
||||||
|
look: '1', |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
isDetail: Boolean(this.$route.query.show), |
||||||
|
userId: this.$store.state.userLoginId, |
||||||
|
username: this.$store.state.name, |
||||||
|
classificationId: '', |
||||||
|
coverUrl: '', |
||||||
|
name: '', |
||||||
|
classificationList: [], |
||||||
|
uploadList: [], |
||||||
|
description: '', |
||||||
|
selectVisible: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.id = this.$route.query.id |
||||||
|
this.id && this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
save() { |
||||||
|
if(!this.name) return this.$message.warning('请填写课程名称') |
||||||
|
if(!this.classificationId) return this.$message.warning('请选择课程分类') |
||||||
|
if(!this.coverUrl) return this.$message.warning('请上传课程封面') |
||||||
|
|
||||||
|
let data = { |
||||||
|
id: this.id, |
||||||
|
classificationId: this.classificationId, |
||||||
|
coverUrl: this.coverUrl, |
||||||
|
description: this.description, |
||||||
|
name: this.name, |
||||||
|
founderId: this.userId, |
||||||
|
schoolId: this.schoolId, |
||||||
|
founderName: this.username |
||||||
|
} |
||||||
|
if(this.id){ |
||||||
|
this.$put(this.api.editCourse, data).then(res => { |
||||||
|
this.$message.success('修改成功'); |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
}else{ |
||||||
|
this.$post(this.api.addCourse, data).then(res => { |
||||||
|
this.$message.success('创建成功'); |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
getData() { |
||||||
|
this.$get(`${this.api.getCourse}/${this.id}`) |
||||||
|
.then(res => { |
||||||
|
let data = res.data.course |
||||||
|
this.name = data.name |
||||||
|
this.classificationId = data.classificationId |
||||||
|
this.description = data.description |
||||||
|
this.coverUrl = data.coverUrl |
||||||
|
this.uploadList.push({ |
||||||
|
name: 'cover.jpg', |
||||||
|
url: this.coverUrl |
||||||
|
}) |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
goback() { |
||||||
|
if(this.isDetail){ |
||||||
|
this.$router.back() |
||||||
|
}else{ |
||||||
|
this.$confirm('确定返回?未更新的信息将不会保存。', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.title{ |
||||||
|
text-align: center; |
||||||
|
font-size: 18px; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
.metas{ |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
margin: 20px 0 30px; |
||||||
|
.name{ |
||||||
|
font-size: 12px; |
||||||
|
color: #717171; |
||||||
|
} |
||||||
|
.val{ |
||||||
|
font-size: 12px; |
||||||
|
color: #929292; |
||||||
|
} |
||||||
|
} |
||||||
|
.wrap{ |
||||||
|
padding: 20px; |
||||||
|
background-color: #fbfbfb; |
||||||
|
|
||||||
|
.select{ |
||||||
|
padding: 10px; |
||||||
|
margin-bottom: 20px; |
||||||
|
border-bottom: 1px solid #f4f4f4; |
||||||
|
} |
||||||
|
|
||||||
|
.item{ |
||||||
|
padding-bottom: 30px; |
||||||
|
margin-bottom: 30px; |
||||||
|
border-bottom: 1px dashed #f4f4f4; |
||||||
|
|
||||||
|
.status{ |
||||||
|
color: #cb221c; |
||||||
|
&.done{ |
||||||
|
color: #56d5bf; |
||||||
|
} |
||||||
|
} |
||||||
|
.name{ |
||||||
|
margin-top: 15px; |
||||||
|
font-size: 14px; |
||||||
|
color: #555555; |
||||||
|
} |
||||||
|
.key{ |
||||||
|
font-weight: bold; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
.val{ |
||||||
|
color: #757575; |
||||||
|
} |
||||||
|
.answer{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 15px; |
||||||
|
margin: 15px 0; |
||||||
|
font-size: 12px; |
||||||
|
border: 1px solid #e8e8e8; |
||||||
|
background-color: #f3f2f2; |
||||||
|
} |
||||||
|
.meta{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding-left: 10px; |
||||||
|
margin: 10px 0; |
||||||
|
font-size: 12px; |
||||||
|
.key{ |
||||||
|
width: 70px; |
||||||
|
margin-right: 10px; |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
input{ |
||||||
|
width: 60px; |
||||||
|
height: 28px; |
||||||
|
padding: 0 5px; |
||||||
|
margin-right: 5px; |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #ebebeb; |
||||||
|
box-sizing: border-box; |
||||||
|
&:focus{ |
||||||
|
outline: none; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,72 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div class="message" @click="showMessage"> |
||||||
|
<img src="../../assets/img/message.png"> |
||||||
|
留言板 |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-dialog title="留言内容" :visible.sync="messageVisible" width="30%" @close="closeMessage" :close-on-click-modal="false" :modal-append-to-body="false" :modal="true"> |
||||||
|
<div class="message-wrap"> |
||||||
|
<div class="people">张三提问于2020-12-11</div> |
||||||
|
<el-input type="textarea" rows="3"></el-input> |
||||||
|
<div class="btn-wrap"> |
||||||
|
<el-button type="primary" size="small">回复</el-button> |
||||||
|
<el-button type="error" size="small">删除</el-button> |
||||||
|
</div> |
||||||
|
<!-- <quill :border="true" :height="100"></quill> --> |
||||||
|
<el-input type="textarea" rows="3"></el-input> |
||||||
|
</div> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="messageVisible = false" size="small">取消</el-button> |
||||||
|
<el-button type="primary" size="small">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import Setting from '@/setting'; |
||||||
|
import quill from '@/components/quill'; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
messageVisible: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: {quill}, |
||||||
|
methods: { |
||||||
|
closeMessage(){ |
||||||
|
|
||||||
|
}, |
||||||
|
showMessage(){ |
||||||
|
this.messageVisible = true |
||||||
|
} |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
.message{ |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
margin-right: 20px; |
||||||
|
color: #666; |
||||||
|
font-size: 12px; |
||||||
|
cursor: pointer; |
||||||
|
&:hover{ |
||||||
|
opacity: .8; |
||||||
|
} |
||||||
|
img{ |
||||||
|
margin-right: 5px; |
||||||
|
} |
||||||
|
} |
||||||
|
.message-wrap{ |
||||||
|
.people{ |
||||||
|
margin-bottom: 10px; |
||||||
|
font-size: 12px; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
.btn-wrap{ |
||||||
|
margin: 10px 0; |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,173 @@ |
|||||||
|
<template> |
||||||
|
<div class="quill" :class="classes"> |
||||||
|
<div ref="editor" :style="styles" v-loading="loading"></div> |
||||||
|
|
||||||
|
<el-upload :action="this.api.fileupload" :before-upload="beforeUpload" :on-success="editorUploadSuccess" style="display: none"> |
||||||
|
<el-button class="editorUpload" size="small" type="primary">点击上传</el-button> |
||||||
|
</el-upload> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Quill from 'quill'; |
||||||
|
import 'quill/dist/quill.core.css'; |
||||||
|
import 'quill/dist/quill.snow.css'; |
||||||
|
import 'quill/dist/quill.bubble.css'; |
||||||
|
import toolbarOptions from './options' |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'quill', |
||||||
|
props: { |
||||||
|
value: { |
||||||
|
type: String, |
||||||
|
default: '' |
||||||
|
}, |
||||||
|
readonly: { |
||||||
|
type: Boolean, |
||||||
|
default: false |
||||||
|
}, |
||||||
|
border: { |
||||||
|
type: Boolean, |
||||||
|
default: false |
||||||
|
}, |
||||||
|
height: { |
||||||
|
type: Number |
||||||
|
}, |
||||||
|
minHeight: { |
||||||
|
type: Number |
||||||
|
} |
||||||
|
}, |
||||||
|
data () { |
||||||
|
return { |
||||||
|
Quill: null, |
||||||
|
currentValue: '', |
||||||
|
options: { |
||||||
|
theme: 'snow', |
||||||
|
bounds: document.body, |
||||||
|
debug: 'warn', |
||||||
|
modules: { |
||||||
|
toolbar: { |
||||||
|
container: toolbarOptions, |
||||||
|
handlers: { |
||||||
|
'image': function (value) { |
||||||
|
if (value) { |
||||||
|
// 调用iview图片上传 |
||||||
|
document.querySelector('.editorUpload').click() |
||||||
|
} else { |
||||||
|
this.Quill.format('image', false); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
placeholder: '', |
||||||
|
readOnly: this.readonly |
||||||
|
}, |
||||||
|
loading: false |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
classes () { |
||||||
|
return [ |
||||||
|
{ |
||||||
|
'quill-no-border': !this.border |
||||||
|
} |
||||||
|
]; |
||||||
|
}, |
||||||
|
styles () { |
||||||
|
let style = {}; |
||||||
|
if (this.minHeight) { |
||||||
|
style.minHeight = `${this.minHeight}px`; |
||||||
|
} |
||||||
|
if (this.height) { |
||||||
|
style.height = `${this.height}px`; |
||||||
|
} |
||||||
|
return style; |
||||||
|
} |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
value: { |
||||||
|
handler (val) { |
||||||
|
if (val !== this.currentValue) { |
||||||
|
this.currentValue = val; |
||||||
|
if (this.Quill) { |
||||||
|
this.Quill.pasteHTML(this.value); |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
immediate: true |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted () { |
||||||
|
this.init(); |
||||||
|
}, |
||||||
|
beforeDestroy () { |
||||||
|
// 在组件销毁后销毁实例 |
||||||
|
this.Quill = null; |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
init () { |
||||||
|
const editor = this.$refs.editor; |
||||||
|
// 初始化编辑器 |
||||||
|
this.Quill = new Quill(editor, this.options); |
||||||
|
// 默认值 |
||||||
|
this.Quill.pasteHTML(this.currentValue); |
||||||
|
this.$nextTick(() => { |
||||||
|
window.scrollTo(0,0) |
||||||
|
}) |
||||||
|
// 绑定事件 |
||||||
|
this.Quill.on('text-change', (delta, oldDelta, source) => { |
||||||
|
const html = this.$refs.editor.children[0].innerHTML; |
||||||
|
const text = this.Quill.getText(); |
||||||
|
const quill = this.Quill; |
||||||
|
// 更新内部的值 |
||||||
|
this.currentValue = html; |
||||||
|
// 发出事件 v-model |
||||||
|
this.$emit('input', html); |
||||||
|
// 发出事件 |
||||||
|
this.$emit('on-change', { html, text, quill }); |
||||||
|
}); |
||||||
|
// 将一些 quill 自带的事件传递出去 |
||||||
|
this.Quill.on('text-change', (delta, oldDelta, source) => { |
||||||
|
this.$emit('on-text-change', delta, oldDelta, source); |
||||||
|
}); |
||||||
|
this.Quill.on('selection-change', (range, oldRange, source) => { |
||||||
|
this.$emit('on-selection-change', range, oldRange, source); |
||||||
|
}); |
||||||
|
this.Quill.on('editor-change', (eventName, ...args) => { |
||||||
|
this.$emit('on-editor-change', eventName, ...args); |
||||||
|
}); |
||||||
|
}, |
||||||
|
beforeUpload(file){ |
||||||
|
this.loading = true |
||||||
|
}, |
||||||
|
editorUploadSuccess (res) { |
||||||
|
// 获取富文本组件实例 |
||||||
|
let quill = this.Quill |
||||||
|
// 如果上传成功 |
||||||
|
if (res.data.filesResult.fileUrl) { |
||||||
|
// 获取光标所在位置 |
||||||
|
let length = quill.getSelection().index; |
||||||
|
// 插入图片,res为服务器返回的图片链接地址 |
||||||
|
quill.insertEmbed(length, 'image', res.data.filesResult.fileUrl) |
||||||
|
// 调整光标到最后 |
||||||
|
quill.setSelection(length + 1) |
||||||
|
} else { |
||||||
|
this.$message.success('图片插入失败') |
||||||
|
} |
||||||
|
this.loading = false |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
.quill-no-border{ |
||||||
|
.ql-toolbar.ql-snow{ |
||||||
|
border: none; |
||||||
|
border-bottom: 1px solid #e8eaec; |
||||||
|
} |
||||||
|
.ql-container.ql-snow{ |
||||||
|
border: none; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,16 @@ |
|||||||
|
export default [ |
||||||
|
['bold', 'italic', 'underline', 'strike'], |
||||||
|
['blockquote', 'code-block'], |
||||||
|
[{ 'header': 1 }, { 'header': 2 }], |
||||||
|
[{ 'list': 'ordered' }, { 'list': 'bullet' }], |
||||||
|
[{ 'script': 'sub' }, { 'script': 'super' }], |
||||||
|
[{ 'indent': '-1' }, { 'indent': '+1' }], |
||||||
|
[{ 'direction': 'rtl' }], |
||||||
|
[{ 'size': ['small', false, 'large', 'huge'] }], |
||||||
|
[{ 'header': [1, 2, 3, 4, 5, 6, false] }], |
||||||
|
[{ 'color': [] }, { 'background': [] }], |
||||||
|
[{ 'font': [] }], |
||||||
|
[{ 'align': [] }], |
||||||
|
['clean'], |
||||||
|
['link', 'image', 'video'] |
||||||
|
] |
@ -0,0 +1,254 @@ |
|||||||
|
<template> |
||||||
|
<div class="box"> |
||||||
|
<h1 class="title">期中测评</h1> |
||||||
|
<div class="metas"> |
||||||
|
<div style="margin-right: 20px;"> |
||||||
|
<span class="name">总分:</span> |
||||||
|
<span class="val">100分</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<span class="name">考试时长:</span> |
||||||
|
<span class="val">2分钟</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<ul class="tab"> |
||||||
|
<li v-for="(item,index) in tabs" :key="index" :class="{active: active == item.id}" @click="tabChange(item.id)">{{item.name}}</li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
<div class="wrap"> |
||||||
|
<div class="item" v-for="(item,index) in curType" :key="index"> |
||||||
|
<div class="answer"> |
||||||
|
<div class="info"> |
||||||
|
<p class="key">序号:</p> |
||||||
|
<p class="val">{{index+1}}</p> |
||||||
|
</div> |
||||||
|
<div class="info" v-if="item.point"> |
||||||
|
<p class="key">得分:</p> |
||||||
|
<p class="val">{{item.point}}</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="meta"> |
||||||
|
<p class="key">题干:</p> |
||||||
|
<p class="val" v-html="item.questionStem"></p> |
||||||
|
</div> |
||||||
|
<div class="meta"> |
||||||
|
<p class="key">选项:</p> |
||||||
|
<div class="val"> |
||||||
|
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{option[i]}}</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="meta ans"> |
||||||
|
<div class="info"> |
||||||
|
<p class="key">正确答案:</p> |
||||||
|
<p class="val">{{item.answer}}</p> |
||||||
|
</div> |
||||||
|
<div class="info" v-if="item.studentAnswer"> |
||||||
|
<p class="key">学生答案:</p> |
||||||
|
<p class="val">{{item.studentAnswer}}</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="meta"> |
||||||
|
<p class="key">答案解析:</p> |
||||||
|
<p class="val" v-html="item.answerAnalysis"></p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import mixins from '@/mixins/setBackground'; |
||||||
|
export default { |
||||||
|
mixins: [ mixins ], |
||||||
|
data() { |
||||||
|
return { |
||||||
|
id: this.$route.query.id, |
||||||
|
selectVisible: false, |
||||||
|
tabs: [ |
||||||
|
{ |
||||||
|
id: 1, |
||||||
|
name: '单选题' |
||||||
|
},{ |
||||||
|
id: 2, |
||||||
|
name: '多选题' |
||||||
|
},{ |
||||||
|
id: 3, |
||||||
|
name: '填空题' |
||||||
|
},{ |
||||||
|
id: 4, |
||||||
|
name: '判断题' |
||||||
|
},{ |
||||||
|
id: 5, |
||||||
|
name: '简答题' |
||||||
|
} |
||||||
|
], |
||||||
|
active: 1, |
||||||
|
curType: [] |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
this.$post(`${this.api.previewtestPaper}?id=${1}`) |
||||||
|
.then(res => { |
||||||
|
this.allData = res.data |
||||||
|
this.curType = this.allData.list1 |
||||||
|
this.handleOptions() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
tabChange(id){ |
||||||
|
this.active = id |
||||||
|
this.curType = this.allData[`list${id}`] |
||||||
|
this.handleOptions() |
||||||
|
}, |
||||||
|
handleOptions(){ |
||||||
|
let curType = this.curType |
||||||
|
curType.forEach(n => { |
||||||
|
if(!n.options){ |
||||||
|
let options = {} |
||||||
|
for(let i in n){ |
||||||
|
if(i.includes('option') && n[i]){ |
||||||
|
console.log(i.replace('option','')) |
||||||
|
options[i.replace('option','')] = { |
||||||
|
[i.replace('option','')]: n[i] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
n.options = options |
||||||
|
} |
||||||
|
}) |
||||||
|
this.curType = curType |
||||||
|
console.log(22,this.curType) |
||||||
|
} |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.box{ |
||||||
|
width: 90%; |
||||||
|
margin: 0 auto; |
||||||
|
} |
||||||
|
.title{ |
||||||
|
text-align: center; |
||||||
|
font-size: 18px; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
.metas{ |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
margin: 20px 0 30px; |
||||||
|
.name{ |
||||||
|
font-size: 12px; |
||||||
|
color: #717171; |
||||||
|
} |
||||||
|
.val{ |
||||||
|
font-size: 12px; |
||||||
|
color: #929292; |
||||||
|
} |
||||||
|
} |
||||||
|
.tab{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 10px; |
||||||
|
li{ |
||||||
|
position: relative; |
||||||
|
padding: 0 44px; |
||||||
|
margin-right: 7px; |
||||||
|
font-size: 13px; |
||||||
|
line-height: 46px; |
||||||
|
text-align: center; |
||||||
|
color: #444; |
||||||
|
border: 1px solid #ececec; |
||||||
|
cursor: pointer; |
||||||
|
&:hover{ |
||||||
|
opacity: .8; |
||||||
|
} |
||||||
|
&.active:after{ |
||||||
|
content: ''; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
width: 100%; |
||||||
|
height: 4px; |
||||||
|
background-color: #e80909; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.wrap{ |
||||||
|
.item{ |
||||||
|
padding-bottom: 30px; |
||||||
|
margin-bottom: 30px; |
||||||
|
border-bottom: 1px dashed #f4f4f4; |
||||||
|
|
||||||
|
.key{ |
||||||
|
font-weight: bold; |
||||||
|
color: #333; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
.val{ |
||||||
|
color: #757575; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
.answer{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 15px; |
||||||
|
margin: 15px 0; |
||||||
|
font-size: 12px; |
||||||
|
border: 1px solid #e8e8e8; |
||||||
|
background-color: #f3f2f2; |
||||||
|
.info{ |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
margin-right: 30px; |
||||||
|
} |
||||||
|
} |
||||||
|
.meta{ |
||||||
|
padding-left: 10px; |
||||||
|
margin: 20px 0; |
||||||
|
font-size: 12px; |
||||||
|
&.ans{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
.info{ |
||||||
|
margin-right: 20px; |
||||||
|
} |
||||||
|
} |
||||||
|
.key{ |
||||||
|
margin-bottom: 5px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.btns{ |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
margin-top: 20px; |
||||||
|
button{ |
||||||
|
height: 30px; |
||||||
|
padding: 0 30px; |
||||||
|
margin: 0 15px; |
||||||
|
font-size: 14px; |
||||||
|
color: #333; |
||||||
|
line-height: 30px; |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #ededed; |
||||||
|
border-radius: 4px; |
||||||
|
cursor: pointer; |
||||||
|
&.submit{ |
||||||
|
color: #fff; |
||||||
|
background-color: #e80909; |
||||||
|
border-color: #e80909; |
||||||
|
} |
||||||
|
&:hover{ |
||||||
|
opacity: .8; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,30 @@ |
|||||||
|
export const messages = { |
||||||
|
'zh': { |
||||||
|
i18n: { |
||||||
|
breadcrumb: '国际化产品', |
||||||
|
tips: '通过切换语言按钮,来改变当前内容的语言。', |
||||||
|
btn: '切换英文', |
||||||
|
title1: '常用用法', |
||||||
|
p1: '要是你把你的秘密告诉了风,那就别怪风把它带给树。', |
||||||
|
p2: '没有什么比信念更能支撑我们度过艰难的时光了。', |
||||||
|
p3: '只要能把自己的事做好,并让自己快乐,你就领先于大多数人了。', |
||||||
|
title2: '组件插值', |
||||||
|
info: 'Element组件需要国际化,请参考 {action}。', |
||||||
|
value: '文档' |
||||||
|
} |
||||||
|
}, |
||||||
|
'en': { |
||||||
|
i18n: { |
||||||
|
breadcrumb: 'International Products', |
||||||
|
tips: 'Click on the button to change the current language. ', |
||||||
|
btn: 'Switch Chinese', |
||||||
|
title1: 'Common usage', |
||||||
|
p1: "If you reveal your secrets to the wind you should not blame the wind for revealing them to the trees.", |
||||||
|
p2: "Nothing can help us endure dark times better than our faith. ", |
||||||
|
p3: "If you can do what you do best and be happy, you're further along in life than most people.", |
||||||
|
title2: 'Component interpolation', |
||||||
|
info: 'The default language of Element is Chinese. If you wish to use another language, please refer to the {action}.', |
||||||
|
value: 'documentation' |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,152 @@ |
|||||||
|
<template> |
||||||
|
<div class="header flex-between"> |
||||||
|
<div v-if="showBack" class="goBack" v-throttle @click="back"><i class="el-icon-arrow-left"></i>返回</div> |
||||||
|
<div v-else class="logo"> |
||||||
|
<img src="../../assets/img/logo-fill.png"> |
||||||
|
</div> |
||||||
|
<div class="header-right"> |
||||||
|
<div class="header-user-con"> |
||||||
|
<message-board></message-board> |
||||||
|
<div class="user" @click="toPerson"> |
||||||
|
<el-avatar :size="40" :src="circleUrl"></el-avatar> |
||||||
|
<span class="user-avator">{{username}}</span> |
||||||
|
</div> |
||||||
|
<el-divider class="ml20" direction="vertical"></el-divider> |
||||||
|
<el-button type="text" class="ml20" @click="loginout">退出</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import bus from '@/libs/bus'; |
||||||
|
import Setting from '@/setting'; |
||||||
|
import messageBoard from '@/components/messageBoard'; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
collapse: false, |
||||||
|
fullscreen: false, |
||||||
|
name: 'huoran', |
||||||
|
message: 2, |
||||||
|
circleUrl: "https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png", |
||||||
|
showBackList: Setting.layout.hideNavList, |
||||||
|
messageVisible: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: {messageBoard}, |
||||||
|
computed: { |
||||||
|
username() { |
||||||
|
let username = sessionStorage.getItem(Setting.usernameKey); |
||||||
|
return username ? username : this.name; |
||||||
|
}, |
||||||
|
showBack(){ |
||||||
|
let route = this.$route.name |
||||||
|
if(this.showBackList.includes(route)) return true |
||||||
|
return false |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
toPerson(){ |
||||||
|
this.$router.push('/setting/person') |
||||||
|
}, |
||||||
|
loginout() { |
||||||
|
sessionStorage.removeItem(Setting.usernameKey); |
||||||
|
sessionStorage.removeItem(Setting.storeKey); |
||||||
|
location.reload() |
||||||
|
}, |
||||||
|
back(){ |
||||||
|
this.$router.back() |
||||||
|
}, |
||||||
|
closeMessage(){ |
||||||
|
|
||||||
|
}, |
||||||
|
showMessage(){ |
||||||
|
this.messageVisible = true |
||||||
|
} |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
.goBack{ |
||||||
|
cursor: pointer; |
||||||
|
line-height: 60px; |
||||||
|
height: 60px; |
||||||
|
font-size: 16px; |
||||||
|
font-weight: bold; |
||||||
|
margin-left: 20px; |
||||||
|
} |
||||||
|
.goBack i{ |
||||||
|
color: #cb221c; |
||||||
|
font-size: 20px; |
||||||
|
} |
||||||
|
.header { |
||||||
|
position: relative; |
||||||
|
box-sizing: border-box; |
||||||
|
width: 100%; |
||||||
|
height: 60px; |
||||||
|
font-size: 16px; |
||||||
|
color: #333; |
||||||
|
border-bottom: 1px solid #efefef; |
||||||
|
box-shadow: 0 0 1.5625rem 0.125rem rgba(255, 45, 45, 0.14); |
||||||
|
} |
||||||
|
.header .logo { |
||||||
|
float: left; |
||||||
|
width: 170px; |
||||||
|
height: 40px; |
||||||
|
margin-left: 20px; |
||||||
|
} |
||||||
|
.header .logo img{ |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
.header-right { |
||||||
|
float: right; |
||||||
|
padding-right: 50px; |
||||||
|
} |
||||||
|
.header-user-con { |
||||||
|
display: flex; |
||||||
|
height: 70px; |
||||||
|
align-items: center; |
||||||
|
|
||||||
|
.user{ |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
.user-avator { |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
.ml20{ |
||||||
|
margin-left: 20px; |
||||||
|
} |
||||||
|
.user-avator img { |
||||||
|
display: block; |
||||||
|
width: 40px; |
||||||
|
height: 40px; |
||||||
|
border-radius: 50%; |
||||||
|
} |
||||||
|
.header-right .el-button--text{ |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
.header-right .el-divider--vertical{ |
||||||
|
width: 2px; |
||||||
|
height: 15px; |
||||||
|
} |
||||||
|
.header-right .el-divider{ |
||||||
|
background-color: #333; |
||||||
|
} |
||||||
|
.message{ |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
margin-right: 20px; |
||||||
|
color: #666; |
||||||
|
font-size: 12px; |
||||||
|
cursor: pointer; |
||||||
|
&:hover{ |
||||||
|
opacity: .8; |
||||||
|
} |
||||||
|
img{ |
||||||
|
margin-right: 5px; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,78 @@ |
|||||||
|
<template> |
||||||
|
<div class="wrapper"> |
||||||
|
<div class="placeholder" :class="{mini: !hideNavbar}"></div> |
||||||
|
<div class="fixed"> |
||||||
|
<v-head></v-head> |
||||||
|
<v-navbar v-show="hideNavbar"></v-navbar> |
||||||
|
</div> |
||||||
|
<div class="content-box" :class="{'content-collapse':collapse}"> |
||||||
|
<!-- <v-tags></v-tags> --> |
||||||
|
<div class="content"> |
||||||
|
<transition name="move" mode="out-in"> |
||||||
|
<keep-alive :include="tagsList"> |
||||||
|
<router-view></router-view> |
||||||
|
</keep-alive> |
||||||
|
</transition> |
||||||
|
<el-backtop target=".content"></el-backtop> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import vHead from '../header/index.vue'; |
||||||
|
import vNavbar from '../navbar/index.vue'; |
||||||
|
import vTags from '../tags/index.vue'; |
||||||
|
import bus from '@/libs/bus'; |
||||||
|
import Setting from '@/setting'; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
tagsList: [], |
||||||
|
collapse: false, |
||||||
|
hideNavList: Setting.layout.hideNavList |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
vHead, |
||||||
|
vNavbar, |
||||||
|
vTags |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
hideNavbar() { |
||||||
|
let route = this.$route.name |
||||||
|
if(this.hideNavList.includes(route)) return false |
||||||
|
return true |
||||||
|
} |
||||||
|
}, |
||||||
|
created() { |
||||||
|
bus.$on('collapse-content', msg => { |
||||||
|
this.collapse = msg; |
||||||
|
}); |
||||||
|
|
||||||
|
// 只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。 |
||||||
|
bus.$on('tags', msg => { |
||||||
|
let arr = []; |
||||||
|
for (let i = 0, len = msg.length; i < len; i++) { |
||||||
|
msg[i].name && arr.push(msg[i].name); |
||||||
|
} |
||||||
|
this.tagsList = arr; |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
.fixed{ |
||||||
|
z-index: 10; |
||||||
|
position: fixed; |
||||||
|
top: 0; |
||||||
|
width: 100%; |
||||||
|
background-color: #fff; |
||||||
|
} |
||||||
|
.placeholder{ |
||||||
|
height: 120px; |
||||||
|
&.mini{ |
||||||
|
height: 60px; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,136 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
|
||||||
|
<el-menu |
||||||
|
class="sidebar-el-menu" |
||||||
|
:default-active="onRoutes" |
||||||
|
:collapse="collapse" |
||||||
|
background-color="#324157" |
||||||
|
text-color="#bfcbd9" |
||||||
|
active-text-color="#cb221c" |
||||||
|
unique-opened |
||||||
|
mode="horizontal" |
||||||
|
router |
||||||
|
> |
||||||
|
<template v-for="item in menus"> |
||||||
|
<template v-if="item.subs"> |
||||||
|
<el-submenu :index="item.index" :key="item.index"> |
||||||
|
<template slot="title"> |
||||||
|
<i :class="item.icon"></i> |
||||||
|
<span slot="title">{{ item.title }}</span> |
||||||
|
</template> |
||||||
|
<template v-for="subItem in item.subs"> |
||||||
|
<el-submenu |
||||||
|
v-if="subItem.subs" |
||||||
|
:index="subItem.index" |
||||||
|
:key="subItem.index" |
||||||
|
> |
||||||
|
<template slot="title">{{ subItem.title }}</template> |
||||||
|
<el-menu-item |
||||||
|
v-for="(threeItem,i) in subItem.subs" |
||||||
|
:key="i" |
||||||
|
:index="threeItem.index" |
||||||
|
>{{ threeItem.title }}</el-menu-item> |
||||||
|
</el-submenu> |
||||||
|
<el-menu-item |
||||||
|
v-else |
||||||
|
:index="subItem.index" |
||||||
|
:key="subItem.index" |
||||||
|
>{{ subItem.title }}</el-menu-item> |
||||||
|
</template> |
||||||
|
</el-submenu> |
||||||
|
</template> |
||||||
|
<template v-else> |
||||||
|
<el-menu-item :index="item.index" :key="item.index"> |
||||||
|
<i :class="item.icon"></i> |
||||||
|
<span slot="title">{{ item.title }}</span> |
||||||
|
</el-menu-item> |
||||||
|
</template> |
||||||
|
</template> |
||||||
|
</el-menu> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import bus from '@/libs/bus'; |
||||||
|
import Setting from '@/setting'; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
collapse: false, |
||||||
|
defaultMenus: [ |
||||||
|
{ |
||||||
|
icon: 'el-icon-monitor', |
||||||
|
index: '/index/list', |
||||||
|
title: '学生管理' |
||||||
|
}, |
||||||
|
{ |
||||||
|
icon: 'el-icon-news', |
||||||
|
index: '/quesBank/list', |
||||||
|
title: '题库管理' |
||||||
|
}, |
||||||
|
{ |
||||||
|
icon: 'el-icon-user', |
||||||
|
index: '/testPaper/list', |
||||||
|
title: '试卷管理' |
||||||
|
}, |
||||||
|
{ |
||||||
|
icon: 'el-icon-user', |
||||||
|
index: '/assessment/list', |
||||||
|
title: '考核管理' |
||||||
|
}, |
||||||
|
{ |
||||||
|
icon: 'el-icon-user', |
||||||
|
index: '/achievement/list', |
||||||
|
title: '成绩管理' |
||||||
|
}, |
||||||
|
{ |
||||||
|
icon: 'el-icon-takeaway-box', |
||||||
|
index: '/system/list', |
||||||
|
title: '系统设置' |
||||||
|
} |
||||||
|
], |
||||||
|
menus: [] |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
onRoutes() { |
||||||
|
return this.$route.path |
||||||
|
} |
||||||
|
}, |
||||||
|
created() { |
||||||
|
this.initMenu() |
||||||
|
// 通过 Event Bus 进行组件间通信,来折叠侧边栏 |
||||||
|
bus.$on('collapse', msg => { |
||||||
|
this.collapse = msg; |
||||||
|
bus.$emit('collapse-content', msg); |
||||||
|
}); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
initMenu(){ |
||||||
|
if(Setting.dynamicRoute){ |
||||||
|
let routes = this.$store.state.routes[1].children |
||||||
|
let menus = [] |
||||||
|
this.defaultMenus.map(e => { |
||||||
|
routes.find(n => n.path == e.index) && menus.push(e) |
||||||
|
}) |
||||||
|
this.menus = menus |
||||||
|
}else{ |
||||||
|
this.menus = this.defaultMenus |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.sidebar::-webkit-scrollbar { |
||||||
|
width: 0; |
||||||
|
} |
||||||
|
.sidebar-el-menu:not(.el-menu--collapse) { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
.sidebar > ul { |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,186 @@ |
|||||||
|
<template> |
||||||
|
<div class="tags" v-if="showTags"> |
||||||
|
<ul> |
||||||
|
<li class="tags-li" v-for="(item,index) in tagsList" :class="{'active': isActive(item.path)}" :key="index"> |
||||||
|
<router-link :to="item.path" class="tags-li-title"> |
||||||
|
{{item.title}} |
||||||
|
</router-link> |
||||||
|
<span class="tags-li-icon" @click="closeTags(index)"><i class="el-icon-close"></i></span> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
<div class="tags-close-box"> |
||||||
|
<el-dropdown @command="handleTags"> |
||||||
|
<el-button size="mini" type="primary"> |
||||||
|
标签选项<i class="el-icon-arrow-down el-icon--right"></i> |
||||||
|
</el-button> |
||||||
|
<el-dropdown-menu size="small" slot="dropdown"> |
||||||
|
<el-dropdown-item command="other">关闭其他</el-dropdown-item> |
||||||
|
<el-dropdown-item command="all">关闭所有</el-dropdown-item> |
||||||
|
</el-dropdown-menu> |
||||||
|
</el-dropdown> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import bus from '@/libs/bus'; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
tagsList: [] |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
isActive(path) { |
||||||
|
return path === this.$route.fullPath; |
||||||
|
}, |
||||||
|
// 关闭单个标签 |
||||||
|
closeTags(index) { |
||||||
|
const delItem = this.tagsList.splice(index, 1)[0]; |
||||||
|
const item = this.tagsList[index] ? this.tagsList[index] : this.tagsList[index - 1]; |
||||||
|
if (item) { |
||||||
|
delItem.path === this.$route.fullPath && this.$router.push(item.path); |
||||||
|
}else{ |
||||||
|
this.$router.push('/dashboard'); |
||||||
|
} |
||||||
|
}, |
||||||
|
// 关闭全部标签 |
||||||
|
closeAll(){ |
||||||
|
this.tagsList = []; |
||||||
|
this.$router.push('/dashboard'); |
||||||
|
}, |
||||||
|
// 关闭其他标签 |
||||||
|
closeOther(){ |
||||||
|
const curItem = this.tagsList.filter(item => { |
||||||
|
return item.path === this.$route.fullPath; |
||||||
|
}) |
||||||
|
this.tagsList = curItem; |
||||||
|
}, |
||||||
|
// 设置标签 |
||||||
|
setTags(route){ |
||||||
|
const isExist = this.tagsList.some(item => { |
||||||
|
return item.path === route.fullPath; |
||||||
|
}) |
||||||
|
if(!isExist){ |
||||||
|
if(this.tagsList.length >= 8){ |
||||||
|
this.tagsList.shift(); |
||||||
|
} |
||||||
|
this.tagsList.push({ |
||||||
|
title: route.meta.title, |
||||||
|
path: route.fullPath, |
||||||
|
name: route.matched[1].components.default.name |
||||||
|
}) |
||||||
|
} |
||||||
|
bus.$emit('tags', this.tagsList); |
||||||
|
}, |
||||||
|
handleTags(command){ |
||||||
|
command === 'other' ? this.closeOther() : this.closeAll(); |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
showTags() { |
||||||
|
return this.tagsList.length > 0; |
||||||
|
} |
||||||
|
}, |
||||||
|
watch:{ |
||||||
|
$route(newValue, oldValue){ |
||||||
|
this.setTags(newValue); |
||||||
|
} |
||||||
|
}, |
||||||
|
created(){ |
||||||
|
this.setTags(this.$route); |
||||||
|
// 监听关闭当前页面的标签页 |
||||||
|
bus.$on('close_current_tags', () => { |
||||||
|
for (let i = 0, len = this.tagsList.length; i < len; i++) { |
||||||
|
const item = this.tagsList[i]; |
||||||
|
if(item.path === this.$route.fullPath){ |
||||||
|
if(i < len - 1){ |
||||||
|
this.$router.push(this.tagsList[i+1].path); |
||||||
|
}else if(i > 0){ |
||||||
|
this.$router.push(this.tagsList[i-1].path); |
||||||
|
}else{ |
||||||
|
this.$router.push('/'); |
||||||
|
} |
||||||
|
this.tagsList.splice(i, 1); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
</script> |
||||||
|
|
||||||
|
|
||||||
|
<style> |
||||||
|
.tags { |
||||||
|
position: relative; |
||||||
|
height: 30px; |
||||||
|
overflow: hidden; |
||||||
|
background: #fff; |
||||||
|
padding-right: 120px; |
||||||
|
box-shadow: 0 5px 10px #ddd; |
||||||
|
} |
||||||
|
|
||||||
|
.tags ul { |
||||||
|
box-sizing: border-box; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.tags-li { |
||||||
|
float: left; |
||||||
|
margin: 3px 5px 2px 3px; |
||||||
|
border-radius: 3px; |
||||||
|
font-size: 12px; |
||||||
|
overflow: hidden; |
||||||
|
cursor: pointer; |
||||||
|
height: 23px; |
||||||
|
line-height: 23px; |
||||||
|
border: 1px solid #e9eaec; |
||||||
|
background: #fff; |
||||||
|
padding: 0 5px 0 12px; |
||||||
|
vertical-align: middle; |
||||||
|
color: #666; |
||||||
|
-webkit-transition: all .3s ease-in; |
||||||
|
-moz-transition: all .3s ease-in; |
||||||
|
transition: all .3s ease-in; |
||||||
|
} |
||||||
|
|
||||||
|
.tags-li:not(.active):hover { |
||||||
|
background: #f8f8f8; |
||||||
|
} |
||||||
|
|
||||||
|
.tags-li.active { |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.tags-li-title { |
||||||
|
float: left; |
||||||
|
max-width: 80px; |
||||||
|
overflow: hidden; |
||||||
|
white-space: nowrap; |
||||||
|
text-overflow: ellipsis; |
||||||
|
margin-right: 5px; |
||||||
|
color: #666; |
||||||
|
} |
||||||
|
|
||||||
|
.tags-li.active .tags-li-title { |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
.tags-close-box { |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
top: 0; |
||||||
|
box-sizing: border-box; |
||||||
|
padding-top: 1px; |
||||||
|
text-align: center; |
||||||
|
width: 110px; |
||||||
|
height: 30px; |
||||||
|
background: #fff; |
||||||
|
box-shadow: -3px 0 15px 3px rgba(0, 0, 0, .1); |
||||||
|
z-index: 10; |
||||||
|
} |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,26 @@ |
|||||||
|
/** |
||||||
|
* @description 生成按钮级别权限组 |
||||||
|
* */ |
||||||
|
|
||||||
|
import store from '@/store'; |
||||||
|
export default function(data){ |
||||||
|
let result = [] |
||||||
|
data.map(e => { |
||||||
|
if(e.select){ |
||||||
|
e.children.map(n => { |
||||||
|
if(n.select){ |
||||||
|
if(n.children.length){ |
||||||
|
result.push(`${e.name}:${n.name}`) |
||||||
|
n.children.map(j => { |
||||||
|
j.select && (e.component ? result.push(`${e.component}:${n.name}:${j.name}`) : result.push(`${n.component}:${j.name}`)) |
||||||
|
}) |
||||||
|
}else{ |
||||||
|
result.push(`${e.component}:${n.name}`) |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
}) |
||||||
|
store.commit('addBtnPerData',{btnPermissions: result}) |
||||||
|
// console.log('geneBtn:',result)
|
||||||
|
} |
@ -0,0 +1,6 @@ |
|||||||
|
import Vue from 'vue'; |
||||||
|
|
||||||
|
// 使用 Event Bus
|
||||||
|
const bus = new Vue(); |
||||||
|
|
||||||
|
export default bus; |
@ -0,0 +1,10 @@ |
|||||||
|
// 生成随机字符串
|
||||||
|
export default function (len = 32) { |
||||||
|
const $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; |
||||||
|
const maxPos = $chars.length; |
||||||
|
let str = ''; |
||||||
|
for (let i = 0; i < len; i++) { |
||||||
|
str += $chars.charAt(Math.floor(Math.random() * maxPos)); |
||||||
|
} |
||||||
|
return str; |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
// rem等比适配配置文件
|
||||||
|
// 基准大小
|
||||||
|
const baseSize = 16 |
||||||
|
// 设置 rem 函数
|
||||||
|
function setRem () { |
||||||
|
// 当前页面宽度相对于 1920宽的缩放比例,可根据自己需要修改。
|
||||||
|
const scale = document.documentElement.clientWidth / 1920 |
||||||
|
// 设置页面根节点字体大小(“Math.min(scale, 2)” 指最高放大比例为2,可根据实际业务需求调整)
|
||||||
|
document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px' |
||||||
|
} |
||||||
|
// 初始化
|
||||||
|
setRem() |
||||||
|
// 改变窗口大小时重新设置 rem
|
||||||
|
window.onresize = function () { |
||||||
|
setRem() |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
import store from '@/store'; |
||||||
|
import router from '@/router'; |
||||||
|
import generateBtnPermission from '../auth/generateBtnPermission'; |
||||||
|
|
||||||
|
const newRoutes = [] |
||||||
|
|
||||||
|
function createMeta(item){ |
||||||
|
let meta = { title: item.name } |
||||||
|
return meta |
||||||
|
} |
||||||
|
|
||||||
|
function createRoute(data){ |
||||||
|
data.map(e => { |
||||||
|
if(e.select && e.component){ |
||||||
|
let meta = createMeta(e) |
||||||
|
newRoutes.push({ |
||||||
|
name: e.component, |
||||||
|
path: e.component, |
||||||
|
component: () => import(`@/pages/${e.component}.vue`), |
||||||
|
meta |
||||||
|
}) |
||||||
|
} |
||||||
|
e.children && e.children.length && createRoute(e.children) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
export default function(data,path){ |
||||||
|
generateBtnPermission(data) |
||||||
|
createRoute(data) |
||||||
|
let routes = router.options.routes |
||||||
|
routes[1].children = [...routes[1].children,...newRoutes] |
||||||
|
store.commit("addRoutesData", { routes }) |
||||||
|
router.addRoutes(routes) |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
import store from '@/store'; |
||||||
|
import router from '@/router'; |
||||||
|
|
||||||
|
export default function(){ |
||||||
|
setTimeout(() => { |
||||||
|
let routes = store.state.routes |
||||||
|
routes.forEach(e => { |
||||||
|
if(e.path == '/'){ |
||||||
|
e.component = () => import('@/layouts/home/index.vue') |
||||||
|
}else{ |
||||||
|
e.component = () => import(`@/pages/${e.path}.vue`) |
||||||
|
} |
||||||
|
|
||||||
|
e.children && e.children.forEach(n => { |
||||||
|
n.path && (n.component = () => import(`@/pages/${n.path}.vue`)) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
routes.push({ |
||||||
|
path: '*', |
||||||
|
redirect: '404' |
||||||
|
}) |
||||||
|
|
||||||
|
router.addRoutes(routes) |
||||||
|
},500) |
||||||
|
} |
@ -0,0 +1,6 @@ |
|||||||
|
import router from '@/router'; |
||||||
|
|
||||||
|
export default function(){ |
||||||
|
const newRouter = createRouter() |
||||||
|
router.matcher = newRouter.matcher |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
import Cookies from 'js-cookie'; |
||||||
|
import Setting from '@/setting'; |
||||||
|
|
||||||
|
const cookies = {}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @description 存储 cookie 值 |
||||||
|
* @param {String} name cookie name |
||||||
|
* @param {String} value cookie value |
||||||
|
* @param {Object} cookieSetting cookie setting |
||||||
|
*/ |
||||||
|
cookies.set = function (name = 'default', value = '', cookieSetting = {}) { |
||||||
|
let currentCookieSetting = { |
||||||
|
expires: Setting.cookiesExpires |
||||||
|
}; |
||||||
|
Object.assign(currentCookieSetting, cookieSetting); |
||||||
|
Cookies.set(`admin-${name}`, value, currentCookieSetting); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @description 拿到 cookie 值 |
||||||
|
* @param {String} name cookie name |
||||||
|
*/ |
||||||
|
cookies.get = function (name = 'default') { |
||||||
|
return Cookies.get(`admin-${name}`); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @description 拿到 cookie 全部的值 |
||||||
|
*/ |
||||||
|
cookies.getAll = function () { |
||||||
|
return Cookies.get(); |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* @description 删除 cookie |
||||||
|
* @param {String} name cookie name |
||||||
|
*/ |
||||||
|
cookies.remove = function (name = 'default') { |
||||||
|
return Cookies.remove(`admin-${name}`); |
||||||
|
}; |
||||||
|
|
||||||
|
export default cookies; |
@ -0,0 +1,82 @@ |
|||||||
|
/** |
||||||
|
* localStorage |
||||||
|
* @调用:_local.set('access_token', '123456', 5000); |
||||||
|
* @调用:_local.get('access_token'); |
||||||
|
*/ |
||||||
|
|
||||||
|
var _local = { |
||||||
|
//存储,可设置过期时间
|
||||||
|
set(key, value, expires) { |
||||||
|
let params = { key, value, expires }; |
||||||
|
if (expires) { |
||||||
|
// 记录何时将值存入缓存,毫秒级
|
||||||
|
var data = Object.assign(params, { startTime: new Date().getTime() }); |
||||||
|
localStorage.setItem(key, JSON.stringify(data)); |
||||||
|
} else { |
||||||
|
if (Object.prototype.toString.call(value) == '[object Object]') { |
||||||
|
value = JSON.stringify(value); |
||||||
|
} |
||||||
|
if (Object.prototype.toString.call(value) == '[object Array]') { |
||||||
|
value = JSON.stringify(value); |
||||||
|
} |
||||||
|
localStorage.setItem(key, value); |
||||||
|
} |
||||||
|
}, |
||||||
|
//取出
|
||||||
|
get(key) { |
||||||
|
let item = localStorage.getItem(key); |
||||||
|
// 先将拿到的试着进行json转为对象的形式
|
||||||
|
try { |
||||||
|
item = JSON.parse(item); |
||||||
|
} catch (error) { |
||||||
|
// eslint-disable-next-line no-self-assign
|
||||||
|
item = item; |
||||||
|
} |
||||||
|
// 如果有startTime的值,说明设置了失效时间
|
||||||
|
if (item && item.startTime) { |
||||||
|
let date = new Date().getTime(); |
||||||
|
// 如果大于就是过期了,如果小于或等于就还没过期
|
||||||
|
if (date - item.startTime > item.expires) { |
||||||
|
localStorage.removeItem(name); |
||||||
|
return false; |
||||||
|
} else { |
||||||
|
return item.value; |
||||||
|
} |
||||||
|
} else { |
||||||
|
return item; |
||||||
|
} |
||||||
|
}, |
||||||
|
// 删除
|
||||||
|
remove(key) { |
||||||
|
localStorage.removeItem(key); |
||||||
|
}, |
||||||
|
// 清除全部
|
||||||
|
clear() { |
||||||
|
localStorage.clear(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* sessionStorage |
||||||
|
*/ |
||||||
|
var _session = { |
||||||
|
get: function (key) { |
||||||
|
var data = sessionStorage[key]; |
||||||
|
if (!data || data === "null") { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return data; |
||||||
|
}, |
||||||
|
set: function (key, value) { |
||||||
|
sessionStorage[key] = value; |
||||||
|
}, |
||||||
|
// 删除
|
||||||
|
remove(key) { |
||||||
|
sessionStorage.removeItem(key); |
||||||
|
}, |
||||||
|
// 清除全部
|
||||||
|
clear() { |
||||||
|
sessionStorage.clear(); |
||||||
|
} |
||||||
|
} |
||||||
|
export { _local, _session } |
@ -0,0 +1,54 @@ |
|||||||
|
import cookies from './util.cookies'; |
||||||
|
import {_local,_session} from './util.db'; |
||||||
|
|
||||||
|
const util = { |
||||||
|
cookies, |
||||||
|
local: _local, |
||||||
|
session: _session, |
||||||
|
// 传入身份证获取生日
|
||||||
|
getBirth(idCard) { |
||||||
|
var birthday = ""; |
||||||
|
if(idCard != null && idCard != ""){ |
||||||
|
if(idCard.length == 15){ |
||||||
|
birthday = "19"+idCard.slice(6,12); |
||||||
|
} else if(idCard.length == 18){ |
||||||
|
birthday = idCard.slice(6,14); |
||||||
|
}
|
||||||
|
birthday = birthday.replace(/(.{4})(.{2})/,"$1-$2-"); |
||||||
|
//通过正则表达式来指定输出格式为:1990-01-01
|
||||||
|
}
|
||||||
|
return birthday; |
||||||
|
}, |
||||||
|
// new Date('2020-11-12 00:00:00') 在IE下失效,因此把-替换成/
|
||||||
|
dateCompatible(date) { |
||||||
|
return date.replace(/\-/g, '/') |
||||||
|
}, |
||||||
|
// 日期时间前面补零
|
||||||
|
formateTime(num) { |
||||||
|
return num < 10 ? `0${num}` : num |
||||||
|
}, |
||||||
|
//返回格式化时间,传参例如:"yyyy-MM-dd hh:mm:ss"
|
||||||
|
formatDate(fmt,date) { |
||||||
|
var date = date ? date : new Date() |
||||||
|
var o = {
|
||||||
|
"M+" : date.getMonth()+1, //月份
|
||||||
|
"d+" : date.getDate(), //日
|
||||||
|
"h+" : date.getHours(), //小时
|
||||||
|
"m+" : date.getMinutes(), //分
|
||||||
|
"s+" : date.getSeconds(), //秒
|
||||||
|
"q+" : Math.floor((date.getMonth()+3)/3), //季度
|
||||||
|
"S" : date.getMilliseconds() //毫秒
|
||||||
|
};
|
||||||
|
if(/(y+)/.test(fmt)) { |
||||||
|
fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
|
||||||
|
} |
||||||
|
for(var k in o) { |
||||||
|
if(new RegExp("("+ k +")").test(fmt)){ |
||||||
|
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length))); |
||||||
|
} |
||||||
|
} |
||||||
|
return fmt;
|
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
export default util; |
@ -0,0 +1,45 @@ |
|||||||
|
import Vue from 'vue'; |
||||||
|
import App from '@/App.vue'; |
||||||
|
import router from '@/router'; |
||||||
|
import ElementUI from 'element-ui'; |
||||||
|
import mixinApp from '@/mixins/app'; |
||||||
|
import VueI18n from 'vue-i18n'; |
||||||
|
import { messages } from '@/i18n'; |
||||||
|
// import 'element-ui/lib/theme-chalk/index.css'; // 默认主题
|
||||||
|
import './assets/css/theme-green/index.css'; // 浅绿色主题
|
||||||
|
import './assets/css/icon.css'; |
||||||
|
import './assets/icon/iconfont.css'; |
||||||
|
import 'babel-polyfill'; |
||||||
|
import '@/libs/resize'; |
||||||
|
import api from '@/api'; |
||||||
|
import {post,get,del,put} from '@/plugins/requests/index.js'; |
||||||
|
import store from '@/store' |
||||||
|
import permission from '@/router/permission'; |
||||||
|
import Setting from '@/setting'; |
||||||
|
|
||||||
|
// 插件
|
||||||
|
import plugins from '@/plugins'; |
||||||
|
|
||||||
|
Vue.use(plugins); |
||||||
|
|
||||||
|
Vue.prototype.api = api; |
||||||
|
Vue.prototype.$get = get; |
||||||
|
Vue.prototype.$post = post; |
||||||
|
Vue.prototype.$del = del; |
||||||
|
Vue.prototype.$put = put; |
||||||
|
|
||||||
|
Vue.config.productionTip = false; |
||||||
|
Vue.use(VueI18n); |
||||||
|
Vue.use(ElementUI); |
||||||
|
const i18n = new VueI18n({ |
||||||
|
locale: Setting.i18n.default, |
||||||
|
messages |
||||||
|
}); |
||||||
|
|
||||||
|
new Vue({ |
||||||
|
mixins: [mixinApp], |
||||||
|
router, |
||||||
|
store, |
||||||
|
i18n, |
||||||
|
render: h => h(App) |
||||||
|
}).$mount('#app'); |
@ -0,0 +1,11 @@ |
|||||||
|
/** |
||||||
|
* 通用混合 |
||||||
|
* */ |
||||||
|
export default { |
||||||
|
methods: { |
||||||
|
// 当 $route 更新时触发
|
||||||
|
appRouteChange (to, from) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
export default { |
||||||
|
beforeCreate() { |
||||||
|
document.querySelector('body').setAttribute('style', 'background-color:#fff') |
||||||
|
}, |
||||||
|
beforeDestroy() { |
||||||
|
document.body.removeAttribute('style') |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,252 @@ |
|||||||
|
<template> |
||||||
|
<div class="wrap"> |
||||||
|
|
||||||
|
<div class="header"> |
||||||
|
<div class="inner"> |
||||||
|
<img class="logo" src="../../../assets/img/logo.png" alt=""> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="main"> |
||||||
|
<div class="left"> |
||||||
|
<div class="text"> |
||||||
|
<p>欢迎进入</p> |
||||||
|
<p>电子竞技<br>数字化考试系统</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="right"> |
||||||
|
<h2>密码登录</h2> |
||||||
|
<el-form :model="loginForm" :rules="loginRules" ref="login" label-width="0px"> |
||||||
|
<el-form-item prop="username"> |
||||||
|
<p class="label">用户名</p> |
||||||
|
<el-input v-model="loginForm.username" placeholder="请输入账号/手机号" @keyup.enter.native="submitForm()"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="password"> |
||||||
|
<p class="label">密码</p> |
||||||
|
<el-input |
||||||
|
type="password" |
||||||
|
placeholder="请输入密码" |
||||||
|
v-model="loginForm.password" |
||||||
|
@keyup.enter.native="submitForm()" |
||||||
|
> |
||||||
|
</el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-button class="submit" type="primary" @click="submitForm">登录</el-button> |
||||||
|
<!-- <div class="links flex-between"> |
||||||
|
<el-button type="text" class="ques" @click="toReg">前往注册</el-button> |
||||||
|
<el-button type="text" class="forget">忘记密码?</el-button> |
||||||
|
</div> --> |
||||||
|
<!-- <p class="login-tips">其他登陆方式</p> |
||||||
|
<div class="thirdParty"> |
||||||
|
<div class="item"> |
||||||
|
<img src="../../../assets/img/icon_wechat.png" alt=""> |
||||||
|
微信扫码登录 |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<img src="../../../assets/img/icon_qq.png" alt=""> |
||||||
|
QQ一键登录 |
||||||
|
</div> |
||||||
|
</div> --> |
||||||
|
</el-form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { mapActions } from 'vuex'; |
||||||
|
export default { |
||||||
|
data: function() { |
||||||
|
return { |
||||||
|
loginForm: { |
||||||
|
// username: '18818574533', |
||||||
|
username: '123456', |
||||||
|
password: '123456', |
||||||
|
}, |
||||||
|
loginRules: { |
||||||
|
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }], |
||||||
|
password: [{ required: true, message: '请输入密码', trigger: 'blur' }], |
||||||
|
}, |
||||||
|
roleDialog: false, |
||||||
|
userId: '', |
||||||
|
schoolId: '', |
||||||
|
schoolName: '', |
||||||
|
roleId: '', |
||||||
|
roleList: [] |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted(){ |
||||||
|
|
||||||
|
}, |
||||||
|
methods: { |
||||||
|
...mapActions('user', [ |
||||||
|
'login' |
||||||
|
]), |
||||||
|
updateInfo(data){ |
||||||
|
this.loginForm.username = data.username |
||||||
|
this.loginForm.password = data.password |
||||||
|
}, |
||||||
|
submitForm() { |
||||||
|
this.$refs.login.validate(valid => { |
||||||
|
if (valid) { |
||||||
|
let data = { |
||||||
|
username: this.loginForm.username, |
||||||
|
password: this.loginForm.password |
||||||
|
} |
||||||
|
this.login(data).then(() => { |
||||||
|
this.$router.replace('/index') |
||||||
|
}) |
||||||
|
.catch(() => { |
||||||
|
|
||||||
|
}) |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped lang="scss"> |
||||||
|
.header{ |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
background-color: #333; |
||||||
|
.inner{ |
||||||
|
display: inline-flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
width: 65%; |
||||||
|
padding: 5px 0; |
||||||
|
font-size: 16px; |
||||||
|
color: #fff; |
||||||
|
.logo{ |
||||||
|
width: 200px; |
||||||
|
} |
||||||
|
.reg{ |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.wrap { |
||||||
|
position: relative; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
background: url(../../../assets/img/login_bg.png) 0 0/100% 100% no-repeat; |
||||||
|
overflow: hidden; |
||||||
|
.mask{ |
||||||
|
z-index: -1; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
bottom: 0; |
||||||
|
right: 0; |
||||||
|
background-color: rgba(0,0,0,1); |
||||||
|
} |
||||||
|
|
||||||
|
.main{ |
||||||
|
height: calc(100% - 60px); |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
background-color: rgba(0,0,0,.4); |
||||||
|
} |
||||||
|
.left{ |
||||||
|
margin-top: -200px; |
||||||
|
margin-right: 10%; |
||||||
|
|
||||||
|
img{ |
||||||
|
width: 447px;; |
||||||
|
margin-bottom: 30px; |
||||||
|
} |
||||||
|
.text{ |
||||||
|
font-size: 52px; |
||||||
|
color: #fff; |
||||||
|
p:first-child{ |
||||||
|
margin-bottom: 30px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.right{ |
||||||
|
width: 580px; |
||||||
|
padding: 40px 70px 50px; |
||||||
|
background-color: #fff; |
||||||
|
box-sizing: border-box; |
||||||
|
box-shadow: 0 1px 20px rgba(0,0,0,0.16); |
||||||
|
|
||||||
|
h2{ |
||||||
|
padding-bottom: 10px; |
||||||
|
font-size: 24px; |
||||||
|
font-weight: 400; |
||||||
|
color: #303d4c; |
||||||
|
text-align: center; |
||||||
|
border-bottom: 1px solid #E5E5E5; |
||||||
|
} |
||||||
|
.el-form{ |
||||||
|
margin-top: 30px; |
||||||
|
.label{ |
||||||
|
margin-bottom: 10px; |
||||||
|
color: #105CB2; |
||||||
|
} |
||||||
|
/deep/.el-input__inner{ |
||||||
|
height: 46px; |
||||||
|
padding: 0 23px; |
||||||
|
line-height: 46px; |
||||||
|
border: 1px solid #AFB5BB; |
||||||
|
border-radius: 23px !important; |
||||||
|
} |
||||||
|
/deep/.el-form-item__error{ |
||||||
|
top: 105%; |
||||||
|
left: auto; |
||||||
|
right: 0; |
||||||
|
color: #FFA94E; |
||||||
|
} |
||||||
|
.submit{ |
||||||
|
width: 100%; |
||||||
|
height: 48px; |
||||||
|
margin-top: 60px; |
||||||
|
line-height: 48px; |
||||||
|
padding: 0; |
||||||
|
font-size: 20px; |
||||||
|
background-color: #cb221c; |
||||||
|
border-radius: 23px; |
||||||
|
border: 0; |
||||||
|
} |
||||||
|
.links{ |
||||||
|
margin: 20px 0 20px; |
||||||
|
} |
||||||
|
.ques{ |
||||||
|
color: #cb221c; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
.forget{ |
||||||
|
color: #ffa94e; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
.login-tips{ |
||||||
|
margin-bottom: 20px; |
||||||
|
font-size: 16px; |
||||||
|
color: #105CB2; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
.thirdParty{ |
||||||
|
.item{ |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 20px; |
||||||
|
padding: 10px 0; |
||||||
|
color: #AFB5BB; |
||||||
|
font-size: 16px; |
||||||
|
background-color: #eff0f1; |
||||||
|
border-radius: 36px; |
||||||
|
cursor: pointer; |
||||||
|
img{ |
||||||
|
width: 40px; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,195 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-row :gutter="20"> |
||||||
|
<el-col :span="24"> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div class="flex-center mgb20"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>筛选</span> |
||||||
|
</div> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-form label-width="80px" inline> |
||||||
|
<el-form-item class="no-mb" label="教学班级"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择教学班级" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item class="no-mb" label="考试名称"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择考试名称" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div> |
||||||
|
<el-input |
||||||
|
placeholder="请输入学生姓名或学号" |
||||||
|
prefix-icon="el-icon-search" |
||||||
|
v-model="keyword" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</el-col> |
||||||
|
|
||||||
|
<el-col :span="24"> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div class="flex-between mgb20"> |
||||||
|
<div class="flex-center"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>考试成绩</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-button |
||||||
|
type="primary" |
||||||
|
size="small" |
||||||
|
round |
||||||
|
@click="toStat" |
||||||
|
>成绩统计</el-button> |
||||||
|
<el-button |
||||||
|
type="primary" |
||||||
|
size="small" |
||||||
|
round |
||||||
|
@click="showBatchUpload" |
||||||
|
>导出</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table |
||||||
|
:data="listData" |
||||||
|
ref="table" |
||||||
|
row-key="id" |
||||||
|
class="table" |
||||||
|
stripe |
||||||
|
header-align="center" |
||||||
|
@selection-change="handleSelectionChange" |
||||||
|
> |
||||||
|
<el-table-column |
||||||
|
type="selection" |
||||||
|
width="55" |
||||||
|
align="center" |
||||||
|
:reserve-selection="true" |
||||||
|
></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template |
||||||
|
slot-scope="scope" |
||||||
|
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="真实姓名" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="学号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="得分" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="用时(分钟)" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="考试时间" align="center"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="show(scope.row)">查看详情</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination |
||||||
|
background |
||||||
|
@current-change="handleCurrentChange" |
||||||
|
:current-page="page" |
||||||
|
:page-size="pageSize" |
||||||
|
layout="total,prev, pager, next" |
||||||
|
:total="total" |
||||||
|
></el-pagination> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
listData: [{}], |
||||||
|
keyword: '', |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
searchTimer: null, |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
// this.$get(this.api.list, { |
||||||
|
// page: this.page, |
||||||
|
// size: this.pageSize, |
||||||
|
// questionStem: this.keyword, |
||||||
|
// questionType: this.subject |
||||||
|
// }) |
||||||
|
// .then(res => { |
||||||
|
// this.total = res.page.totalCount; //总条数 |
||||||
|
// this.page = res.page.currPage; //当前页数 |
||||||
|
// this.listData = res.page.list; |
||||||
|
// this.$refs.table.clearSelection() |
||||||
|
// }) |
||||||
|
// .catch(err => {}) |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.page = val |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
closeTopics() { |
||||||
|
this.isShowTopics = false |
||||||
|
this.resetForm() |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
show(row){ |
||||||
|
this.$router.push('/testPaper/show') |
||||||
|
}, |
||||||
|
toStat(){ |
||||||
|
this.$router.push('statistics') |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
/deep/.no-mb.el-form-item{ |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
/deep/.el-radio{ |
||||||
|
margin-right: 15px; |
||||||
|
} |
||||||
|
::v-deep .el-checkbox-group{ |
||||||
|
font-size: 2px; |
||||||
|
} |
||||||
|
.Upload { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
.bt { |
||||||
|
margin-bottom: 15px; |
||||||
|
} |
||||||
|
.flex_around { |
||||||
|
display: flex; |
||||||
|
justify-content: space-around; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
.card_m { |
||||||
|
margin: 10px 0 20px 0; |
||||||
|
} |
||||||
|
.input ::v-deep .el-input { |
||||||
|
width: 50%; |
||||||
|
} |
||||||
|
.radio { |
||||||
|
margin: 0 15px 0 30px; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,42 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div class="tabs mgb20"> |
||||||
|
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{item}}</a> |
||||||
|
</div> |
||||||
|
|
||||||
|
<practice-results v-if="active == 'practice'"></practice-results> |
||||||
|
<exam-results v-else-if="active == 'exam'"></exam-results> |
||||||
|
<wrong-book v-else></wrong-book> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import practiceResults from './practiceResults' |
||||||
|
import examResults from './examResults' |
||||||
|
import wrongBook from './wrongBook' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
active: 'practice', |
||||||
|
tabs: { |
||||||
|
practice: '练习成绩', |
||||||
|
exam: '考试成绩', |
||||||
|
wrong: '错题管理' |
||||||
|
} |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
practiceResults, |
||||||
|
examResults, |
||||||
|
wrongBook, |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
tabChange(index){ |
||||||
|
this.active = index |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,257 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-row :gutter="20"> |
||||||
|
<el-col :span="24"> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div class="flex-center mgb20"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>筛选</span> |
||||||
|
</div> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-form label-width="80px"> |
||||||
|
<el-form-item class="no-mb" label="教学班级"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择教学班级" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div> |
||||||
|
<el-input |
||||||
|
placeholder="请输入学生姓名或学号" |
||||||
|
prefix-icon="el-icon-search" |
||||||
|
v-model="keyword" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</el-col> |
||||||
|
|
||||||
|
<el-col :span="24"> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div class="flex-between mgb20"> |
||||||
|
<div class="flex-center"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>练习成绩</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-button |
||||||
|
type="primary" |
||||||
|
size="small" |
||||||
|
round |
||||||
|
@click="showBatchUpload" |
||||||
|
>导出</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table |
||||||
|
:data="listData" |
||||||
|
ref="table" |
||||||
|
row-key="id" |
||||||
|
class="table" |
||||||
|
stripe |
||||||
|
header-align="center" |
||||||
|
@selection-change="handleSelectionChange" |
||||||
|
> |
||||||
|
<el-table-column |
||||||
|
type="selection" |
||||||
|
width="55" |
||||||
|
align="center" |
||||||
|
:reserve-selection="true" |
||||||
|
></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template |
||||||
|
slot-scope="scope" |
||||||
|
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="真实姓名" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="学号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="最高分" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="最低分" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="平均分" align="center"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="show(scope.row)">查看详情</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination |
||||||
|
background |
||||||
|
@current-change="handleCurrentChange" |
||||||
|
:current-page="page" |
||||||
|
:page-size="pageSize" |
||||||
|
layout="total,prev, pager, next" |
||||||
|
:total="total" |
||||||
|
></el-pagination> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
|
||||||
|
<el-dialog title="练习成绩详情" :visible.sync="detailVisible" width="40%" @close="closeSelect" :close-on-click-modal="false"> |
||||||
|
<div class="flex-justify-end"> |
||||||
|
<div class="mgb20"> |
||||||
|
<el-input |
||||||
|
placeholder="请输入练习项目名称" |
||||||
|
prefix-icon="el-icon-search" |
||||||
|
v-model="keyword" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table |
||||||
|
:data="projectData" |
||||||
|
ref="table" |
||||||
|
row-key="id" |
||||||
|
class="table" |
||||||
|
stripe |
||||||
|
header-align="center" |
||||||
|
@selection-change="handleSelectionChange" |
||||||
|
> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template |
||||||
|
slot-scope="scope" |
||||||
|
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="练习试卷名称" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="开始时间" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="得分" align="center"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="showQues(scope.row)">查看</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination |
||||||
|
background |
||||||
|
@current-change="handleCurrentChange" |
||||||
|
:current-page="page" |
||||||
|
:page-size="pageSize" |
||||||
|
layout="total,prev, pager, next" |
||||||
|
:total="total" |
||||||
|
></el-pagination> |
||||||
|
</div> |
||||||
|
|
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="detailVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" @click="uploadSure">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
keyword: '', |
||||||
|
listData: [{}], |
||||||
|
subjectList: [ |
||||||
|
{ |
||||||
|
id: '', |
||||||
|
name: '不限' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 1, |
||||||
|
name: '单选题' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 2, |
||||||
|
name: '多选题' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 3, |
||||||
|
name: '判断题' |
||||||
|
} |
||||||
|
], |
||||||
|
total: 0, // 总条数,根据接口获取数据长度(注意:这里不能为空) |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
multipleSelection: [], |
||||||
|
isShowTopics: false, |
||||||
|
topicsTitle: '', |
||||||
|
uploadList: [], |
||||||
|
uploadDataList: [], |
||||||
|
searchTimer: null, |
||||||
|
detailVisible: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
// this.$get(this.api.list, { |
||||||
|
// page: this.page, |
||||||
|
// size: this.pageSize, |
||||||
|
// questionStem: this.keyword, |
||||||
|
// questionType: this.subject |
||||||
|
// }) |
||||||
|
// .then(res => { |
||||||
|
// this.total = res.page.totalCount; //总条数 |
||||||
|
// this.page = res.page.currPage; //当前页数 |
||||||
|
// this.listData = res.page.list; |
||||||
|
// this.$refs.table.clearSelection() |
||||||
|
// }) |
||||||
|
// .catch(err => {}) |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.page = val |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
closeTopics() { |
||||||
|
this.isShowTopics = false |
||||||
|
this.resetForm() |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
show(row){ |
||||||
|
this.detailVisible = true |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
/deep/.no-mb.el-form-item{ |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
/deep/.el-radio{ |
||||||
|
margin-right: 15px; |
||||||
|
} |
||||||
|
::v-deep .el-checkbox-group{ |
||||||
|
font-size: 2px; |
||||||
|
} |
||||||
|
.Upload { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
.bt { |
||||||
|
margin-bottom: 15px; |
||||||
|
} |
||||||
|
.flex_around { |
||||||
|
display: flex; |
||||||
|
justify-content: space-around; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
.card_m { |
||||||
|
margin: 10px 0 20px 0; |
||||||
|
} |
||||||
|
.input ::v-deep .el-input { |
||||||
|
width: 50%; |
||||||
|
} |
||||||
|
.radio { |
||||||
|
margin: 0 15px 0 30px; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,182 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-row :gutter="20"> |
||||||
|
<el-col :span="24"> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div class="flex-center mgb20"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>筛选</span> |
||||||
|
</div> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-form label-width="80px" inline> |
||||||
|
<el-form-item class="no-mb" label="错题来源"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择错题来源" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item class="no-mb" label="试卷名称"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择试卷名称" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div> |
||||||
|
<el-input |
||||||
|
placeholder="请输入学生姓名或学号" |
||||||
|
prefix-icon="el-icon-search" |
||||||
|
v-model="keyword" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</el-col> |
||||||
|
|
||||||
|
<el-col :span="24"> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div class="flex-between mgb20"> |
||||||
|
<div class="flex-center"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>错题管理</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table |
||||||
|
:data="listData" |
||||||
|
ref="table" |
||||||
|
row-key="id" |
||||||
|
class="table" |
||||||
|
stripe |
||||||
|
header-align="center" |
||||||
|
@selection-change="handleSelectionChange" |
||||||
|
> |
||||||
|
<el-table-column |
||||||
|
type="selection" |
||||||
|
width="55" |
||||||
|
align="center" |
||||||
|
:reserve-selection="true" |
||||||
|
></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template |
||||||
|
slot-scope="scope" |
||||||
|
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="错题来源" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="试卷名称" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="所需知识点" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="教学班级" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="真实姓名" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="学号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="错题数" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="重做正确率" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="知识点掌握程度" align="center"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="show(scope.row)">查看详情</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination |
||||||
|
background |
||||||
|
@current-change="handleCurrentChange" |
||||||
|
:current-page="page" |
||||||
|
:page-size="pageSize" |
||||||
|
layout="total,prev, pager, next" |
||||||
|
:total="total" |
||||||
|
></el-pagination> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
listData: [{}], |
||||||
|
keyword: '', |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
searchTimer: null, |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
// this.$get(this.api.list, { |
||||||
|
// page: this.page, |
||||||
|
// size: this.pageSize, |
||||||
|
// questionStem: this.keyword, |
||||||
|
// questionType: this.subject |
||||||
|
// }) |
||||||
|
// .then(res => { |
||||||
|
// this.total = res.page.totalCount; //总条数 |
||||||
|
// this.page = res.page.currPage; //当前页数 |
||||||
|
// this.listData = res.page.list; |
||||||
|
// this.$refs.table.clearSelection() |
||||||
|
// }) |
||||||
|
// .catch(err => {}) |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.page = val |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
closeTopics() { |
||||||
|
this.isShowTopics = false |
||||||
|
this.resetForm() |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
show(row){ |
||||||
|
this.$router.push('/testPaper/show') |
||||||
|
}, |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
/deep/.no-mb.el-form-item{ |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
/deep/.el-radio{ |
||||||
|
margin-right: 15px; |
||||||
|
} |
||||||
|
::v-deep .el-checkbox-group{ |
||||||
|
font-size: 2px; |
||||||
|
} |
||||||
|
.Upload { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
.bt { |
||||||
|
margin-bottom: 15px; |
||||||
|
} |
||||||
|
.flex_around { |
||||||
|
display: flex; |
||||||
|
justify-content: space-around; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
.card_m { |
||||||
|
margin: 10px 0 20px 0; |
||||||
|
} |
||||||
|
.input ::v-deep .el-input { |
||||||
|
width: 50%; |
||||||
|
} |
||||||
|
.radio { |
||||||
|
margin: 0 15px 0 30px; |
||||||
|
font-weight: 600; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,264 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-form :disabled="isDetail"> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div class="flex-between"> |
||||||
|
<div class="per_title" v-throttle @click="goback()"> |
||||||
|
<i class="el-icon-arrow-left"></i> |
||||||
|
<span class="per_back">返回</span> |
||||||
|
<span class="per_school">{{isDetail ? '查看' : (id ? '更新' : '创建')}}考核</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-button type="primary" size="small" round v-throttle @click="save" v-show="!isDetail">{{id ? '更新' : '创建'}}</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div> |
||||||
|
<p class="mgb20">考核名称</p> |
||||||
|
<el-input |
||||||
|
placeholder="请输入考核名称" |
||||||
|
v-model="assessmentName" |
||||||
|
clearable |
||||||
|
maxlength="25" |
||||||
|
class="inline_input" |
||||||
|
></el-input> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div> |
||||||
|
<p class="mgb20">考核类型</p> |
||||||
|
<div class="inline_input"> |
||||||
|
<el-select v-model="classificationId" placeholder="请选择考核类型"> |
||||||
|
<el-option |
||||||
|
v-for="item in classificationList" |
||||||
|
:key="item.id" |
||||||
|
:label="item.name" |
||||||
|
:value="item.id"> |
||||||
|
</el-option> |
||||||
|
</el-select> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div> |
||||||
|
<p class="mgb20">考核时间</p> |
||||||
|
<el-date-picker |
||||||
|
size="small" |
||||||
|
v-model="date" |
||||||
|
value-format="yyyy-MM-dd HH:mm:ss" |
||||||
|
type="datetimerange" |
||||||
|
range-separator="-" |
||||||
|
start-placeholder="开始日期" |
||||||
|
end-placeholder="结束日期" |
||||||
|
:picker-options="pickerOptions" |
||||||
|
></el-date-picker> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div> |
||||||
|
<p class="mgb20">试卷选择</p> |
||||||
|
<div class="inline_input"> |
||||||
|
<el-button type="primary" @click="openSelect">试卷选择</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div> |
||||||
|
<p class="mgb20">发布班级</p> |
||||||
|
<div class="inline_input"> |
||||||
|
<div class="per-wrap"> |
||||||
|
<el-tree |
||||||
|
ref="per" |
||||||
|
:data="permissions" |
||||||
|
show-checkbox |
||||||
|
node-key="id" |
||||||
|
:default-expanded-keys="checkedIds" |
||||||
|
:default-checked-keys="checkedIds" |
||||||
|
:props="defaultProps"> |
||||||
|
</el-tree> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</el-form> |
||||||
|
|
||||||
|
<el-dialog title="试卷选择" :visible.sync="selectVisible" width="40%" @close="closeSelect" :close-on-click-modal="false"> |
||||||
|
<div class="flex-justify-end"> |
||||||
|
<el-form label-width="80px" inline> |
||||||
|
<el-form-item class="no-mb" label="所属考核"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择所属考核" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item class="no-mb"> |
||||||
|
<el-input |
||||||
|
placeholder="请输入试卷名称" |
||||||
|
prefix-icon="el-icon-search" |
||||||
|
v-model="keyword" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table |
||||||
|
:data="listData" |
||||||
|
ref="table" |
||||||
|
row-key="id" |
||||||
|
class="table" |
||||||
|
stripe |
||||||
|
header-align="center" |
||||||
|
@selection-change="handleSelectionChange" |
||||||
|
> |
||||||
|
<el-table-column width="60" label="选择" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-radio v-model="projectId" :label="scope.row.projectId"> </el-radio> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template |
||||||
|
slot-scope="scope" |
||||||
|
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="试卷名称" align="center"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="showQues(scope.row)">预览</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination |
||||||
|
background |
||||||
|
@current-change="handleCurrentChange" |
||||||
|
:current-page="page" |
||||||
|
:page-size="pageSize" |
||||||
|
layout="total,prev, pager, next" |
||||||
|
:total="total" |
||||||
|
></el-pagination> |
||||||
|
</div> |
||||||
|
|
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="importVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" @click="uploadSure">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import { mapState } from 'vuex' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
id: '', |
||||||
|
assessmentName: '', |
||||||
|
classId: '', |
||||||
|
date: [], |
||||||
|
startTime: '', |
||||||
|
endTime: '', |
||||||
|
state: '', |
||||||
|
testPaperId: '', |
||||||
|
type: '', |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
isDetail: Boolean(this.$route.query.show), |
||||||
|
selectVisible: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
...mapState('user', [ |
||||||
|
'userId','clientId' |
||||||
|
]) |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
date: function(val){ |
||||||
|
if(val){ |
||||||
|
this.startTime = val[0] |
||||||
|
this.endTime = val[1] |
||||||
|
}else{ |
||||||
|
this.startTime = '' |
||||||
|
this.endTime = '' |
||||||
|
} |
||||||
|
this.getData() |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.id = this.$route.query.id |
||||||
|
this.id && this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
save() { |
||||||
|
if(this.assessmentName === '') return this.$message.warning('请填写考核名称') |
||||||
|
if(this.type === '') return this.$message.warning('请选择考核类型') |
||||||
|
if(this.startTime === '') return this.$message.warning('请选择考核时间') |
||||||
|
if(this.testPaperId === '') return this.$message.warning('请选择试卷') |
||||||
|
|
||||||
|
let data = { |
||||||
|
id: this.id, |
||||||
|
userId: this.userId, |
||||||
|
assessmentName: this.assessmentName, |
||||||
|
type: this.type, |
||||||
|
startTime: this.startTime, |
||||||
|
endTime: this.endTime, |
||||||
|
} |
||||||
|
if(this.id){ |
||||||
|
this.$put(this.api.editCourse, data).then(res => { |
||||||
|
this.$message.success('修改成功'); |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
}else{ |
||||||
|
this.$post(this.api.addCourse, data).then(res => { |
||||||
|
this.$message.success('创建成功'); |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
getData() { |
||||||
|
this.$get(`${this.api.getCourse}/${this.id}`) |
||||||
|
.then(res => { |
||||||
|
|
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
goback() { |
||||||
|
if(this.isDetail){ |
||||||
|
this.$router.back() |
||||||
|
}else{ |
||||||
|
this.$confirm('确定返回?未更新的信息将不会保存。', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
} |
||||||
|
}, |
||||||
|
openSelect(){ |
||||||
|
this.selectVisible = true |
||||||
|
} |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.inline_input { |
||||||
|
width: 300px; |
||||||
|
} |
||||||
|
.per-wrap{ |
||||||
|
max-height: 400px; |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,311 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div> |
||||||
|
<div class="flex-center mgb20"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>筛选</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<div class="flex-between no-mb"> |
||||||
|
<div> |
||||||
|
<el-form label-width="80px" inline> |
||||||
|
<el-form-item label="考核类型" class="no-mb"> |
||||||
|
<el-select v-model="type" clearable placeholder="请选择考核类型" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in typeList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="考试状态" class="no-mb"> |
||||||
|
<el-select v-model="state" clearable placeholder="请选择考试状态" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in stateList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-input placeholder="请输入考核名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover"> |
||||||
|
<div class="flex-between mgb20"> |
||||||
|
<div class="flex-center"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>考核列表</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-button type="primary" size="small" round @click="addAss" v-auth>创建考核</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table :data="listData" class="table" stripe header-align="center" row-key="id"> |
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="assessmentName" label="考核名称" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="考核类型" align="center"></el-table-column> |
||||||
|
<el-table-column prop="startTime" label="考试开始时间" align="center"></el-table-column> |
||||||
|
<el-table-column prop="endTime" label="考试结束时间" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="考核状态" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="考试班级" align="center"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="300"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="show(scope.row)" v-auth>查看</el-button> |
||||||
|
<el-button type="text" @click="edit(scope.row)" v-auth>修改</el-button> |
||||||
|
<el-button type="text" @click="monitor(scope.row)" v-auth>监控</el-button> |
||||||
|
<el-button type="text" @click="review(scope.row)" v-auth>批阅</el-button> |
||||||
|
<el-button type="text" @click="finish(scope.row)" v-auth>结束考试</el-button> |
||||||
|
<el-button type="text" @click="scoreQuery(scope.row)" v-auth>成绩查询</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> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-dialog title="创建考核" :visible.sync="addVisible" width="50%" @close="closeAdd" :close-on-click-modal="false"> |
||||||
|
<el-form ref="form" label-width="100px"> |
||||||
|
<el-form-item prop="account" label="考核名称"> |
||||||
|
<el-input v-model="account" placeholder="请输入考核名称"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="userName" label="考核类型"> |
||||||
|
<el-select v-model="classificationId" placeholder="请选择考核类型"> |
||||||
|
<el-option |
||||||
|
v-for="item in classificationList" |
||||||
|
:key="item.id" |
||||||
|
:label="item.name" |
||||||
|
:value="item.id"> |
||||||
|
</el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="account" label="考核时间"> |
||||||
|
<el-date-picker |
||||||
|
size="small" |
||||||
|
v-model="time" |
||||||
|
value-format="yyyy-MM-dd HH:mm:ss" |
||||||
|
type="datetimerange" |
||||||
|
range-separator="-" |
||||||
|
start-placeholder="开始日期" |
||||||
|
end-placeholder="结束日期" |
||||||
|
:picker-options="pickerOptions" |
||||||
|
></el-date-picker> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="account" label="试卷选择"> |
||||||
|
<el-button type="primary" @click="openSelect">试卷选择</el-button> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="account" label="发布班级"> |
||||||
|
<el-tree |
||||||
|
ref="per" |
||||||
|
:data="permissions" |
||||||
|
show-checkbox |
||||||
|
node-key="id" |
||||||
|
:default-expanded-keys="checkedIds" |
||||||
|
:default-checked-keys="checkedIds" |
||||||
|
:props="defaultProps"> |
||||||
|
</el-tree> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
|
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="addVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" @click="uploadSure">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog title="试卷选择" :visible.sync="selectVisible" width="40%" @close="closeSelect" :close-on-click-modal="false"> |
||||||
|
<div class="flex-justify-end"> |
||||||
|
<el-form label-width="80px" inline> |
||||||
|
<el-form-item class="no-mb" label="所属课程"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择所属课程" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item class="no-mb"> |
||||||
|
<el-input |
||||||
|
placeholder="请输入试卷名称" |
||||||
|
prefix-icon="el-icon-search" |
||||||
|
v-model="keyword" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table |
||||||
|
:data="listData" |
||||||
|
ref="table" |
||||||
|
row-key="id" |
||||||
|
class="table" |
||||||
|
stripe |
||||||
|
header-align="center" |
||||||
|
@selection-change="handleSelectionChange" |
||||||
|
> |
||||||
|
<el-table-column width="60" label="选择" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-radio v-model="projectId" :label="scope.row.projectId"> </el-radio> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template |
||||||
|
slot-scope="scope" |
||||||
|
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="试卷名称" align="center"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="showQues(scope.row)">预览</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination |
||||||
|
background |
||||||
|
@current-change="handleCurrentChange" |
||||||
|
:current-page="page" |
||||||
|
:page-size="pageSize" |
||||||
|
layout="total,prev, pager, next" |
||||||
|
:total="total" |
||||||
|
></el-pagination> |
||||||
|
</div> |
||||||
|
|
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="selectVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" @click="uploadSure">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog title="详情" :visible.sync="detailVisible" width="40%" @close="closeDetail" :close-on-click-modal="false"> |
||||||
|
<div class="details"> |
||||||
|
<div class="line"> |
||||||
|
<span class="key">考核内容:</span> |
||||||
|
<p class="val">测试</p> |
||||||
|
</div> |
||||||
|
<div class="line"> |
||||||
|
<span class="key">考核题数:</span> |
||||||
|
<p class="val">12000</p> |
||||||
|
</div> |
||||||
|
<div class="line"> |
||||||
|
<span class="key">考核人数:</span> |
||||||
|
<p class="val">211</p> |
||||||
|
</div> |
||||||
|
<div class="line"> |
||||||
|
<span class="key">考核总分:</span> |
||||||
|
<p class="val">100分</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
listData: [], |
||||||
|
keyword: '', |
||||||
|
type: '', |
||||||
|
typeList: [], |
||||||
|
state: '', |
||||||
|
stateList: [], |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
searchTimer: null, |
||||||
|
addVisible: false, |
||||||
|
selectVisible: false, |
||||||
|
detailVisible: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
this.$get(this.api.queryAssessment, { |
||||||
|
page: this.page, |
||||||
|
size: this.pageSize, |
||||||
|
type: this.type, |
||||||
|
state: this.state, |
||||||
|
assessmentName: this.keyword |
||||||
|
}) |
||||||
|
.then(res => { |
||||||
|
this.listData = res.data.Assessment |
||||||
|
this.total = res.data.total |
||||||
|
}) |
||||||
|
.catch(err => {}) |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.page = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
edit(row){ |
||||||
|
this.$router.push('add') |
||||||
|
}, |
||||||
|
monitor(row){ |
||||||
|
this.$router.push('monitor') |
||||||
|
}, |
||||||
|
finish(row){ |
||||||
|
|
||||||
|
}, |
||||||
|
scoreQuery(){ |
||||||
|
this.$router.push('scoreQuery') |
||||||
|
}, |
||||||
|
review(row){ |
||||||
|
this.$router.push('review') |
||||||
|
}, |
||||||
|
addAss(){ |
||||||
|
this.addVisible = true |
||||||
|
}, |
||||||
|
closeAdd(){ |
||||||
|
|
||||||
|
}, |
||||||
|
openSelect(){ |
||||||
|
this.selectVisible = true |
||||||
|
}, |
||||||
|
closeSelect(){ |
||||||
|
|
||||||
|
}, |
||||||
|
show(row){ |
||||||
|
this.detailVisible = true |
||||||
|
}, |
||||||
|
closeDetail(){ |
||||||
|
|
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
/deep/.no-mb.el-form-item{ |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
.details{ |
||||||
|
.line{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin: 10px 0; |
||||||
|
&:first-child{ |
||||||
|
margin-top: 0; |
||||||
|
} |
||||||
|
.key{ |
||||||
|
font-weight: bold; |
||||||
|
color: #333; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
.val{ |
||||||
|
color: #757575; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,204 @@ |
|||||||
|
<template> |
||||||
|
<div class="box"> |
||||||
|
<div class="left"> |
||||||
|
<div class="title">考试信息</div> |
||||||
|
<div class="info"> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">试卷名称:</p> |
||||||
|
<p class="val">测试</p> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">试卷总分:</p> |
||||||
|
<p class="val">发布考试的名称</p> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">剩余时间:</p> |
||||||
|
<p class="val">发布考试的名称</p> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">应考人数:</p> |
||||||
|
<p class="val">发布考试的名称</p> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">在考人数:</p> |
||||||
|
<p class="val">发布考试的名称</p> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">已考人数:</p> |
||||||
|
<p class="val">发布考试的名称</p> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">未考人数:</p> |
||||||
|
<p class="val">发布考试的名称</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="right"> |
||||||
|
<div class="filter"> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">考试状态</p> |
||||||
|
<el-select v-model="purpose" placeholder="请选择考试状态" size="small"> |
||||||
|
<el-option v-for="(item,index) in purposeList" :key="index" :label="item.label" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">试卷用途:</p> |
||||||
|
<el-input placeholder="请输入学生姓名/学号" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="table"> |
||||||
|
<div class="flex-justify-end"> |
||||||
|
<el-button type="primary" size="small" round>强制收卷</el-button> |
||||||
|
</div> |
||||||
|
<el-table |
||||||
|
:data="listData" |
||||||
|
ref="table" |
||||||
|
row-key="id" |
||||||
|
class="table" |
||||||
|
stripe |
||||||
|
header-align="center" |
||||||
|
> |
||||||
|
<el-table-column |
||||||
|
type="selection" |
||||||
|
width="55" |
||||||
|
align="center" |
||||||
|
:reserve-selection="true" |
||||||
|
></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template |
||||||
|
slot-scope="scope" |
||||||
|
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="真实姓名" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="学号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="所属班级" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="考试状态" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="开始时间" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="提交时间" align="center"></el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination |
||||||
|
background |
||||||
|
@current-change="handleCurrentChange" |
||||||
|
:current-page="page" |
||||||
|
:page-size="pageSize" |
||||||
|
layout="total,prev, pager, next" |
||||||
|
:total="total" |
||||||
|
></el-pagination> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import mixins from '@/mixins/setBackground'; |
||||||
|
export default { |
||||||
|
mixins: [ mixins ], |
||||||
|
data() { |
||||||
|
return { |
||||||
|
keyword: '', |
||||||
|
listData: [], |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0 |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
this.$get(`${this.api.getCourse}/${this.id}`) |
||||||
|
.then(res => { |
||||||
|
|
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.page = val |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.box{ |
||||||
|
display: flex; |
||||||
|
width: 90%; |
||||||
|
margin: 0 auto; |
||||||
|
border: 1px solid #e8e8e8; |
||||||
|
.left{ |
||||||
|
width: 25%; |
||||||
|
padding: 30px; |
||||||
|
border-right: 1px solid #e8e8e8; |
||||||
|
box-sizing: border-box; |
||||||
|
.title{ |
||||||
|
font-size: 14px; |
||||||
|
color: #444; |
||||||
|
} |
||||||
|
.info{ |
||||||
|
.item{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin: 10px 0; |
||||||
|
.key{ |
||||||
|
color: #555; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
.val{ |
||||||
|
flex: 1; |
||||||
|
margin-left: 20px; |
||||||
|
color: #333; |
||||||
|
text-align: center; |
||||||
|
line-height: 36px; |
||||||
|
font-size: 14px; |
||||||
|
background-color: #f4f4f4; |
||||||
|
border: 1px solid #e8e8e8; |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
.right{ |
||||||
|
width: 70%; |
||||||
|
padding: 20px; |
||||||
|
box-sizing: border-box; |
||||||
|
.filter{ |
||||||
|
display: flex; |
||||||
|
justify-content: flex-end; |
||||||
|
padding: 10px; |
||||||
|
background-color: #efefef; |
||||||
|
.item{ |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
margin-left: 20px; |
||||||
|
/deep/.el-select{ |
||||||
|
flex: 1; |
||||||
|
} |
||||||
|
.key{ |
||||||
|
margin-right: 20px; |
||||||
|
white-space: nowrap; |
||||||
|
font-size: 14px; |
||||||
|
color: #555; |
||||||
|
} |
||||||
|
&.lg .key{ |
||||||
|
width: 220px; |
||||||
|
margin-right: 10px; |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.table{ |
||||||
|
padding: 10px; |
||||||
|
margin-top: 10px; |
||||||
|
background-color: #efefef; |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,138 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div class="flex-center mgb20"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>筛选</span> |
||||||
|
</div> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-form label-width="80px" inline> |
||||||
|
<el-form-item class="no-mb" label="批阅状态"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择授课专业" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div> |
||||||
|
<el-input |
||||||
|
placeholder="请输入真实姓名/学号" |
||||||
|
prefix-icon="el-icon-search" |
||||||
|
v-model="keyword" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div class="flex-between mgb20"> |
||||||
|
<div class="flex-center"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>考试批阅</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table |
||||||
|
:data="listData" |
||||||
|
ref="table" |
||||||
|
row-key="id" |
||||||
|
class="table" |
||||||
|
stripe |
||||||
|
header-align="center" |
||||||
|
@selection-change="handleSelectionChange" |
||||||
|
> |
||||||
|
<el-table-column |
||||||
|
type="selection" |
||||||
|
width="55" |
||||||
|
align="center" |
||||||
|
:reserve-selection="true" |
||||||
|
></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template |
||||||
|
slot-scope="scope" |
||||||
|
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="真实姓名" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="学号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="交卷时间" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="答题用时(分钟)" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="考试状态" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="批阅状态" align="center"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="show(scope.row)">查看</el-button> |
||||||
|
<el-button type="text" @click="review(scope.row)">批阅</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination |
||||||
|
background |
||||||
|
@current-change="handleCurrentChange" |
||||||
|
:current-page="page" |
||||||
|
:page-size="pageSize" |
||||||
|
layout="total,prev, pager, next" |
||||||
|
:total="total" |
||||||
|
></el-pagination> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
listData: [{}], |
||||||
|
keyword: '', |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
searchTimer: null, |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
// this.$get(this.api.list, { |
||||||
|
// page: this.page, |
||||||
|
// size: this.pageSize, |
||||||
|
// questionStem: this.keyword, |
||||||
|
// questionType: this.subject |
||||||
|
// }) |
||||||
|
// .then(res => { |
||||||
|
// this.total = res.page.totalCount; //总条数 |
||||||
|
// this.page = res.page.currPage; //当前页数 |
||||||
|
// this.listData = res.page.list; |
||||||
|
// this.$refs.table.clearSelection() |
||||||
|
// }) |
||||||
|
// .catch(err => {}) |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.page = val |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
show(row){ |
||||||
|
this.$router.push('/testPaper/doReview') |
||||||
|
}, |
||||||
|
review(row){ |
||||||
|
this.$router.push('/testPaper/doReview') |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
/deep/.no-mb.el-form-item{ |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,141 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div class="flex-center mgb20"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>筛选</span> |
||||||
|
</div> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-form label-width="80px" inline> |
||||||
|
<el-form-item class="no-mb" label="教学班级"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择教学班级" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item class="no-mb" label="考试名称"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择考试名称" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div> |
||||||
|
<el-input |
||||||
|
placeholder="请输入学生姓名/学号" |
||||||
|
prefix-icon="el-icon-search" |
||||||
|
v-model="keyword" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div class="flex-between mgb20"> |
||||||
|
<div class="flex-center"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>成绩查询</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-button type="primary" size="small" round @click="stat">成绩统计</el-button> |
||||||
|
<el-button type="primary" size="small" round>导出</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table |
||||||
|
:data="listData" |
||||||
|
ref="table" |
||||||
|
row-key="id" |
||||||
|
class="table" |
||||||
|
stripe |
||||||
|
header-align="center" |
||||||
|
@selection-change="handleSelectionChange" |
||||||
|
> |
||||||
|
<el-table-column |
||||||
|
type="selection" |
||||||
|
width="55" |
||||||
|
align="center" |
||||||
|
:reserve-selection="true" |
||||||
|
></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template |
||||||
|
slot-scope="scope" |
||||||
|
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="真实姓名" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="学号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="得分" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="用时(分钟)" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="考试时间" align="center"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="show(scope.row)">查看</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination |
||||||
|
background |
||||||
|
@current-change="handleCurrentChange" |
||||||
|
:current-page="page" |
||||||
|
:page-size="pageSize" |
||||||
|
layout="total,prev, pager, next" |
||||||
|
:total="total" |
||||||
|
></el-pagination> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
listData: [{}], |
||||||
|
keyword: '', |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
searchTimer: null, |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
// this.$get(this.api.list, { |
||||||
|
// page: this.page, |
||||||
|
// size: this.pageSize, |
||||||
|
// questionStem: this.keyword, |
||||||
|
// questionType: this.subject |
||||||
|
// }) |
||||||
|
// .then(res => { |
||||||
|
// this.total = res.page.totalCount; //总条数 |
||||||
|
// this.page = res.page.currPage; //当前页数 |
||||||
|
// this.listData = res.page.list; |
||||||
|
// this.$refs.table.clearSelection() |
||||||
|
// }) |
||||||
|
// .catch(err => {}) |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.page = val |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
stat(row){ |
||||||
|
this.$router.push('/achievement/statistics') |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
/deep/.no-mb.el-form-item{ |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,56 @@ |
|||||||
|
<template> |
||||||
|
<div class="error-page"> |
||||||
|
<div class="error-code">4<span>0</span>3</div> |
||||||
|
<div class="error-desc">啊哦~ 你没有权限访问该页面哦</div> |
||||||
|
<div class="error-handle"> |
||||||
|
<router-link to="/"> |
||||||
|
<el-button type="primary" size="large">返回首页</el-button> |
||||||
|
</router-link> |
||||||
|
<el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
methods: { |
||||||
|
goBack(){ |
||||||
|
this.$router.go(-1); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
|
||||||
|
<style scoped> |
||||||
|
.error-page{ |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
flex-direction: column; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
background: #f3f3f3; |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
.error-code{ |
||||||
|
line-height: 1; |
||||||
|
font-size: 250px; |
||||||
|
font-weight: bolder; |
||||||
|
color: #f02d2d; |
||||||
|
} |
||||||
|
.error-code span{ |
||||||
|
color: #00a854; |
||||||
|
} |
||||||
|
.error-desc{ |
||||||
|
font-size: 30px; |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.error-handle{ |
||||||
|
margin-top: 30px; |
||||||
|
padding-bottom: 200px; |
||||||
|
} |
||||||
|
.error-btn{ |
||||||
|
margin-left: 100px; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,56 @@ |
|||||||
|
<template> |
||||||
|
<div class="error-page"> |
||||||
|
<div class="error-code">4<span>0</span>4</div> |
||||||
|
<div class="error-desc">啊哦~ 你所访问的页面不存在</div> |
||||||
|
<div class="error-handle"> |
||||||
|
<router-link to="/"> |
||||||
|
<el-button type="primary" size="large">返回首页</el-button> |
||||||
|
</router-link> |
||||||
|
<el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
methods: { |
||||||
|
goBack(){ |
||||||
|
this.$router.go(-1); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
|
||||||
|
<style scoped> |
||||||
|
.error-page{ |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
flex-direction: column; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
background: #f3f3f3; |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
.error-code{ |
||||||
|
line-height: 1; |
||||||
|
font-size: 250px; |
||||||
|
font-weight: bolder; |
||||||
|
color: #2d8cf0; |
||||||
|
} |
||||||
|
.error-code span{ |
||||||
|
color: #00a854; |
||||||
|
} |
||||||
|
.error-desc{ |
||||||
|
font-size: 30px; |
||||||
|
color: #777; |
||||||
|
} |
||||||
|
.error-handle{ |
||||||
|
margin-top: 30px; |
||||||
|
padding-bottom: 200px; |
||||||
|
} |
||||||
|
.error-btn{ |
||||||
|
margin-left: 100px; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,46 @@ |
|||||||
|
<template> |
||||||
|
<section class="main"> |
||||||
|
<div class="crumbs"> |
||||||
|
<el-breadcrumb separator="/"> |
||||||
|
<el-breadcrumb-item><i class="el-icon-lx-global"></i> {{$t('i18n.breadcrumb')}}</el-breadcrumb-item> |
||||||
|
</el-breadcrumb> |
||||||
|
</div> |
||||||
|
<div class="container"> |
||||||
|
<span>{{$t('i18n.tips')}}</span> |
||||||
|
<el-button type="primary" @click="$i18n.locale = $i18n.locale === 'zh'?'en':'zh';">{{$t('i18n.btn')}}</el-button> |
||||||
|
<div class="list"> |
||||||
|
<h2>{{$t('i18n.title1')}}</h2> |
||||||
|
<p>{{$t('i18n.p1')}}</p> |
||||||
|
<p>{{$t('i18n.p2')}}</p> |
||||||
|
<p>{{$t('i18n.p3')}}</p> |
||||||
|
</div> |
||||||
|
<h2>{{$t('i18n.title2')}}</h2> |
||||||
|
<div> |
||||||
|
<i18n path="i18n.info" tag="p"> |
||||||
|
<a place="action" href="https://element.eleme.cn/2.0/#/zh-CN/component/i18n">{{ $t('i18n.value') }}</a> |
||||||
|
</i18n> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</section> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
data(){ |
||||||
|
return { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
.list{ |
||||||
|
padding: 30px 0; |
||||||
|
} |
||||||
|
.list p{ |
||||||
|
margin-bottom: 20px; |
||||||
|
} |
||||||
|
a{ |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,225 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div class="crumbs"> |
||||||
|
<el-breadcrumb separator="/"> |
||||||
|
<el-breadcrumb-item><i class="el-icon-lx-emoji"></i> 自定义图标</el-breadcrumb-item> |
||||||
|
</el-breadcrumb> |
||||||
|
</div> |
||||||
|
<div class="container"> |
||||||
|
<h2>使用方法</h2> |
||||||
|
<p style="line-height: 50px;"> |
||||||
|
直接通过设置类名为 el-icon-lx-iconName 来使用即可。例如:(共{{iconList.length}}个图标) |
||||||
|
</p> |
||||||
|
<p class="example-p"> |
||||||
|
<i class="el-icon-lx-redpacket_fill" style="font-size: 30px;color: #ff5900"></i> |
||||||
|
<span><i class="el-icon-lx-redpacket_fill"></i></span> |
||||||
|
</p> |
||||||
|
<p class="example-p"> |
||||||
|
<i class="el-icon-lx-weibo" style="font-size: 30px;color:#fd5656"></i> |
||||||
|
<span><i class="el-icon-lx-weibo"></i></span> |
||||||
|
</p> |
||||||
|
<p class="example-p"> |
||||||
|
<i class="el-icon-lx-emojifill" style="font-size: 30px;color: #ffc300"></i> |
||||||
|
<span><i class="el-icon-lx-emojifill"></i></span> |
||||||
|
</p> |
||||||
|
<br> |
||||||
|
<h2>图标</h2> |
||||||
|
<div class="search-box"> |
||||||
|
<el-input class="search" size="large" v-model="keyword" clearable placeholder="请输入图标名称"></el-input> |
||||||
|
</div> |
||||||
|
<ul> |
||||||
|
<li class="icon-li" v-for="(item,index) in list" :key="index"> |
||||||
|
<div class="icon-li-content"> |
||||||
|
<i :class="`el-icon-lx-${item}`"></i> |
||||||
|
<span>{{item}}</span> |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
data: function(){ |
||||||
|
return { |
||||||
|
keyword: '', |
||||||
|
iconList: [ |
||||||
|
'attentionforbid', |
||||||
|
'attentionforbidfill', |
||||||
|
'attention', |
||||||
|
'attentionfill', |
||||||
|
'tag', |
||||||
|
'tagfill', |
||||||
|
'people', |
||||||
|
'peoplefill', |
||||||
|
'notice', |
||||||
|
'noticefill', |
||||||
|
'mobile', |
||||||
|
'mobilefill', |
||||||
|
'voice', |
||||||
|
'voicefill', |
||||||
|
'unlock', |
||||||
|
'lock', |
||||||
|
'home', |
||||||
|
'homefill', |
||||||
|
'delete', |
||||||
|
'deletefill', |
||||||
|
'notification', |
||||||
|
'notificationfill', |
||||||
|
'notificationforbidfill', |
||||||
|
'like', |
||||||
|
'likefill', |
||||||
|
'comment', |
||||||
|
'commentfill', |
||||||
|
'camera', |
||||||
|
'camerafill', |
||||||
|
'warn', |
||||||
|
'warnfill', |
||||||
|
'time', |
||||||
|
'timefill', |
||||||
|
'location', |
||||||
|
'locationfill', |
||||||
|
'favor', |
||||||
|
'favorfill', |
||||||
|
'skin', |
||||||
|
'skinfill', |
||||||
|
'news', |
||||||
|
'newsfill', |
||||||
|
'record', |
||||||
|
'recordfill', |
||||||
|
'emoji', |
||||||
|
'emojifill', |
||||||
|
'message', |
||||||
|
'messagefill', |
||||||
|
'goods', |
||||||
|
'goodsfill', |
||||||
|
'crown', |
||||||
|
'crownfill', |
||||||
|
'move', |
||||||
|
'add', |
||||||
|
'hot', |
||||||
|
'hotfill', |
||||||
|
'service', |
||||||
|
'servicefill', |
||||||
|
'present', |
||||||
|
'presentfill', |
||||||
|
'pic', |
||||||
|
'picfill', |
||||||
|
'rank', |
||||||
|
'rankfill', |
||||||
|
'male', |
||||||
|
'female', |
||||||
|
'down', |
||||||
|
'top', |
||||||
|
'recharge', |
||||||
|
'rechargefill', |
||||||
|
'forward', |
||||||
|
'forwardfill', |
||||||
|
'info', |
||||||
|
'infofill', |
||||||
|
'redpacket', |
||||||
|
'redpacket_fill', |
||||||
|
'roundadd', |
||||||
|
'roundaddfill', |
||||||
|
'friendadd', |
||||||
|
'friendaddfill', |
||||||
|
'cart', |
||||||
|
'cartfill', |
||||||
|
'more', |
||||||
|
'moreandroid', |
||||||
|
'back', |
||||||
|
'right', |
||||||
|
'shop', |
||||||
|
'shopfill', |
||||||
|
'question', |
||||||
|
'questionfill', |
||||||
|
'roundclose', |
||||||
|
'roundclosefill', |
||||||
|
'roundcheck', |
||||||
|
'roundcheckfill', |
||||||
|
'global', |
||||||
|
'mail', |
||||||
|
'punch', |
||||||
|
'exit', |
||||||
|
'upload', |
||||||
|
'read', |
||||||
|
'file', |
||||||
|
'link', |
||||||
|
'full', |
||||||
|
'group', |
||||||
|
'friend', |
||||||
|
'profile', |
||||||
|
'addressbook', |
||||||
|
'calendar', |
||||||
|
'text', |
||||||
|
'copy', |
||||||
|
'share', |
||||||
|
'wifi', |
||||||
|
'vipcard', |
||||||
|
'weibo', |
||||||
|
'remind', |
||||||
|
'refresh', |
||||||
|
'filter', |
||||||
|
'settings', |
||||||
|
'scan', |
||||||
|
'qrcode', |
||||||
|
'cascades', |
||||||
|
'apps', |
||||||
|
'sort', |
||||||
|
'searchlist', |
||||||
|
'search', |
||||||
|
'edit' |
||||||
|
] |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
list(){ |
||||||
|
return this.iconList.filter((item) => { |
||||||
|
return item.indexOf(this.keyword) !== -1; |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
.example-p{ |
||||||
|
height: 45px; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
.search-box{ |
||||||
|
text-align: center; |
||||||
|
margin-top: 10px; |
||||||
|
} |
||||||
|
.search{ |
||||||
|
width: 300px; |
||||||
|
} |
||||||
|
ul,li{ |
||||||
|
list-style: none; |
||||||
|
} |
||||||
|
.icon-li{ |
||||||
|
display: inline-block; |
||||||
|
padding: 10px; |
||||||
|
width: 120px; |
||||||
|
height: 120px; |
||||||
|
} |
||||||
|
.icon-li-content{ |
||||||
|
display: flex; |
||||||
|
height: 100%; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.icon-li-content i{ |
||||||
|
font-size: 36px; |
||||||
|
color: #606266; |
||||||
|
} |
||||||
|
.icon-li-content span{ |
||||||
|
margin-top: 10px; |
||||||
|
color: #787878; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,156 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div> |
||||||
|
<div class="flex-center mgb20"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>筛选</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<div class="flex-between no-mb"> |
||||||
|
<div> |
||||||
|
<el-form label-width="80px" inline> |
||||||
|
<el-form-item label="创建人"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择创建人" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="试题类型"> |
||||||
|
<el-select v-model="publishStatus" clearable placeholder="请选择试题类型" @change="getData"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-input placeholder="请输入题库名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover"> |
||||||
|
<div class="flex-between mgb20"> |
||||||
|
<div class="flex-center"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>分类管理</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-button type="primary" size="small" round @click="delAllSelection" v-auth>批量删除</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table :data="listData" class="table" stripe header-align="center" row-key="id"> |
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="题干" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="试题类型" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="对应课程" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="所属题库" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="知识点" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="使用次数" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="共享时间" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="创建人" align="center"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="300"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="editFirst(scope.row)" v-auth>修改</el-button> |
||||||
|
<el-button type="text" @click="handleDelete(scope.row)" v-auth>删除</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> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-dialog :title="firstId ? '编辑一级分类' : '添加一级分类'" :visible.sync="firstVisible" width="24%" center :close-on-click-modal="false"> |
||||||
|
<el-form> |
||||||
|
<el-form-item> |
||||||
|
<el-input placeholder="请输入题库分类名称" v-model="firstName"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="firstVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" @click="firstSubmit">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog :title="secondId ? '编辑二级分类' : '添加二级分类'" :visible.sync="secondVisible" width="24%" center :close-on-click-modal="false"> |
||||||
|
<el-form> |
||||||
|
<el-form-item> |
||||||
|
<el-input placeholder="请输入题库分类名称" v-model="secondName"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="secondVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" @click="secondSubmit">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
listData: [], |
||||||
|
keyword: '', |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
searchTimer: null, |
||||||
|
firstVisible: false, |
||||||
|
firstId: '', |
||||||
|
firstName: '', |
||||||
|
secondVisible: false, |
||||||
|
secondName: '', |
||||||
|
secondId: '' |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
// this.$get(this.api.list, { |
||||||
|
// page: this.page, |
||||||
|
// size: this.pageSize, |
||||||
|
// questionStem: this.keyword, |
||||||
|
// questionType: this.subject |
||||||
|
// }) |
||||||
|
// .then(res => { |
||||||
|
// this.dataTotal = res.page.totalCount; //总条数 |
||||||
|
// this.page = res.page.currPage; //当前页数 |
||||||
|
// this.orderData = res.page.list; |
||||||
|
// this.$refs.table.clearSelection() |
||||||
|
// }) |
||||||
|
// .catch(err => {}) |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.page = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
handleDelete(row) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.deleteColumn}/${row.id}`).then(res => { |
||||||
|
this.$message.success('删除成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
@ -0,0 +1,41 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div class="tabs mgb20"> |
||||||
|
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{item}}</a> |
||||||
|
</div> |
||||||
|
|
||||||
|
<my-ques-bank v-if="active == 'my'"></my-ques-bank> |
||||||
|
<global-ques-bank v-else></global-ques-bank> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import myQuesBank from './myQuesBank' |
||||||
|
import globalQuesBank from './globalQuesBank' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
active: 'my', |
||||||
|
tabs: { |
||||||
|
my: '我上传的题库', |
||||||
|
global: '公共题库' |
||||||
|
} |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
myQuesBank, |
||||||
|
globalQuesBank, |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
|
||||||
|
}, |
||||||
|
methods: { |
||||||
|
tabChange(index){ |
||||||
|
this.active = index |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,752 @@ |
|||||||
|
<template> |
||||||
|
<div |
||||||
|
style="width:100%;height:100%;display:flex; |
||||||
|
align-items: center;flex-direction:column " |
||||||
|
> |
||||||
|
<!-- 头像部分 --> |
||||||
|
<div class="header"> |
||||||
|
<img :src="avatar" class="HeadPortrait" /> |
||||||
|
<div style="color:#cb221c;font-size:14px;font-family:MicrosoftYaHei;margin-top:5px;"> |
||||||
|
<el-upload |
||||||
|
class="upload-demo" |
||||||
|
action="http://www.liuwanr.cn:8080/user/uploadUserAvatars" |
||||||
|
:data="{userId:this.userId}" |
||||||
|
name="file" |
||||||
|
:limit="3" |
||||||
|
:on-success="getRes" |
||||||
|
> |
||||||
|
<div>点击更改头像</div> |
||||||
|
</el-upload> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 用户信息 --> |
||||||
|
<div class="card"> |
||||||
|
<p class="block-title" style="display: flex;justify-content: space-between;align-items: center;"> |
||||||
|
用户信息 |
||||||
|
<el-button type="success" size="small" v-throttle @click="save">更新资料</el-button> |
||||||
|
</p> |
||||||
|
<p class="meta-title">个人信息</p> |
||||||
|
<div class="information"> |
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">姓名</p> |
||||||
|
<div class="block-right"> |
||||||
|
<input |
||||||
|
id="username" |
||||||
|
type="text" |
||||||
|
v-model="personalInformation.userName" |
||||||
|
/> |
||||||
|
<div class="ii"> |
||||||
|
<label for="username"> |
||||||
|
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i> |
||||||
|
</label> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">性别</p> |
||||||
|
<el-select |
||||||
|
v-model="personalInformation.sex" |
||||||
|
placeholder |
||||||
|
> |
||||||
|
<el-option |
||||||
|
v-for="item in sexList" |
||||||
|
:key="item.value" |
||||||
|
:label="item.name" |
||||||
|
:value="item.value" |
||||||
|
></el-option> |
||||||
|
</el-select> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">所在国家</p> |
||||||
|
<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-select> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">所在省份</p> |
||||||
|
<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-select> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">所在省市</p> |
||||||
|
<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-select> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">出生年月日</p> |
||||||
|
<el-date-picker |
||||||
|
v-model="personalInformation.dateBirth" |
||||||
|
:clearable="false" |
||||||
|
class="block-right" |
||||||
|
type="date"> |
||||||
|
</el-date-picker> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">证件</p> |
||||||
|
<div class="block-right"> |
||||||
|
<input |
||||||
|
id="idnumber" |
||||||
|
type="text" |
||||||
|
v-model="personalInformation.idnumber" |
||||||
|
/> |
||||||
|
<div class="ii"> |
||||||
|
<label for="idnumber"> |
||||||
|
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i> |
||||||
|
</label> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">教育程度</p> |
||||||
|
<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-select> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">当前所在学校</p> |
||||||
|
<el-select v-model="personalInformation.clientId" filterable placeholder="请选择学校"> |
||||||
|
<el-option v-for="(item,index) in schoolList" :key="index" :label="item.clientName" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="card mgb20"> |
||||||
|
<p class="block-title">账号信息</p> |
||||||
|
<div class="information"> |
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">用户账号</p> |
||||||
|
<div class="block-right"> |
||||||
|
<input |
||||||
|
id="account" |
||||||
|
type="text" |
||||||
|
v-model="personalInformation.account" |
||||||
|
@change="accountChange" |
||||||
|
/> |
||||||
|
<div class="ii"> |
||||||
|
<label for="account"> |
||||||
|
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i> |
||||||
|
</label> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">手机号</p> |
||||||
|
<div class="block-right"> |
||||||
|
<input |
||||||
|
id="phone" |
||||||
|
type="text" |
||||||
|
maxlength="11" |
||||||
|
v-model="personalInformation.phone" |
||||||
|
/> |
||||||
|
<div class="ii"> |
||||||
|
<label for="phone"> |
||||||
|
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i> |
||||||
|
</label> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<!-- <div class="near-right"> |
||||||
|
{{personalInformation.phone}} |
||||||
|
<el-button size="small" @click="bindPhone">更换</el-button> |
||||||
|
</div> --> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">邮箱</p> |
||||||
|
<div class="block-right"> |
||||||
|
<input |
||||||
|
id="email" |
||||||
|
type="text" |
||||||
|
class="block-right" |
||||||
|
v-model="personalInformation.email" |
||||||
|
/> |
||||||
|
<div class="ii"> |
||||||
|
<label for="email"> |
||||||
|
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i> |
||||||
|
</label> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<!-- <div class="near-right"> --> |
||||||
|
<!-- {{personalInformation.email}} --> |
||||||
|
<!-- <el-button size="small" @click="bindEmail">绑定</el-button> --> |
||||||
|
<!-- </div> --> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- <div class="block"> |
||||||
|
<p class="block-left">微信</p> --> |
||||||
|
<!-- <input |
||||||
|
id="wechat" |
||||||
|
type="text" |
||||||
|
class="block-right" |
||||||
|
v-model="personalInformation.weChatID" |
||||||
|
/> |
||||||
|
<div class="ii"> |
||||||
|
<label for="wechat"> |
||||||
|
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i> |
||||||
|
</label> |
||||||
|
</div> --> |
||||||
|
<!-- <div class="near-right"> |
||||||
|
{{personalInformation.weChatID}} |
||||||
|
<el-button size="small">绑定</el-button> |
||||||
|
</div> |
||||||
|
</div> --> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="block-left">密码</p> |
||||||
|
<div class="near-right"> |
||||||
|
<el-button size="small" @click="bindPassword">更换密码</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-dialog |
||||||
|
title="更换密码" |
||||||
|
:visible.sync="passwordVisible" |
||||||
|
:close-on-click-modal="false" |
||||||
|
@close="closePassword" |
||||||
|
width="30%"> |
||||||
|
<el-form ref="passwordForm" :model="form" label-width="60px"> |
||||||
|
<el-form-item label="原密码"> |
||||||
|
<el-input type="password" v-model="passwordForm.password" placeholder="请输入原密码"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="新密码"> |
||||||
|
<el-input type="password" v-model="passwordForm.newPassword" placeholder="请输入新密码" @keyup.enter.native="editPassword"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="新密码"> |
||||||
|
<el-input type="password" v-model="passwordForm.reNewPassword" placeholder="请确认新密码" @keyup.enter.native="editPassword"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="passwordVisible = false">取 消</el-button> |
||||||
|
<el-button type="primary" @click="editPassword">确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { mapState,mapActions } from 'vuex'; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
personalInformation: { |
||||||
|
name:'', |
||||||
|
workNumber:'', |
||||||
|
password:"", |
||||||
|
phone:'', |
||||||
|
email:'', |
||||||
|
provinceName:'', |
||||||
|
cityName:'', |
||||||
|
schoolName:'', |
||||||
|
professionalName:'', |
||||||
|
}, |
||||||
|
passwordVisible: false, |
||||||
|
passwordForm: { |
||||||
|
password: '', |
||||||
|
newPassword: '', |
||||||
|
reNewPassword: '' |
||||||
|
}, |
||||||
|
sexList: [ |
||||||
|
{ |
||||||
|
name: '男', |
||||||
|
value: 1 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '女', |
||||||
|
value: 2 |
||||||
|
} |
||||||
|
], |
||||||
|
countryList: [ |
||||||
|
{ |
||||||
|
label: '中国' |
||||||
|
} |
||||||
|
], |
||||||
|
form: {}, |
||||||
|
provinceList: [], //省份 |
||||||
|
cityList: [], //城市 |
||||||
|
// 教育程度 |
||||||
|
educationDegreeList: [ |
||||||
|
{ |
||||||
|
name: '专科', |
||||||
|
value: 1 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '本科', |
||||||
|
value: 2 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '硕士', |
||||||
|
value: 3 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '博士', |
||||||
|
value: 4 |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '其他', |
||||||
|
value: 5 |
||||||
|
} |
||||||
|
], |
||||||
|
schoolList: [], |
||||||
|
curPassword: '', |
||||||
|
accountRepeat: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
...mapState('user', [ |
||||||
|
'userId','avatar' |
||||||
|
]) |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getdata(); |
||||||
|
this.getProvince() |
||||||
|
this.getSchoolData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
...mapActions('user', [ |
||||||
|
'setAvatar' |
||||||
|
]), |
||||||
|
getProvince(){ |
||||||
|
this.$get(this.api.queryProvince).then(res => { |
||||||
|
this.provinceList = res.data.list |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
// 获取城市 |
||||||
|
getCity(id,type){ |
||||||
|
this.personalInformation.cityId = 1 |
||||||
|
this.getCityData() |
||||||
|
}, |
||||||
|
getCityData(index){ |
||||||
|
let provinceId = this.personalInformation.provinceId |
||||||
|
this.$get(this.api.queryCity,{provinceId}).then(res => { |
||||||
|
this.cityList = res.data.list |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
// 获取学校名称 |
||||||
|
getSchoolData(){ |
||||||
|
let data = { |
||||||
|
searchContent: '', |
||||||
|
provinceId: '', |
||||||
|
cityId: '' |
||||||
|
} |
||||||
|
this.$get(`${this.api.queryClient}/1/1000`,data).then(res => { |
||||||
|
this.schoolList = res.data.list |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
accountChange(){ |
||||||
|
this.$get(`${this.api.getAccount}?account=${this.form.account}`).then(res => { |
||||||
|
if(res.data.userInfo){ |
||||||
|
this.accountRepeat = true |
||||||
|
this.$message.warning('该账号已存在') |
||||||
|
}else{ |
||||||
|
this.accountRepeat = false |
||||||
|
} |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
//取得头像地址 |
||||||
|
getRes(res) { |
||||||
|
this.setAvatar(res.message) |
||||||
|
}, |
||||||
|
uploadHeadImg: function() { |
||||||
|
this.$el.querySelector('.hiddenInput').click(); |
||||||
|
}, |
||||||
|
getdata() { |
||||||
|
this.$get(`${this.api.userinfo}?userId=${this.userId}`) |
||||||
|
.then(res => { |
||||||
|
this.personalInformation = res.data.userInfo |
||||||
|
this.personalInformation.countries = '中国' |
||||||
|
this.curPassword = this.personalInformation.password |
||||||
|
this.$nextTick(() => { |
||||||
|
if(this.personalInformation.provinceId){ |
||||||
|
this.getCityData(1) |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
console.log(err); |
||||||
|
}); |
||||||
|
}, |
||||||
|
bindPassword() { |
||||||
|
this.passwordVisible = true |
||||||
|
}, |
||||||
|
editPassword() { |
||||||
|
if(!this.passwordForm.password) return this.$message.warning('请输入原密码') |
||||||
|
if(!this.passwordForm.newPassword) return this.$message.warning('请输入新密码') |
||||||
|
if(!this.passwordForm.reNewPassword) return this.$message.warning('请确认新密码') |
||||||
|
if(this.passwordForm.newPassword.length < 6 || this.passwordForm.reNewPassword.length < 6) return this.$message.warning('请输入6位数以上的密码') |
||||||
|
if(this.passwordForm.newPassword !== this.passwordForm.reNewPassword) return this.$message.warning('输入的新密码不一致,请重新确认') |
||||||
|
if(this.curPassword === this.passwordForm.newPassword) return this.$message.warning('原密码跟新密码不能一致') |
||||||
|
|
||||||
|
let data = { |
||||||
|
userId: this.personalInformation.userId, |
||||||
|
password: this.passwordForm.password |
||||||
|
} |
||||||
|
this.$post(this.api.userinfoUpdate,data) |
||||||
|
.then(res => { |
||||||
|
if(res.success){ |
||||||
|
this.$message.success('更换成功') |
||||||
|
this.curPassword = this.passwordForm.newPassword |
||||||
|
this.passwordVisible = false |
||||||
|
}else{ |
||||||
|
this.$message.error('更换失败') |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
console.log(err); |
||||||
|
}); |
||||||
|
}, |
||||||
|
closePassword() { |
||||||
|
this.passwordForm = { |
||||||
|
password: '', |
||||||
|
newPassword: '', |
||||||
|
reNewPassword: '' |
||||||
|
} |
||||||
|
}, |
||||||
|
save() { |
||||||
|
if(this.personalInformation.idnumber && !/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)/.test(this.personalInformation.idnumber)) return this.$message.warning('请输入正确的证件号码') |
||||||
|
if(this.accountRepeat) return this.$message.warning('该账号已存在') |
||||||
|
if(this.personalInformation.phone && !/^1[3456789]\d{9}$/.test(this.personalInformation.phone)) return this.$message.warning('请输入正确的手机号') |
||||||
|
if(this.personalInformation.email && !/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(this.personalInformation.email)) return this.$message.warning('请输入正确的邮箱') |
||||||
|
let personalInformation = this.personalInformation |
||||||
|
let userInfoEntity = { |
||||||
|
idnumber: personalInformation.idnumber, |
||||||
|
account: personalInformation.account, |
||||||
|
cityId: personalInformation.cityId, |
||||||
|
countries: personalInformation.countries, |
||||||
|
dateBirth: personalInformation.dateBirth, |
||||||
|
educationDegree: personalInformation.educationDegree, |
||||||
|
email: personalInformation.email, |
||||||
|
phone: personalInformation.phone, |
||||||
|
provinceId: personalInformation.provinceId, |
||||||
|
clientId: personalInformation.clientId, |
||||||
|
clientName: this.schoolList.find(n => n.id == personalInformation.clientId).clientName, |
||||||
|
sex: personalInformation.sex, |
||||||
|
userId: personalInformation.userId, |
||||||
|
userName: personalInformation.userName, |
||||||
|
} |
||||||
|
let data = userInfoEntity |
||||||
|
this.$post(this.api.userinfoUpdate,data).then(res => { |
||||||
|
if(res.success){ |
||||||
|
this.$message.success('提交成功') |
||||||
|
this.$router.back() |
||||||
|
}else{ |
||||||
|
this.$message.error('提交失败') |
||||||
|
} |
||||||
|
}).catch(res => {}); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.header{ |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
.header /deep/.el-upload-list__item-name { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
.header /deep/.el-icon-upload-success{ |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
.header /deep/.el-upload-list__item-status-label{ |
||||||
|
display: none; |
||||||
|
} |
||||||
|
.header /deep/ .el-upload-list{ |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
/deep/.el-input__inner{ |
||||||
|
height: 32px !important; |
||||||
|
} |
||||||
|
/deep/.el-select .el-input .el-select__caret{ |
||||||
|
line-height: 32px; |
||||||
|
} |
||||||
|
input:focus { |
||||||
|
outline: 0; |
||||||
|
} |
||||||
|
.header { |
||||||
|
background: #f0f0f0; |
||||||
|
} |
||||||
|
.openfile { |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.HeadPortrait { |
||||||
|
margin-top: 10px; |
||||||
|
width: 80px; |
||||||
|
height: 80px; |
||||||
|
background: url('../../../assets/img/img.jpg'); |
||||||
|
border-radius: 50%; |
||||||
|
|
||||||
|
.head { |
||||||
|
width: 34px; |
||||||
|
height: 34px; |
||||||
|
background: rgba(255, 255, 255, 1); |
||||||
|
border-radius: 50%; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
position: relative; |
||||||
|
.eee { |
||||||
|
height: 10px; |
||||||
|
width: 16px; |
||||||
|
background-color: rgba(255, 255, 255, 1); |
||||||
|
margin-bottom: -10px; |
||||||
|
position: absolute; |
||||||
|
top: 8px; |
||||||
|
z-index: 2; |
||||||
|
} |
||||||
|
.Semicircle { |
||||||
|
width: 12px; |
||||||
|
height: 12px; |
||||||
|
border: 2px solid #cb221c; |
||||||
|
border-radius: 50px; |
||||||
|
margin-bottom: 10px; |
||||||
|
position: absolute; |
||||||
|
} |
||||||
|
} |
||||||
|
.body { |
||||||
|
color: #cb221c; |
||||||
|
width: 30px; |
||||||
|
height: 20px; |
||||||
|
border: 3px solid #f5f5f5; |
||||||
|
border-radius: 100%; |
||||||
|
margin-top: 5px; |
||||||
|
margin-bottom: -10px; |
||||||
|
} |
||||||
|
.body::after { |
||||||
|
content: ''; |
||||||
|
width: 40px; |
||||||
|
height: 30px; |
||||||
|
display: inline-block; |
||||||
|
background-color: #cb221c; |
||||||
|
margin-top: 8px; |
||||||
|
margin-left: -6px; |
||||||
|
} |
||||||
|
} |
||||||
|
input { |
||||||
|
height: 50px; |
||||||
|
width: 300px; |
||||||
|
border: 0; |
||||||
|
text-align: right; |
||||||
|
outline: none; |
||||||
|
} |
||||||
|
|
||||||
|
.card { |
||||||
|
margin-top: 10px; |
||||||
|
width: 750px; |
||||||
|
padding: 20px; |
||||||
|
background: rgba(255, 255, 255, 1); |
||||||
|
box-shadow: 0px 0px 21px 0px rgba(48, 115, 248, 0.1); |
||||||
|
border-radius: 10px; |
||||||
|
position: relative; |
||||||
|
.block-title{ |
||||||
|
font-weight: bold; |
||||||
|
font-size: 20px; |
||||||
|
} |
||||||
|
.meta-title{ |
||||||
|
margin: 10px 0 0; |
||||||
|
color: #cdbcec; |
||||||
|
font-size: 15px; |
||||||
|
} |
||||||
|
.el-icon-document { |
||||||
|
color: #cb221c; |
||||||
|
font-size: 30px; |
||||||
|
} |
||||||
|
.el-icon-collection { |
||||||
|
color: #cb221c; |
||||||
|
position: absolute; |
||||||
|
left: 31px; |
||||||
|
top: 31px; |
||||||
|
font-size: 30px; |
||||||
|
} |
||||||
|
span { |
||||||
|
color: #333333; |
||||||
|
font-size: 20px; |
||||||
|
} |
||||||
|
.plus{ |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
i{ |
||||||
|
font-size: 22px; |
||||||
|
color: #21d749; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
.archives{ |
||||||
|
padding: 10px 20px; |
||||||
|
margin-top: 20px; |
||||||
|
border: 1px dashed #bbb; |
||||||
|
border-radius: 12px; |
||||||
|
|
||||||
|
&.default-arch{ |
||||||
|
margin-bottom: 20px; |
||||||
|
/deep/.el-select{ |
||||||
|
width: 10rem; |
||||||
|
} |
||||||
|
/deep/input{ |
||||||
|
background-color: transparent; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.archives-wrap{ |
||||||
|
.block{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 8px; |
||||||
|
&:last-child{ |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.block-left{ |
||||||
|
width: 30%; |
||||||
|
font-family: MicrosoftYaHei; |
||||||
|
font-size: 14px; |
||||||
|
color: #101010; |
||||||
|
} |
||||||
|
/deep/.el-input__inner{ |
||||||
|
border-radius: 8px !important; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.information { |
||||||
|
.block { |
||||||
|
line-height: 38px; |
||||||
|
position: relative; |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
.block-left { |
||||||
|
font-family: MicrosoftYaHei; |
||||||
|
font-size: 14px; |
||||||
|
color: #101010; |
||||||
|
} |
||||||
|
input{ |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
/deep/.el-date-editor .el-input__prefix{ |
||||||
|
line-height: 32px; |
||||||
|
} |
||||||
|
/deep/.el-input__prefix,/deep/.el-input__suffix{ |
||||||
|
left: auto; |
||||||
|
right: 0; |
||||||
|
} |
||||||
|
.block-right,.near-right { |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
color: #333333ff; |
||||||
|
font-size: 18px; |
||||||
|
} |
||||||
|
.near-right{ |
||||||
|
right: 0; |
||||||
|
font-size: 18px; |
||||||
|
} |
||||||
|
.ii { |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
width: 22px; |
||||||
|
height: 22px; |
||||||
|
margin-left: 10px; |
||||||
|
border-radius: 50%; |
||||||
|
background-color: #cb221c; |
||||||
|
i{ |
||||||
|
font-size: 12px; |
||||||
|
} |
||||||
|
} |
||||||
|
/deep/.el-input__inner { |
||||||
|
padding-right: 1.8rem; |
||||||
|
margin-right: 5px; |
||||||
|
color: #333333ff; |
||||||
|
font-size: 16px; |
||||||
|
text-align: right; |
||||||
|
border: 0px; |
||||||
|
} |
||||||
|
/deep/.el-input__icon { |
||||||
|
background: #cb221c; |
||||||
|
width: 22px; |
||||||
|
height: 22px; |
||||||
|
line-height: 22px; |
||||||
|
color: rgba(255, 255, 255, 1); |
||||||
|
border-radius: 50%; |
||||||
|
|
||||||
|
&.el-icon-date{ |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/deep/.el-icon-arrow-up:before { |
||||||
|
content: '\e6e1'; |
||||||
|
margin-top: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
&.readonly .block-left{ |
||||||
|
color: #a5a7adff; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.fold{ |
||||||
|
margin-top: 20px; |
||||||
|
text-align: center; |
||||||
|
i{ |
||||||
|
font-size: 22px; |
||||||
|
color: #8e8e8e; |
||||||
|
cursor: pointer; |
||||||
|
&:hover{ |
||||||
|
opacity: .8; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,550 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-container> |
||||||
|
<el-aside width="350px"> |
||||||
|
<StudentSide ref="getSelectData" @fircheck="fircheck" @twocheck="twocheck" @threecheck="threecheck"></StudentSide> |
||||||
|
</el-aside> |
||||||
|
|
||||||
|
<el-main style="padding-top: 0"> |
||||||
|
<el-col :span="24"> |
||||||
|
<el-card shadow="hover" class="mgb20 student_tab"> |
||||||
|
<div class="flex-between mgb20"> |
||||||
|
<div> |
||||||
|
<el-input placeholder="请输入学生名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-button type="primary" size="small" round @click="addstudent">新增学生</el-button> |
||||||
|
<el-button type="primary" size="small" round class="mag" @click="batchImport">批量导入</el-button> |
||||||
|
<el-button type="primary" size="small" round @click="delAllSelection">批量删除</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange"> |
||||||
|
<el-table-column type="selection" width="55" align="center"></el-table-column> |
||||||
|
<el-table-column type="index" label="序号" width="55" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="studentName" label="学生姓名" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="workNumber" label="学生学号" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="professionalName" label="专业" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="gradeName" label="年级" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="className" label="班级" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="roleId" label="账号角色" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
学生 |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="loginNumber" label="登录次数" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="lastLoginTime" label="上次登录时间" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<!-- <el-button type="text">查看</el-button> --> |
||||||
|
<el-button type="text" @click="editstudent(scope.row)">编辑</el-button> |
||||||
|
<el-button type="text" @click="delstudent(scope.row)">删除</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background layout="prev, pager, next" :current-page="page" @current-change="handleCurrentChange" :total="total"> |
||||||
|
</el-pagination> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</el-col> |
||||||
|
</el-main> |
||||||
|
</el-container> |
||||||
|
|
||||||
|
<el-dialog :title="isAdd ? '新增学生' : '编辑学生'" :visible.sync="studentVisible" |
||||||
|
width="30%" center @close="closestudent" class="dialog" :close-on-click-modal="false"> |
||||||
|
<el-form ref="studentForm" :model="studentForm" :rules="rules" label-width="80px"> |
||||||
|
<el-form-item prop="account" label="账号"> |
||||||
|
<el-input v-model="studentForm.account" placeholder="请输入学生账号" @change="accountChange"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="userName" label="学生姓名"> |
||||||
|
<el-input v-model="studentForm.userName" placeholder="请输入学生姓名"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="账号角色"> |
||||||
|
学生 |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="uniqueIdentificationAccount" label="唯一标识"> |
||||||
|
<el-input disabled v-model="studentForm.uniqueIdentificationAccount" placeholder="请输入学生学号获取唯一标识"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="workNumber" label="学生学号"> |
||||||
|
<el-input v-model="studentForm.workNumber" placeholder="请输入学生学号" @change="workNumberChange"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="professionalId" label="专业"> |
||||||
|
<el-select v-model="studentForm.professionalId" placeholder="请选择专业" @change="getGrade"> |
||||||
|
<el-option v-for="(item,index) in majorList" :key="index" |
||||||
|
:label="item.stuProfessionalArchitectureName" :value="item.stuProfessionalArchitectureId"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="gradeId" label="年级"> |
||||||
|
<el-select v-model="studentForm.gradeId" placeholder="请选择年级" :disabled="studentForm.professionalId ? false : true" @change="getClass"> |
||||||
|
<el-option v-for="(item,index) in gradeList" :key="index" |
||||||
|
:label="item.gradeName" :value="item.gradeId"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="classId" label="班级"> |
||||||
|
<el-select v-model="studentForm.classId" placeholder="请选择班级" :disabled="studentForm.gradeId ? false : true"> |
||||||
|
<el-option v-for="(item,index) in classList" :key="index" |
||||||
|
:label="item.className" :value="item.classId"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="phone" label="手机号"> |
||||||
|
<el-input v-model="studentForm.phone" placeholder="可以用于登录平台,以及找回密码" maxlength="11"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="email" label="邮箱"> |
||||||
|
<el-input v-model="studentForm.email" placeholder="可以用于登录平台,以及找回密码"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="studentVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" @click="saveSure('studentForm')">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" center :close-on-click-modal="false"> |
||||||
|
<div style="text-align: center"> |
||||||
|
<div style="margin-bottom: 10px;"><el-button type="primary" @click="downLoad">模板下载<i class="el-icon-download el-icon--right"></i></el-button></div> |
||||||
|
<el-upload |
||||||
|
accept=".xls,.xlsx" |
||||||
|
:on-remove="handleRemove" |
||||||
|
:on-error="uploadError" |
||||||
|
:on-success="uploadSuccess" |
||||||
|
:before-remove="beforeRemove" |
||||||
|
:limit="1" |
||||||
|
:on-exceed="handleExceed" |
||||||
|
:action="this.api.uploadFileStudent" |
||||||
|
:file-list="uploadList" |
||||||
|
name="file" |
||||||
|
> |
||||||
|
<el-button type="primary" class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button> |
||||||
|
</el-upload> |
||||||
|
<el-link v-if="uploadFaild" type="primary" @click="showFaild">导入失败,查看原因</el-link> |
||||||
|
</div> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="importVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" @click="uploadSure">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import StudentSide from './studentSide' |
||||||
|
import { mapState,mapGetters } from 'vuex' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
studentVisible: false, |
||||||
|
studentForm: { |
||||||
|
clientId: this.clientId, |
||||||
|
clientName: this.clientName, |
||||||
|
studentId: '', |
||||||
|
userName: '', |
||||||
|
workNumber: '', |
||||||
|
phone: '', |
||||||
|
email: '', |
||||||
|
professionalId: '', |
||||||
|
gradeId: '', |
||||||
|
classId: '' , |
||||||
|
uniqueIdentificationAccount: '', |
||||||
|
account: '' |
||||||
|
}, |
||||||
|
rules: { |
||||||
|
userName: [ |
||||||
|
{ required: true, message: '请输入学生姓名', trigger: 'blur' } |
||||||
|
], |
||||||
|
workNumber: [ |
||||||
|
{ required: true, message: '请输入学生学号', trigger: 'blur' }, |
||||||
|
{ |
||||||
|
pattern: /^[A-Za-z0-9]+$/, |
||||||
|
message: '请输入正确的学生学号', |
||||||
|
trigger: 'blur' |
||||||
|
} |
||||||
|
], |
||||||
|
account: [ |
||||||
|
{ required: true, message: '请输入账号', trigger: 'blur' }, |
||||||
|
{ |
||||||
|
pattern: /^[A-Za-z0-9]*$/, |
||||||
|
message: '请输入正确的账号', |
||||||
|
trigger: 'blur' |
||||||
|
} |
||||||
|
], |
||||||
|
professionalId: [ |
||||||
|
{ required: true, message: '请选择专业', trigger: 'change' } |
||||||
|
], |
||||||
|
gradeId: [ |
||||||
|
{ required: true, message: '请选择年级', trigger: 'change' } |
||||||
|
], |
||||||
|
classId: [ |
||||||
|
// { required: true, message: '请选择班级', trigger: 'change' } |
||||||
|
], |
||||||
|
phone: [ |
||||||
|
{ |
||||||
|
pattern: /^1[3456789]\d{9}$/, |
||||||
|
message: '请输入正确的手机号', |
||||||
|
trigger: 'blur' |
||||||
|
} |
||||||
|
], |
||||||
|
email: [ |
||||||
|
{ |
||||||
|
pattern: /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/, |
||||||
|
message: '请输入正确的邮箱', |
||||||
|
trigger: 'blur' |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
listData: [], |
||||||
|
importVisible: false, |
||||||
|
keyword: '', |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
searchTimer: null, |
||||||
|
majorList: [], |
||||||
|
gradeList: [], |
||||||
|
classList: [], |
||||||
|
professionalIds: '', |
||||||
|
professionalStudentIds: '', |
||||||
|
gradeIds: '', |
||||||
|
classIds: '', |
||||||
|
multipleSelection: [], |
||||||
|
uploadList: [], |
||||||
|
parmData: [], |
||||||
|
uploadFaild: false, |
||||||
|
token: '', |
||||||
|
schooldId: 1, |
||||||
|
isAdd: true, |
||||||
|
accountRepeat: false, |
||||||
|
workNumberRepeat: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
...mapState('user', [ |
||||||
|
'userId','clientId','clientName' |
||||||
|
]) |
||||||
|
}, |
||||||
|
components: { |
||||||
|
StudentSide |
||||||
|
}, |
||||||
|
mounted(){ |
||||||
|
this.studentForm.clientId = this.clientId |
||||||
|
this.studentForm.clientName = this.clientName |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData(){ |
||||||
|
let data = { |
||||||
|
searchContent: this.keyword, |
||||||
|
professionalId: this.professionalStudentIds, |
||||||
|
gradeIds: this.gradeIds, |
||||||
|
classIds: this.classIds, |
||||||
|
schoolId: this.clientId |
||||||
|
} |
||||||
|
this.$get(`${this.api.queryStudent}/${this.page}/${this.pageSize}`,data).then(res => { |
||||||
|
this.listData = res.data.studentList |
||||||
|
this.total = res.data.total |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
fircheck(val){ |
||||||
|
val.ischeck = !val.ischeck |
||||||
|
val.children.map(e => { |
||||||
|
e.children.map(r => { |
||||||
|
if(val.ischeck){ |
||||||
|
e.ischeck = true |
||||||
|
r.ischeck = true |
||||||
|
this.parmData.push(r.classId) |
||||||
|
}else{ |
||||||
|
e.ischeck = false |
||||||
|
r.ischeck = false |
||||||
|
this.core.removeByValue(this.parmData, r.classId); |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
this.classIds = this.parmData.toString() |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
twocheck(val,val2){ |
||||||
|
const twoStatus = val.ischeck |
||||||
|
val.ischeck = !twoStatus |
||||||
|
val2.map(e => { |
||||||
|
e.children.map(r => { |
||||||
|
r.children.map(k =>{ |
||||||
|
if(r.gradeId == val.gradeId){ |
||||||
|
if(r.ischeck){ |
||||||
|
e.ischeck = true |
||||||
|
k.ischeck = true |
||||||
|
this.parmData.push(k.classId) |
||||||
|
} else { |
||||||
|
e.ischeck = false |
||||||
|
k.ischeck = false |
||||||
|
this.core.removeByValue(this.parmData, k.classId); |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
this.classIds = this.parmData.toString() |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
threecheck(val,val2){ |
||||||
|
const threeStatus = val.ischeck |
||||||
|
val.ischeck = !threeStatus |
||||||
|
val2.map(e => { |
||||||
|
e.children.map(r => { |
||||||
|
r.children.map(k =>{ |
||||||
|
if(k.classId == val.classId){ |
||||||
|
if(k.ischeck){ |
||||||
|
e.ischeck = true |
||||||
|
r.ischeck = true |
||||||
|
this.parmData.push(val.classId) |
||||||
|
} else { |
||||||
|
e.ischeck = false |
||||||
|
r.ischeck = false |
||||||
|
this.core.removeByValue(this.parmData,val.classId); |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
this.classIds = this.parmData.toString() |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
closestudent(){ |
||||||
|
this.$refs.studentForm.resetFields() |
||||||
|
}, |
||||||
|
addstudent(){ |
||||||
|
this.studentForm.studentId = '' |
||||||
|
this.studentVisible = true |
||||||
|
this.isAdd = true |
||||||
|
this.majorList = this.$refs.getSelectData.majorList |
||||||
|
}, |
||||||
|
editstudent(row){ |
||||||
|
this.studentVisible = true |
||||||
|
this.isAdd = false |
||||||
|
this.studentForm.studentId = row.studentId |
||||||
|
this.majorList = this.$refs.getSelectData.majorList |
||||||
|
console.log(12,row) |
||||||
|
|
||||||
|
this.$get(`${this.api.getStudent}/${row.studentId}`).then(res => { |
||||||
|
let student = res.data.student |
||||||
|
let userInfo = res.data.userInfo |
||||||
|
this.studentForm.userName = userInfo.userName, |
||||||
|
this.studentForm.workNumber = student.workNumber, |
||||||
|
this.studentForm.uniqueIdentificationAccount = userInfo.uniqueIdentificationAccount, |
||||||
|
this.studentForm.professionalId = student.professionalId, |
||||||
|
this.studentForm.gradeId = student.gradeId, |
||||||
|
this.studentForm.classId = student.classId, |
||||||
|
this.studentForm.phone = userInfo.phone, |
||||||
|
this.studentForm.email = userInfo.email, |
||||||
|
this.studentForm.account = userInfo.account |
||||||
|
this.getGradeData() |
||||||
|
this.getClassData() |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
// 获取年级 |
||||||
|
getGrade(){ |
||||||
|
this.studentForm.gradeId = '' |
||||||
|
this.studentForm.classId = '' |
||||||
|
this.getGradeData() |
||||||
|
}, |
||||||
|
getGradeData(){ |
||||||
|
let data = { |
||||||
|
stuProfessionalArchitectureId: this.studentForm.professionalId |
||||||
|
} |
||||||
|
this.$get(this.api.queryGrade,data).then(res => { |
||||||
|
this.gradeList = res.data.Grade |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
//获取班级 |
||||||
|
getClass(){ |
||||||
|
this.studentForm.classId = '' |
||||||
|
this.getClassData() |
||||||
|
}, |
||||||
|
getClassData(){ |
||||||
|
let data = { |
||||||
|
classId: this.studentForm.gradeId |
||||||
|
} |
||||||
|
this.$get(this.api.queryClass,data).then(res => { |
||||||
|
this.classList = res.data.Class |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
async accountChange(){ |
||||||
|
this.$get(`${this.api.getAccount}?account=${this.studentForm.account}`).then(res => { |
||||||
|
if(res.data.userInfo){ |
||||||
|
this.accountRepeat = true |
||||||
|
this.$message.warning('该账号已存在') |
||||||
|
}else{ |
||||||
|
this.accountRepeat = false |
||||||
|
} |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
workNumberChange(){ |
||||||
|
this.$get(`${this.api.studentGetWorkNumber}?workNumber=${this.studentForm.workNumber}`).then(res => { |
||||||
|
if(res.data.student){ |
||||||
|
this.workNumberRepeat = true |
||||||
|
this.$message.warning('该学号已存在') |
||||||
|
}else{ |
||||||
|
this.workNumberRepeat = false |
||||||
|
} |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
saveSure(studentForm){ |
||||||
|
this.$refs[studentForm].validate((valid) => { |
||||||
|
if (valid) { |
||||||
|
if(this.accountRepeat) return this.$message.warning('该账号已存在') |
||||||
|
if(this.workNumberRepeat) return this.$message.warning('该学号已存在') |
||||||
|
let data = { |
||||||
|
userInfo: { |
||||||
|
isPort: 2, |
||||||
|
roleId: 4, |
||||||
|
clientId: this.studentForm.clientId, |
||||||
|
clientName: this.studentForm.clientName, |
||||||
|
userName: this.studentForm.userName, |
||||||
|
account: this.studentForm.account, |
||||||
|
phone: this.studentForm.phone, |
||||||
|
email: this.studentForm.email, |
||||||
|
uniqueIdentificationAccount: this.studentForm.uniqueIdentificationAccount, |
||||||
|
userId: this.studentForm.userId ? this.studentForm.userId : '' |
||||||
|
}, |
||||||
|
student: { |
||||||
|
roleId: 4, |
||||||
|
isPort: 2, |
||||||
|
professionalId: this.studentForm.professionalId, |
||||||
|
gradeId: this.studentForm.gradeId, |
||||||
|
classId: this.studentForm.classId, |
||||||
|
workNumber: this.studentForm.workNumber, |
||||||
|
schoolId: this.clientId |
||||||
|
} |
||||||
|
} |
||||||
|
if(this.studentForm.studentId){ |
||||||
|
this.$post(this.api.updateStudent,data).then(res => { |
||||||
|
this.studentVisible = false |
||||||
|
this.$message.success('编辑成功') |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}else{ |
||||||
|
this.$post(this.api.addStudent,data).then(res => { |
||||||
|
this.studentVisible = false |
||||||
|
this.$message.success('添加成功') |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
} |
||||||
|
}else{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
delstudent(row){ |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
let data = [row.studentId] |
||||||
|
this.$del(this.api.deleteStudents,data).then(res => { |
||||||
|
this.$message.success('删除成功') |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
delAllSelection() { |
||||||
|
if(this.multipleSelection.length != ''){ |
||||||
|
let newArr = this.multipleSelection |
||||||
|
let delList = newArr.map(item => { |
||||||
|
return item.studentId |
||||||
|
}) |
||||||
|
// 批量删除 |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
let data = delList |
||||||
|
this.$del(this.api.deleteStudents,data).then(res => { |
||||||
|
this.multipleSelection = [] |
||||||
|
this.$message.success('删除成功') |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}).catch(() => {}); |
||||||
|
}else{ |
||||||
|
this.$message.error('请先选择学生') |
||||||
|
} |
||||||
|
}, |
||||||
|
batchImport(){ |
||||||
|
this.importVisible = true |
||||||
|
}, |
||||||
|
searchstudent(){ |
||||||
|
this.page = 1 |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.page = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
downLoad(){ |
||||||
|
location.href = this.api.downloadStudentTemp |
||||||
|
}, |
||||||
|
// 上传文件 |
||||||
|
handleExceed(files, fileList) { |
||||||
|
this.$message.warning( |
||||||
|
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` |
||||||
|
); |
||||||
|
}, |
||||||
|
showFaild(){ |
||||||
|
location.href = `${this.api.exportFailureStudent}?token=${this.token}` |
||||||
|
}, |
||||||
|
uploadSuccess(res, file, fileList) { |
||||||
|
this.uploadFaild = false |
||||||
|
if(res.success){ |
||||||
|
if(res.data.data.token){ |
||||||
|
this.token = res.data.data.token |
||||||
|
this.uploadFaild = true |
||||||
|
}else{ |
||||||
|
this.$message.success('上传成功') |
||||||
|
} |
||||||
|
}else{ |
||||||
|
res.data.message ? this.$message.error(res.data.message) : this.$message.error('上传失败,请检查数据') |
||||||
|
} |
||||||
|
}, |
||||||
|
uploadError(err, file, fileList) { |
||||||
|
this.$message({ |
||||||
|
message: "上传出错,请重试!", |
||||||
|
type: "error", |
||||||
|
center: true |
||||||
|
}); |
||||||
|
}, |
||||||
|
beforeRemove(file, fileList) { |
||||||
|
return this.$confirm(`确定移除 ${file.name}?`); |
||||||
|
}, |
||||||
|
handleRemove(file, fileList) { |
||||||
|
this.uploadList = fileList |
||||||
|
this.uploadFaild = false |
||||||
|
}, |
||||||
|
uploadSure(){ |
||||||
|
this.importVisible = false |
||||||
|
this.page = 1 |
||||||
|
this.classIds = '' |
||||||
|
this.keyword = '' |
||||||
|
this.getData() |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,515 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div> |
||||||
|
<!-- <p class="side_icon mab20"> |
||||||
|
<i class="icon-jiahao mar20" @click="addMajor()"></i> --> |
||||||
|
<!-- <i class="icon-delete"></i> --> |
||||||
|
<!-- </p> --> |
||||||
|
<lctree :data="majorList" |
||||||
|
@addMajor="addMajor" @editmajorClass="editmajorClass" @delClassDepartment="delClassDepartment" |
||||||
|
@addClassDepartment="addClassDepartment" @editDepartment="editDepartment" @delDepart="delDepart" |
||||||
|
@addClass="addClass" @editClass="editClass" @delClass="delClass" |
||||||
|
@fircheckitem="fircheckitem" @twocheckitem="twocheckitem" @threecheckitem="threecheckitem" |
||||||
|
></lctree> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 添加专业 --> |
||||||
|
<el-dialog :title="Form.classmajorId ? '编辑专业' : '新增专业'" :visible.sync="isaddClassMajor" width="24%" center @close="closeAddClass" :close-on-click-modal="false"> |
||||||
|
<el-form ref="Form" :model="Form" :rules="rules"> |
||||||
|
<el-form-item prop="classmajorName"> |
||||||
|
<el-input placeholder="请输入专业名称" v-model="Form.classmajorName" @change="majorChange"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="isaddClassMajor = false">取 消</el-button> |
||||||
|
<el-button type="primary" @click="sure">确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<!-- 添加年级 --> |
||||||
|
<el-dialog :title="Form2.departmentId ? '编辑年级' : '新增年级'" :visible.sync="isAddDepartment" width="24%" center @close="closeAddClass2" :close-on-click-modal="false"> |
||||||
|
<el-form ref="Form2" :model="Form2" :rules="rules"> |
||||||
|
<el-form-item prop="departmentName"> |
||||||
|
<el-input placeholder="请输入年级名称" v-model="Form2.departmentName"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="isAddDepartment = false">取 消</el-button> |
||||||
|
<el-button type="primary" @click="sureDepartment">确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<!-- 添加班级 --> |
||||||
|
<el-dialog :title="Form3.classId ? '编辑班级' : '新增班级'" :visible.sync="isAddClass" width="24%" center @close="closeAddClass3" :close-on-click-modal="false"> |
||||||
|
<el-form ref="Form3" :model="Form3" :rules="rules"> |
||||||
|
<el-form-item prop="className"> |
||||||
|
<el-input placeholder="请输入班级名称" v-model="Form3.className"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="isAddClass = false">取 消</el-button> |
||||||
|
<el-button type="primary" @click="sureClass('Form3')">确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import lctree from './studentTree' |
||||||
|
import { mapState } from 'vuex' |
||||||
|
export default { |
||||||
|
props:["Data"], |
||||||
|
data() { |
||||||
|
return { |
||||||
|
majorList: [], |
||||||
|
firactive: 0, |
||||||
|
twoactive: 0, |
||||||
|
threeactive: 0, |
||||||
|
isaddClassMajor: false, |
||||||
|
isAddDepartment: false, |
||||||
|
isAddClass: false, |
||||||
|
Form: { |
||||||
|
classmajorId: '', |
||||||
|
classmajorName: '', |
||||||
|
}, |
||||||
|
Form2: { |
||||||
|
departmentId: '', |
||||||
|
departmentName: '', |
||||||
|
}, |
||||||
|
Form3: { |
||||||
|
classId: '', |
||||||
|
className: '' |
||||||
|
}, |
||||||
|
rules: { |
||||||
|
departmentName: [ |
||||||
|
{ required: true, message: '请输入年级名称', trigger: 'blur' }, |
||||||
|
{ |
||||||
|
pattern: /^[0-9]*$/, |
||||||
|
message: '年级名称必须为数字', |
||||||
|
trigger: 'blur' |
||||||
|
} |
||||||
|
], |
||||||
|
className: [ |
||||||
|
{ required: true, message: '请输入班级名称', trigger: 'blur' }, |
||||||
|
{ |
||||||
|
pattern: /^[0-9]*$/, |
||||||
|
message: '班级名称必须为数字', |
||||||
|
trigger: 'blur' |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
majorNoAdd: true, |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
...mapState('user', [ |
||||||
|
'userId','clientId' |
||||||
|
]) |
||||||
|
}, |
||||||
|
components: { |
||||||
|
lctree |
||||||
|
}, |
||||||
|
mounted(){ |
||||||
|
this.getStaff() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getStaff(){ |
||||||
|
let data = { |
||||||
|
schoolId: this.clientId |
||||||
|
} |
||||||
|
this.$get(this.api.queryStudentProfessionalArchitecture,data).then(res => { |
||||||
|
let StaffProfessionalArchitectureList = res.data.StaffProfessionalArchitectureList |
||||||
|
StaffProfessionalArchitectureList.map(e => { |
||||||
|
(e.ifVisible = false), (e.ischeck = false), (e.label = e.stuProfessionalArchitectureName); |
||||||
|
let data = { |
||||||
|
stuProfessionalArchitectureId: e.stuProfessionalArchitectureId |
||||||
|
} |
||||||
|
this.$get(this.api.queryGrade,data).then(res => { |
||||||
|
e.children = res.data.Grade |
||||||
|
e.children.map(e => { |
||||||
|
(e.ifVisible = false), (e.ischeck = false), (e.label = e.gradeName); |
||||||
|
let data = { |
||||||
|
classId: e.gradeId |
||||||
|
} |
||||||
|
this.$get(this.api.queryClass,data).then(res => { |
||||||
|
res.data.Class.map(e => { |
||||||
|
(e.ifVisible = false), (e.ischeck = false), (e.label = e.className); |
||||||
|
}) |
||||||
|
e.children = res.message |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
setTimeout(() => { |
||||||
|
this.majorList = StaffProfessionalArchitectureList |
||||||
|
}, 500); |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
// 选择专业 |
||||||
|
fircheckitem(item){ |
||||||
|
this.$emit("fircheck",item) |
||||||
|
}, |
||||||
|
// 选择年级 |
||||||
|
twocheckitem(item){ |
||||||
|
this.$emit("twocheck",item,this.majorList) |
||||||
|
}, |
||||||
|
threeClick(index){ |
||||||
|
this.threeactive = index |
||||||
|
}, |
||||||
|
// 选择班级 |
||||||
|
threecheckitem(three){ |
||||||
|
this.$emit("threecheck",three,this.majorList) |
||||||
|
}, |
||||||
|
closeAddClass(){ |
||||||
|
this.$refs.Form.resetFields() |
||||||
|
}, |
||||||
|
closeAddClass2(){ |
||||||
|
this.$refs.Form2.resetFields() |
||||||
|
}, |
||||||
|
closeAddClass3(){ |
||||||
|
this.$refs.Form3.resetFields() |
||||||
|
}, |
||||||
|
// 新增编辑专业 |
||||||
|
addMajor(){ |
||||||
|
this.Form.classmajorId = '' |
||||||
|
this.Form.classmajorName = '' |
||||||
|
this.isaddClassMajor = true |
||||||
|
}, |
||||||
|
editmajorClass(item){ |
||||||
|
console.log(item) |
||||||
|
this.Form.classmajorId = item.stuProfessionalArchitectureId, |
||||||
|
this.Form.classmajorName = item.stuProfessionalArchitectureName |
||||||
|
this.isaddClassMajor = true |
||||||
|
}, |
||||||
|
delClassDepartment(item,index){ |
||||||
|
this.$confirm('确定要删除该专业吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$post(`${this.api.deleteStaffProfessionalArchitecture}?staffProfessionalArchitectureIds=${item.stuProfessionalArchitectureId}`).then(res => { |
||||||
|
this.$message.success('删除成功'); |
||||||
|
this.majorList.splice(index, 1) |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
sure(){ |
||||||
|
if(!this.Form.classmajorName) return this.$message.warning('请输入专业名称'); |
||||||
|
if(!this.majorNoAdd) return this.$message.warning('该一级部门已存在'); |
||||||
|
let data = { |
||||||
|
stuProfessionalArchitectureName: this.Form.classmajorName, |
||||||
|
stuProfessionalArchitectureId: this.Form.classmajorId, |
||||||
|
schoolId: this.clientId |
||||||
|
} |
||||||
|
if(this.Form.classmajorId){ |
||||||
|
this.$post(this.api.updateStaffProfessionalArchitecture,data).then(res => { |
||||||
|
this.$message.success('编辑成功'); |
||||||
|
this.isaddClassMajor = false |
||||||
|
this.majorList.map(e =>{ |
||||||
|
if(e.stuProfessionalArchitectureId == this.Form.classmajorId){ |
||||||
|
e.stuProfessionalArchitectureName = this.Form.classmajorName |
||||||
|
e.label = this.Form.classmajorName |
||||||
|
} |
||||||
|
}) |
||||||
|
}).catch(res => {}); |
||||||
|
}else{ |
||||||
|
this.$post(this.api.addStudentProfessionalArchitecture,data).then(res => { |
||||||
|
this.$message.success('添加成功'); |
||||||
|
this.isaddClassMajor = false |
||||||
|
let newData = { |
||||||
|
stuProfessionalArchitectureId: res.data.stuProfessionalArchitectureId, |
||||||
|
stuProfessionalArchitectureName : this.Form.classmajorName, |
||||||
|
label: this.Form.classmajorName, |
||||||
|
ifVisible: false, |
||||||
|
ischeck: false, |
||||||
|
children: [] |
||||||
|
} |
||||||
|
this.majorList.push(newData) |
||||||
|
}).catch(res => {}); |
||||||
|
} |
||||||
|
|
||||||
|
}, |
||||||
|
// 新增编辑年级 |
||||||
|
addClassDepartment(item){ |
||||||
|
this.Form2.departmentId = '' |
||||||
|
this.Form2.departmentName = '' |
||||||
|
this.isAddDepartment = true |
||||||
|
this.Form.classmajorId = item.stuProfessionalArchitectureId |
||||||
|
}, |
||||||
|
editDepartment(item){ |
||||||
|
this.Form2.departmentId = item.gradeId, |
||||||
|
this.Form2.departmentName = item.gradeName |
||||||
|
this.isAddDepartment = true |
||||||
|
for (let j = 0; j < this.majorList.length; j++) { |
||||||
|
for (let k = 0; k < this.majorList[j].children.length; k++) { |
||||||
|
if(this.majorList[j].children[k].gradeName == item.gradeName){ |
||||||
|
this.Form.classmajorId = this.majorList[j].stuProfessionalArchitectureId |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
delDepart(item,index){ |
||||||
|
console.log(item) |
||||||
|
this.$confirm('确定要删除该年级吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$post(`${this.api.deleteGrade}?gradeIds=${item.gradeId}`).then(res => { |
||||||
|
this.$message.success('删除成功'); |
||||||
|
|
||||||
|
this.majorList.map(e =>{ |
||||||
|
e.children.map(r =>{ |
||||||
|
if(r.gradeId == item.gradeId){ |
||||||
|
e.children.splice(index,1) |
||||||
|
if(e.children.length == 0){ |
||||||
|
e.ifVisible = false |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
sureDepartment(){ |
||||||
|
if(!this.Form2.departmentName) return this.$message.warning('请输入年级名称'); |
||||||
|
let data = { |
||||||
|
gradeName: this.Form2.departmentName, |
||||||
|
gradeId: this.Form2.departmentId, |
||||||
|
stuProfessionalArchitectureId: this.Form.classmajorId, |
||||||
|
} |
||||||
|
if(this.Form2.departmentId){ |
||||||
|
this.$post(this.api.updateGrade,data).then(res => { |
||||||
|
this.$message.success('编辑成功'); |
||||||
|
this.isAddDepartment = false |
||||||
|
this.majorList.map(e =>{ |
||||||
|
e.children.map(r =>{ |
||||||
|
if(r.gradeId == this.Form2.departmentId){ |
||||||
|
r.gradeName = this.Form2.departmentName |
||||||
|
r.label = this.Form2.departmentName |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
}).catch(res => {}); |
||||||
|
}else{ |
||||||
|
this.$post(this.api.addGrade,data).then(res => { |
||||||
|
this.$message.success('添加成功'); |
||||||
|
this.isAddDepartment = false |
||||||
|
let newData = { |
||||||
|
gradeId: res.data.gradeId, |
||||||
|
gradeName: this.Form2.departmentName, |
||||||
|
label: this.Form2.departmentName, |
||||||
|
ifVisible: false, |
||||||
|
ischeck: false, |
||||||
|
children: [] |
||||||
|
} |
||||||
|
this.majorList.map(e =>{ |
||||||
|
if(e.stuProfessionalArchitectureId == this.Form.classmajorId){ |
||||||
|
e.ifVisible = true |
||||||
|
e.children.push(newData) |
||||||
|
} |
||||||
|
}) |
||||||
|
}).catch(res => {}); |
||||||
|
} |
||||||
|
|
||||||
|
}, |
||||||
|
async majorChange(){ |
||||||
|
let res = await this.$get(this.api.queryStaffPAN, { name: this.Form.classmajorName,schoolId: this.clientId }); |
||||||
|
if(res.data.StaffProfessionalArchitecture != null){ |
||||||
|
this.$message.warning('该专业组织已存在'); |
||||||
|
this.majorNoAdd = false |
||||||
|
}else{ |
||||||
|
this.majorNoAdd = true |
||||||
|
} |
||||||
|
}, |
||||||
|
// 新增编辑班级 |
||||||
|
addClass(two){ |
||||||
|
this.Form3.classId = '' |
||||||
|
this.Form3.className = '' |
||||||
|
this.isAddClass = true |
||||||
|
this.Form2.departmentId = two.gradeId |
||||||
|
}, |
||||||
|
editClass(three){ |
||||||
|
this.Form3.classId = three.classId, |
||||||
|
this.Form3.className = three.className |
||||||
|
this.isAddClass = true |
||||||
|
for (let j = 0; j < this.majorList.length; j++) { |
||||||
|
for (let k = 0; k < this.majorList[j].children.length; k++) { |
||||||
|
for(let l = 0; l < this.majorList[j].children[k].children.length; l++){ |
||||||
|
if(this.majorList[j].children[k].children[l].className == three.className){ |
||||||
|
this.Form2.departmentId = this.majorList[j].gradeId |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
delClass(item,index){ |
||||||
|
this.$confirm('确定要删除该班级吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$post(`${this.api.deleteClass}?classIds=${item.classId}`).then(res => { |
||||||
|
this.$message.success('删除成功'); |
||||||
|
this.majorList.map(e =>{ |
||||||
|
e.children.map(r =>{ |
||||||
|
r.children.map(c =>{ |
||||||
|
if(c.classId == item.classId){ |
||||||
|
r.children.splice(index,1) |
||||||
|
if(r.children.length == 0){ |
||||||
|
r.ifVisible = false |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
sureClass(){ |
||||||
|
if(!this.Form3.className) return this.$message.warning('请输入班级名称'); |
||||||
|
let data = { |
||||||
|
className: this.Form3.className, |
||||||
|
classId: this.Form3.classId, |
||||||
|
gradeId: this.Form2.departmentId |
||||||
|
} |
||||||
|
if(this.Form3.classId){ |
||||||
|
this.$post(this.api.updateClass,data).then(res => { |
||||||
|
this.$message.success('编辑成功'); |
||||||
|
this.isAddClass = false |
||||||
|
this.majorList.map(e =>{ |
||||||
|
e.children.map(r =>{ |
||||||
|
r.children.map(c =>{ |
||||||
|
if(c.classId == this.Form3.classId){ |
||||||
|
c.className = this.Form3.className |
||||||
|
c.label = this.Form3.className |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
}).catch(res => {}); |
||||||
|
}else{ |
||||||
|
this.$post(this.api.addClass,data).then(res => { |
||||||
|
this.$message.success('添加成功'); |
||||||
|
this.isAddClass = false |
||||||
|
let newData = { |
||||||
|
classId: res.data.classId, |
||||||
|
className: this.Form3.className, |
||||||
|
label: this.Form3.className, |
||||||
|
ifVisible: false, |
||||||
|
ischeck: false |
||||||
|
} |
||||||
|
this.majorList.map(e =>{ |
||||||
|
e.children.map(r =>{ |
||||||
|
if(r.gradeId == this.Form2.departmentId){ |
||||||
|
r.ifVisible = true |
||||||
|
if(r.children.length == 0){ |
||||||
|
let arr = [] |
||||||
|
arr.push(newData) |
||||||
|
r.children = arr |
||||||
|
}else{ |
||||||
|
r.children.push(newData) |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
}).catch(res => {}); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
.side_view{ |
||||||
|
height: 800px; |
||||||
|
padding: 40px 20px; |
||||||
|
background-color: #fff; |
||||||
|
box-shadow:-2px 0px 57px 0px rgba(192,189,216,0.39); |
||||||
|
} |
||||||
|
.side_icon{ |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
.side_icon i{ |
||||||
|
cursor:pointer; |
||||||
|
font-size: 30px; |
||||||
|
color: #9278FF; |
||||||
|
} |
||||||
|
.side_tree{ |
||||||
|
width: 100%; |
||||||
|
font-size: 18px; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
.side_tree i{ |
||||||
|
color: #9278FF; |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
.fir_back{ |
||||||
|
width: 100%; |
||||||
|
padding: 15px 0; |
||||||
|
background:rgba(255,255,255,1); |
||||||
|
/* box-shadow:1px 14px 29px 0px rgba(138,97,250,0.19); */ |
||||||
|
border-radius:10px; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
.fir_back:first-child{ |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
.fir_back:hover{ |
||||||
|
box-shadow:1px 14px 29px 0px rgba(138,97,250,0.19); |
||||||
|
cursor:pointer; |
||||||
|
} |
||||||
|
.fir_back span{ |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
.two_active{ |
||||||
|
color: #9278FF; |
||||||
|
} |
||||||
|
/* .two_active:hover{ |
||||||
|
color: #9278FF; |
||||||
|
cursor:pointer; |
||||||
|
} */ |
||||||
|
.two_back{ |
||||||
|
width: 100%; |
||||||
|
margin-top: 20px; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
.two_back:hover{ |
||||||
|
cursor:pointer; |
||||||
|
color: #9278FF; |
||||||
|
} |
||||||
|
.three_back{ |
||||||
|
width: 100%; |
||||||
|
margin-top: 20px; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
.three_back:hover{ |
||||||
|
cursor:pointer; |
||||||
|
color: #9278FF; |
||||||
|
} |
||||||
|
.mar_top{ |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
.back_active{ |
||||||
|
box-shadow:1px 14px 29px 0px rgba(138,97,250,0.19); |
||||||
|
} |
||||||
|
.bor_lef{ |
||||||
|
padding: 10px 0; |
||||||
|
margin-left: 40px; |
||||||
|
} |
||||||
|
.three_lef{ |
||||||
|
margin-left: 60px; |
||||||
|
padding: 20px 0; |
||||||
|
} |
||||||
|
.three_text{ |
||||||
|
font-size: 18px; |
||||||
|
margin-top: 10px; |
||||||
|
} |
||||||
|
.teacher_tab{ |
||||||
|
margin-left: 20px; |
||||||
|
} |
||||||
|
.icon_select:before{ |
||||||
|
transform: rotate(180deg); |
||||||
|
} |
||||||
|
.list-enter-active, .list-leave-active { transition: all 1s; } |
||||||
|
.list-enter, .list-leave-to { opacity: 0; transform: translateY(-30px); } |
||||||
|
</style> |
@ -0,0 +1,284 @@ |
|||||||
|
<template> |
||||||
|
<div class="side_view"> |
||||||
|
<p class="side_icon mab20"> |
||||||
|
<i class="icon-jiahao mar20" @click="addMajor()"></i> |
||||||
|
<!-- <i class="icon-delete"></i> --> |
||||||
|
</p> |
||||||
|
<div class="side_tree" @click.stop="open(item)" v-for="(item,index) in data" :key="index"> |
||||||
|
<div class="item" @click.stop="open(item)"> |
||||||
|
<!-- <i :class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}" class="icon-shixiangyoujiantou-"></i> --> |
||||||
|
<img |
||||||
|
:class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}" |
||||||
|
src="../../../assets/img/icon-xiangyou.png" |
||||||
|
alt |
||||||
|
/> |
||||||
|
<i :class="item.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="fircheckitem(item)"></i> |
||||||
|
<span>{{item.label}}</span> |
||||||
|
<i class="edit ft" @click.stop="editmajorClass(item)"></i> |
||||||
|
<i class="el-icon-circle-plus ft" @click.stop="addClassDepartment(item)"></i> |
||||||
|
<i class="icon-delete ft" @click.stop="delClassDepartment(item,index)"></i> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div v-show="item.ifVisible" v-if="item.children&&item.children.length!=0"> |
||||||
|
<div v-for="(item1,index1) in item.children" :key="index1"> |
||||||
|
<div class="item1" @click.stop="open(item1)"> |
||||||
|
<img |
||||||
|
:class="{ 'arrowTransform': !item1.ifVisible, 'arrowTransformReturn': item1.ifVisible}" |
||||||
|
src="../../../assets/img/icon-xiangyou.png" |
||||||
|
alt |
||||||
|
style="margin-left:30px" |
||||||
|
/> |
||||||
|
<i :class="item1.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="twocheckitem(item1)"></i> |
||||||
|
<span>{{item1.label}}年级</span> |
||||||
|
<i class="edit ft" @click.stop="editDepartment(item1)"></i> |
||||||
|
<i class="el-icon-circle-plus ft" @click.stop="addClass(item1)"></i> |
||||||
|
<i class="icon-delete ft" @click.stop="delDepart(item1,index1)"></i> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div v-show="item1.ifVisible" v-if="item1.children&&item1.children.length!=0"> |
||||||
|
<div v-for="(item2,index2) in item1.children" :key="index2"> |
||||||
|
<div class="item2" @click.stop="open(item2)"> |
||||||
|
<i :class="item2.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="threecheckitem(item2)"></i> |
||||||
|
<span>{{item2.label}}班</span> |
||||||
|
<i class="edit ft" @click.stop="editClass(item2)"></i> |
||||||
|
<i class="icon-delete ft" @click.stop="delClass(item2,index2)"></i> |
||||||
|
</div> |
||||||
|
<!-- <div |
||||||
|
v-show="item2.ifVisible" |
||||||
|
v-if="item2.children&&item2.children.length!=0" |
||||||
|
> |
||||||
|
<div |
||||||
|
class="item4" |
||||||
|
@click.stop="choose(item3)" |
||||||
|
v-for="(item3,index3) in item2.children" |
||||||
|
:key="index3" |
||||||
|
> |
||||||
|
<span :class="{checkBox:true,isActive:item3.ifVisible}"></span> |
||||||
|
{{item3.label}} |
||||||
|
</div> |
||||||
|
</div> --> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
Array.prototype.removeByValue = function (val) { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
if (JSON.stringify(this[i]).indexOf(JSON.stringify(val)) != -1) { |
||||||
|
this.splice(i, 1); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
chooseList: [] |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
chooseList(n, o) { |
||||||
|
this.$emit('chooseNode', n); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
props: { |
||||||
|
data: { |
||||||
|
type: Array |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
//点击节点时伸展或收缩列表 |
||||||
|
open(item) { |
||||||
|
item.ifVisible = !item.ifVisible; |
||||||
|
}, |
||||||
|
|
||||||
|
//选中叶子节点时将选中的叶子节点添加进数组,如果叶子节点存在则删除,removeByvalue函数定义在main.js中 |
||||||
|
choose(item) { |
||||||
|
item.ifVisible = !item.ifVisible; |
||||||
|
if (item.ifVisible) { |
||||||
|
this.chooseList.push(item); |
||||||
|
} else { |
||||||
|
this.chooseList.removeByValue(item); |
||||||
|
} |
||||||
|
}, |
||||||
|
fircheckitem(item){ |
||||||
|
this.$emit('fircheckitem',item); |
||||||
|
}, |
||||||
|
twocheckitem(item){ |
||||||
|
this.$emit('twocheckitem',item); |
||||||
|
}, |
||||||
|
threecheckitem(item){ |
||||||
|
this.$emit('threecheckitem',item); |
||||||
|
}, |
||||||
|
// 专业 |
||||||
|
addMajor(){ |
||||||
|
this.$emit('addMajor'); |
||||||
|
}, |
||||||
|
editmajorClass(item){ |
||||||
|
this.$emit('editmajorClass',item); |
||||||
|
}, |
||||||
|
delClassDepartment(item,index){ |
||||||
|
this.$emit('delClassDepartment',item,index); |
||||||
|
}, |
||||||
|
// 年级 |
||||||
|
addClassDepartment(item){ |
||||||
|
this.$emit('addClassDepartment',item); |
||||||
|
}, |
||||||
|
editDepartment(item){ |
||||||
|
this.$emit('editDepartment',item); |
||||||
|
}, |
||||||
|
delDepart(item,index){ |
||||||
|
this.$emit('delDepart',item,index); |
||||||
|
}, |
||||||
|
// 班级 |
||||||
|
addClass(item){ |
||||||
|
this.$emit('addClass',item); |
||||||
|
}, |
||||||
|
editClass(item){ |
||||||
|
this.$emit('editClass',item); |
||||||
|
}, |
||||||
|
delClass(item,index){ |
||||||
|
this.$emit('delClass',item,index); |
||||||
|
}, |
||||||
|
//判断数组中是否包含某个对象 |
||||||
|
isHasObj(arr, val) { |
||||||
|
var flag = 0; //1为有 0为没有 |
||||||
|
for (var i = 0; i < arr.length; i++) { |
||||||
|
if (JSON.stringify(arr[i]).indexOf(JSON.stringify(val)) != -1) { |
||||||
|
flag = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
if (flag == 1) { |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
$insideColor: rgba(245, 242, 255, 0.8); //内部节点的边框颜色 |
||||||
|
$outColor: rgba(255, 255, 255, 0.8); //外部节点的边框颜色 |
||||||
|
|
||||||
|
//混合代码,提取item共同样式 |
||||||
|
@mixin public { |
||||||
|
cursor: pointer; |
||||||
|
font-size: 14px; |
||||||
|
color: #333333; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
img { |
||||||
|
height: 20px; |
||||||
|
width: 20px; |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.main { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.item { |
||||||
|
@include public; |
||||||
|
width: 100%; |
||||||
|
padding: 15px 0; |
||||||
|
background:rgba(255,255,255,1); |
||||||
|
box-shadow:1px 14px 29px 0px rgba(255,69,69,0.19); |
||||||
|
border-radius:10px; |
||||||
|
text-align: left; |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
.item:first{ |
||||||
|
margin-top: 0; |
||||||
|
} |
||||||
|
.item1 { |
||||||
|
@include public; |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
.item2 { |
||||||
|
@include public; |
||||||
|
margin-top: 20px; |
||||||
|
margin-left:60px |
||||||
|
} |
||||||
|
.item2:hover{ |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
.edit{ |
||||||
|
display: inline-block; |
||||||
|
width: 17px; |
||||||
|
height: 17px; |
||||||
|
background: url(../../../assets/img/edit.svg) 0 0/cover no-repeat; |
||||||
|
} |
||||||
|
//清除ul,li的默认样式 |
||||||
|
ul, |
||||||
|
li { |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
list-style: none; |
||||||
|
} |
||||||
|
|
||||||
|
// 使三角形旋转动画 |
||||||
|
.arrowTransform { |
||||||
|
transition: 0.4s; |
||||||
|
transform-origin: center; |
||||||
|
transform: rotateZ(0deg); |
||||||
|
} |
||||||
|
.arrowTransformReturn { |
||||||
|
transition: 0.4s; |
||||||
|
transform-origin: center; |
||||||
|
transform: rotateZ(90deg); |
||||||
|
} |
||||||
|
|
||||||
|
//复选框样式 |
||||||
|
.checkBox { |
||||||
|
width: 14px; |
||||||
|
height: 14px; |
||||||
|
border-radius: 7px; |
||||||
|
margin-left: 10px; |
||||||
|
margin-right: 10px; |
||||||
|
border: 2px solid rgba(146, 120, 255, 1); |
||||||
|
} |
||||||
|
|
||||||
|
//当点击复选框时候切换背景图片 |
||||||
|
.isActive { |
||||||
|
background: url('../../../assets/img/icon-yigouxuan.png'); |
||||||
|
background-size: 14px 14px; /*按比例缩放*/ |
||||||
|
} |
||||||
|
|
||||||
|
.side_view{ |
||||||
|
// height: 800px; |
||||||
|
padding: 40px 20px; |
||||||
|
background-color: #fff; |
||||||
|
box-shadow:-2px 0px 57px 0px rgba(192,189,216,0.39); |
||||||
|
i { |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
} |
||||||
|
.side_icon{ |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
.side_icon i{ |
||||||
|
cursor:pointer; |
||||||
|
font-size: 20px; |
||||||
|
} |
||||||
|
.side_tree{ |
||||||
|
width: 100%; |
||||||
|
font-size: 14px; |
||||||
|
color: #333; |
||||||
|
i{ |
||||||
|
margin-left: 5px; |
||||||
|
font-size: 17px; |
||||||
|
} |
||||||
|
span{ |
||||||
|
margin-left: 5px; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,82 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div class="tabs" v-if="showTabs"> |
||||||
|
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == activeName}" @click="tabChange(index)">{{item}}</a> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="score-table" v-if="activeName == 'staff'" v-auth="'系统设置:员工管理'"> |
||||||
|
<staff></staff> |
||||||
|
</div> |
||||||
|
<div class="score-table" v-else v-auth="'系统设置:角色权限'"> |
||||||
|
<role></role> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Setting from '@/setting'; |
||||||
|
import staff from './staff.vue'; |
||||||
|
import role from './role.vue'; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
activeName: 'staff', |
||||||
|
userId: this.$store.state.userId, |
||||||
|
tabs: { |
||||||
|
staff: '员工管理', |
||||||
|
role: '角色权限' |
||||||
|
}, |
||||||
|
showTabs: true |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
staff, |
||||||
|
role |
||||||
|
}, |
||||||
|
created() { |
||||||
|
Setting.dynamicRoute && this.initTabs() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
tabChange(index){ |
||||||
|
this.activeName = index |
||||||
|
}, |
||||||
|
initTabs(){ |
||||||
|
let btnPermissions = this.$store.state.btnPermissions |
||||||
|
let showStaff = btnPermissions.includes('系统设置:员工管理') |
||||||
|
let showRole = btnPermissions.includes('系统设置:角色权限') |
||||||
|
|
||||||
|
if(!showStaff || !showRole){ |
||||||
|
this.showTabs = false |
||||||
|
} |
||||||
|
!showStaff && showRole && (this.activeName = 'role') |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scopted> |
||||||
|
.tabs{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 20px 1.5% 20px; |
||||||
|
margin-bottom: 20px; |
||||||
|
z-index: 999; |
||||||
|
background-color: #fff; |
||||||
|
.item{ |
||||||
|
padding: 12px 20px; |
||||||
|
margin-right: 10px; |
||||||
|
color:#606266; |
||||||
|
line-height: 1; |
||||||
|
border-radius: 4px; |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #dcdfe6; |
||||||
|
cursor: pointer; |
||||||
|
|
||||||
|
&.active{ |
||||||
|
color: #fff; |
||||||
|
background-color: #cb221c; |
||||||
|
border-color: #cb221c; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,296 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div> |
||||||
|
<div class="flex-center mgb20"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>筛选</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<div style="display: flex;"> |
||||||
|
<div> |
||||||
|
<el-input placeholder="请输入角色名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover"> |
||||||
|
<div class="flex-between mgb20"> |
||||||
|
<div class="flex-center"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>角色列表</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-button type="primary" size="small" round @click="addRole" v-auth="'system:角色权限:新增角色'">新增角色</el-button> |
||||||
|
<el-button type="primary" size="small" round @click="delAllSelection" v-auth="'system:角色权限:批量删除'">批量删除</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table :data="roleData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" :row-key="getRowKeys"> |
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="roleName" label="角色名称" align="center" width="100"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="角色描述" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-input disabled placeholder="该角色用于管理全部功能权限" v-model="scope.row.remark "></el-input> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" width="180"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="showRole(scope.row)" v-auth="'system:角色权限:查看'">查看</el-button> |
||||||
|
<template v-if="scope.row.id != 1"> |
||||||
|
<el-button type="text" @click="editRole(scope.row)" v-auth="'system:角色权限:编辑'">编辑</el-button> |
||||||
|
<el-button type="text" @click="handleDelete(scope.row)" v-auth="'system:角色权限:删除'">删除</el-button> |
||||||
|
</template> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background @current-change="currentChange" :current-page="pageNo" layout="total, prev, pager, next" :total="totals"> |
||||||
|
</el-pagination> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-dialog :title="isDetail ? '查看角色' : (isAdd ? '新增角色' : '编辑角色')" :visible.sync="roleVisible" |
||||||
|
width="30%" center @close="closeRole" class="dialog" :close-on-click-modal="false"> |
||||||
|
<el-form ref="form" :model="form" label-width="100px" :disabled="isDetail"> |
||||||
|
<el-form-item label="角色名称"> |
||||||
|
<el-input v-model="form.roleName " ref="account" placeholder="请输入角色名称"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="角色描述"> |
||||||
|
<el-input v-model="form.remark " placeholder="请输入角色描述" type="textarea" rows="5"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="role" label="角色权限"> |
||||||
|
<div class="per-wrap"> |
||||||
|
<el-tree |
||||||
|
ref="per" |
||||||
|
:data="permissions" |
||||||
|
show-checkbox |
||||||
|
node-key="id" |
||||||
|
:default-expanded-keys="checkedIds" |
||||||
|
:default-checked-keys="checkedIds" |
||||||
|
:props="defaultProps"> |
||||||
|
</el-tree> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer" v-if="!isDetail"> |
||||||
|
<el-button @click="roleVisible = false">取 消</el-button> |
||||||
|
<el-button type="primary" @click="saveData">确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { mapState } from 'vuex'; |
||||||
|
export default { |
||||||
|
name: 'role', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
keyword: '', |
||||||
|
form: { |
||||||
|
roleName : '', |
||||||
|
remark : '', |
||||||
|
id: '' |
||||||
|
}, |
||||||
|
isDetail: false, |
||||||
|
roleData:[], |
||||||
|
defaultProps: { |
||||||
|
children: 'children', |
||||||
|
label: 'name' |
||||||
|
}, |
||||||
|
pageNo: 1, |
||||||
|
pageSize: 10, |
||||||
|
totals: 0, |
||||||
|
multipleSelection: [], |
||||||
|
importVisible: false, |
||||||
|
isAdd: true, |
||||||
|
roleVisible: false, |
||||||
|
searchTimer: null, |
||||||
|
permissions: [], |
||||||
|
checkedIds: [] |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
...mapState('user', [ |
||||||
|
'clientId','clientName' |
||||||
|
]) |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
let data = { |
||||||
|
clientId: this.clientId |
||||||
|
} |
||||||
|
if(this.keyword.length){ |
||||||
|
data.name = this.keyword |
||||||
|
} |
||||||
|
this.$get(`${this.api.queryRoles}/${this.pageNo}/${this.pageSize}`,data).then(res => { |
||||||
|
this.roleData = res.data.items |
||||||
|
this.totals = res.data.total |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
closeRole(){ |
||||||
|
this.isDetail = false |
||||||
|
this.form = { |
||||||
|
roleName : '', |
||||||
|
remark : '', |
||||||
|
id: '' |
||||||
|
} |
||||||
|
this.checkedIds = [] |
||||||
|
this.permissions = [] |
||||||
|
}, |
||||||
|
currentChange(val) { |
||||||
|
this.pageNo = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
getPer(){ |
||||||
|
if(!this.permissions.length){ |
||||||
|
this.$get(this.api.queryPermissionMenu).then(res => { |
||||||
|
this.permissions = res.data.children[0].children |
||||||
|
}).catch(res => {}) |
||||||
|
} |
||||||
|
}, |
||||||
|
addRole(){ |
||||||
|
this.isAdd = true |
||||||
|
this.getPer() |
||||||
|
this.checkedIds = [] |
||||||
|
this.permissions.length && this.$refs.per.setCheckedNodes([]) |
||||||
|
this.roleVisible = true |
||||||
|
}, |
||||||
|
handleRolePer(data,permissions){ |
||||||
|
let result = data |
||||||
|
if(permissions.length){ |
||||||
|
permissions.map(e => { |
||||||
|
if(result.includes(e.id) && e.children.length){ |
||||||
|
e.children.every(n => result.includes(n)) || result.splice(result.indexOf(e.id),1) |
||||||
|
} |
||||||
|
e.children.length && this.handleRolePer(data,e.children) |
||||||
|
}) |
||||||
|
} |
||||||
|
return result |
||||||
|
}, |
||||||
|
async getDetail(row){ |
||||||
|
this.getPer() |
||||||
|
let roleRes = await this.$get(`${this.api.getRole}/${row.id}`) |
||||||
|
if(roleRes.success){ |
||||||
|
this.form = roleRes.data.item |
||||||
|
let perRes = await this.$get(`${this.api.toAssign}/${row.id}`) |
||||||
|
if(perRes.success){ |
||||||
|
this.checkedIds = this.handleRolePer(perRes.data.rolePermissions,this.permissions) |
||||||
|
this.$refs.per.setCheckedNodes(this.checkedIds) |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
showRole(row){ |
||||||
|
this.isDetail = true |
||||||
|
this.isAdd = false |
||||||
|
this.getDetail(row) |
||||||
|
this.roleVisible = true |
||||||
|
}, |
||||||
|
editRole(row){ |
||||||
|
this.isAdd = false |
||||||
|
this.getDetail(row) |
||||||
|
this.roleVisible = true |
||||||
|
}, |
||||||
|
async saveData() { |
||||||
|
if(!this.form.roleName) return this.$message.warning('请填写角色名称') |
||||||
|
if(!this.form.remark) return this.$message.warning('请填写角色描述') |
||||||
|
// if(!this.$refs.per.getCheckedKeys().length) return this.$message.warning('请选择角色权限') |
||||||
|
let roleData = { |
||||||
|
clientId: this.clientId, |
||||||
|
id: this.form.id, |
||||||
|
roleName: this.form.roleName, |
||||||
|
remark: this.form.remark, |
||||||
|
isPort: 2 |
||||||
|
} |
||||||
|
let roleRes = await this.$post(this.api.saveOrUpdate,roleData) |
||||||
|
if(roleRes.success){ |
||||||
|
let permissionId = [...this.$refs.per.getHalfCheckedKeys(),...this.$refs.per.getCheckedKeys()] |
||||||
|
let perData = { |
||||||
|
clientId: this.clientId, |
||||||
|
roleId: roleRes.data.roleId, |
||||||
|
permissionId, |
||||||
|
isPort: 2 |
||||||
|
} |
||||||
|
let perRes = await this.$post(this.api.doAssign,perData) |
||||||
|
if(perRes.success){ |
||||||
|
this.$message.success('新增成功') |
||||||
|
this.getData() |
||||||
|
this.roleVisible = false |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
handleDelete(row) { |
||||||
|
this.$confirm('该角色下已有账号,删除角色会将该角色下的账号一并删除,是否继续删除?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.removeRole}?roleIds=${row.id}`).then(res => { |
||||||
|
if(res.success){ |
||||||
|
this.$message.success('删除成功'); |
||||||
|
this.getData() |
||||||
|
} |
||||||
|
}).catch(res => {}) |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
getRowKeys(row) { |
||||||
|
return row.id; |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
delAllSelection() { |
||||||
|
if(this.multipleSelection.length != ''){ |
||||||
|
let newArr = this.multipleSelection |
||||||
|
let delList = newArr.map(item => { |
||||||
|
return item.id |
||||||
|
}) |
||||||
|
// 批量删除 |
||||||
|
this.$confirm('确定要删除选中角色吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.removeRole}?roleIds=${delList.join()}`).then(res => { |
||||||
|
if(res.success){ |
||||||
|
this.$message.success('删除成功'); |
||||||
|
this.getData() |
||||||
|
} |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(() => {}); |
||||||
|
}else{ |
||||||
|
this.$message.error('请先选择数据 !'); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.no-mb /deep/.el-form-item{ |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
/deep/.el-row{ |
||||||
|
padding: 0 !important; |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
.per-wrap{ |
||||||
|
max-height: 400px; |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,610 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-container> |
||||||
|
<el-aside width="350px"> |
||||||
|
<TeacherSide ref="getSelectData" @fircheck="fircheck" @twocheck="twocheck" @getData="getData"></TeacherSide> |
||||||
|
</el-aside> |
||||||
|
|
||||||
|
<el-main style="padding-top: 0"> |
||||||
|
<el-col :span="24"> |
||||||
|
<el-card shadow="hover" class="mgb20 teacher_tab"> |
||||||
|
<div class="flex-between mgb20"> |
||||||
|
<div> |
||||||
|
<el-input placeholder="请输入员工姓名/工号" v-model="keyword" prefix-icon="el-icon-search" clearable></el-input> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<el-button type="primary" size="small" round @click="addTeacher" v-auth="'system:员工管理:新增员工'">新增员工</el-button> |
||||||
|
<el-button type="primary" size="small" round @click="batchImport" v-auth="'system:员工管理:批量导入'">批量导入</el-button> |
||||||
|
<el-button type="primary" size="small" round @click="delAllSelection" v-auth="'system:员工管理:批量删除'">批量删除</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange"> |
||||||
|
<el-table-column type="selection" width="55" align="center"></el-table-column> |
||||||
|
<el-table-column type="index" label="序号" width="55" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="userName" label="职工姓名" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="account" label="账号" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="workNumber" label="职工工号" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="staffProfessionalArchitectureName" label="一级部门" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="staffGradeName" label="二级部门" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="roleName" label="账号角色" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="loginNumber" label="登录次数" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{scope.row.loginNumber ? scope.row.loginNumber : 0}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="lastLoginTime" label="上次登录时间" width="160" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="200"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="showTeacher(scope.row)" v-auth="'system:员工管理:查看'">查看</el-button> |
||||||
|
<el-button type="text" @click="editTeacher(scope.row)" v-auth="'system:员工管理:编辑'">编辑</el-button> |
||||||
|
<el-button type="text" @click="resetPassword(scope.row)" v-auth="'system:员工管理:重置密码'">重置密码</el-button> |
||||||
|
<el-button type="text" @click="delTeacher(scope.row)" v-auth="'system:员工管理:删除'">删除</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background layout="total,prev, pager, next" :current-page="pageNo" @current-change="handleCurrentChange" :total="total"> |
||||||
|
</el-pagination> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</el-col> |
||||||
|
</el-main> |
||||||
|
</el-container> |
||||||
|
|
||||||
|
<!-- 新增用户 --> |
||||||
|
<el-dialog :title="isDetail ? '查看员工' : (isAddteacher ? '新增员工' : '编辑员工')" :visible.sync="teacherVisible" |
||||||
|
width="30%" :center="!isIE" @close="closeTeacher" class="dialog" :close-on-click-modal="false"> |
||||||
|
<el-form ref="teacherForm" :model="teacherForm" :rules="rules" label-width="120px" :disabled="isDetail"> |
||||||
|
<el-form-item prop="userAccount" label="账号"> |
||||||
|
<el-input v-model="teacherForm.userAccount" ref="account" placeholder="请输入职工账号" @change="accountChange"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="userName" label="用户姓名"> |
||||||
|
<el-input v-model="teacherForm.userName" placeholder="请输入员工姓名"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="roleValue" label="账号角色"> |
||||||
|
<el-select v-model="teacherForm.roleValue" placeholder="请选择账号角色" :disabled="!isAddteacher"> |
||||||
|
<el-option v-for="(item,index) in roleList" :key="index" :label="item.roleName" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="uniqueIdentificationAccount" label="唯一标识"> |
||||||
|
<el-input disabled v-model="teacherForm.uniqueIdentificationAccount" placeholder="请输入职工工号获取唯一标识"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="workNumber" label="职工工号"> |
||||||
|
<el-input v-model="teacherForm.workNumber" placeholder="请输入职工工号" @change="workNumberChange"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="major" label="一级部门"> |
||||||
|
<el-select v-model="teacherForm.major" placeholder="请选择一级部门" @change="getDepartment"> |
||||||
|
<el-option v-for="(item,index) in majorList" :key="index" |
||||||
|
:label="item.staffProfessionalArchitectureName" :value="item.staffProfessionalArchitectureId"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="department" label="二级部门"> |
||||||
|
<el-select v-model="teacherForm.department" placeholder="请选择二级部门" :disabled="teacherForm.major ? false : true"> |
||||||
|
<el-option v-for="(item,index) in departmentList" :key="index" |
||||||
|
:label="item.staffGradeName" :value="item.staffGradeId"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="phone" label="手机号"> |
||||||
|
<el-input v-model="teacherForm.phone" placeholder="请输入手机号" maxlength="11"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="email" label="邮箱"> |
||||||
|
<el-input v-model="teacherForm.email" placeholder="请输入邮箱"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="email" label="默认密码"> |
||||||
|
<el-input v-model="password" disabled></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer" v-if="!isDetail"> |
||||||
|
<el-button @click="teacherVisible = false">取 消</el-button> |
||||||
|
<el-button type="primary" @click="saveSure('teacherForm')">确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<!-- 批量导入 --> |
||||||
|
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" center :close-on-click-modal="false"> |
||||||
|
<div style="text-align: center"> |
||||||
|
<div style="margin-bottom: 10px;"><el-button type="primary" @click="downLoad">模板下载<i class="el-icon-download el-icon--right"></i></el-button></div> |
||||||
|
<el-upload |
||||||
|
accept=".xls,.xlsx" |
||||||
|
:on-remove="handleRemove" |
||||||
|
:on-error="uploadError" |
||||||
|
:on-success="uploadSuccess" |
||||||
|
:before-remove="beforeRemove" |
||||||
|
:limit="1" |
||||||
|
:on-exceed="handleExceed" |
||||||
|
:action="this.api.uploadFileStaff" |
||||||
|
:file-list="uploadList" |
||||||
|
name="file" |
||||||
|
> |
||||||
|
<el-button type="primary" class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button> |
||||||
|
</el-upload> |
||||||
|
<el-link v-if="uploadFaild" type="primary" @click="showFaild">导入失败,查看原因</el-link> |
||||||
|
</div> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="importVisible = false">取 消</el-button> |
||||||
|
<el-button type="primary" @click="uploadSure">确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import TeacherSide from './staffSide.vue'; |
||||||
|
import Setting from '@/setting'; |
||||||
|
import { mapState } from 'vuex'; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
isDetail: false, |
||||||
|
isAddteacher: false, |
||||||
|
teacherVisible: false, |
||||||
|
roleList: [], |
||||||
|
teacherForm: { |
||||||
|
teacherId: '', |
||||||
|
userName: '', |
||||||
|
roleValue: '', |
||||||
|
phone: '', |
||||||
|
uniqueIdentificationAccount: '', |
||||||
|
workNumber: '', |
||||||
|
email: '', |
||||||
|
major: '', |
||||||
|
department: '', |
||||||
|
userAccount: '', |
||||||
|
major: '', |
||||||
|
schoolId: this.clientId |
||||||
|
}, |
||||||
|
rules: { |
||||||
|
userAccount: [ |
||||||
|
{ required: true, message: '请输入账号', trigger: 'blur' }, |
||||||
|
{ |
||||||
|
pattern: /^[A-Za-z0-9]+$/, |
||||||
|
message: '请输入正确的账号', |
||||||
|
trigger: 'blur' |
||||||
|
} |
||||||
|
], |
||||||
|
userName: [ |
||||||
|
{ required: true, message: '请输入用户姓名', trigger: 'blur' } |
||||||
|
], |
||||||
|
roleValue: [ |
||||||
|
{ required: true, message: '请选择账号角色', trigger: 'change' } |
||||||
|
], |
||||||
|
uniqueIdentificationAccount: [ |
||||||
|
// { required: true, message: '请输入唯一标识', trigger: 'blur' }, |
||||||
|
], |
||||||
|
major: [ |
||||||
|
{ required: true, message: '请选择一级部门', trigger: 'change' } |
||||||
|
], |
||||||
|
workNumber: [ |
||||||
|
{ required: true, message: '请输入职工工号', trigger: 'blur' }, |
||||||
|
{ |
||||||
|
pattern: /^[A-Za-z0-9]+$/, |
||||||
|
message: '请输入正确的职工工号', |
||||||
|
trigger: 'blur' |
||||||
|
} |
||||||
|
], |
||||||
|
department: [ |
||||||
|
{ required: true, message: '请选择二级部门', trigger: 'change' } |
||||||
|
], |
||||||
|
phone: [ |
||||||
|
// { required: true, message: '请输入职工手机号', trigger: 'blur' }, |
||||||
|
{ |
||||||
|
pattern: /^1[3456789]\d{9}$/, |
||||||
|
message: '请输入正确的手机号', |
||||||
|
trigger: 'blur' |
||||||
|
} |
||||||
|
], |
||||||
|
email: [ |
||||||
|
// { required: true, message: '请输入邮箱', trigger: 'blur' }, |
||||||
|
{ |
||||||
|
pattern: /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/, |
||||||
|
message: '请输入正确的邮箱', |
||||||
|
trigger: 'blur' |
||||||
|
} |
||||||
|
], |
||||||
|
// schoolId: [ |
||||||
|
// { required: true, message: '请选择所在院校', trigger: 'change' } |
||||||
|
// ], |
||||||
|
}, |
||||||
|
majorList: [], |
||||||
|
listData: [], |
||||||
|
importVisible: false, |
||||||
|
keyword: '', |
||||||
|
pageNo: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
departmentList: [], |
||||||
|
teacherDepartmentList: [], |
||||||
|
staffstateProfessId: '', |
||||||
|
staffGradeId: '', |
||||||
|
multipleSelection: [], |
||||||
|
uploadList: [], |
||||||
|
provinceId: this.$store.state.provinceId, |
||||||
|
cityId: this.$store.state.cityId, |
||||||
|
userId: this.$store.state.userId, |
||||||
|
oneDepartmentIds: '', |
||||||
|
twoDepartmentIds: '', |
||||||
|
ProfessionalClassList: [], |
||||||
|
subjectList: [], |
||||||
|
ProfessionalList: [], |
||||||
|
NoAdd: '', |
||||||
|
AccountNoAdd: '', |
||||||
|
NumberNoAdd: '', |
||||||
|
platformId: this.$store.state.platformId, |
||||||
|
schoolList: [], |
||||||
|
uploadFaild: false, |
||||||
|
token: '', |
||||||
|
accountRepeat: false, |
||||||
|
workNumberRepeat: false, |
||||||
|
originalAccount: '', |
||||||
|
originalWorkNumber: '', |
||||||
|
password: Setting.initialPassword |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
...mapState('user', [ |
||||||
|
'clientId','clientName' |
||||||
|
]), |
||||||
|
...mapState('layout', [ |
||||||
|
'isIE' |
||||||
|
]) |
||||||
|
}, |
||||||
|
components: { |
||||||
|
TeacherSide |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted(){ |
||||||
|
this.getData() |
||||||
|
this.getRoles() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
handleCheck(data){ |
||||||
|
let oneDepartmentIds = [] |
||||||
|
let twoDepartmentIds = [] |
||||||
|
|
||||||
|
data.forEach( e => { |
||||||
|
if(e.ischeck){ |
||||||
|
oneDepartmentIds.push(e.staffProfessionalArchitectureId) |
||||||
|
}else{ |
||||||
|
this.removeByValue(oneDepartmentIds, e.staffProfessionalArchitectureId); |
||||||
|
} |
||||||
|
e.children.forEach( r => { |
||||||
|
if(r.ischeck){ |
||||||
|
twoDepartmentIds.push(r.staffGradeId) |
||||||
|
}else{ |
||||||
|
this.removeByValue(twoDepartmentIds, r.staffGradeId); |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
this.oneDepartmentIds = oneDepartmentIds.toString() |
||||||
|
this.twoDepartmentIds = twoDepartmentIds.toString() |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
fircheck(val,val2){ |
||||||
|
val.ischeck = !val.ischeck |
||||||
|
val.children.map( e => e.ischeck = val.ischeck) |
||||||
|
this.handleCheck(val2) |
||||||
|
}, |
||||||
|
twocheck(val,val2){ |
||||||
|
this.handleCheck(val2) |
||||||
|
}, |
||||||
|
getData(){ |
||||||
|
let data = { |
||||||
|
staffProfessionalArchitectureIds: this.oneDepartmentIds, |
||||||
|
staffGradeIds: this.twoDepartmentIds, |
||||||
|
searchContent: this.keyword, |
||||||
|
schoolId: this.clientId |
||||||
|
} |
||||||
|
this.$get(`${this.api.queryStaff}/${this.pageNo}/${this.pageSize}`,data).then(res => { |
||||||
|
this.listData = res.data.staffList |
||||||
|
this.total = res.data.total |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
getRoles(){ |
||||||
|
let data = { |
||||||
|
clientId: this.clientId |
||||||
|
} |
||||||
|
this.$get(`${this.api.queryRoles}/1/100`,data).then(res => { |
||||||
|
this.roleList = res.data.items |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
resetPassword(row){ |
||||||
|
this.$confirm(`重置后的密码为:${Setting.initialPassword},确定重置?`, '提示', { |
||||||
|
}).then(() => { |
||||||
|
let data = { |
||||||
|
userId: row.userId, |
||||||
|
password: Setting.initialPassword |
||||||
|
} |
||||||
|
this.$post(this.api.userinfoUpdate,data).then(res => { |
||||||
|
if(res.success){ |
||||||
|
this.$message.success('重置成功') |
||||||
|
}else{ |
||||||
|
this.$message.error('重置失败') |
||||||
|
} |
||||||
|
}).catch(res => {}); |
||||||
|
}).catch(() => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
accountChange(){ |
||||||
|
if(this.teacherForm.userAccount !== this.originalAccount){ |
||||||
|
this.$get(`${this.api.getAccount}?account=${this.teacherForm.userAccount}`).then(res => { |
||||||
|
if(res.data.userInfo){ |
||||||
|
this.accountRepeat = true |
||||||
|
this.$message.warning('该账号已存在') |
||||||
|
}else{ |
||||||
|
this.accountRepeat = false |
||||||
|
} |
||||||
|
}).catch(res => {}); |
||||||
|
}else{ |
||||||
|
this.accountRepeat = false |
||||||
|
} |
||||||
|
}, |
||||||
|
workNumberChange(){ |
||||||
|
if(this.teacherForm.workNumber !== this.originalWorkNumber){ |
||||||
|
this.$get(`${this.api.getWorkNumber}?workNumber=${this.teacherForm.workNumber}`).then(res => { |
||||||
|
if(res.data.staff){ |
||||||
|
this.workNumberRepeat = true |
||||||
|
this.$message.warning('该工号已存在') |
||||||
|
}else{ |
||||||
|
this.workNumberRepeat = false |
||||||
|
} |
||||||
|
}).catch(res => {}); |
||||||
|
}else{ |
||||||
|
this.workNumberRepeat = false |
||||||
|
} |
||||||
|
}, |
||||||
|
closeTeacher(){ |
||||||
|
this.$refs.teacherForm.resetFields() |
||||||
|
this.teacherForm.clientId = this.$store.state.schoolId |
||||||
|
this.teacherForm.clientName = this.$store.state.schoolName |
||||||
|
this.teacherForm.department = '' |
||||||
|
this.teacherForm.major = '' |
||||||
|
this.teacherForm.workNumber = '' |
||||||
|
this.teacherForm.userId = '' |
||||||
|
this.teacherForm.staffId = '' |
||||||
|
}, |
||||||
|
addTeacher(){ |
||||||
|
this.isDetail = false |
||||||
|
this.teacherVisible = true |
||||||
|
this.isAddteacher = true |
||||||
|
this.teacherForm.teacherId = '' |
||||||
|
this.majorList = this.$refs.getSelectData.majorList |
||||||
|
}, |
||||||
|
getStaffDetail(userId){ |
||||||
|
this.$get(`${this.api.getStaff}/${userId}`).then(res => { |
||||||
|
let user = res.data.userInfo; |
||||||
|
let or = res.data.staff; |
||||||
|
this.teacherForm.uniqueIdentificationAccount = user.uniqueIdentificationAccount |
||||||
|
this.teacherForm.clientId = user.clientId |
||||||
|
this.teacherForm.clientName = user.clientName |
||||||
|
this.teacherForm.userName = user.userName |
||||||
|
this.teacherForm.phone = user.phone |
||||||
|
this.teacherForm.email = user.email |
||||||
|
this.teacherForm.userAccount = user.account |
||||||
|
this.originalAccount = Number(user.account) |
||||||
|
this.teacherForm.userId = user.userId |
||||||
|
this.teacherForm.schoolId = user.schoolId |
||||||
|
this.teacherForm.roleValue = user.roleId |
||||||
|
|
||||||
|
this.teacherForm.major = or.staffProfessionalArchitectureId |
||||||
|
this.teacherForm.department = or.staffGradeId |
||||||
|
this.teacherForm.workNumber = or.workNumber |
||||||
|
this.originalWorkNumber = or.workNumber |
||||||
|
this.isManager = true |
||||||
|
this.teacherForm.staffId = or.staffId |
||||||
|
this.getDepartment() |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
editTeacher(row){ |
||||||
|
this.isDetail = false |
||||||
|
this.teacherVisible = true |
||||||
|
this.isAddteacher = false |
||||||
|
this.AccountNoAdd = false |
||||||
|
this.teacherForm.teacherId = row.staffId |
||||||
|
this.majorList = this.$refs.getSelectData.majorList |
||||||
|
this.getStaffDetail(row.staffId) |
||||||
|
}, |
||||||
|
showTeacher(row){ |
||||||
|
this.isDetail = true |
||||||
|
this.teacherVisible = true |
||||||
|
this.isAddteacher = false |
||||||
|
this.AccountNoAdd = false |
||||||
|
this.teacherForm.teacherId = row.staffId |
||||||
|
this.majorList = this.$refs.getSelectData.majorList |
||||||
|
this.getStaffDetail(row.staffId) |
||||||
|
}, |
||||||
|
getDepartment(){ |
||||||
|
let data = { |
||||||
|
staffProfessionalArchitectureId: this.teacherForm.major |
||||||
|
} |
||||||
|
this.$get(this.api.queryStaffGrade,data).then(res => { |
||||||
|
this.departmentList = res.data.staffGradeList |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
async saveSure(teacherForm){ |
||||||
|
this.$refs[teacherForm].validate((valid) => { |
||||||
|
if (valid) { |
||||||
|
if(this.accountRepeat) return this.$message.warning('该账号已存在') |
||||||
|
if(this.workNumberRepeat) return this.$message.warning('该工号已存在') |
||||||
|
let isTeacher = false |
||||||
|
let isManager = false |
||||||
|
let data = { |
||||||
|
userInfo: { |
||||||
|
userId: this.teacherForm.userId, |
||||||
|
userName: this.teacherForm.userName, |
||||||
|
account: this.teacherForm.userAccount, |
||||||
|
schoolId: this.teacherForm.schoolId, |
||||||
|
clientId: this.teacherForm.clientId, |
||||||
|
clientName: this.teacherForm.clientName, |
||||||
|
roleId: this.teacherForm.roleValue, |
||||||
|
phone: this.teacherForm.phone, |
||||||
|
email: this.teacherForm.email, |
||||||
|
isPort: 2, |
||||||
|
uniqueIdentificationAccount: this.teacherForm.uniqueIdentificationAccount ? this.teacherForm.uniqueIdentificationAccount : Date.parse(new Date()), |
||||||
|
} |
||||||
|
} |
||||||
|
let oneDepartmentName = ''; |
||||||
|
for(let i in this.majorList){ |
||||||
|
if(this.majorList[i].staffProfessionalArchitectureId == this.teacherForm.major) { |
||||||
|
oneDepartmentName = this.majorList[i].staffProfessionalArchitectureName |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
let twoDepartmentName = this.departmentList.find((n) => { |
||||||
|
return n.staffGradeId == this.teacherForm.department |
||||||
|
}).staffGradeName; |
||||||
|
data.staff = { |
||||||
|
roleId: this.teacherForm.roleValue, |
||||||
|
isPort: 2, |
||||||
|
schoolId: this.schoolId, |
||||||
|
staffId: this.teacherForm.staffId, |
||||||
|
userId: this.teacherForm.userId, |
||||||
|
workNumber: this.teacherForm.workNumber, |
||||||
|
staffProfessionalArchitectureId: this.teacherForm.major, |
||||||
|
staffGradeId: this.teacherForm.department, |
||||||
|
staffProfessionalArchitectureName: oneDepartmentName, |
||||||
|
staffGradeName: twoDepartmentName, |
||||||
|
}; |
||||||
|
if(this.teacherForm.teacherId){ |
||||||
|
this.$post(this.api.updateStaff,data).then(res => { |
||||||
|
this.teacherVisible = false |
||||||
|
this.$message.success('编辑成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}else{ |
||||||
|
this.$post(this.api.addStaff,data).then(res => { |
||||||
|
this.teacherVisible = false |
||||||
|
this.$message.success('添加成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
} |
||||||
|
}else{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
delTeacher(row){ |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
let data = { |
||||||
|
staffIds: row.staffId |
||||||
|
} |
||||||
|
this.$del(this.api.deleteStaffs,data).then(res => { |
||||||
|
this.$message.success('删除成功') |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
delAllSelection() { |
||||||
|
if(this.multipleSelection.length != ''){ |
||||||
|
let newArr = this.multipleSelection |
||||||
|
let delList = newArr.map(item => { |
||||||
|
return item.staffId |
||||||
|
}) |
||||||
|
// 批量删除 |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
let data = { |
||||||
|
staffIds: delList.join(',') |
||||||
|
} |
||||||
|
this.$del(this.api.deleteStaffs,data).then(res => { |
||||||
|
this.multipleSelection = []; |
||||||
|
this.$message.success('删除成功') |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}).catch(() => {}); |
||||||
|
}else{ |
||||||
|
this.$message.error('请先选择数据 !') |
||||||
|
} |
||||||
|
}, |
||||||
|
batchImport(){ |
||||||
|
this.importVisible = true |
||||||
|
this.uploadList = [] |
||||||
|
this.uploadFaild = false |
||||||
|
}, |
||||||
|
searchTeacher(){ |
||||||
|
this.pageNo = 1; |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.pageNo = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
downLoad(){ |
||||||
|
location.href = this.api.downloadStaffTemp |
||||||
|
}, |
||||||
|
showFaild(){ |
||||||
|
location.href = `${this.api.exportFailureStaff}?token=${this.token}` |
||||||
|
}, |
||||||
|
// 上传文件 |
||||||
|
handleExceed(files, fileList) { |
||||||
|
this.$message.warning( |
||||||
|
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` |
||||||
|
); |
||||||
|
}, |
||||||
|
uploadSuccess(res, file, fileList) { |
||||||
|
this.uploadFaild = false |
||||||
|
if(res.success){ |
||||||
|
if(res.data.data.token){ |
||||||
|
this.token = res.data.data.token |
||||||
|
this.uploadFaild = true |
||||||
|
}else{ |
||||||
|
this.$message.success('上传成功') |
||||||
|
} |
||||||
|
}else{ |
||||||
|
res.data.message ? this.$message.error(res.data.message) : this.$message.error('上传失败,请检查数据') |
||||||
|
} |
||||||
|
}, |
||||||
|
uploadError(err, file, fileList) { |
||||||
|
this.$message({ |
||||||
|
message: "上传出错,请重试!", |
||||||
|
type: "error", |
||||||
|
center: true |
||||||
|
}); |
||||||
|
}, |
||||||
|
beforeRemove(file, fileList) { |
||||||
|
return this.$confirm(`确定移除 ${file.name}?`); |
||||||
|
}, |
||||||
|
handleRemove(file, fileList) { |
||||||
|
this.uploadList = fileList |
||||||
|
this.uploadFaild = false |
||||||
|
}, |
||||||
|
uploadSure(){ |
||||||
|
this.importVisible = false |
||||||
|
this.pageNo = 1 |
||||||
|
this.keyword = '' |
||||||
|
this.getData() |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
.el-container{ |
||||||
|
background-color: #f0f0f0; |
||||||
|
} |
||||||
|
.mag{ |
||||||
|
margin-right: 20px; |
||||||
|
margin-left: 20px; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,489 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div> |
||||||
|
<div class="side_view"> |
||||||
|
<p class="side_icon mab20"> |
||||||
|
<i class="icon-jiahao mar20" @click="addMajor"></i> |
||||||
|
<!-- <i class="icon-delete"></i> --> |
||||||
|
</p> |
||||||
|
<div class="side_tree" @click.stop="open(item)" v-for="(item,index) in majorList" :key="index"> |
||||||
|
<div class="item" @click.stop="open(item)"> |
||||||
|
<!-- <i :class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}" class="icon-shixiangyoujiantou-"></i> --> |
||||||
|
<img |
||||||
|
v-if="item.children&&item.children.length!=0" |
||||||
|
:class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}" |
||||||
|
src="../../../assets/img/icon-xiangyou.png" |
||||||
|
alt |
||||||
|
/> |
||||||
|
<i v-else class="empty"></i> |
||||||
|
<i :class="item.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="fircheckitem(item)"></i> |
||||||
|
<span @click.stop="fircheckitem(item)">{{item.staffProfessionalArchitectureName}}</span> |
||||||
|
<i class="edit ft" @click.stop="editMajor(item)"></i> |
||||||
|
<i class="el-icon-circle-plus ft" @click.stop="addDepartment(item)"></i> |
||||||
|
<i class="icon-delete ft" @click.stop="delMajor(item,index)"></i> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div v-show="item.ifVisible" v-if="item.children&&item.children.length!=0"> |
||||||
|
<div v-for="(item1,index1) in item.children" :key="index1"> |
||||||
|
<div class="item2" @click.stop="open(item1)"> |
||||||
|
<i :class="item1.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="twocheckitem(item1)"></i> |
||||||
|
<span @click.stop="twocheckitem(item1)">{{item1.label}}</span> |
||||||
|
<i class="edit ft" @click.stop="editDepartment(item1)"></i> |
||||||
|
<i class="icon-delete ft" @click.stop="delDepartment(item1,index1)"></i> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- 添加专业 --> |
||||||
|
<el-dialog :title="Form.MajorId ? '编辑专业' : '新增专业'" :visible.sync="isaddMajor" width="24%" center @close="closeAdd" :close-on-click-modal="false"> |
||||||
|
<el-form ref="Form" :model="Form"> |
||||||
|
<el-form-item prop="majorName"> |
||||||
|
<el-input placeholder="请输入专业名称" v-model="Form.majorName" @change="majorChange"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="isaddMajor = false">取 消</el-button> |
||||||
|
<el-button type="primary" @click="sure('Form')">确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<!-- 添加部门 --> |
||||||
|
<el-dialog :title="Form.departmentId ? '编辑部门' : '新增部门'" :visible.sync="isAddDepartment" width="24%" center @close="closeAdd" :close-on-click-modal="false"> |
||||||
|
<el-form ref="Form" :model="Form"> |
||||||
|
<el-form-item prop="departmentName"> |
||||||
|
<el-input placeholder="请输入部门名称" v-model="Form.departmentName" @change="depChange"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="isAddDepartment = false">取 消</el-button> |
||||||
|
<el-button type="primary" @click="sureDepartment('Form')">确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import { mapState } from 'vuex'; |
||||||
|
export default { |
||||||
|
props:["Data"], |
||||||
|
data() { |
||||||
|
return { |
||||||
|
majorList: [], |
||||||
|
firactive: 0, |
||||||
|
twoactive: 0, |
||||||
|
isaddMajor: false, |
||||||
|
isAddDepartment: false, |
||||||
|
Form: { |
||||||
|
MajorId: '', |
||||||
|
majorName: '', |
||||||
|
departmentId: '', |
||||||
|
departmentName: '' |
||||||
|
}, |
||||||
|
staffstateProfessId: '', |
||||||
|
staffstateId: '', |
||||||
|
majorNoAdd: true, |
||||||
|
depNoAdd: true |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
...mapState('user', [ |
||||||
|
'clientId','clientName' |
||||||
|
]) |
||||||
|
}, |
||||||
|
mounted(){ |
||||||
|
this.getStaff() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getStaff(majorIds){ |
||||||
|
let data = { |
||||||
|
schoolId: this.clientId |
||||||
|
} |
||||||
|
this.$get(this.api.queryStaffPro,data).then(res => { |
||||||
|
let firList = res.data.StaffProfessionalArchitectureList |
||||||
|
if(firList){ |
||||||
|
firList.map(e => { |
||||||
|
(e.ifVisible = false), (e.ischeck = false), (e.label = e.staffProfessionalArchitectureName); |
||||||
|
majorIds && majorIds.includes(e.staffProfessionalArchitectureId) && (e.ifVisible = true) |
||||||
|
let data = { |
||||||
|
staffProfessionalArchitectureId: e.staffProfessionalArchitectureId |
||||||
|
} |
||||||
|
this.$get(this.api.queryStaffGrade,data).then(res1 => { |
||||||
|
res1.data.staffGradeList.map(e => { |
||||||
|
(e.ischeck = false), (e.label = e.staffGradeName); |
||||||
|
}) |
||||||
|
e.children = res1.data.staffGradeList |
||||||
|
}).catch(res1 => {}); |
||||||
|
}) |
||||||
|
} |
||||||
|
setTimeout(() => { |
||||||
|
this.majorList = firList |
||||||
|
majorIds || (this.majorList[0].ifVisible = true) |
||||||
|
}, 500); |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
//点击节点时伸展或收缩列表 |
||||||
|
open(item) { |
||||||
|
item.ifVisible = !item.ifVisible; |
||||||
|
}, |
||||||
|
|
||||||
|
//选中叶子节点时将选中的叶子节点添加进数组,如果叶子节点存在则删除,removeByvalue函数定义在main.js中 |
||||||
|
choose(item) { |
||||||
|
item.ifVisible = !item.ifVisible; |
||||||
|
if (item.ifVisible) { |
||||||
|
this.chooseList.push(item); |
||||||
|
} else { |
||||||
|
this.chooseList.removeByValue(item); |
||||||
|
} |
||||||
|
}, |
||||||
|
// 选择专业 |
||||||
|
fircheckitem(item){ |
||||||
|
this.$emit("fircheck",item,this.majorList) |
||||||
|
}, |
||||||
|
// 选择部门 |
||||||
|
twocheckitem(item){ |
||||||
|
item.ischeck = !item.ischeck |
||||||
|
this.majorList.forEach( e => { |
||||||
|
e.children.forEach( r => { |
||||||
|
if(r.staffGradeId == item.staffGradeId){ |
||||||
|
if(e.children.every(i => i.ischeck)){ |
||||||
|
e.ischeck = true |
||||||
|
}else{ |
||||||
|
e.ischeck = false |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
this.$emit("twocheck",item,this.majorList) |
||||||
|
}, |
||||||
|
closeAdd(){ |
||||||
|
this.$refs.Form.resetFields() |
||||||
|
}, |
||||||
|
// 新增编辑专业 |
||||||
|
addMajor(){ |
||||||
|
this.Form.MajorId = '' |
||||||
|
this.Form.majorName = '' |
||||||
|
this.isaddMajor = true |
||||||
|
}, |
||||||
|
editMajor(item){ |
||||||
|
this.Form.MajorId = item.staffProfessionalArchitectureId, |
||||||
|
this.Form.majorName = item.staffProfessionalArchitectureName |
||||||
|
this.isaddMajor = true |
||||||
|
}, |
||||||
|
async majorChange(){ |
||||||
|
let res = await this.$get(this.api.queryStaffPAN, { name: this.Form.majorName,schoolId: this.clientId }); |
||||||
|
if(res.data.StaffProfessionalArchitecture != null){ |
||||||
|
this.$message.warning('该一级部门已存在'); |
||||||
|
this.majorNoAdd = false |
||||||
|
}else{ |
||||||
|
this.majorNoAdd = true |
||||||
|
} |
||||||
|
}, |
||||||
|
async depChange(){ |
||||||
|
let res = await this.$get(this.api.queryStaffName, { staffGradeName: this.Form.departmentName,staffProfessionalArchitectureId: this.Form.MajorId }); |
||||||
|
if(res.data.staffGrade != null){ |
||||||
|
this.$message.warning('该二级部门已存在'); |
||||||
|
this.depNoAdd = false |
||||||
|
}else{ |
||||||
|
this.depNoAdd = true |
||||||
|
} |
||||||
|
}, |
||||||
|
sure(Form){ |
||||||
|
if(!this.Form.majorName) return this.$message.warning('请输入专业名称'); |
||||||
|
if(!this.majorNoAdd) return this.$message.warning('该一级部门已存在'); |
||||||
|
let data = { |
||||||
|
staffProfessionalArchitectureName: this.Form.majorName, |
||||||
|
staffProfessionalArchitectureId: this.Form.MajorId, |
||||||
|
schoolId: this.clientId, |
||||||
|
} |
||||||
|
if(this.Form.MajorId){ |
||||||
|
this.$post(this.api.updateStaffPro,data).then(res => { |
||||||
|
this.$message.success('编辑成功'); |
||||||
|
this.isaddMajor = false |
||||||
|
this.getStaff() |
||||||
|
this.$emit('getData') |
||||||
|
}).catch(res => {}); |
||||||
|
}else{ |
||||||
|
this.$post(this.api.addStaffPro,data).then(res => { |
||||||
|
this.$message.success('添加成功'); |
||||||
|
this.isaddMajor = false |
||||||
|
this.getStaff() |
||||||
|
}).catch(res => {}); |
||||||
|
} |
||||||
|
}, |
||||||
|
// 新增编辑部门 |
||||||
|
addDepartment(item){ |
||||||
|
this.Form.departmentId = '' |
||||||
|
this.Form.departmentName = '' |
||||||
|
this.isAddDepartment = true |
||||||
|
this.Form.MajorId = item.staffProfessionalArchitectureId |
||||||
|
}, |
||||||
|
editDepartment(item){ |
||||||
|
this.Form.departmentId = item.staffGradeId, |
||||||
|
this.Form.departmentName = item.staffGradeName |
||||||
|
this.isAddDepartment = true |
||||||
|
for (let j = 0; j < this.majorList.length; j++) { |
||||||
|
for (let k = 0; k < this.majorList[j].children.length; k++) { |
||||||
|
if(this.majorList[j].children[k].staffGradeId == item.staffGradeId){ |
||||||
|
this.Form.MajorId = this.majorList[j].staffProfessionalArchitectureId |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
sureDepartment(Form){ |
||||||
|
if(!this.Form.departmentName) return this.$message.warning('请输入部门名称'); |
||||||
|
if(!this.depNoAdd) return this.$message.warning('该二级部门已存在'); |
||||||
|
let data = { |
||||||
|
schoolId: this.clientId, |
||||||
|
staffGradeName: this.Form.departmentName, |
||||||
|
staffProfessionalArchitectureId: this.Form.MajorId, |
||||||
|
staffGradeId: this.Form.departmentId |
||||||
|
} |
||||||
|
if(this.Form.departmentId){ |
||||||
|
this.$post(this.api.updateStaffGrade,data).then(res => { |
||||||
|
this.$message.success('编辑成功'); |
||||||
|
this.isAddDepartment = false |
||||||
|
this.majorList.map(e =>{ |
||||||
|
e.children.map(r =>{ |
||||||
|
if(r.staffGradeId == this.Form.departmentId){ |
||||||
|
r.staffGradeName = this.Form.departmentName |
||||||
|
r.label = this.Form.departmentName |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
}).catch(res => {}); |
||||||
|
}else{ |
||||||
|
let showMajorIds = this.majorList.map(e => {if(e.ifVisible) return e.staffProfessionalArchitectureId}).filter(n => n) |
||||||
|
this.$post(this.api.addStaffGrade,data).then(res => { |
||||||
|
this.$message.success('添加成功'); |
||||||
|
this.isAddDepartment = false |
||||||
|
this.getStaff(showMajorIds) |
||||||
|
}).catch(res => {}); |
||||||
|
} |
||||||
|
}, |
||||||
|
delMajor(item,index){ |
||||||
|
this.$confirm('确定要删除该专业吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$post(`${this.api.deleteStaffPro}?staffProfessionalArchitectureIds=${item.staffProfessionalArchitectureId}`).then(res => { |
||||||
|
this.$message.success('删除成功'); |
||||||
|
this.majorList.splice(index, 1) |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
delDepartment(item,indx){ |
||||||
|
this.$confirm('确定要删除该部门吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$post(`${this.api.deleteStaffGrade}?staffGradeIds=${item.staffGradeId}`).then(res => { |
||||||
|
this.$message.success('删除成功'); |
||||||
|
this.majorList.map(e =>{ |
||||||
|
e.children.map(r =>{ |
||||||
|
if(r.staffGradeId == item.staffGradeId){ |
||||||
|
e.children.splice(indx,1) |
||||||
|
if(e.children.length == 0){ |
||||||
|
e.ifVisible = false |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
$insideColor: rgba(245, 242, 255, 0.8); //内部节点的边框颜色 |
||||||
|
$outColor: rgba(255, 255, 255, 0.8); //外部节点的边框颜色 |
||||||
|
|
||||||
|
//混合代码,提取item共同样式 |
||||||
|
@mixin public { |
||||||
|
cursor: pointer; |
||||||
|
font-size: 16px; |
||||||
|
color: #333333; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
img { |
||||||
|
height: 20px; |
||||||
|
width: 20px; |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.main { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.item { |
||||||
|
@include public; |
||||||
|
width: 100%; |
||||||
|
padding: 15px 0; |
||||||
|
background:rgba(255,255,255,1); |
||||||
|
box-shadow:1px 14px 29px 0px rgba(255,69,69,0.19); |
||||||
|
border-radius:10px; |
||||||
|
text-align: left; |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
.item:first{ |
||||||
|
margin-top: 0; |
||||||
|
} |
||||||
|
.item2 { |
||||||
|
@include public; |
||||||
|
margin-top: 20px; |
||||||
|
margin-left:50px |
||||||
|
} |
||||||
|
.item2:hover{ |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
.item .empty{ |
||||||
|
width: 20px; |
||||||
|
} |
||||||
|
.edit{ |
||||||
|
display: inline-block; |
||||||
|
width: 17px; |
||||||
|
height: 17px; |
||||||
|
background: url(../../../assets/img/edit.svg) 0 0/cover no-repeat; |
||||||
|
} |
||||||
|
|
||||||
|
//清除ul,li的默认样式 |
||||||
|
ul, |
||||||
|
li { |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
list-style: none; |
||||||
|
} |
||||||
|
|
||||||
|
// 使三角形旋转动画 |
||||||
|
.arrowTransform { |
||||||
|
transition: 0.4s; |
||||||
|
transform-origin: center; |
||||||
|
transform: rotateZ(0deg); |
||||||
|
} |
||||||
|
.arrowTransformReturn { |
||||||
|
transition: 0.4s; |
||||||
|
transform-origin: center; |
||||||
|
transform: rotateZ(90deg); |
||||||
|
} |
||||||
|
|
||||||
|
//复选框样式 |
||||||
|
.checkBox { |
||||||
|
width: 14px; |
||||||
|
height: 14px; |
||||||
|
border-radius: 7px; |
||||||
|
margin-left: 10px; |
||||||
|
margin-right: 10px; |
||||||
|
border: 2px solid rgba(146, 120, 255, 1); |
||||||
|
} |
||||||
|
|
||||||
|
//当点击复选框时候切换背景图片 |
||||||
|
.isActive { |
||||||
|
background: url('../../../assets/img/icon-yigouxuan.png'); |
||||||
|
background-size: 14px 14px; /*按比例缩放*/ |
||||||
|
} |
||||||
|
|
||||||
|
.side_view{ |
||||||
|
padding: 40px 20px; |
||||||
|
background-color: #fff; |
||||||
|
i { |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
} |
||||||
|
.side_icon{ |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
.side_icon i{ |
||||||
|
cursor:pointer; |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
.side_tree{ |
||||||
|
width: 100%; |
||||||
|
font-size: 14px; |
||||||
|
color: #333; |
||||||
|
i{ |
||||||
|
color: #cb221c; |
||||||
|
margin-left: 5px; |
||||||
|
font-size: 17px; |
||||||
|
} |
||||||
|
span{ |
||||||
|
margin-left: 5px; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.side_view{ |
||||||
|
height: 800px; |
||||||
|
padding: 40px 20px; |
||||||
|
background-color: #fff; |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
.side_icon{ |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
.side_icon i{ |
||||||
|
cursor:pointer; |
||||||
|
font-size: 20px; |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
|
||||||
|
.fir_back{ |
||||||
|
width: 100%; |
||||||
|
padding: 15px 0; |
||||||
|
background:rgba(255,255,255,1); |
||||||
|
/* box-shadow:1px 14px 29px 0px rgba(138,97,250,0.19); */ |
||||||
|
border-radius:10px; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
.fir_back:first-child{ |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
.fir_back:hover{ |
||||||
|
box-shadow:1px 14px 29px 0px rgba(138,97,250,0.19); |
||||||
|
cursor:pointer; |
||||||
|
} |
||||||
|
.fir_back span{ |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
.two_active{ |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
/* .two_active:hover{ |
||||||
|
color: #cb221c; |
||||||
|
cursor:pointer; |
||||||
|
} */ |
||||||
|
.two_back:hover{ |
||||||
|
cursor:pointer; |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
.mar_top{ |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
.back_active{ |
||||||
|
box-shadow:1px 14px 29px 0px rgba(138,97,250,0.19); |
||||||
|
} |
||||||
|
.bor_lef{ |
||||||
|
padding: 20px 0 0 0; |
||||||
|
margin-left: 40px; |
||||||
|
} |
||||||
|
.three_lef{ |
||||||
|
margin-left: 60px; |
||||||
|
padding: 20px 0; |
||||||
|
} |
||||||
|
.three_text{ |
||||||
|
font-size: 14px; |
||||||
|
margin-top: 10px; |
||||||
|
} |
||||||
|
.teacher_tab{ |
||||||
|
margin-left: 20px; |
||||||
|
} |
||||||
|
.icon_select:before{ |
||||||
|
transform: rotate(180deg); |
||||||
|
} |
||||||
|
.list-enter-active, .list-leave-active { transition: all 1s; } |
||||||
|
.list-enter, .list-leave-to { opacity: 0; transform: translateY(-30px); } |
||||||
|
</style> |
@ -0,0 +1,239 @@ |
|||||||
|
<template> |
||||||
|
<div class="side_view"> |
||||||
|
<p class="side_icon mab20"> |
||||||
|
<i class="icon-jiahao mar20" @click="addMajor"></i> |
||||||
|
<!-- <i class="icon-delete"></i> --> |
||||||
|
</p> |
||||||
|
<div class="side_tree" @click.stop="open(item)" v-for="(item,index) in data" :key="index"> |
||||||
|
<div class="item" @click.stop="open(item)"> |
||||||
|
<!-- <i :class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}" class="icon-shixiangyoujiantou-"></i> --> |
||||||
|
<img |
||||||
|
:class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}" |
||||||
|
src="../../../assets/img/icon-xiangyou.png" |
||||||
|
alt |
||||||
|
/> |
||||||
|
<i :class="item.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="fircheckitem(item)"></i> |
||||||
|
<span>{{item.staffProfessionalArchitectureName}}</span> |
||||||
|
<i class="el-icon-info ft" @click.stop="editMajor(item)"></i> |
||||||
|
<i class="el-icon-circle-plus ft" @click.stop="addDepartment(item)"></i> |
||||||
|
<i class="icon-delete ft" @click.stop="delMajor(item,index)"></i> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div v-show="item.ifVisible" v-if="item.children&&item.children.length!=0"> |
||||||
|
<div v-for="(item1,index1) in item.children" :key="index1"> |
||||||
|
<div class="item2" @click.stop="open(item1)"> |
||||||
|
<i :class="item1.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="twocheckitem(item1)"></i> |
||||||
|
<span>{{item1.label}}</span> |
||||||
|
<i class="el-icon-info ft" @click.stop="editDepartment(item1)"></i> |
||||||
|
<i class="icon-delete ft" @click.stop="delDepartment(item1,index1)"></i> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
Array.prototype.removeByValue = function (val) { |
||||||
|
for (var i = 0; i < this.length; i++) { |
||||||
|
if (JSON.stringify(this[i]).indexOf(JSON.stringify(val)) != -1) { |
||||||
|
this.splice(i, 1); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
chooseList: [] |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
chooseList(n, o) { |
||||||
|
this.$emit('chooseNode', n); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
props: { |
||||||
|
data: { |
||||||
|
type: Array |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
//点击节点时伸展或收缩列表 |
||||||
|
open(item) { |
||||||
|
item.ifVisible = !item.ifVisible; |
||||||
|
}, |
||||||
|
|
||||||
|
//选中叶子节点时将选中的叶子节点添加进数组,如果叶子节点存在则删除,removeByvalue函数定义在main.js中 |
||||||
|
choose(item) { |
||||||
|
item.ifVisible = !item.ifVisible; |
||||||
|
if (item.ifVisible) { |
||||||
|
this.chooseList.push(item); |
||||||
|
} else { |
||||||
|
this.chooseList.removeByValue(item); |
||||||
|
} |
||||||
|
}, |
||||||
|
fircheckitem(item){ |
||||||
|
this.$emit('fircheckitem',item); |
||||||
|
}, |
||||||
|
twocheckitem(item){ |
||||||
|
this.$emit('twocheckitem',item); |
||||||
|
}, |
||||||
|
// 专业 |
||||||
|
addMajor(){ |
||||||
|
this.$emit('addMajor'); |
||||||
|
}, |
||||||
|
editMajor(item){ |
||||||
|
this.$emit('editMajor',item); |
||||||
|
}, |
||||||
|
delMajor(item,index){ |
||||||
|
this.$emit('delMajor',item,index); |
||||||
|
}, |
||||||
|
// 年级 |
||||||
|
addDepartment(item){ |
||||||
|
this.$emit('addDepartment',item); |
||||||
|
}, |
||||||
|
editDepartment(item){ |
||||||
|
this.$emit('editDepartment',item); |
||||||
|
}, |
||||||
|
delDepart(item,index){ |
||||||
|
this.$emit('delDepart',item,index); |
||||||
|
}, |
||||||
|
// 班级 |
||||||
|
addClass(item){ |
||||||
|
this.$emit('addClass',item); |
||||||
|
}, |
||||||
|
editDepartment(item){ |
||||||
|
this.$emit('editDepartment',item); |
||||||
|
}, |
||||||
|
delDepartment(item,index){ |
||||||
|
this.$emit('delDepartment',item,index); |
||||||
|
}, |
||||||
|
//判断数组中是否包含某个对象 |
||||||
|
isHasObj(arr, val) { |
||||||
|
var flag = 0; //1为有 0为没有 |
||||||
|
for (var i = 0; i < arr.length; i++) { |
||||||
|
if (JSON.stringify(arr[i]).indexOf(JSON.stringify(val)) != -1) { |
||||||
|
flag = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
if (flag == 1) { |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
$insideColor: rgba(245, 242, 255, 0.8); //内部节点的边框颜色 |
||||||
|
$outColor: rgba(255, 255, 255, 0.8); //外部节点的边框颜色 |
||||||
|
|
||||||
|
//混合代码,提取item共同样式 |
||||||
|
@mixin public { |
||||||
|
cursor: pointer; |
||||||
|
font-size: 14px; |
||||||
|
color: #333333; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
img { |
||||||
|
height: 20px; |
||||||
|
width: 20px; |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.main { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.item { |
||||||
|
@include public; |
||||||
|
width: 100%; |
||||||
|
padding: 15px 0; |
||||||
|
background:rgba(255,255,255,1); |
||||||
|
box-shadow:1px 14px 29px 0px rgba(138,97,250,0.19); |
||||||
|
border-radius:10px; |
||||||
|
text-align: left; |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
.item:first{ |
||||||
|
margin-top: 0; |
||||||
|
} |
||||||
|
.item2 { |
||||||
|
@include public; |
||||||
|
margin-top: 20px; |
||||||
|
margin-left:60px |
||||||
|
} |
||||||
|
.item2:hover{ |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
|
||||||
|
//清除ul,li的默认样式 |
||||||
|
ul, |
||||||
|
li { |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
list-style: none; |
||||||
|
} |
||||||
|
|
||||||
|
// 使三角形旋转动画 |
||||||
|
.arrowTransform { |
||||||
|
transition: 0.4s; |
||||||
|
transform-origin: center; |
||||||
|
transform: rotateZ(0deg); |
||||||
|
} |
||||||
|
.arrowTransformReturn { |
||||||
|
transition: 0.4s; |
||||||
|
transform-origin: center; |
||||||
|
transform: rotateZ(90deg); |
||||||
|
} |
||||||
|
|
||||||
|
//复选框样式 |
||||||
|
.checkBox { |
||||||
|
width: 14px; |
||||||
|
height: 14px; |
||||||
|
border-radius: 7px; |
||||||
|
margin-left: 10px; |
||||||
|
margin-right: 10px; |
||||||
|
border: 2px solid rgba(146, 120, 255, 1); |
||||||
|
} |
||||||
|
|
||||||
|
//当点击复选框时候切换背景图片 |
||||||
|
.isActive { |
||||||
|
background: url('../../../assets/img/icon-yigouxuan.png'); |
||||||
|
background-size: 14px 14px; /*按比例缩放*/ |
||||||
|
} |
||||||
|
|
||||||
|
.side_view{ |
||||||
|
// height: 800px; |
||||||
|
padding: 40px 20px; |
||||||
|
background-color: #fff; |
||||||
|
box-shadow:-2px 0px 57px 0px rgba(192,189,216,0.39); |
||||||
|
i { |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
} |
||||||
|
.side_icon{ |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
.side_icon i{ |
||||||
|
cursor:pointer; |
||||||
|
font-size: 20px; |
||||||
|
} |
||||||
|
.side_tree{ |
||||||
|
width: 100%; |
||||||
|
font-size: 14px; |
||||||
|
color: #333; |
||||||
|
i{ |
||||||
|
margin-left: 10px; |
||||||
|
} |
||||||
|
span{ |
||||||
|
margin-left: 5px; |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,923 @@ |
|||||||
|
<template> |
||||||
|
<div class="box"> |
||||||
|
<div class="form"> |
||||||
|
<div class="line"> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">试卷名称:</p> |
||||||
|
<el-input v-model="name"></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="line"> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">试卷用途:</p> |
||||||
|
<el-select v-model="effect" placeholder="请选择试卷用途"> |
||||||
|
<el-option v-for="(item,index) in effectList" :key="index" :label="item.label" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</div> |
||||||
|
<div class="item lg"> |
||||||
|
<p class="key">所属课程:</p> |
||||||
|
<el-input v-model="courses"></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="line"> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">难易程度:</p> |
||||||
|
<el-select v-model="degree" placeholder="请选择难易程度"> |
||||||
|
<el-option v-for="(item,index) in degreeList" :key="index" :label="item.label" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</div> |
||||||
|
<div class="item lg"> |
||||||
|
<p class="key">建议时长(分钟):</p> |
||||||
|
<el-input v-model.number="duration"></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="line"> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">组卷方式:</p> |
||||||
|
<div> |
||||||
|
<el-radio v-for="(item,index) in typeList" :key="index" v-model="type" :label="item.id">{{item.label}}</el-radio> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="line"> |
||||||
|
<div class="item"> |
||||||
|
<p class="key">组卷方式:</p> |
||||||
|
<div> |
||||||
|
<el-button type="primary" @click="selectQues">选择试题</el-button> |
||||||
|
<el-button type="primary" @click="removeQues">移除试题</el-button> |
||||||
|
<el-button type="primary" @click="preview">试卷预览</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="testpaper"> |
||||||
|
<el-table :data="selectedData" ref="selectedTable" class="table" stripe header-align="center" row-key="id" @selection-change="handleSelecteChange"> |
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="questionSource" label="题库来源" align="center"></el-table-column> |
||||||
|
<el-table-column prop="questionStem" label="题干" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<div v-html="scope.row.questionStem"></div> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="试题类型" align="center"></el-table-column> |
||||||
|
<el-table-column prop="courses" label="对应课程" align="center"></el-table-column> |
||||||
|
<el-table-column prop="knowledgePoints" label="知识点" align="center"></el-table-column> |
||||||
|
<el-table-column prop="useNum" label="使用次数" align="center"></el-table-column> |
||||||
|
<el-table-column prop="createTime" label="上传时间" align="center"></el-table-column> |
||||||
|
<el-table-column prop="createUser" label="创建人" align="center"></el-table-column> |
||||||
|
</el-table> |
||||||
|
|
||||||
|
<div class="point"> |
||||||
|
<p class="key">设置分值:</p> |
||||||
|
<div class="inputs"> |
||||||
|
<div class="line"> |
||||||
|
<div class="item"> |
||||||
|
<p class="label">单选题</p> |
||||||
|
<input type="text" :disabled="type == 1" v-model.number="singleCount"> 道 |
||||||
|
<input type="text" v-model.number="singleChoiceScore"> 分/题 |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="label">多选题</p> |
||||||
|
<input type="text" :disabled="type == 1" v-model.number="multipleCount"> 道 |
||||||
|
<input type="text" v-model.number="multipleChoiceScore"> 分/题 |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="label">填空题</p> |
||||||
|
<input type="text" :disabled="type == 1" v-model.number="fillBlankCount"> 道 |
||||||
|
<input type="text" v-model.number="fillBlanksScore"> 分/题 |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="line"> |
||||||
|
<div class="item"> |
||||||
|
<p class="label">判断题</p> |
||||||
|
<input type="text" :disabled="type == 1" v-model.number="judgeCount"> 道 |
||||||
|
<input type="text" v-model.number="judgeScore"> 分/题 |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="label">简答题</p> |
||||||
|
<input type="text" :disabled="type == 1" v-model.number="briefCount"> 道 |
||||||
|
<input type="text" v-model.number="briefAnswerScore"> 分/题 |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="label">总分:</p> |
||||||
|
<input type="text" disabled v-model.number="totalScore"> 分 |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="btns"> |
||||||
|
<button type="button" v-throttle @click="save(0)">保存</button> |
||||||
|
<button type="button" v-throttle class="submit" @click="save(1)">完成并发布</button> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-dialog title="选择试题" :visible.sync="manualVisible" width="60%" @close="closeManual" :close-on-click-modal="false"> |
||||||
|
<div class="mini-form"> |
||||||
|
<el-form label-width="80px" inline size="mini"> |
||||||
|
<el-form-item class="no-mb" label="课程名称"> |
||||||
|
<el-select v-model="selectManual.courses" clearable placeholder="请选择课程名称" @change="getManualData"> |
||||||
|
<el-option label="不限" value=""></el-option> |
||||||
|
<el-option v-for="(item,index) in courseList" :key="index" :label="item.courses" :value="item.courses"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item class="no-mb" label="知识点"> |
||||||
|
<el-select v-model="selectManual.knowledgePoints" clearable placeholder="请选择知识点" @change="getManualData"> |
||||||
|
<el-option label="不限" value=""></el-option> |
||||||
|
<el-option v-for="(item,index) in pointList" :key="index" :label="item.knowledgePoint" :value="item.knowledgePoint"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div class="flex-between" style="align-items: flex-start"> |
||||||
|
<el-form label-width="80px" inline size="mini"> |
||||||
|
<el-form-item class="no-mb" label="试题类型"> |
||||||
|
<el-select v-model="selectManual.name" clearable placeholder="请选择试题类型" @change="getManualData"> |
||||||
|
<el-option label="不限" value=""></el-option> |
||||||
|
<el-option v-for="(item,index) in nameList" :key="index" :label="item.name" :value="item.name"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item class="no-mb" label="所属题库"> |
||||||
|
<el-select v-model="selectManual.typeName" clearable placeholder="请选择所属题库" @change="getManualData"> |
||||||
|
<el-option label="不限" value=""></el-option> |
||||||
|
<el-option v-for="(item,index) in quesBankList" :key="index" :label="item.typeName" :value="item.cid"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div> |
||||||
|
<el-input |
||||||
|
size="mini" |
||||||
|
placeholder="请输入题干名称" |
||||||
|
prefix-icon="el-icon-search" |
||||||
|
v-model="keyword" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table |
||||||
|
:data="listData" |
||||||
|
ref="table" |
||||||
|
row-key="id" |
||||||
|
class="table" |
||||||
|
stripe |
||||||
|
header-align="center" |
||||||
|
@selection-change="handleSelectionChange" |
||||||
|
> |
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template |
||||||
|
slot-scope="scope" |
||||||
|
>{{scope.$index + (page - 1) * pageSize + 1}}</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="questionSource" label="题库来源" align="center"></el-table-column> |
||||||
|
<el-table-column prop="questionStem" label="题干" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<div v-html="scope.row.questionStem"></div> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="试题类型" align="center"></el-table-column> |
||||||
|
<el-table-column prop="courses" label="对应课程" align="center"></el-table-column> |
||||||
|
<el-table-column prop="knowledgePoints" label="知识点" align="center"></el-table-column> |
||||||
|
<el-table-column prop="useNum" label="使用次数" align="center"></el-table-column> |
||||||
|
<el-table-column prop="createTime" label="上传时间" align="center"></el-table-column> |
||||||
|
<el-table-column prop="createUser" label="创建人" align="center"></el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination |
||||||
|
background |
||||||
|
@current-change="handleCurrentChange" |
||||||
|
:current-page="page" |
||||||
|
:page-size="pageSize" |
||||||
|
layout="total,prev, pager, next" |
||||||
|
:total="total" |
||||||
|
></el-pagination> |
||||||
|
</div> |
||||||
|
|
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button v-throttle @click="manualVisible = false">取消</el-button> |
||||||
|
<el-button v-throttle type="primary" @click="submitManual">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog title="选择试题" :visible.sync="inteVisible" width="60%" @close="closeInte" :close-on-click-modal="false"> |
||||||
|
<div class="select-wrap"> |
||||||
|
<div class="block" style="margin-bottom: 30px;"> |
||||||
|
<p class="key">试题课程:</p> |
||||||
|
<el-transfer v-model="course" :data="inteListData" :props="courseProps" filterable filter-placeholder="请输入课程名称" :titles="['未选', '已选']" @change="courseChange"></el-transfer> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="block"> |
||||||
|
<p class="key">题型配置:</p> |
||||||
|
<div class="types"> |
||||||
|
<div class="item"> |
||||||
|
<el-checkbox v-model="countCheck.countCheck1">单选题</el-checkbox> |
||||||
|
<input type="text" v-model.number="countNumberInput1" :disabled="!countCheck.countCheck1"> 题 (可选{{countNumber1}}题) |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<el-checkbox v-model="countCheck.countCheck2">多选题</el-checkbox> |
||||||
|
<input type="text" v-model.number="countNumberInput2" :disabled="!countCheck.countCheck2"> 题 (可选{{countNumber2}}题) |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<el-checkbox v-model="countCheck.countCheck5">填空题</el-checkbox> |
||||||
|
<input type="text" v-model.number="countNumberInput5" :disabled="!countCheck.countCheck5"> 题 (可选{{countNumber5}}题) |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<el-checkbox v-model="countCheck.countCheck3">判断题</el-checkbox> |
||||||
|
<input type="text" v-model.number="countNumberInput3" :disabled="!countCheck.countCheck3"> 题 (可选{{countNumber3}}题) |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<el-checkbox v-model="countCheck.countCheck4">简答题</el-checkbox> |
||||||
|
<input type="text" v-model.number="countNumberInput4" :disabled="!countCheck.countCheck4"> 题 (可选{{countNumber4}}题) |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button v-throttle @click="inteVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" v-throttle @click="submitInte">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import mixins from '@/mixins/setBackground'; |
||||||
|
import { mapState } from 'vuex' |
||||||
|
export default { |
||||||
|
mixins: [ mixins ], |
||||||
|
data() { |
||||||
|
return { |
||||||
|
id: this.$route.query.id, |
||||||
|
isDetail: Boolean(this.$route.query.show), |
||||||
|
name: '', |
||||||
|
courses: '', |
||||||
|
type: 0, |
||||||
|
effect: '', |
||||||
|
degree: '', |
||||||
|
duration: '', |
||||||
|
qid: '', |
||||||
|
singleCount: '', |
||||||
|
multipleCount: '', |
||||||
|
fillBlankCount: '', |
||||||
|
judgeCount: '', |
||||||
|
briefCount: '', |
||||||
|
singleChoiceScore: '', |
||||||
|
multipleChoiceScore: '', |
||||||
|
judgeScore: '', |
||||||
|
fillBlanksScore: '', |
||||||
|
briefAnswerScore: '', |
||||||
|
multipleSelected: [], |
||||||
|
typeNameList: ['单选题','多选题','判断题','简答题','填空题'], |
||||||
|
|
||||||
|
// 手动组卷 |
||||||
|
manualVisible: false, |
||||||
|
multipleSelection: [], |
||||||
|
listData: [], |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
keyword: '', |
||||||
|
searchTimer: null, |
||||||
|
selectManual: { |
||||||
|
courses: '', |
||||||
|
name: '', |
||||||
|
questionStem: '', |
||||||
|
typeName: '', |
||||||
|
knowledgePoints: '', |
||||||
|
}, |
||||||
|
courseList: [], |
||||||
|
pointList: [], |
||||||
|
nameList: [], |
||||||
|
quesBankList: [], |
||||||
|
// 智能组卷 |
||||||
|
inteVisible: false, |
||||||
|
inteListData: [], |
||||||
|
course: [], |
||||||
|
courseProps: { |
||||||
|
key: 'courses', |
||||||
|
label: 'courses' |
||||||
|
}, |
||||||
|
countNumber1: 0, |
||||||
|
countNumber2: 0, |
||||||
|
countNumber3: 0, |
||||||
|
countNumber4: 0, |
||||||
|
countNumber5: 0, |
||||||
|
countNumberInput1: '', |
||||||
|
countNumberInput2: '', |
||||||
|
countNumberInput3: '', |
||||||
|
countNumberInput4: '', |
||||||
|
countNumberInput5: '', |
||||||
|
countCheck: { |
||||||
|
countCheck1: false, |
||||||
|
countCheck2: false, |
||||||
|
countCheck3: false, |
||||||
|
countCheck4: false, |
||||||
|
countCheck5: false, |
||||||
|
}, |
||||||
|
pointRules: [30,20,10,2,10], |
||||||
|
selectedData: [] |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
...mapState('user', [ |
||||||
|
'userId','clientId' |
||||||
|
]), |
||||||
|
...mapState('testpaper', [ |
||||||
|
'degreeList','effectList','typeList' |
||||||
|
]), |
||||||
|
totalScore(){ |
||||||
|
let totalScore = this.singleCount * this.singleChoiceScore + this.multipleCount * this.multipleChoiceScore + this.fillBlankCount * this.fillBlanksScore + this.judgeCount * this.judgeScore + this.briefCount * this.briefAnswerScore |
||||||
|
return totalScore ? totalScore : '' |
||||||
|
} |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getManualData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.id && this.getInfo() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getInfo() { |
||||||
|
this.$post(`${this.api.detailtestPaper}?id=${this.id}`) |
||||||
|
.then(res => { |
||||||
|
let list = res.data.list |
||||||
|
this.name = list.name |
||||||
|
this.effect = list.effect |
||||||
|
this.courses = list.courses |
||||||
|
this.degree = list.degree |
||||||
|
this.duration = list.duration |
||||||
|
this.type = list.type |
||||||
|
this.qid = list.qid |
||||||
|
this.singleChoiceScore = list.singleChoiceScore |
||||||
|
this.multipleChoiceScore = list.multipleChoiceScore |
||||||
|
this.fillBlanksScore = list.fillBlanksScore |
||||||
|
this.judgeScore = list.judgeScore |
||||||
|
this.briefAnswerScore = list.briefAnswerScore |
||||||
|
this.getQuesList() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
getQuesList(){ |
||||||
|
if(this.qid){ |
||||||
|
let data = { |
||||||
|
ids: this.qid.split(','), |
||||||
|
schoolId: this.clientId, |
||||||
|
userId: this.userId |
||||||
|
} |
||||||
|
this.$post(this.api.getModifyByList, data).then(res => { |
||||||
|
this.selectedData = res.data.list |
||||||
|
this.computeTypeCount() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
defaultZero(val){ |
||||||
|
return val === '' ? 0 : val |
||||||
|
}, |
||||||
|
save(status) { |
||||||
|
if(!this.name) return this.$message.warning('请填写试卷名称') |
||||||
|
let qid = this.selectedData.map(n => n.id).join() |
||||||
|
if(status == 1){ |
||||||
|
if(this.effect === '') return this.$message.warning('请选择试卷用途') |
||||||
|
if(this.courses === '') return this.$message.warning('请填写所属课程') |
||||||
|
if(this.degree === '') return this.$message.warning('请选择难易程度') |
||||||
|
if(this.duration === '') return this.$message.warning('请填写建议时长') |
||||||
|
if(qid === '') return this.$message.warning('请选择试题') |
||||||
|
if(this.totalScore < 100) return this.$message.warning('总分值未满100分,请重新设置') |
||||||
|
if(this.totalScore > 100) return this.$message.warning('总分值超过100分,请重新设置') |
||||||
|
} |
||||||
|
|
||||||
|
let data = { |
||||||
|
id: this.id, |
||||||
|
schoolId: this.clientId, |
||||||
|
userId: this.userId, |
||||||
|
name: this.name, |
||||||
|
effect: this.effect, |
||||||
|
courses: this.courses, |
||||||
|
degree: this.degree, |
||||||
|
duration: this.duration, |
||||||
|
qid: qid, |
||||||
|
state: status, |
||||||
|
type: this.type, |
||||||
|
singleChoiceScore : this.defaultZero(this.singleChoiceScore), |
||||||
|
multipleChoiceScore : this.defaultZero(this.multipleChoiceScore), |
||||||
|
fillBlanksScore : this.defaultZero(this.fillBlanksScore), |
||||||
|
judgeScore : this.defaultZero(this.judgeScore), |
||||||
|
briefAnswerScore : this.defaultZero(this.briefAnswerScore) |
||||||
|
} |
||||||
|
if(this.id){ |
||||||
|
this.$post(this.api.saveOrUpdatetestPaper, data).then(res => { |
||||||
|
this.$message.success('修改成功') |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
}else{ |
||||||
|
this.$post(this.api.saveOrUpdatetestPaper, data).then(res => { |
||||||
|
this.$message.success('创建成功') |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
selectQues(){ |
||||||
|
if(this.type == 0){ |
||||||
|
this.getSelectFilter() |
||||||
|
this.getType() |
||||||
|
this.getQuesBank() |
||||||
|
this.getManualData() |
||||||
|
this.manualVisible = true |
||||||
|
}else{ |
||||||
|
this.getInteData() |
||||||
|
this.inteVisible = true |
||||||
|
} |
||||||
|
}, |
||||||
|
getManualData() { |
||||||
|
let data = { |
||||||
|
courses: this.selectManual.courses, |
||||||
|
knowledgePoints: this.selectManual.knowledgePoints, |
||||||
|
name: this.selectManual.name, |
||||||
|
pageNum: this.page, |
||||||
|
pageSize: this.pageSize, |
||||||
|
questionStem: this.keyword, |
||||||
|
typeName: this.selectManual.typeName, |
||||||
|
userId: this.userId, |
||||||
|
} |
||||||
|
this.$post(this.api.pageByChoiceList,data) |
||||||
|
.then(res => { |
||||||
|
this.listData = res.data.list.list |
||||||
|
this.total = res.data.list.totalCount |
||||||
|
}) |
||||||
|
.catch(err => {}); |
||||||
|
}, |
||||||
|
handleSelecteChange(val){ |
||||||
|
this.multipleSelected = val; |
||||||
|
}, |
||||||
|
removeQues(){ |
||||||
|
if(this.multipleSelected.length){ |
||||||
|
this.$confirm('确定要移除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
let newData = [] |
||||||
|
this.selectedData.forEach((n,i) => { |
||||||
|
this.multipleSelected.every(e => e.id != n.id) && newData.push(n) |
||||||
|
}) |
||||||
|
console.log(33,newData,this.selectedData,this.multipleSelected) |
||||||
|
this.selectedData = newData |
||||||
|
this.computeTypeCount() |
||||||
|
this.$refs.selectedTable.clearSelection() |
||||||
|
this.$message.success('移除成功') |
||||||
|
}) |
||||||
|
.catch(() => {}) |
||||||
|
}else{ |
||||||
|
this.$message.error('请先选择数据') |
||||||
|
} |
||||||
|
}, |
||||||
|
preview(){ |
||||||
|
if(this.multipleSelected.length == 1){ |
||||||
|
this.$router.push(`show?id=${this.multipleSelected[0].id}`) |
||||||
|
}else{ |
||||||
|
this.$message.error('请选择一条数据') |
||||||
|
} |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.page = val; |
||||||
|
this.getManualData(); |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
getSelectFilter(){ |
||||||
|
this.$post(`${this.api.getSelectInfo}?type=1`) |
||||||
|
.then(res => { |
||||||
|
this.pointList = res.data.pointList |
||||||
|
}) |
||||||
|
.catch(err => {}); |
||||||
|
|
||||||
|
this.$post(`${this.api.getSelectInfo}?type=2`) |
||||||
|
.then(res => { |
||||||
|
this.courseList = res.data.pointList |
||||||
|
}) |
||||||
|
.catch(err => {}); |
||||||
|
}, |
||||||
|
getType() { |
||||||
|
this.$get(this.api.typesList) |
||||||
|
.then(res => { |
||||||
|
this.nameList = res.data.list |
||||||
|
}) |
||||||
|
.catch(err => {}) |
||||||
|
}, |
||||||
|
getQuesBank() { |
||||||
|
this.$get(this.api.getTypeByOneLever) |
||||||
|
.then(res => { |
||||||
|
this.quesBankList = res.data.list |
||||||
|
}) |
||||||
|
.catch(err => {}) |
||||||
|
}, |
||||||
|
computeTypeCount(){ |
||||||
|
let selected = this.selectedData |
||||||
|
this.singleCount = selected.filter(n => n.name == '单项选择').length |
||||||
|
this.multipleCount = selected.filter(n => n.name == '多项选择').length |
||||||
|
this.fillBlankCount = selected.filter(n => n.name == '填空题').length |
||||||
|
this.judgeCount = selected.filter(n => n.name == '判断题').length |
||||||
|
this.briefCount = selected.filter(n => n.name == '简答题').length |
||||||
|
}, |
||||||
|
submitManual(){ |
||||||
|
if(this.multipleSelection.length){ |
||||||
|
this.selectedData = this.multipleSelection |
||||||
|
this.computeTypeCount() |
||||||
|
this.manualVisible = false |
||||||
|
}else{ |
||||||
|
this.$message.error('请选择试题') |
||||||
|
} |
||||||
|
}, |
||||||
|
closeManual(){ |
||||||
|
this.selectManual = { |
||||||
|
courses: '', |
||||||
|
name: '', |
||||||
|
questionStem: '', |
||||||
|
typeName: '', |
||||||
|
knowledgePoints: '', |
||||||
|
} |
||||||
|
this.$refs.selectedTable.clearSelection() |
||||||
|
this.keyword = '' |
||||||
|
this.page = 1 |
||||||
|
}, |
||||||
|
getInteData() { |
||||||
|
let data = { |
||||||
|
// courses: '', |
||||||
|
// schoolId: this.clientId, |
||||||
|
// userId: this.userId, |
||||||
|
schoolId: 2, |
||||||
|
userId: 2, |
||||||
|
} |
||||||
|
this.$post(this.api.fuzzyQuery,data) |
||||||
|
.then(res => { |
||||||
|
this.inteListData = res.data.fuzzyList |
||||||
|
}) |
||||||
|
.catch(err => {}); |
||||||
|
}, |
||||||
|
courseChange(val,dir,allData){ |
||||||
|
console.log(val,dir,allData) |
||||||
|
let data = { |
||||||
|
coursesList: val, |
||||||
|
// schoolId: this.clientId, |
||||||
|
// userId: this.userId, |
||||||
|
schoolId: 2, |
||||||
|
userId: 2, |
||||||
|
} |
||||||
|
this.$post(this.api.statistical,data) |
||||||
|
.then(res => { |
||||||
|
let data = res.data.count |
||||||
|
this.countNumber1 = data.countNumber1 |
||||||
|
this.countNumber2 = data.countNumber2 |
||||||
|
this.countNumber3 = data.countNumber3 |
||||||
|
this.countNumber4 = data.countNumber4 |
||||||
|
this.countNumber5 = data.countNumber5 |
||||||
|
}) |
||||||
|
.catch(err => {}); |
||||||
|
}, |
||||||
|
typeValid(index){ |
||||||
|
return this.countCheck[`countCheck${index}`] && this[`countNumberInput${index}`] && this[`countNumber${index}`] |
||||||
|
}, |
||||||
|
countValid(index){ |
||||||
|
if(this[`countNumberInput${index}`] > this[`countNumber${index}`]){ |
||||||
|
this.$message.error(`${this.typeNameList[index-1]}输入题数不能大于可选题数`) |
||||||
|
return false |
||||||
|
} |
||||||
|
return true |
||||||
|
}, |
||||||
|
submitInte(){ |
||||||
|
// return false |
||||||
|
let invalid = false |
||||||
|
let everyUnchecked = true |
||||||
|
let everyIsZero = true |
||||||
|
for(let i in this.countCheck){ |
||||||
|
if(this.countCheck[i]){ |
||||||
|
everyUnchecked = false |
||||||
|
let index = i.replace('countCheck','') |
||||||
|
// console.log(33,this[`countNumberInput${index}`]) |
||||||
|
|
||||||
|
if(this[`countNumberInput${index}`]){ |
||||||
|
everyIsZero = false |
||||||
|
// if(this[`countNumberInput${index}`] !== ''){ |
||||||
|
if(this[`countNumberInput${index}`] < this.pointRules[index-1]){ |
||||||
|
invalid = true |
||||||
|
}else if(this[`countNumberInput${index}`] > this.pointRules[index-1]){ |
||||||
|
this.$message.error('题目数量不能大于可选题数') |
||||||
|
return false |
||||||
|
} |
||||||
|
// } |
||||||
|
} |
||||||
|
}else{ |
||||||
|
invalid = true |
||||||
|
} |
||||||
|
} |
||||||
|
// console.log(11,everyIsZero) |
||||||
|
if(everyUnchecked) return this.$message.error('请选择题型') |
||||||
|
if(everyIsZero) return this.$message.error('请输入题目数量') |
||||||
|
let totalCount = 0 |
||||||
|
if(invalid){ |
||||||
|
for(let i in this.countCheck){ |
||||||
|
let index = i.replace('countCheck','') |
||||||
|
if(this.countCheck[i]) totalCount += this[`countNumberInput${index}`] |
||||||
|
} |
||||||
|
let remainder = 100 % totalCount |
||||||
|
let avgPoint = 100 / totalCount |
||||||
|
if(remainder) avgPoint = (100 - remainder) / totalCount |
||||||
|
|
||||||
|
this.singleCount = '' |
||||||
|
this.multipleCount = '' |
||||||
|
this.fillBlankCount = '' |
||||||
|
this.judgeCount = '' |
||||||
|
this.briefCount = '' |
||||||
|
this.singleChoiceScore = '' |
||||||
|
this.multipleChoiceScore = '' |
||||||
|
this.judgeScore = '' |
||||||
|
this.fillBlanksScore = '' |
||||||
|
this.briefAnswerScore = '' |
||||||
|
|
||||||
|
if(this.typeValid(1)){ |
||||||
|
if(this.countValid(1)){ |
||||||
|
this.singleCount = this.countNumberInput1 |
||||||
|
this.singleChoiceScore = avgPoint |
||||||
|
}else{ |
||||||
|
return false |
||||||
|
} |
||||||
|
} |
||||||
|
if(this.typeValid(2)){ |
||||||
|
if(this.countValid(2)){ |
||||||
|
this.multipleCount = this.countNumberInput2 |
||||||
|
this.multipleChoiceScore = avgPoint |
||||||
|
}else{ |
||||||
|
return false |
||||||
|
} |
||||||
|
} |
||||||
|
if(this.typeValid(5)){ |
||||||
|
if(this.countValid(5)){ |
||||||
|
this.fillBlankCount = this.countNumberInput5 |
||||||
|
this.fillBlanksScore = avgPoint |
||||||
|
}else{ |
||||||
|
return false |
||||||
|
} |
||||||
|
} |
||||||
|
if(this.typeValid(3)){ |
||||||
|
if(this.countValid(3)){ |
||||||
|
this.judgeCount = this.countNumberInput3 |
||||||
|
this.judgeScore = avgPoint |
||||||
|
}else{ |
||||||
|
return false |
||||||
|
} |
||||||
|
} |
||||||
|
if(this.typeValid(4)){ |
||||||
|
if(this.countValid(4)){ |
||||||
|
this.briefCount = this.countNumberInput4 |
||||||
|
this.briefAnswerScore = avgPoint |
||||||
|
}else{ |
||||||
|
return false |
||||||
|
} |
||||||
|
} |
||||||
|
if(remainder){ |
||||||
|
let remainScore = 0 |
||||||
|
let remainPlusAvg = remainder + avgPoint |
||||||
|
let invalid = false |
||||||
|
if(this.typeValid(4)){ |
||||||
|
remainScore = this.briefCount * avgPoint + remainder |
||||||
|
console.log(11,remainScore,remainScore % this.briefCount) |
||||||
|
if(remainScore % this.briefCount){ |
||||||
|
invalid = true |
||||||
|
}else{ |
||||||
|
this.briefAnswerScore = remainScore / this.briefCount |
||||||
|
invalid = false |
||||||
|
} |
||||||
|
}else{ |
||||||
|
invalid = true |
||||||
|
} |
||||||
|
if(invalid){ |
||||||
|
if(this.typeValid(3)){ |
||||||
|
remainScore = this.judgeCount * avgPoint + remainder |
||||||
|
if(remainScore % this.judgeCount){ |
||||||
|
invalid = true |
||||||
|
}else{ |
||||||
|
this.judgeScore = remainScore / this.judgeCount |
||||||
|
invalid = false |
||||||
|
} |
||||||
|
}else{ |
||||||
|
invalid = true |
||||||
|
} |
||||||
|
if(invalid){ |
||||||
|
if(this.typeValid(5)){ |
||||||
|
remainScore = this.fillBlankCount * avgPoint + remainder |
||||||
|
if(remainScore % this.fillBlankCount){ |
||||||
|
invalid = true |
||||||
|
}else{ |
||||||
|
this.fillBlanksScore = remainScore / this.fillBlankCount |
||||||
|
invalid = false |
||||||
|
} |
||||||
|
}else{ |
||||||
|
invalid = true |
||||||
|
} |
||||||
|
if(invalid){ |
||||||
|
if(this.typeValid(2)){ |
||||||
|
remainScore = this.multipleCount * avgPoint + remainder |
||||||
|
if(remainScore % this.multipleCount){ |
||||||
|
invalid = true |
||||||
|
}else{ |
||||||
|
this.multipleChoiceScore = remainScore / this.multipleCount |
||||||
|
invalid = false |
||||||
|
} |
||||||
|
}else{ |
||||||
|
invalid = true |
||||||
|
} |
||||||
|
if(invalid){ |
||||||
|
if(this.typeValid(1)){ |
||||||
|
remainScore = this.singleCount * avgPoint + remainder |
||||||
|
if(remainScore % this.singleCount){ |
||||||
|
invalid = true |
||||||
|
}else{ |
||||||
|
this.singleChoiceScore = remainScore / this.singleCount |
||||||
|
invalid = false |
||||||
|
} |
||||||
|
}else{ |
||||||
|
invalid = true |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
let data = { |
||||||
|
coursesList: this.course, |
||||||
|
// schoolId: this.clientId, |
||||||
|
// userId: this.userId, |
||||||
|
schoolId: 2, |
||||||
|
userId: 2, |
||||||
|
} |
||||||
|
this.$post(this.api.getQuestionListBySelect,data) |
||||||
|
.then(res => { |
||||||
|
this.selectedData = res.data.count.splice(0,totalCount) |
||||||
|
this.inteVisible = false |
||||||
|
}) |
||||||
|
.catch(err => {}); |
||||||
|
}, |
||||||
|
closeInte(){ |
||||||
|
this.course = [], |
||||||
|
this.countNumber1 = 0 |
||||||
|
this.countNumber2 = 0 |
||||||
|
this.countNumber3 = 0 |
||||||
|
this.countNumber4 = 0 |
||||||
|
this.countNumber5 = 0 |
||||||
|
this.countNumberInput1 = '' |
||||||
|
this.countNumberInput2 = '' |
||||||
|
this.countNumberInput3 = '' |
||||||
|
this.countNumberInput4 = '' |
||||||
|
this.countNumberInput5 = '' |
||||||
|
this.countCheck = { |
||||||
|
countCheck1: false, |
||||||
|
countCheck2: false, |
||||||
|
countCheck3: false, |
||||||
|
countCheck4: false, |
||||||
|
countCheck5: false, |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.box{ |
||||||
|
width: 90%; |
||||||
|
margin: 0 auto; |
||||||
|
.form{ |
||||||
|
.line{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 20px; |
||||||
|
.item{ |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
flex: 1; |
||||||
|
/deep/.el-select{ |
||||||
|
flex: 1; |
||||||
|
} |
||||||
|
.key{ |
||||||
|
margin-right: 20px; |
||||||
|
white-space: nowrap; |
||||||
|
font-size: 14px; |
||||||
|
color: #555; |
||||||
|
} |
||||||
|
&.lg .key{ |
||||||
|
width: 220px; |
||||||
|
margin-right: 10px; |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.testpaper{ |
||||||
|
padding: 10px; |
||||||
|
background-color: #f7f7f7; |
||||||
|
.point{ |
||||||
|
display: flex; |
||||||
|
margin-top: 20px; |
||||||
|
.key{ |
||||||
|
margin: 8px 20px 0 10px; |
||||||
|
font-size: 13px; |
||||||
|
color: #444; |
||||||
|
} |
||||||
|
.line{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 13px; |
||||||
|
.item{ |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
margin-right: 30px; |
||||||
|
color: #444; |
||||||
|
font-size: 12px; |
||||||
|
input{ |
||||||
|
width: 80px; |
||||||
|
height: 30px; |
||||||
|
padding: 0 10px; |
||||||
|
margin: 0 10px; |
||||||
|
line-height: 30px; |
||||||
|
border: 1px solid #e8e8e8; |
||||||
|
background-color: #fff; |
||||||
|
box-sizing: border-box; |
||||||
|
&:focus{ |
||||||
|
outline: none; |
||||||
|
} |
||||||
|
&:disabled{ |
||||||
|
background-color: #e8e8e8; |
||||||
|
cursor: not-allowed; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.mini-form{ |
||||||
|
/deep/.el-form-item__content{ |
||||||
|
width: 150px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.select-wrap{ |
||||||
|
width: 90%; |
||||||
|
margin: 0 auto; |
||||||
|
.block{ |
||||||
|
display: flex; |
||||||
|
.key{ |
||||||
|
margin-right: 20px; |
||||||
|
font-size: 14px; |
||||||
|
color: #555; |
||||||
|
} |
||||||
|
.types{ |
||||||
|
.item{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 10px; |
||||||
|
color: #444; |
||||||
|
font-size: 12px; |
||||||
|
/deep/.el-checkbox__label{ |
||||||
|
color: #444; |
||||||
|
font-size: 12px; |
||||||
|
} |
||||||
|
input{ |
||||||
|
width: 80px; |
||||||
|
height: 24px; |
||||||
|
padding: 0 10px; |
||||||
|
margin: 0 10px; |
||||||
|
line-height: 24px; |
||||||
|
color: #333; |
||||||
|
font-size: 12px; |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #eaeaea; |
||||||
|
&:focus{ |
||||||
|
outline: none; |
||||||
|
} |
||||||
|
&:disabled{ |
||||||
|
background-color: #e8e8e8; |
||||||
|
cursor: not-allowed; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,193 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="mgb20"> |
||||||
|
<div> |
||||||
|
<div class="flex-center mgb20"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>筛选</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<div class="no-mb"> |
||||||
|
<el-form label-width="80px" inline> |
||||||
|
<el-form-item label="所属课程" class="userRadio"> |
||||||
|
<el-select v-model="cid" clearable placeholder="请选择所属题库"> |
||||||
|
<el-option v-for="(item,index) in quesBankList" :key="index" :label="item.typeName" :value="item.cid"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="试卷状态" class="userRadio"> |
||||||
|
<el-radio-group v-model="statusId" @change="getData"> |
||||||
|
<el-radio label="" border>全部</el-radio> |
||||||
|
<el-radio v-for="(item,index) in statusList" :key="index" :label="item.id" border>{{item.name}}</el-radio> |
||||||
|
</el-radio-group> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-form label-width="80px" inline> |
||||||
|
<el-form-item label="试卷用途" class="userRadio no-mb"> |
||||||
|
<el-radio-group v-model="purposeId" @change="getData"> |
||||||
|
<el-radio label="" border>全部</el-radio> |
||||||
|
<el-radio v-for="(item,index) in effectList" :key="index" :label="item.id" border>用于{{item.label}}</el-radio> |
||||||
|
</el-radio-group> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="创建时间" class="userRadio no-mb"> |
||||||
|
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" |
||||||
|
start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable></el-date-picker> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div> |
||||||
|
<el-input placeholder="请输入试卷名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover"> |
||||||
|
<div class="flex-between mgb20"> |
||||||
|
<div class="flex-center"> |
||||||
|
<p class="hr_tag"></p> |
||||||
|
<span>所有试卷</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table :data="listData" class="table" stripe header-align="center" row-key="id" @selection-change="handleSelecteChange"> |
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="试卷名称" align="center"></el-table-column> |
||||||
|
<el-table-column prop="courses" label="所属课程" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="试卷用途" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{getEffectName(scope.row.effect)}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="难易程度" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{getDegreeName(scope.row.degree)}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="组卷方式" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{getTypeName(scope.row.type)}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="duration" label="时长(分钟)" align="center"></el-table-column> |
||||||
|
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column> |
||||||
|
<el-table-column prop="releaseTime" label="发布时间" align="center"></el-table-column> |
||||||
|
<el-table-column prop="name" label="试卷状态" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{getStatusName(scope.row.state)}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" width="120"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" v-if="scope.row.state == 0 && userId == scope.row.userId" @click="publish(scope.row)" v-auth>发布</el-button> |
||||||
|
<el-button type="text" @click="preview(scope.row)" v-auth>预览</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> |
||||||
|
</el-card> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { mapState,mapGetters } from 'vuex' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
listData: [], |
||||||
|
multipleSelection: [], |
||||||
|
date: [], |
||||||
|
startTime: '', |
||||||
|
endTime: '', |
||||||
|
cid: '', |
||||||
|
quesBankList: [], |
||||||
|
statusId: '', |
||||||
|
purposeId: '', |
||||||
|
keyword: '', |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
searchTimer: null, |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
...mapState('user', [ |
||||||
|
'userId','clientId' |
||||||
|
]), |
||||||
|
...mapState('testpaper', [ |
||||||
|
'statusList','effectList' |
||||||
|
]), |
||||||
|
...mapGetters('testpaper', [ |
||||||
|
'getStatusName','getEffectName','getDegreeName','getTypeName' |
||||||
|
]) |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
this.getQuesBank() |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
}, |
||||||
|
date: function(val){ |
||||||
|
if(val){ |
||||||
|
this.startTime = val[0] |
||||||
|
this.endTime = val[1] |
||||||
|
}else{ |
||||||
|
this.startTime = '' |
||||||
|
this.endTime = '' |
||||||
|
} |
||||||
|
this.getData() |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
this.$post(this.api.pageBySchoolTestPaper, { |
||||||
|
pageNum: this.page, |
||||||
|
pageSize: this.pageSize, |
||||||
|
userId: this.userId, |
||||||
|
schoolId: this.clientId, |
||||||
|
questionStem: this.keyword, |
||||||
|
}) |
||||||
|
.then(res => { |
||||||
|
this.listData = res.data.list.list |
||||||
|
this.total = res.data.list.totalCount |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
}) |
||||||
|
.catch(err => {}) |
||||||
|
}, |
||||||
|
handleSelecteChange(val){ |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
getQuesBank() { |
||||||
|
this.$get(this.api.getTypeByOneLever) |
||||||
|
.then(res => { |
||||||
|
this.quesBankList = res.data.list |
||||||
|
}) |
||||||
|
.catch(err => {}) |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.page = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
preview(row){ |
||||||
|
this.$router.push(`show?id=${row.id}`) |
||||||
|
}, |
||||||
|
review(row){ |
||||||
|
this.$router.push('review') |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
/deep/.no-mb.el-form-item{ |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
</style> |