Commit b32564ca8a1d0ef59530817c619131f5ed8d1d74

Authored by 周超
1 parent e4f60134

11

src/api/log.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +
  4 +
  5 +//用户列表
  6 +export function GetList(params) {
  7 + return request({
  8 + url: `/SystemLogs/List`,
  9 + method: 'get',
  10 + params
  11 + })
  12 +}
  13 +
  14 +
  15 +
  16 +export function ChangeClass(id,type) {
  17 + return request({
  18 + url: `/Users/ChangeClass?id=${id}&type=${type}`,
  19 + method: 'post',
  20 + })
  21 +}
0 22 \ No newline at end of file
... ...
src/api/role.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function GetInfo(id) {
  4 + return request({
  5 + url: `/role/Get?id=${id}`,
  6 + method: 'get',
  7 + })
  8 +}
  9 +
  10 +
  11 +export function GetUserList(param) {
  12 + return request({
  13 + url: `/role/List`,
  14 + method: 'get',
  15 + param
  16 + })
  17 +}
  18 +export function UsersCreate(data) {
  19 + return request({
  20 + url: `/role/Create`,
  21 + method: 'post',
  22 + data
  23 + })
  24 +}
  25 +
  26 +export function UsersUpdate(data) {
  27 + return request({
  28 + url: `/role/Update`,
  29 + method: 'post',
  30 + data
  31 + })
  32 +}
  33 +
  34 +export function UsersDelete(data) {
  35 + return request({
  36 + url: `/role/Delete`,
  37 + method: 'post',
  38 + params: data
  39 + })
  40 +}
  41 +
  42 +
  43 +//权限菜单列表
  44 +export async function GetMenueRole() {
  45 + return request({
  46 + url: `/role/GetMenueRole`,
  47 + method: 'get'
  48 + })
  49 +}
  50 +
  51 + //权限菜单列表
  52 +export function GetMenue() {
  53 + return request({
  54 + url: `/role/GetMenue`,
  55 + method: 'get'
  56 + })
  57 +}
  58 +
  59 +
0 60 \ No newline at end of file
... ...
src/api/setting.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function GetInfo(id) {
  4 + return request({
  5 + url: `/Setting/Get?id=${id}`,
  6 + method: 'get',
  7 + })
  8 +}
  9 +
  10 +export function Create(data) {
  11 + return request({
  12 + url: `/Setting/Create`,
  13 + method: 'post',
  14 + data
  15 + })
  16 +}
  17 +
  18 +export function Update(data) {
  19 + return request({
  20 + url: `/Setting/Update`,
  21 + method: 'post',
  22 + data
  23 + })
  24 +}
  25 +
  26 +export function Delete(data) {
  27 + return request({
  28 + url: `/Setting/Delete`,
  29 + method: 'post',
  30 + params: data
  31 + })
  32 +}
  33 +
  34 +
0 35 \ No newline at end of file
... ...
src/api/user.js
... ... @@ -87,6 +87,15 @@ export function GetUserListByAdmin(data) {
87 87 data
88 88 })
89 89 }
  90 +
  91 +
  92 +export function GetUserListByAdminSimple(data) {
  93 + return request({
  94 + url: `/Users/GetUserListByAdminSimple`,
  95 + method: 'post',
  96 + data
  97 + })
  98 +}
90 99 //修改管理员密码
91 100 export function UpdateCurrentPasswordById(data) {
92 101 return request({
... ...
src/permission.js
... ... @@ -19,7 +19,6 @@ router.beforeEach(async(to, from, next) => {
19 19  
20 20 // determine whether the user has logged in
21 21 const hasToken = getToken()
22   -
23 22 if (hasToken) {
24 23 if (to.path === '/login') {
25 24 // if is logged in, redirect to the home page
... ...
src/router/index.js
... ... @@ -30,9 +30,9 @@ import { getRoutes } from "@/utils/routerList.js"
30 30 * constantRoutes
31 31 * a base page that does not have permission requirements
32 32 * all roles can be accessed
33   - */
34   -export const constantRoutes = getRoutes();
35   -
  33 + */
  34 +export const constantRoutes = getRoutes();
  35 +
36 36 const createRouter = () => new Router({
37 37 // mode: 'history', // require service support
38 38 scrollBehavior: () => ({
... ...
src/utils/request.js
... ... @@ -19,13 +19,16 @@ const service = axios.create({
19 19 service.interceptors.request.use(
20 20 config => {
21 21 // do something before request is sent
22   -
23   - if (store.getters.token) {
  22 +
  23 + if (store && store.getters && store.getters.token) {
24 24 // let each request carry token
25 25 // ['X-Token'] is a custom headers key
26 26 // please modify it according to the actual situation
27 27 config.headers['Authorization'] = getToken()
28 28 }
  29 + else if(localStorage.token){
  30 + config.headers['Authorization'] = localStorage.token
  31 + }
29 32 return config
30 33 },
31 34 error => {
... ...
src/utils/routerList.js
1 1 import Layout from '@/layout'
2 2 import { getInfo } from '../store/modules/user.js'
  3 +import {GetMenueRole} from '@/api/role'
3 4  
4   -
5   -export function getRoutes(permissions) {
  5 +export function getRoutes(permissions) {
6 6 let userInfo = {}
7 7 if (localStorage.userinfo) {
8 8 userInfo = JSON.parse(localStorage.userinfo)
9 9 }
10 10 var permissions = userInfo.permissions || [];
11   -
12   -
13   -
14   -
15   - console.log(userInfo)
  11 +
  12 +// var roles = await GetMenueRole();
  13 +// roles = roles.data.map(o=>o.code);
  14 +
16 15 let constantRoutes1 = []
17 16 if (userInfo.UserId == 1 || 1 == 1) {
18 17 constantRoutes1 = [{
... ... @@ -39,6 +38,7 @@ export function getRoutes(permissions) {
39 38  
40 39  
41 40 {
  41 + code:'home',
42 42 path: '/',
43 43 component: Layout,
44 44 redirect: '/dashboard',
... ... @@ -65,6 +65,7 @@ export function getRoutes(permissions) {
65 65 },
66 66  
67 67 {
  68 + code:'example',
68 69 path: '/example',
69 70 component: Layout,
70 71 redirect: '/example/table',
... ... @@ -75,6 +76,7 @@ export function getRoutes(permissions) {
75 76 permissions: ['admin']
76 77 },
77 78 children: [{
  79 + code:'题库',
78 80 path: 'QuestionBank',
79 81 name: 'Table',
80 82 component: () =>
... ... @@ -129,6 +131,7 @@ export function getRoutes(permissions) {
129 131 // },
130 132  
131 133 {
  134 + code:'试卷管理',
132 135 path: '/views',
133 136 component: Layout,
134 137 redirect: '/views/TestPaper',
... ... @@ -138,6 +141,7 @@ export function getRoutes(permissions) {
138 141 icon: 'el-icon-s-help'
139 142 },
140 143 children: [{
  144 + code:'试卷列表',
141 145 path: 'TestPaperList',
142 146 name: 'Table',
143 147 component: () =>
... ... @@ -159,6 +163,7 @@ export function getRoutes(permissions) {
159 163 }
160 164 },
161 165 {
  166 + code:'组卷',
162 167 path: 'ManualTestPaper',
163 168 name: 'Table',
164 169 component: () =>
... ... @@ -199,6 +204,7 @@ export function getRoutes(permissions) {
199 204 // }]
200 205 // },
201 206 {
  207 + code:'用户管理',
202 208 path: '/user',
203 209 component: Layout,
204 210 redirect: '/',
... ... @@ -208,6 +214,7 @@ export function getRoutes(permissions) {
208 214 icon: 'el-icon-s-help'
209 215 },
210 216 children: [{
  217 + code:'人才库',
211 218 path: 'user',
212 219 name: 'User',
213 220 component: () =>
... ... @@ -217,6 +224,7 @@ export function getRoutes(permissions) {
217 224 }
218 225 },
219 226 {
  227 + code:'面试时间表',
220 228 path: 'interviewSchedule',
221 229 name: 'interviewSchedule',
222 230 component: () =>
... ... @@ -227,6 +235,7 @@ export function getRoutes(permissions) {
227 235 },
228 236  
229 237 {
  238 + code:'importuser',
230 239 path: 'importuser',
231 240 name: 'importuser',
232 241  
... ... @@ -237,6 +246,7 @@ export function getRoutes(permissions) {
237 246 }
238 247 },
239 248 {
  249 + code: 'admin',
240 250 path: 'admin',
241 251 name: 'admin',
242 252 component: () =>
... ... @@ -249,7 +259,8 @@ export function getRoutes(permissions) {
249 259  
250 260 ]
251 261 }, {
252   - path: '/password',
  262 + code:'系统管理',
  263 + path: '/system',
253 264 component: Layout,
254 265 redirect: '/',
255 266 name: 'password',
... ... @@ -259,6 +270,7 @@ export function getRoutes(permissions) {
259 270 },
260 271 children: [
261 272 {
  273 + code: 'userdimset',
262 274 path: 'userdimset',
263 275 name: 'impouserdimsetrtuser',
264 276  
... ... @@ -277,7 +289,19 @@ export function getRoutes(permissions) {
277 289 meta: {
278 290 title: '忘记密码',
279 291 }
280   - }, {
  292 + },
  293 + {
  294 + code:'settings',
  295 + path: 'settings',
  296 + name: 'settings',
  297 + component: () =>
  298 + import('@/views/settings/index'),
  299 + meta: {
  300 + title: '系统设置',
  301 + }
  302 + },
  303 + {
  304 + code:'TestPaperClass',
281 305 path: 'TestPaperClass',
282 306 name: 'Table',
283 307 component: () =>
... ... @@ -287,6 +311,7 @@ export function getRoutes(permissions) {
287 311 permissions:['admin' ]
288 312 }
289 313 }, {
  314 + code: 'carousel',
290 315 path: 'carousel',
291 316 name: 'carousel',
292 317 component: () =>
... ... @@ -296,6 +321,7 @@ export function getRoutes(permissions) {
296 321 permissions:['admin' ]
297 322 }
298 323 }, {
  324 + code: 'new',
299 325 path: 'new',
300 326 name: 'new',
301 327 component: () =>
... ... @@ -304,7 +330,32 @@ export function getRoutes(permissions) {
304 330 title: '最新资讯',
305 331 permissions:['admin']
306 332 }
307   - }]
  333 + }
  334 + , {
  335 + code: 'rolelist',
  336 + path: 'role',
  337 + name: 'rolelist',
  338 + component: () =>
  339 + import('@/views/user/rolelist'),
  340 + meta: {
  341 + title: '角色权限',
  342 + permissions:['admin']
  343 + }
  344 + },
  345 + {
  346 + code:'logs',
  347 + path: 'logs',
  348 + name: 'logs',
  349 +
  350 + component: () =>
  351 + import('@/views/user/loglist'),
  352 + meta: {
  353 + title: '系统日志',
  354 + }
  355 + },
  356 +
  357 +
  358 + ]
308 359 },
309 360 // 404 page must be placed at the end !!!
310 361 {
... ... @@ -562,7 +613,8 @@ export function getRoutes(permissions) {
562 613 const finallyRoutes = [];
563 614 routes.forEach((route) => {
564 615 const item = { ...route };
565   - if (hasPermission(permissions, item)) {
  616 + // if (hasPermission(permissions, item)) {
  617 + if (permissions.includes(item.code) || !item.code) {
566 618 if (item.children) {
567 619 item.children = filterAsyncRoutes(item.children, permissions);
568 620 }
... ... @@ -572,6 +624,6 @@ export function getRoutes(permissions) {
572 624 return finallyRoutes;
573 625 }
574 626 constantRoutes1 = filterAsyncRoutes(constantRoutes1, permissions);
575   -
  627 +
576 628 return constantRoutes1;
577 629 }
578 630 \ No newline at end of file
... ...
src/views/QuestionBank/components/EditDimension.vue
1 1 <template>
2 2 <el-dialog title="编辑" :visible.sync="dialogFormVisible" @closed="handleclose" width="75%">
3 3 <el-form :model="data">
  4 + <el-form-item label="上级分类" style="padding-top: 5px">
  5 +
  6 +
  7 + <el-cascader filterable v-model="data.ParentId" style="width: 400px"
  8 + :props="{ emitPath: false ,checkStrictly:true}" :clearable="true" :options="QuestionClass">
  9 +
  10 + <template slot-scope="{ node, data }">
  11 + <span>{{ data.label }}</span>
  12 + <span v-if="!node.isLeaf"> ({{ data.subjectCount || 0 }}) </span>
  13 + </template>
  14 +
  15 +
  16 + </el-cascader>
  17 + </el-form-item>
4 18 <el-form-item label="名称">
5 19 <el-input v-model="data.ClassificationName"></el-input>
6 20  
... ... @@ -100,7 +114,9 @@
100 114 getQuestionClass,
101 115  
102 116 } from "@/api/QuestionClass";
103   -
  117 + import {
  118 + getQuestionClassList
  119 + } from "@/api/QuestionBank";
104 120  
105 121 export default {
106 122 components: {
... ... @@ -124,7 +140,7 @@
124 140 dialogFormVisible: false,
125 141 form: {},
126 142 level:0,
127   -
  143 + QuestionClass: [],
128 144 ruleOptions: [
129 145 { label: '大于', value: '>' },
130 146 { label: '小于', value: '<' },
... ... @@ -158,8 +174,64 @@
158 174 },
159 175 created() {
160 176 // this.show();
  177 +
  178 + },
  179 + mounted(){
  180 +
161 181 },
162   - methods: {
  182 + methods: {
  183 + getSubTree(id, list) {
  184 + let result = [];
  185 + result = list.filter((t) => t.ParentId == id);
  186 + if (result.length) {
  187 + result = result.map((item) => {
  188 + item.children = this.getSubTree(item.id, list);
  189 + return item;
  190 + });
  191 + }
  192 + return result;
  193 + },
  194 + getQuestionClassListHeadler(node) {
  195 + var classtype = node.data.ClassType || 0;
  196 + let _this = this;
  197 + getQuestionClassList().then((res) => {
  198 + let list = [{id:0,ClassificationName:'顶级',ClassType : classtype}];
  199 + res.data.data.forEach(o=>{list.push(o);});
  200 + var rootlist = list.filter(o=> o.ClassType == classtype && (!o.ParentId || o.ParentId == 0 )).map((t) => {
  201 + t.value = t.id;
  202 + t.label = t.ClassificationName;
  203 + return t;
  204 + });
  205 + // let firstClass = list.find((t) => t.id == 6);
  206 + // firstClass.children = this.getSubTree(6, list);
  207 + // let secondClass = list.find((t) => t.id == 1);
  208 + // secondClass.children = this.getSubTree(1, list);
  209 + this.QuestionClass = rootlist;
  210 + var firstlist = rootlist.filter(o => o.ClassType == 0 && o.ParentId == 0).map(o => {
  211 + o.children = this.getSubTree(o.id, list);
  212 + return o;
  213 + });
  214 +
  215 + var twolist = rootlist.filter(o => o.ClassType == 2 && o.ParentId == 0).map(o => {
  216 + o.children = this.getSubTree(o.id, list);
  217 + return o;
  218 +
  219 + });
  220 + // _this.$nextTick(()=>{
  221 + // if(_this.currentEditNode){
  222 + // _this.$refs.tree.getNode(_this.currentEditNode.parent).loaded = false
  223 + // _this.$refs.tree.getNode(_this.currentEditNode.parent).expand();
  224 + // _this.$refs.tree.getNode(_this.currentEditNode.parent).expanded=true;
  225 + // _this.$forceUpdate()
  226 +
  227 + // }
  228 +
  229 + // });
  230 +
  231 + // this.firstTreeData = [firstClass];
  232 + // this.secondTreeData = [secondClass];
  233 + });
  234 + },
163 235 handleclose(){
164 236 this.dialogFormVisible = false;
165 237 this.$emit('close',this.data);
... ... @@ -245,6 +317,8 @@
245 317 } catch (e) { }
246 318 },
247 319 show(id,node) {
  320 + this.getQuestionClassListHeadler(node);
  321 +
248 322 if(node) this.level = node.level;
249 323 this.data = {
250 324 // id: Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999),
... ... @@ -270,7 +344,7 @@
270 344  
271 345 if (res) {
272 346 var data = res.data.data;
273   - if (!data.rules) {
  347 + if (!data.rules || data.rules.length <1) {
274 348 data.rules = [
275 349 {
276 350 QuestionClassId: 0,
... ...
src/views/QuestionBank/index.vue
... ... @@ -18,10 +18,11 @@
18 18 添加顶级
19 19 </el-button>
20 20 <el-tree :data="activeTab == 'first' ? firstTreeData : secondTreeData"
21   - :default-expanded-keys="currentExpend" :props="activeTab == 'first' ? firstTreeData : secondTreeData"
22   - @node-click="handleNodeClick" class="eltree" :expand-on-click-node="false" ref="tree">
  21 + :props="activeTab == 'first' ? firstTreeData : secondTreeData" @node-click="handleNodeClick"
  22 + class="eltree" :expand-on-click-node="false" node-key="value" :default-expanded-keys="defaultexpand"
  23 + @node-expand="handleNodeExpand" ref="tree">
23 24 <span class="custom-tree-node" slot-scope="{ node, data }">
24   - <span>{{ node.label }} ({{data.subjectCount || 0}})</span>
  25 + <span>[{{data.id}}] {{ node.label }} ({{data.subjectCount || 0}})</span>
25 26 <span style="">
26 27 <!-- v-if="activeTab == 'first'?true:node.level<2?true:false" -->
27 28 <el-button type="text" size="mini" @click="showClassDialog(node)" v-if="node.level <3">
... ... @@ -50,8 +51,9 @@
50 51 </el-button>
51 52 <el-button type="danger" @click="handleChangeCat">批量修改分类
52 53 </el-button>
53   - <el-button type="danger" @click="handleChangeType">批量修改题型
54   - </el-button>
  54 + <el-button type="danger" @click="dialogFormVisible = true">导入题目</el-button>
  55 + <!-- <el-button type="danger" @click="handleChangeType">批量修改题型
  56 + </el-button> -->
55 57 </div>
56 58 <div class="areadiv" :style="{ height: TableColHeight + 'px' }">
57 59 <el-table :data="QuestList" id="QuestionTable" border style="
... ... @@ -150,8 +152,12 @@
150 152 :close-on-click-modal="false">
151 153 <el-form ref="QuestionClassInfo" :model="QuestionClassInfo" label-width="70px">
152 154 <el-form-item label="分类名称">
  155 +
153 156 <el-input v-model="QuestionClassInfo.ClassificationName" placeholder="请输入分类名称"></el-input>
154 157 </el-form-item>
  158 +
  159 +
  160 +
155 161 </el-form>
156 162 <!-- {{QuestionClassInfo}} -->
157 163 <el-button @click="CreateQuestionClassHealder" style="margin: 10px 0 0 0; float: right" type="primary">确定
... ... @@ -169,7 +175,7 @@
169 175 <el-input v-model="Dataform.subject" placeholder="请输入题目名称"></el-input>
170 176 </el-form-item>
171 177 <el-form-item label="分类" style="padding-top: 5px" prop="QuestionClassId">
172   -
  178 +
173 179 <el-cascader @change="changequestionclass" filterable v-model="Dataform.QuestionClassId" style="width: 400px"
174 180 :props="{ emitPath: false ,checkStrictly:true}" :clearable="true" :options="QuestionClass">
175 181  
... ... @@ -281,6 +287,59 @@
281 287 </el-button>
282 288 <div style="clear: both"></div>
283 289 </el-dialog>
  290 +
  291 +
  292 +
  293 +
  294 +
  295 + <el-dialog title="导入" :visible.sync="dialogFormVisible">
  296 +
  297 +
  298 +
  299 +
  300 + <el-upload class="upload-demo" style="width:80%" :headers="{Authorization:token}" drag
  301 + :on-success="handleSuccess"
  302 + action="/api/QuestionBank/import" :limit="1">
  303 + <i class="el-icon-upload"></i>
  304 + <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  305 + <div class="el-upload__tip" slot="tip">只能上传excel文件,条数尽量不要太多控制在1000内
  306 + <br>
  307 + <br>
  308 + <br>
  309 + <span style="color:red;line-height:20px;font-size:16px">
  310 + 注意:
  311 + <br>
  312 + 1.导入每个选项格式 分为三段 用” @@ “ 隔开 选项内容@@选项分值@@选项权重(权重 分为三个 高 中 低) <br /> 例如:
  313 + <p>选项A 今天感觉怎么样@@10@@高</p>
  314 + <p>选项B 内容@@10@@高</p>
  315 + <p>选项C 内容@@5@@中</p>
  316 + <p>选项D 内容@@8@@低</p>
  317 +
  318 + </span>
  319 +
  320 + <br>
  321 + <span style="color:red;line-height:20px;font-size:16px">
  322 + 2.分类编号 从后台题库管理左侧分类的名称前获取 [1] 只需填写中间的数字即可
  323 + </span>
  324 +
  325 + <br>
  326 +
  327 + <span style="color:red;line-height:20px;font-size:16px">
  328 + 3.多选题 多选题选项 多个用 英文,隔开 如: A,B,C
  329 + </span>
  330 +
  331 + <br>
  332 + <el-link :href="BASE_URL + '/temp/题目导入模板.xlsx'" target="_blank" type="primary">点击下载导入模板</el-link>
  333 +
  334 + </div>
  335 + </el-upload>
  336 +
  337 +
  338 +
  339 +
  340 + </el-dialog>
  341 +
  342 +
284 343 <EditDimension ref="editDimensionDialog" :model="currentEditDimension" @close="closeEditDim" @save="saveEditDim">
285 344 </EditDimension>
286 345 </div>
... ... @@ -297,6 +356,12 @@
297 356 } from "@/api/QuestionBank";
298 357 import { parseTime } from "@/utils/index.js";
299 358 import EditDimension from "./components/EditDimension.vue";
  359 +
  360 + import {
  361 + getToken
  362 + } from '@/utils/auth'
  363 +
  364 +
300 365 export default {
301 366 filters: {},
302 367 components: {
... ... @@ -304,9 +369,12 @@
304 369 },
305 370 data() {
306 371 return {
  372 + token: getToken(),
  373 + dialogFormVisible: false,
307 374 FormClassType: 0,
308 375 loading: false,
309 376 currentEditDimension: {},
  377 + defaultexpand: [],
310 378 activeTab: "first",
311 379 parameter: {
312 380 pageIndex: 1,
... ... @@ -394,7 +462,14 @@
394 462 methods: {
395 463 closeEditDim(data) {
396 464 },
397   -
  465 + handleSuccess(res) {
  466 + var msg = '';
  467 + if(res.data.data){
  468 + msg = `导入完成 共:${res.data.data.tableCount}个题目 成功 ${res.data.data.SuccessCount}个题目`;
  469 + }
  470 + this.$message.success(msg);
  471 + this.GetList();
  472 + },
398 473 saveEditDim(data) {
399 474 // if(this.currentEditNode && this.currentEditNode.parent)
400 475 // this.currentExpend=[this.currentEditNode.parent.data.id];
... ... @@ -448,8 +523,7 @@
448 523 },
449 524 handleChangeCat() {
450 525 var rows = this.$refs.table.selection;
451   - if (!rows || rows.length < 1)
452   - {
  526 + if (!rows || rows.length < 1) {
453 527 this.$message.warning('至少选择一项进行操作!');
454 528 return;
455 529 }
... ... @@ -524,14 +598,14 @@
524 598 type: "warning",
525 599 }).then(() => {
526 600 this.API.deleteQuestionClass(data.value).then((res) => {
527   - if(res.data.success){
528   - this.getQuestionClassListHeadler();
529   - this.$message.success('操作成功!');
  601 + if (res.data.success) {
  602 + this.getQuestionClassListHeadler();
  603 + this.$message.success('操作成功!');
530 604 }
531   - else{
  605 + else {
532 606 this.$message.error(res.data.message || '删除失败!');
533 607 }
534   -
  608 +
535 609 });
536 610 });
537 611  
... ... @@ -586,7 +660,9 @@
586 660 this.$forceUpdate();
587 661 this.dialogClassIVIsible = true;
588 662 console.log(node);
589   - if (parent && parent == 0) this.QuestionClassInfo.ParentId = 0;
  663 + if (parent == 0) {
  664 + this.QuestionClassInfo.ParentId = 0;
  665 + }
590 666 if (node)
591 667 this.QuestionClassInfo.ParentId = node.data.value;
592 668 if (type) this.QuestionClassInfo.ClassType = type;
... ... @@ -654,11 +730,15 @@
654 730 item.option = String.fromCharCode(64 + parseInt(index + 1));
655 731 });
656 732 },
  733 + handleNodeExpand(a, b, c) {
  734 + this.defaultexpand = [a.id];
  735 + },
657 736 handleNodeClick(val) {
658 737 if (this.loading) return;
659 738 this.parameter.QuestionClassId = val.value;
660 739 this.parameter.pageIndex = 1;
661 740 this.Dataform.QuestionClassId = val.value;
  741 + this.defaultexpand = [val.value];
662 742 this.GetList();
663 743 },
664 744 DelQuestionBankEventHeadler(id) {
... ... @@ -677,7 +757,7 @@
677 757 },
678 758 });
679 759 },
680   - EditQuestionHeadler() {
  760 + EditQuestionHeadler() {
681 761 this.$refs['Dataform'].validate((valid) => {
682 762 if (valid) {
683 763  
... ...
src/views/TestPaper/ManualTestPaper copy.vue 0 → 100644
  1 +<template>
  2 + <div class="app-container">
  3 + <div id="id_test_video" style="width:100%; height:auto;"></div>
  4 + <el-row :gutter="20">
  5 + <el-col :span="6" :style="{'height':contentHeight+'px'}" v-show="TestPaper.FLevelCount && TestPaper.FLevelCount >0">
  6 + <div class="grid-content bg-purple">
  7 + <el-tabs v-model="activeTab" style="padding: 0 20px" :stretch="true">
  8 + <el-tab-pane label="专业类" name="6"></el-tab-pane>
  9 + <el-tab-pane label="测评类" name="1"></el-tab-pane>
  10 + </el-tabs>
  11 + <div style="padding:0 10px">
  12 + <el-input size="small" placeholder="输入关键字搜索" v-model="parameter.keyWord"></el-input>
  13 + </div>
  14 + <div style="padding:10.5px">
  15 + <el-button type="primary" @click="randomSubject" style="width:100%">随机抽题</el-button>
  16 + </div>
  17 +
  18 + <draggable :options="{animation:380,filter:'.unmover'}" group="itxst" v-model="arr1" @end="end1"
  19 + @add="RemoveHere" :move="onMove" class="infinite-list" :style="{'height':contentHeight-80+'px'}"
  20 + infinite-scroll-disabled="disabled" v-infinite-scroll="load" style="overflow:auto">
  21 +
  22 + <li v-for="i in arr1" class="infinite-list-item" :key="i.id" v-if="!classarr.some(o=>o == i.id)">{{
  23 + i.subject }}</li>
  24 + <p v-if="loading" style="text-align: center;color: #cdcdcd;" class="unmover">加载中...</p>
  25 + <p v-if="noMore" style="text-align: center;color: #cdcdcd;" class="unmover">没有更多了</p>
  26 + </draggable>
  27 +
  28 + </div>
  29 + </el-col>
  30 + <el-col :span="10" :style="{'height':contentHeight+'px'}">
  31 + <div class="grid-content bg-purple">
  32 + <div class="areahead">
  33 + <!-- <span v-show="!edit" style="font-weight: bold;">{{ TestPaper.TestPaperTitle }}</span> -->
  34 + <!-- <el-input v-show="edit" style="width: 400px;" v-model="TestPaper.TestPaperTitle"></el-input>
  35 + <i :class="{'el-icon-edit': !edit, 'el-icon-check': edit}" @click="edit = !edit"
  36 + style="margin-left: 5px;cursor: pointer;"></i> -->
  37 + 题目内容
  38 + </div>
  39 +
  40 + <draggable :options="{animation:380}" group="itxst" v-model="arr2" class="infinite-list" @end="end2"
  41 + @add="ComeHere" :style="{'height':contentHeight-60+'px'}" style="overflow:auto;padding-top: 10px;">
  42 + <li v-for="(i,index) in arr2" class="infinite-list-item">
  43 + <label> {{index+1}}. [{{i.subjectName}}]{{ i.subject }}</label>
  44 + <div v-for="item in JSON.parse(i.subjectContent)">
  45 + <p class="option-p">{{item.option}}:{{item.optionContent}}</p>
  46 + </div>
  47 + </li>
  48 + </li>
  49 + </draggable>
  50 +
  51 +
  52 + </div>
  53 + </el-col>
  54 + <el-col :span="8" :style="{'height':contentHeight+'px'}">
  55 + <div class="grid-content bg-purple">
  56 + <div class="areahead">组卷基本信息</div>
  57 + <el-form ref="form" class="testPaper-manager" :rules="rules" :model="TestPaper" label-width="100px">
  58 + <el-form-item label="试卷名称:" prop="TestPaperTitle" required class="el-form-item-custom">
  59 + <el-input v-model="TestPaper.TestPaperTitle"></el-input>
  60 + </el-form-item>
  61 + <el-form-item label="题目数量:" class="el-form-item-custom">
  62 +
  63 + </el-form-item>
  64 + <el-form-item label="题型数量:" class="el-form-item-custom">
  65 + <span style="margin-right: 10px;">单选题:{{TestPaper.SingleNumber}}</span>
  66 + <span style="margin-right: 10px;">多选题:{{TestPaper.MultipleNumber}}</span>
  67 + <span style="margin-right: 10px;">主观题:{{TestPaper.SubjectiveNumber}}</span>
  68 + <span style="margin-right: 10px;">主观题:{{TestPaper.VoiceNumber}}</span>
  69 + </el-form-item>
  70 + <el-form-item label="题目总分:" class="el-form-item-custom">
  71 + {{TestPaper.TotalScore || ''}}
  72 + </el-form-item>
  73 +
  74 + <el-form-item label="工种" prop="UserTypeOfWork" required class="el-form-item-custom"
  75 + style="margin-bottom: 20px !important;width:100%;">
  76 + <el-select v-model="TestPaper.UserTypeOfWork" placeholder="请选择工种" style="width:100%">
  77 + <el-option v-for="item in usertypelist" :label="item.name" :value="item.id"></el-option>
  78 + </el-select>
  79 + </el-form-item>
  80 + <el-form-item label="分类" class="el-form-item-custom" prop="QuestionClassId" >
  81 + <el-cascader class="testpaper-input" v-model="TestPaper.QuestionClassId"
  82 + style="width:100%;margin-bottom: 20px;" :props="{emitPath:false}" :clearable=true
  83 + :options="QuestionClass">
  84 + </el-cascader>
  85 + </el-form-item>
  86 +
  87 + <el-form-item label="级别" prop="FLevelCount" class="el-form-item-custom"
  88 + style="margin-bottom: 20px !important;width:100%;">
  89 + <el-select v-model="TestPaper.FLevelCount" placeholder="请选择级别" @change="changelevel" style="width:100%">
  90 + <el-option v-for="item in levellist" :label="item.title" :value="item.f_count"></el-option>
  91 + </el-select>
  92 + </el-form-item>
  93 +
  94 + <el-form-item label="有效时间" required>
  95 + <el-form-item prop="date">
  96 + <el-date-picker v-model="TestPaper.date" @change="changetimestartend" type="datetimerange"
  97 + format="yyyy-MM-dd hh:mm:ss" range-separator="至" start-placeholder="开始时间" style="width:100%"
  98 + end-placeholder="结束时间">
  99 + </el-date-picker>
  100 + </el-form-item>
  101 + </el-form-item>
  102 + <el-form-item label="总时长控制" prop="AnswerTime">
  103 + <el-input class="testpaper-input" type="number" placeholder="总时长控制(分钟)" v-model="TestPaper.AnswerTime">
  104 + </el-input>
  105 + </el-form-item>
  106 +
  107 + <el-form-item label="试卷原价:" prop="OriginalPrice" v-show="false">
  108 + <el-input class="testpaper-input" oninput="value=value.replace(/[^0-9.]/g,'')"
  109 + v-model="TestPaper.OriginalPrice" :precision="0">
  110 + <template slot="append">元</template>
  111 + </el-input>
  112 + </el-form-item>
  113 + <el-form-item label="试卷价格:" prop="PresentPrice" v-show="false">
  114 + <el-input class="testpaper-input" oninput="value=value.replace(/[^0-9.]/g,'')"
  115 + v-model="TestPaper.PresentPrice">
  116 + <template slot="append">元</template>
  117 + </el-input>
  118 + </el-form-item>
  119 + <el-form-item label="会员价:" prop="MembershipPrice" v-show="false">
  120 + <el-input class="testpaper-input" oninput="value=value.replace(/[^0-9.]/g,'')"
  121 + v-model="TestPaper.MembershipPrice">
  122 + <template slot="append">元</template>
  123 + </el-input>
  124 + </el-form-item>
  125 + <el-form-item label="试卷简介:">
  126 + <el-input class="testpaper-input" :rows="10" type="textarea" v-model="TestPaper.Describe">
  127 + </el-input>
  128 + </el-form-item>
  129 + <el-button type="primary" style="float: right;" @click="SubmitTestPaper">保存
  130 + </el-button>
  131 + </el-form>
  132 + </div>
  133 + </el-col>
  134 + </el-row>
  135 +
  136 +
  137 +
  138 + <el-dialog title="随机抽题" :visible.sync="dialogTableVisible">
  139 +
  140 + <ul class="random-list">
  141 + <li v-for="(item,index) in randomSubjectList" :key="index">
  142 + <span>试题分类:</span>
  143 + <el-cascader :multiple="false" style="flex:1" @change="(a)=>{ changetype(a,item)}" v-model="item.QuestionClassId" :options="randomQuestionTypeList"
  144 + clearable>
  145 + <template slot-scope="{ node, data }">
  146 + <span>{{ data.label }}</span>
  147 + <span v-if="data.subjectCount"> ({{ data.subjectCount || '0' }}) </span>
  148 + </template>
  149 + </el-cascader>
  150 + <span style="margin-left:10px;">试题数量:{{item.maxcount}}</span>
  151 + <el-input-number v-model="item.Count" :min="1" :max="item.maxcount" label="描述文字" style="margin-left:10px;">
  152 + </el-input-number>
  153 + <i class="el-icon-remove-outline" @click="changeSubjectCount(-1,index)"
  154 + style="margin-left:10px;color:#f56c6c;"></i>
  155 + <i class="el-icon-circle-plus" @click="changeSubjectCount(1)" style="margin-left:10px;color:#67C23A;"></i>
  156 + </li>
  157 + </ul>
  158 + <div slot="footer">
  159 + <el-button @click="randomCancel">取消</el-button>
  160 + <el-button type="primary" @click="randomSubmit">确定</el-button>
  161 + </div>
  162 + </el-dialog>
  163 +
  164 + </div>
  165 +</template>
  166 +<style lang="scss" scoped>
  167 + .random-list {
  168 + display: flex;
  169 + flex-direction: column;
  170 +
  171 + li {
  172 + margin-bottom: 20px;
  173 + display: flex;
  174 + align-items: center;
  175 +
  176 + [class^="el-icon"] {
  177 + font-size: 24px;
  178 + cursor: pointer;
  179 + }
  180 + }
  181 + }
  182 +</style>
  183 +<script>
  184 + import draggable from "vuedraggable";
  185 + import { PostRandomGetQuestion, getQuestionList, getQuestionClassList } from "@/api/QuestionBank";
  186 + import { GetpaperLevelList } from "@/api/paperLevel";
  187 +
  188 +
  189 + import { GetQuestionClassByType } from "@/api/QuestionClass";
  190 + import { EditTestPaper, GetToplevel } from "@/api/TestPaper";
  191 + import { formatTime } from "@/utils/util";
  192 + import {
  193 + GetTypeSetting
  194 + } from '@/api/user'
  195 + export default {
  196 + //注册draggable组件
  197 + components: {
  198 + draggable,
  199 + },
  200 + data() {
  201 + return {
  202 + randomSubjectList: [
  203 + {
  204 + QuestionClassId: "",
  205 + Count: "",
  206 + },
  207 + {
  208 + QuestionClassId: "",
  209 + Count: "",
  210 + },
  211 + ],
  212 + randomQuestionTypeList: [],
  213 + dynamicValidateForm: {
  214 + domains: [
  215 + {
  216 + value: "",
  217 + },
  218 + ],
  219 + email: "",
  220 + },
  221 + usertypelist: [], //工种
  222 + dialogTableVisible: false,
  223 + loadingType: false,
  224 + activeTab: "6",
  225 + parameter: {
  226 + pageIndex: 0,
  227 + pageSize: 20,
  228 + sort: "id",
  229 + sortOrder: 1,
  230 + keyWord: "",
  231 + QuestionClassId: 6,
  232 + status: 1,
  233 + },
  234 + contentHeight: 0,
  235 + count: 0,
  236 + edit: false,
  237 + arr1: [],
  238 + arr2: [],
  239 + classarr: [],
  240 + moveId: -1,
  241 + TestPaper: {
  242 + TestPaperTitle: "未命名试卷标题",
  243 + TestPaperClassId: 0,
  244 + TotalScore: 0,
  245 + Describe: "",
  246 + SingleNumber: 0,
  247 + MultipleNumber: 0,
  248 + SubjectiveNumber: 0,
  249 + VoiceNumber:0,
  250 + OriginalPrice: "0",
  251 + PresentPrice: "0",
  252 + MembershipPrice: "0",
  253 + QuestionBankIds: [],
  254 + FLevelCount:0
  255 + },
  256 + loading: false,
  257 + rules: {
  258 + OriginalPrice: [
  259 + {
  260 + required: true,
  261 + message: "不能为空",
  262 + },
  263 + ],
  264 + PresentPrice: [
  265 + {
  266 + required: true,
  267 + message: "不能为空",
  268 + },
  269 + ],
  270 + UserTypeOfWork: [
  271 + {
  272 + required: true,
  273 + message: "请选择工种",
  274 + },
  275 + ], QuestionClassId: [
  276 + {
  277 + required: true,
  278 + message: "请选择分类",
  279 + },
  280 + ],date: [
  281 + {
  282 + required: true,
  283 + message: "请选择时间段",
  284 + },
  285 + ],
  286 + TestPaperTitle: [
  287 + {
  288 + required: true,
  289 + message: "请填写试卷名称",
  290 + }
  291 + ],
  292 +
  293 + AnswerTime: [
  294 + {
  295 + required: true,
  296 + message: "请填写试总时长控制",
  297 + },
  298 +
  299 + ],
  300 + },
  301 + QuestionClass: [],
  302 + treeData: [
  303 + {
  304 + value: 0,
  305 + label: "全部",
  306 + },
  307 + ],
  308 + timeout: 0,
  309 + typelist:[],
  310 + levellist:[] //等级
  311 + };
  312 + },
  313 + watch: {
  314 + activeTab() {
  315 + console.log("activeTab watch");
  316 + this.search();
  317 + },
  318 + "parameter.keyWord": {
  319 + handler() {
  320 + clearTimeout(this.timeout);
  321 + this.timeout = setTimeout(() => {
  322 + this.search();
  323 + }, 200);
  324 + },
  325 + },
  326 + },
  327 + computed: {
  328 + noMore() {
  329 + return this.arr1.length >= this.count;
  330 + },
  331 + disabled() {
  332 + return this.loading || this.noMore;
  333 + },
  334 + },
  335 + created() {
  336 + this.getQuestionClassListHeadler();
  337 + this.getQuestionClassListHeadler2();
  338 +
  339 +
  340 + GetTypeSetting({}).then(res => {
  341 + if (res.data) {
  342 + this.usertypelist = res.data || [];
  343 + }
  344 + });
  345 + GetpaperLevelList({pageSize:1000,sortOrder:'asc'}).then(res => {
  346 + if (res.data) {
  347 + this.levellist = res.data.data || [];
  348 + }
  349 + });
  350 + },
  351 + mounted() {
  352 + //计算页面内容区域的高度
  353 + this.contentHeight = window.innerHeight - 90;
  354 + //this.GetList();
  355 + },
  356 + methods: {
  357 + changetype(a,item){
  358 + var type = this.typelist.find(o=>o.id == item.QuestionClassId[item.QuestionClassId.length-1]);
  359 + if(type) {
  360 + item.maxcount = type.subjectCount || 0;
  361 + if(item.Count > item.maxcount) item.Count = item.maxcount;
  362 + }
  363 + },
  364 +
  365 + changelevel(v){
  366 + debugger;
  367 + var type = this.levellist.find(o=>o.f_count == v);
  368 + if(type) {
  369 + this.TestPaper.FLevelTitle = type.title || '';
  370 + }
  371 + },
  372 + getmaxid(item){
  373 + var type = this.randomQuestionTypeList.find(o=>o.id == item.QuestionClassId);
  374 + if(type) return type.subjectCount || 0;
  375 + else return 0;
  376 + },
  377 + getSubTree(id, list) {
  378 + let result = [];
  379 + result = list.filter((t) => t.ParentId == id);
  380 + if (result.length) {
  381 + result = result.map((item) => {
  382 + item.value = item.id;
  383 + item.label = item.ClassificationName;
  384 + item.children = this.getSubTree(item.id, list);
  385 + if (!item.children || !item.children.length) {
  386 + delete item.children;
  387 + }
  388 + return item;
  389 + });
  390 + }
  391 + return result;
  392 + },
  393 + getQuestionClassListHeadler2() {
  394 + let _this = this;
  395 + getQuestionClassList().then((res) => {
  396 + let alllist = res.data.data;
  397 + this.typelist = alllist;
  398 + let list = alllist.filter(t => !t.ParentId);
  399 + list = list.map((t) => {
  400 + t.value = t.id;
  401 + t.label = t.ClassificationName;
  402 + t.children = this.getSubTree(t.id, alllist);
  403 + if (!t.children || !t.children.length) {
  404 + delete t.children;
  405 + }
  406 + return t;
  407 + });
  408 + this.randomQuestionTypeList = list;
  409 + });
  410 + },
  411 + randomCancel() {
  412 + this.dialogTableVisible = false;
  413 + },
  414 + randomSubmit() {
  415 + var list = JSON.parse(JSON.stringify(this.randomSubjectList));
  416 + if (list.findIndex((t) => !t.QuestionClassId || !t.QuestionClassId.length || !t.Count) > -1) {
  417 + this.$message.warning("参数不完整");
  418 + return;
  419 + }
  420 +
  421 + list = list.map(t => {
  422 + t.QuestionClassId = t.QuestionClassId.pop();
  423 + return t;
  424 + });
  425 + PostRandomGetQuestion(list).then((res) => {
  426 + let list = res.data.data;
  427 + this.arr2 = list;
  428 + this.dialogTableVisible = false;
  429 + if (!list.length) {
  430 + this.$message.warning('所选分类没有试题');
  431 + }else{
  432 + this.TestPaper.SingleNumber = list.filter(t=>t.subjectType == 1).length;
  433 + this.TestPaper.MultipleNumber = list.filter(t=>t.subjectType == 2).length;
  434 + this.TestPaper.SubjectiveNumber = list.filter(t=>t.subjectType == 3).length;
  435 + this.TestPaper.VoiceNumber = list.filter(t=>t.subjectType == 4).length;
  436 + }
  437 + });
  438 + },
  439 + changeSubjectCount(type, index) {
  440 + if (type > 0) {
  441 + this.randomSubjectList.push({
  442 + QuestionClassId: "",
  443 + Count: "",
  444 + });
  445 + } else {
  446 + this.randomSubjectList.splice(index, 1);
  447 + }
  448 + },
  449 + randomSubject() {
  450 + this.dialogTableVisible = true;
  451 + },
  452 + submitForm(formName) {
  453 + this.$refs[formName].validate((valid) => {
  454 + if (valid) {
  455 + alert("submit!");
  456 + } else {
  457 + console.log("error submit!!");
  458 + return false;
  459 + }
  460 + });
  461 + },
  462 + resetForm(formName) {
  463 + this.$refs[formName].resetFields();
  464 + },
  465 + removeDomain(item) {
  466 + var index = this.dynamicValidateForm.domains.indexOf(item);
  467 + if (index !== -1) {
  468 + this.dynamicValidateForm.domains.splice(index, 1);
  469 + }
  470 + },
  471 + addDomain() {
  472 + this.dynamicValidateForm.domains.push({
  473 + value: "",
  474 + key: Date.now(),
  475 + });
  476 + },
  477 + changetimestartend(val, aa) {
  478 + this.TestPaper.EffectiveStartTime = formatTime(val[0]);
  479 + this.TestPaper.EffectiveEndTime = formatTime(val[1]);
  480 + },
  481 + search() {
  482 + this.parameter.pageIndex = 1;
  483 + this.parameter.QuestionClassId = Number(this.activeTab);
  484 + this.GetList();
  485 + },
  486 + SubmitTestPaper() {
  487 +
  488 + this.$refs['form'].validate((valid) => {
  489 +
  490 + if(!this.TestPaper.TestPaperTitle){
  491 + this.$notify({
  492 + title: '试卷标题必填!',
  493 + // message: res.data.message,
  494 + type: 'warning'
  495 + });
  496 + return;
  497 + }
  498 + if (valid) {
  499 + this.TestPaper.QuestionBankIds = this.arr2.map((u) => u.id);
  500 + var d = this.TestPaper;
  501 + if (this.arr2.length > 0) {
  502 + EditTestPaper(this.TestPaper).then((res) => {
  503 + if (res.data.code == 200) {
  504 + this.$notify({
  505 + title: '组卷成功!',
  506 + // message: res.data.message,
  507 + type: 'success'
  508 + });
  509 + this.$router.push({
  510 + path: '/views/TestPaperList',
  511 + query: {
  512 + }
  513 + })
  514 + } else {
  515 + this.$confirm("组卷失败!", "消息");
  516 + }
  517 + });
  518 + } else {
  519 + this.$confirm("试题没有题目!", "消息");
  520 + }
  521 + } else {
  522 +
  523 + return false;
  524 + }
  525 + });
  526 +
  527 +
  528 +
  529 + },
  530 + load() {
  531 + this.loading = true;
  532 + this.parameter.pageIndex++;
  533 + this.GetList();
  534 + this.loading = false;
  535 + },
  536 + GetList() {
  537 + if (this.parameter.QuestionClassId == "1") {
  538 + if (!this.loadingType)
  539 + GetQuestionClassByType({ ClassType: 2 }).then((res) => {
  540 + var classarr = res.data.data || [];
  541 + this.arr1 = classarr.map((rs) => {
  542 + rs.subject = rs.subjectName = rs.ClassificationName+'('+(rs.subjectCount || 0)+')';
  543 + rs.type = "wd";
  544 + rs.subjectContent = "[]";
  545 + return rs;
  546 + });
  547 + this.loadingType = true;
  548 + });
  549 + } else {
  550 + getQuestionList(this.parameter).then((res) => {
  551 + if (this.parameter.pageIndex == 1) {
  552 + this.arr1 = [];
  553 + }
  554 + res.data.data.rows.forEach((item, i) => {
  555 + this.arr1.push(item);
  556 + });
  557 + this.count = res.data.data.total;
  558 + this.$forceUpdate();
  559 + });
  560 + }
  561 + },
  562 + end1(e) {
  563 + var that = this;
  564 + if (that.arr1.length < 10) {
  565 + this.load();
  566 + }
  567 +
  568 + var items = this.arr2.filter(function (m) {
  569 + return m.id == that.moveId;
  570 + });
  571 +
  572 + //如果左边
  573 + if (items.length < 2) return;
  574 + this.arr2.splice(e.newDraggableIndex, 1);
  575 +
  576 + // SingleNumber:0,
  577 + // MultipleNumber:0,
  578 + // SubjectiveNumber:0,
  579 + },
  580 + //从右边移除到左边
  581 + RemoveHere(e) {
  582 + if (e.item._underlying_vm_.subjectType == 1) {
  583 + this.TestPaper.SingleNumber -= 1;
  584 + }
  585 + if (e.item._underlying_vm_.subjectType == 2) {
  586 + this.TestPaper.MultipleNumber -= 1;
  587 + }
  588 + if (e.item._underlying_vm_.subjectType == 3) {
  589 + this.TestPaper.SubjectiveNumber -= 1;
  590 + }
  591 + if (e.item._underlying_vm_.subjectType == 4) {
  592 + this.TestPaper.VoiceNumber -= 1;
  593 + }
  594 +
  595 + this.TestPaper.TotalScore -= e.item._underlying_vm_.fraction;
  596 + this.TestPaper.QuestionBankIds = this.arr2.map((u) => u.id);
  597 + },
  598 + //从左边添加到右边
  599 + ComeHere(e) {
  600 + var d = e.item._underlying_vm_;
  601 + if (e.item._underlying_vm_.subjectType == 1) {
  602 + this.TestPaper.SingleNumber += 1;
  603 + }
  604 + if (e.item._underlying_vm_.subjectType == 2) {
  605 + this.TestPaper.MultipleNumber += 1;
  606 + }
  607 + if (e.item._underlying_vm_.subjectType == 3) {
  608 + this.TestPaper.SubjectiveNumber += 1;
  609 + }
  610 + if (e.item._underlying_vm_.subjectType == 4) {
  611 + this.TestPaper.VoiceNumber += 1;
  612 + }
  613 + this.TestPaper.TotalScore += e.item._underlying_vm_.fraction;
  614 +
  615 + this.TestPaper.QuestionBankIds = this.arr2.map((u) => u.id);
  616 +
  617 + if (d.type == "wd") {
  618 + getQuestionList({
  619 + QuestionClassId: d.id,
  620 + PageIndex: 1,
  621 + PageSize: this.TestPaper.FLevelCount || 1000,
  622 + }).then((res) => {
  623 + var data = res.data.data.rows || [];
  624 + data = data.filter(o => !this.arr2.find(d => d.id == o.id));
  625 + this.arr2 = this.arr2.filter((o) => o.type != "wd");
  626 + // this.arr1.splice(this.arr1.findIndex(o=>o.id == d.id),1)
  627 + this.classarr.push(d.id);
  628 + // var test = this.arr2;
  629 + this.arr2.push(...data);
  630 + data.forEach((rs) => {
  631 + if (rs.subjectType == 1) {
  632 + this.TestPaper.SingleNumber += 1;
  633 + }
  634 + if (rs.subjectType == 2) {
  635 + this.TestPaper.MultipleNumber += 1;
  636 + }
  637 + if (rs.subjectType == 3) {
  638 + this.TestPaper.SubjectiveNumber += 1;
  639 + }
  640 + if (rs.subjectType == 4) {
  641 + this.TestPaper.VoiceNumber += 1;
  642 + }
  643 + });
  644 + });
  645 + }
  646 + },
  647 + //右边往左边拖动时的事件
  648 + end2(e) {
  649 + var that = this;
  650 + var items = this.arr1.filter(function (m) {
  651 + return m.id == that.moveId;
  652 + });
  653 + //如果左边
  654 + if (items.length < 2) return;
  655 + this.arr1.splice(e.newDraggableIndex, 1);
  656 + },
  657 + //move回调方法
  658 + onMove(e, originalEvent) {
  659 + //this.moveId = e.relatedContext.element.id;
  660 + return true;
  661 + },
  662 + getQuestionClassListHeadler() {
  663 + let _this = this;
  664 + GetToplevel().then((res) => {
  665 + var gettree = function (titem) {
  666 + titem.children = [];
  667 + let childrenList = res.data.data.filter(
  668 + (u) => u.ParentId == titem.value
  669 + );
  670 + if (childrenList.length == 0) titem.children = undefined;
  671 + res.data.data
  672 + .filter((u) => u.ParentId == titem.value)
  673 + .forEach((item, i) => {
  674 + var model = {
  675 + value: item.id,
  676 + label: item.ClassTitle,
  677 + };
  678 + gettree(model);
  679 + titem.children.push(model);
  680 + });
  681 + };
  682 + res.data.data
  683 + .filter((u) => u.ParentId == 0)
  684 + .forEach((item, i) => {
  685 + var model = {
  686 + value: item.id,
  687 + label: item.ClassTitle,
  688 + };
  689 + gettree(model);
  690 + _this.QuestionClass.push(model);
  691 + _this.treeData.push(model);
  692 + });
  693 + });
  694 + },
  695 + },
  696 + };
  697 +</script>
  698 +
  699 +<style lang="scss" scoped>
  700 + .el-row {
  701 +
  702 + /* margin-bottom: 20px; */
  703 + &:last-child {
  704 + margin-bottom: 0;
  705 + }
  706 + }
  707 +
  708 + .el-col {
  709 + border-radius: 4px;
  710 + }
  711 +
  712 + .bg-purple-dark {
  713 + background: #99a9bf;
  714 + }
  715 +
  716 + .bg-purple {
  717 + background: #efefef;
  718 + }
  719 +
  720 + .bg-purple-light {
  721 + background: #e5e9f2;
  722 + }
  723 +
  724 + .grid-content {
  725 + border-radius: 4px;
  726 + min-height: 36px;
  727 + height: 100%;
  728 + }
  729 +
  730 + .row-bg {
  731 + padding: 10px 0;
  732 + background-color: #f9fafc;
  733 + }
  734 +
  735 + .infinite-list {
  736 + list-style: none;
  737 + margin: 0px;
  738 + padding: 0px;
  739 +
  740 + &::-webkit-scrollbar {
  741 + width: 6px;
  742 + }
  743 +
  744 + //滚动条小方块
  745 + &::-webkit-scrollbar-thumb {
  746 + border-radius: 10px;
  747 + background: #304156;
  748 + }
  749 +
  750 + //滚动条轨道
  751 + &::-webkit-scrollbar-track {
  752 + // border-radius: 10px;
  753 + height: 100px;
  754 + background: #cdcdcd;
  755 + }
  756 +
  757 + .infinite-list-item {
  758 + padding: 10px;
  759 + min-height: 60px;
  760 + width: 95%;
  761 + margin: auto;
  762 + background-color: #fff;
  763 + margin-bottom: 10px;
  764 + border-radius: 5px;
  765 + box-shadow: 0 0 5px #cdcdcd;
  766 +
  767 + &:first-child {
  768 + margin-top: 10px;
  769 + }
  770 + }
  771 + }
  772 +
  773 + .option-p {
  774 + line-height: 15px;
  775 + }
  776 +
  777 + .areahead {
  778 + text-align: center;
  779 + height: 60px;
  780 + line-height: 60px;
  781 + border-bottom: 1px solid #cdcdcd;
  782 + }
  783 +
  784 + .testPaper-manager {
  785 + margin: 10px 20px 10px 10px;
  786 + }
  787 +
  788 + .testPaper-manager .el-form-item {
  789 + margin-bottom: 20px;
  790 + }
  791 +
  792 + .el-form-item-custom {
  793 + margin-bottom: 0px !important;
  794 + }
  795 +
  796 + .testpaper-input {
  797 + //max-width: 400px;
  798 + }
  799 +</style>
0 800 \ No newline at end of file
... ...
src/views/TestPaper/ManualTestPaper.vue
1 1 <template>
2 2 <div class="app-container">
3 3 <div id="id_test_video" style="width:100%; height:auto;"></div>
  4 + <div style="width: 100%;text-align: right;background: #efefef;height: 60px;vertical-align: middle;line-height: 60px;padding-right: 10px;">
  5 +
  6 + <el-button style="margin-top: 12px;" @click="next" v-if="active==1">下一步</el-button>
  7 + <el-button style="margin-top: 12px;z-index:888888888" @click="next" v-if="active==2">编辑基本信息</el-button>
  8 + <el-button type="primary" style="" v-if="active==2" @click="SubmitTestPaper">保存
  9 + </el-button>
  10 + </div>
4 11 <el-row :gutter="20">
5   - <el-col :span="6" :style="{'height':contentHeight+'px'}">
6   - <div class="grid-content bg-purple">
7   - <el-tabs v-model="activeTab" style="padding: 0 20px" :stretch="true">
8   - <el-tab-pane label="专业类" name="6"></el-tab-pane>
9   - <el-tab-pane label="测评类" name="1"></el-tab-pane>
10   - </el-tabs>
11   - <div style="padding:0 10px">
12   - <el-input size="small" placeholder="输入关键字搜索" v-model="parameter.keyWord"></el-input>
13   - </div>
14   - <div style="padding:10.5px">
15   - <el-button type="primary" @click="randomSubject" style="width:100%">随机抽题</el-button>
16   - </div>
17 12  
18   - <draggable :options="{animation:380,filter:'.unmover'}" group="itxst" v-model="arr1" @end="end1"
19   - @add="RemoveHere" :move="onMove" class="infinite-list" :style="{'height':contentHeight-80+'px'}"
20   - infinite-scroll-disabled="disabled" v-infinite-scroll="load" style="overflow:auto">
21 13  
22   - <li v-for="i in arr1" class="infinite-list-item" :key="i.id" v-if="!classarr.some(o=>o == i.id)">{{
23   - i.subject }}</li>
24   - <p v-if="loading" style="text-align: center;color: #cdcdcd;" class="unmover">加载中...</p>
25   - <p v-if="noMore" style="text-align: center;color: #cdcdcd;" class="unmover">没有更多了</p>
26   - </draggable>
  14 + <el-steps :active="active" finish-status="success" simple style="margin:0px 10px">
  15 + <el-step title="基本信息"></el-step>
  16 + <el-step title="组卷"></el-step>
  17 + </el-steps>
27 18  
28   - </div>
29   - </el-col>
30   - <el-col :span="10" :style="{'height':contentHeight+'px'}">
31   - <div class="grid-content bg-purple">
32   - <div class="areahead">
33   - <!-- <span v-show="!edit" style="font-weight: bold;">{{ TestPaper.TestPaperTitle }}</span> -->
34   - <!-- <el-input v-show="edit" style="width: 400px;" v-model="TestPaper.TestPaperTitle"></el-input>
35   - <i :class="{'el-icon-edit': !edit, 'el-icon-check': edit}" @click="edit = !edit"
36   - style="margin-left: 5px;cursor: pointer;"></i> -->
37   - 题目内容
38   - </div>
39 19  
40   - <draggable :options="{animation:380}" group="itxst" v-model="arr2" class="infinite-list" @end="end2"
41   - @add="ComeHere" :style="{'height':contentHeight-60+'px'}" style="overflow:auto;padding-top: 10px;">
42   - <li v-for="(i,index) in arr2" class="infinite-list-item">
43   - <label> {{index+1}}. [{{i.subjectName}}]{{ i.subject }}</label>
44   - <div v-for="item in JSON.parse(i.subjectContent)">
45   - <p class="option-p">{{item.option}}:{{item.optionContent}}</p>
46   - </div>
47   - </li>
48   - </li>
49   - </draggable>
50 20  
  21 + <el-col :span="8" :style="{'height':contentHeight+'px'}" class="jinyongtop">
  22 + <div class="jinyong" v-if="active!=1">
51 23  
52 24 </div>
53   - </el-col>
54   - <el-col :span="8" :style="{'height':contentHeight+'px'}">
55 25 <div class="grid-content bg-purple">
56 26 <div class="areahead">组卷基本信息</div>
57 27 <el-form ref="form" class="testPaper-manager" :rules="rules" :model="TestPaper" label-width="100px">
58   - <el-form-item label="试卷名称:" prop="TestPaperTitle" required class="el-form-item-custom">
59   - <el-input v-model="TestPaper.TestPaperTitle"></el-input>
60   - </el-form-item>
61   - <el-form-item label="题目数量:" class="el-form-item-custom">
62   -
  28 + <el-form-item label="试卷名称:" prop="TestPaperTitle" required class="el-form-item-custom">
  29 + <el-input v-model="TestPaper.TestPaperTitle"></el-input>
63 30 </el-form-item>
  31 + <!-- <el-form-item label="题目数量:" class="el-form-item-custom">
  32 +
  33 + </el-form-item> -->
64 34 <el-form-item label="题型数量:" class="el-form-item-custom">
65 35 <span style="margin-right: 10px;">单选题:{{TestPaper.SingleNumber}}</span>
66 36 <span style="margin-right: 10px;">多选题:{{TestPaper.MultipleNumber}}</span>
... ... @@ -77,15 +47,15 @@
77 47 <el-option v-for="item in usertypelist" :label="item.name" :value="item.id"></el-option>
78 48 </el-select>
79 49 </el-form-item>
80   - <el-form-item label="分类" class="el-form-item-custom" prop="QuestionClassId" >
  50 + <el-form-item label="分类" class="el-form-item-custom" prop="QuestionClassId">
81 51 <el-cascader class="testpaper-input" v-model="TestPaper.QuestionClassId"
82 52 style="width:100%;margin-bottom: 20px;" :props="{emitPath:false}" :clearable=true
83 53 :options="QuestionClass">
84 54 </el-cascader>
85 55 </el-form-item>
86 56  
87   - <el-form-item label="级别" prop="FLevelCount" class="el-form-item-custom"
88   - style="margin-bottom: 20px !important;width:100%;">
  57 + <el-form-item label="级别" prop="FLevelCount" class="el-form-item-custom"
  58 + style="margin-bottom: 20px !important;width:100%;">
89 59 <el-select v-model="TestPaper.FLevelCount" placeholder="请选择级别" @change="changelevel" style="width:100%">
90 60 <el-option v-for="item in levellist" :label="item.title" :value="item.f_count"></el-option>
91 61 </el-select>
... ... @@ -93,7 +63,7 @@
93 63  
94 64 <el-form-item label="有效时间" required>
95 65 <el-form-item prop="date">
96   - <el-date-picker v-model="TestPaper.date" @change="changetimestartend" type="datetimerange"
  66 + <el-date-picker v-model="TestPaper.date" @change="changetimestartend" type="datetimerange"
97 67 format="yyyy-MM-dd hh:mm:ss" range-separator="至" start-placeholder="开始时间" style="width:100%"
98 68 end-placeholder="结束时间">
99 69 </el-date-picker>
... ... @@ -126,24 +96,79 @@
126 96 <el-input class="testpaper-input" :rows="10" type="textarea" v-model="TestPaper.Describe">
127 97 </el-input>
128 98 </el-form-item>
129   - <el-button type="primary" style="float: right;" @click="SubmitTestPaper">保存
130   - </el-button>
  99 +
131 100 </el-form>
132 101 </div>
133 102 </el-col>
  103 + <el-col :span="6" :style="{'height':contentHeight+'px'}" class="jinyongtop">
  104 + <div class="jinyong" v-if="active==1">
  105 +
  106 + </div>
  107 + <div class="grid-content bg-purple">
  108 + <el-tabs v-model="activeTab" style="padding: 0 20px" :stretch="true">
  109 + <el-tab-pane label="专业类" name="6"></el-tab-pane>
  110 + <el-tab-pane label="测评类" name="1"></el-tab-pane>
  111 + </el-tabs>
  112 + <div style="padding:0 10px">
  113 + <el-input size="small" placeholder="输入关键字搜索" v-model="parameter.keyWord"></el-input>
  114 + </div>
  115 + <div style="padding:10.5px">
  116 + <el-button type="primary" @click="randomSubject" style="width:100%">随机抽题</el-button>
  117 + </div>
  118 +
  119 + <draggable :options="{animation:380,filter:'.unmover'}" group="itxst" v-model="arr1" @end="end1"
  120 + @add="RemoveHere" :move="onMove" class="infinite-list" :style="{'height':contentHeight-80+'px'}"
  121 + infinite-scroll-disabled="disabled" v-infinite-scroll="load" style="overflow:auto">
  122 +
  123 + <li v-for="i in arr1" class="infinite-list-item" :key="i.id" v-if="!classarr.some(o=>o == i.id)">{{
  124 + i.subject }}</li>
  125 + <p v-if="loading" style="text-align: center;color: #cdcdcd;" class="unmover">加载中...</p>
  126 + <p v-if="noMore" style="text-align: center;color: #cdcdcd;" class="unmover">没有更多了</p>
  127 + </draggable>
  128 +
  129 + </div>
  130 + </el-col>
  131 + <el-col :span="10" :style="{'height':contentHeight+'px'}" class="jinyongtop">
  132 + <div class="jinyong" v-if="active==1">
  133 +
  134 + </div>
  135 + <div class="grid-content bg-purple">
  136 + <div class="areahead">
  137 + <!-- <span v-show="!edit" style="font-weight: bold;">{{ TestPaper.TestPaperTitle }}</span> -->
  138 + <!-- <el-input v-show="edit" style="width: 400px;" v-model="TestPaper.TestPaperTitle"></el-input>
  139 + <i :class="{'el-icon-edit': !edit, 'el-icon-check': edit}" @click="edit = !edit"
  140 + style="margin-left: 5px;cursor: pointer;"></i> -->
  141 + 题目内容
  142 + </div>
  143 +
  144 + <draggable :options="{animation:380}" group="itxst" v-model="arr2" class="infinite-list" @end="end2"
  145 + @add="ComeHere" :style="{'height':contentHeight-60+'px'}" style="overflow:auto;padding-top: 10px;">
  146 + <li v-for="(i,index) in arr2" class="infinite-list-item">
  147 + <label> {{index+1}}. [{{i.subjectName}}]{{ i.subject }}</label>
  148 + <div v-for="item in JSON.parse(i.subjectContent)">
  149 + <p class="option-p">{{item.option}}:{{item.optionContent}}</p>
  150 + </div>
  151 + </li>
  152 + </li>
  153 + </draggable>
  154 +
  155 +
  156 + </div>
  157 + </el-col>
  158 +
134 159 </el-row>
135 160  
136 161  
137 162  
138   - <el-dialog title="随机抽题" :visible.sync="dialogTableVisible">
  163 + <el-dialog title="随机抽题" :visible.sync="dialogTableVisible" style="margin-left:30%;">
139 164  
140 165 <ul class="random-list">
141 166 <li v-for="(item,index) in randomSubjectList" :key="index">
142 167 <span>试题分类:</span>
143   - <el-cascader :multiple="false" style="flex:1" @change="(a)=>{ changetype(a,item)}" v-model="item.QuestionClassId" :options="randomQuestionTypeList"
144   - clearable>
  168 + <el-cascader :multiple="false" style="flex:1" @change="(a)=>{ changetype(a,item)}"
  169 + v-model="item.QuestionClassId" :options="randomQuestionTypeList" clearable>
145 170 <template slot-scope="{ node, data }">
146   - <span>{{ data.label }}</span>
  171 + <span>{{ data.label }}</span>
147 172 <span v-if="data.subjectCount"> ({{ data.subjectCount || '0' }}) </span>
148 173 </template>
149 174 </el-cascader>
... ... @@ -179,13 +204,31 @@
179 204 }
180 205 }
181 206 }
  207 +
  208 + .jinyongtop {
  209 + position: relative;
  210 + }
  211 +
  212 + .jinyong {
  213 + width: 100%;
  214 + position: absolute;
  215 + width: 100%;
  216 + top: 0px;
  217 + left: opx;
  218 + right: 0;
  219 + left: 0;
  220 + bottom: 0;
  221 + z-index: 8888;
  222 + opacity: 0.1;
  223 + background:black;
  224 + }
182 225 </style>
183 226 <script>
184 227 import draggable from "vuedraggable";
185 228 import { PostRandomGetQuestion, getQuestionList, getQuestionClassList } from "@/api/QuestionBank";
186 229 import { GetpaperLevelList } from "@/api/paperLevel";
187 230  
188   -
  231 +
189 232 import { GetQuestionClassByType } from "@/api/QuestionClass";
190 233 import { EditTestPaper, GetToplevel } from "@/api/TestPaper";
191 234 import { formatTime } from "@/utils/util";
... ... @@ -199,6 +242,7 @@
199 242 },
200 243 data() {
201 244 return {
  245 + active: 1,
202 246 randomSubjectList: [
203 247 {
204 248 QuestionClassId: "",
... ... @@ -246,12 +290,12 @@
246 290 SingleNumber: 0,
247 291 MultipleNumber: 0,
248 292 SubjectiveNumber: 0,
249   - VoiceNumber:0,
  293 + VoiceNumber: 0,
250 294 OriginalPrice: "0",
251 295 PresentPrice: "0",
252 296 MembershipPrice: "0",
253 297 QuestionBankIds: [],
254   - FLevelCount:0
  298 + FLevelCount: null
255 299 },
256 300 loading: false,
257 301 rules: {
... ... @@ -260,7 +304,7 @@
260 304 required: true,
261 305 message: "不能为空",
262 306 },
263   - ],
  307 + ],
264 308 PresentPrice: [
265 309 {
266 310 required: true,
... ... @@ -275,27 +319,38 @@
275 319 ], QuestionClassId: [
276 320 {
277 321 required: true,
278   - message: "请选择分类",
  322 + message: "请选择分类",
279 323 },
280   - ],date: [
  324 + ]
  325 +
  326 + , FLevelCount: [
  327 + {
  328 + required: true,
  329 + message: "请选择级别",
  330 + },
  331 + ]
  332 +
  333 +
  334 +
  335 + , date: [
281 336 {
282 337 required: true,
283   - message: "请选择时间段",
  338 + message: "请选择时间段",
284 339 },
285 340 ],
286 341 TestPaperTitle: [
287 342 {
288 343 required: true,
289   - message: "请填写试卷名称",
290   - }
  344 + message: "请填写试卷名称",
  345 + }
291 346 ],
292 347  
293 348 AnswerTime: [
294 349 {
295 350 required: true,
296   - message: "请填写试总时长控制",
  351 + message: "请填写试总时长控制",
297 352 },
298   -
  353 +
299 354 ],
300 355 },
301 356 QuestionClass: [],
... ... @@ -306,8 +361,8 @@
306 361 },
307 362 ],
308 363 timeout: 0,
309   - typelist:[],
310   - levellist:[] //等级
  364 + typelist: [],
  365 + levellist: [] //等级
311 366 };
312 367 },
313 368 watch: {
... ... @@ -341,8 +396,8 @@
341 396 if (res.data) {
342 397 this.usertypelist = res.data || [];
343 398 }
344   - });
345   - GetpaperLevelList({pageSize:1000,sortOrder:'asc'}).then(res => {
  399 + });
  400 + GetpaperLevelList({ pageSize: 1000, sortOrder: 'asc' }).then(res => {
346 401 if (res.data) {
347 402 this.levellist = res.data.data || [];
348 403 }
... ... @@ -354,23 +409,40 @@
354 409 //this.GetList();
355 410 },
356 411 methods: {
357   - changetype(a,item){
358   - var type = this.typelist.find(o=>o.id == item.QuestionClassId[item.QuestionClassId.length-1]);
359   - if(type) {
  412 + next() {
  413 + var _this = this;
  414 + console.log(this.active);
  415 + if(this.active == 1)
  416 + {
  417 + _this.$refs['form'].validate((valid) => {
  418 + if(valid){
  419 + this.active = 2;
  420 + }
  421 + });
  422 + }
  423 + else{
  424 + if (this.active++ >=2) this.active = 1;
  425 +
  426 + }
  427 +
  428 + },
  429 + changetype(a, item) {
  430 + var type = this.typelist.find(o => o.id == item.QuestionClassId[item.QuestionClassId.length - 1]);
  431 + if (type) {
360 432 item.maxcount = type.subjectCount || 0;
361   - if(item.Count > item.maxcount) item.Count = item.maxcount;
  433 + if (item.Count > item.maxcount) item.Count = item.maxcount;
362 434 }
363 435 },
364 436  
365   - changelevel(v){
366   - var type = this.levellist.find(o=>o.f_count == v);
367   - if(type) {
  437 + changelevel(v) {
  438 + var type = this.levellist.find(o => o.f_count == v);
  439 + if (type) {
368 440 this.TestPaper.FLevelTitle = type.title || '';
369 441 }
370 442 },
371   - getmaxid(item){
372   - var type = this.randomQuestionTypeList.find(o=>o.id == item.QuestionClassId);
373   - if(type) return type.subjectCount || 0;
  443 + getmaxid(item) {
  444 + var type = this.randomQuestionTypeList.find(o => o.id == item.QuestionClassId);
  445 + if (type) return type.subjectCount || 0;
374 446 else return 0;
375 447 },
376 448 getSubTree(id, list) {
... ... @@ -427,11 +499,11 @@
427 499 this.dialogTableVisible = false;
428 500 if (!list.length) {
429 501 this.$message.warning('所选分类没有试题');
430   - }else{
431   - this.TestPaper.SingleNumber = list.filter(t=>t.subjectType == 1).length;
432   - this.TestPaper.MultipleNumber = list.filter(t=>t.subjectType == 2).length;
433   - this.TestPaper.SubjectiveNumber = list.filter(t=>t.subjectType == 3).length;
434   - this.TestPaper.VoiceNumber = list.filter(t=>t.subjectType == 4).length;
  502 + } else {
  503 + this.TestPaper.SingleNumber = list.filter(t => t.subjectType == 1).length;
  504 + this.TestPaper.MultipleNumber = list.filter(t => t.subjectType == 2).length;
  505 + this.TestPaper.SubjectiveNumber = list.filter(t => t.subjectType == 3).length;
  506 + this.TestPaper.VoiceNumber = list.filter(t => t.subjectType == 4).length;
435 507 }
436 508 });
437 509 },
... ... @@ -485,29 +557,29 @@
485 557 SubmitTestPaper() {
486 558  
487 559 this.$refs['form'].validate((valid) => {
488   -
489   - if(!this.TestPaper.TestPaperTitle){
  560 +
  561 + if (!this.TestPaper.TestPaperTitle) {
490 562 this.$notify({
491   - title: '试卷标题必填!',
492   - // message: res.data.message,
493   - type: 'warning'
494   - });
  563 + title: '试卷标题必填!',
  564 + // message: res.data.message,
  565 + type: 'warning'
  566 + });
495 567 return;
496 568 }
497   - if (valid) {
  569 + if (valid) {
498 570 this.TestPaper.QuestionBankIds = this.arr2.map((u) => u.id);
499 571 var d = this.TestPaper;
500 572 if (this.arr2.length > 0) {
501 573 EditTestPaper(this.TestPaper).then((res) => {
502 574 if (res.data.code == 200) {
503 575 this.$notify({
504   - title: '组卷成功!',
505   - // message: res.data.message,
506   - type: 'success'
507   - });
  576 + title: '组卷成功!',
  577 + // message: res.data.message,
  578 + type: 'success'
  579 + });
508 580 this.$router.push({
509 581 path: '/views/TestPaperList',
510   - query: {
  582 + query: {
511 583 }
512 584 })
513 585 } else {
... ... @@ -538,7 +610,7 @@
538 610 GetQuestionClassByType({ ClassType: 2 }).then((res) => {
539 611 var classarr = res.data.data || [];
540 612 this.arr1 = classarr.map((rs) => {
541   - rs.subject = rs.subjectName = rs.ClassificationName+'('+(rs.subjectCount || 0)+')';
  613 + rs.subject = rs.subjectName = rs.ClassificationName + '(' + (rs.subjectCount || 0) + ')';
542 614 rs.type = "wd";
543 615 rs.subjectContent = "[]";
544 616 return rs;
... ... @@ -590,7 +662,7 @@
590 662 if (e.item._underlying_vm_.subjectType == 4) {
591 663 this.TestPaper.VoiceNumber -= 1;
592 664 }
593   -
  665 +
594 666 this.TestPaper.TotalScore -= e.item._underlying_vm_.fraction;
595 667 this.TestPaper.QuestionBankIds = this.arr2.map((u) => u.id);
596 668 },
... ... @@ -617,7 +689,7 @@
617 689 getQuestionList({
618 690 QuestionClassId: d.id,
619 691 PageIndex: 1,
620   - PageSize: this.TestPaper.FLevelCount || 1000,
  692 + PageSize: this.TestPaper.FLevelCount || 1000,
621 693 }).then((res) => {
622 694 var data = res.data.data.rows || [];
623 695 data = data.filter(o => !this.arr2.find(d => d.id == o.id));
... ...
src/views/dashboard/index.vue
... ... @@ -4,10 +4,11 @@
4 4 style="background-color: #334056;border-radius: 5px;color: #FFF;font-size: 16px;padding: 5px 5px 5px 15px;">
5 5 <div style="font-size: 20px;">欢迎使用面试考试系统后台</div>
6 6 </div>
7   - <el-row :gutter="20">
  7 + <el-row :gutter="20" v-if="isAdmin">
8 8 <el-col :span="6">
9 9 <div class="grid-content bg-purple">
10   - <label class="grid-content-number">{{total.PriceNumber/100}}<span style="font-size: 16px;">元</span></label>
  10 + <label class="grid-content-number">{{total.PriceNumber/100}}<span
  11 + style="font-size: 16px;">元</span></label>
11 12 <div>总收益</div>
12 13 </div>
13 14 </el-col>
... ... @@ -30,6 +31,10 @@
30 31 </div>
31 32 </el-col>
32 33 </el-row>
  34 +
  35 + <div style="width:100%">
  36 + <el-image :src="imageUrl" style="width:100%"></el-image>
  37 + </div>
33 38 </div>
34 39 </template>
35 40  
... ... @@ -38,31 +43,41 @@
38 43 GetQuestionTotal,
39 44 GetTestPaperTotal
40 45 } from '@/api/index'
41   - import {
42   - OrderGetPriceNumber
43   - } from '@/api/order.js'
  46 + import {
  47 + OrderGetPriceNumber
  48 + } from '@/api/order.js'
44 49 import {
45 50 mapGetters
46 51 } from 'vuex'
47   -import {
48   - GetUserList
49   - } from '@/api/user'
  52 + import {
  53 + GetUserList
  54 + } from '@/api/user'
  55 +
  56 +
  57 + import {
  58 + GetInfo
  59 + } from '@/api/setting'
  60 +
  61 +
  62 +
50 63 export default {
51 64 name: '安第斯考试系统',
52 65 data() {
53 66 return {
  67 + isAdmin: false,
  68 + imageUrl: '',
54 69 total: {
55 70 questiontotal: 0,
56   - testpapertotal:0,
57   - PriceNumber:0,
58   - Count:0,
  71 + testpapertotal: 0,
  72 + PriceNumber: 0,
  73 + Count: 0,
59 74 },
60   - query: {
61   - UserTypeEnum: 1, //0:管理员,1普通用户
62   - PageIndex: 1,
63   - PageSize: 10,
64   -
65   - }
  75 + query: {
  76 + UserTypeEnum: 1, //0:管理员,1普通用户
  77 + PageIndex: 1,
  78 + PageSize: 10,
  79 +
  80 + }
66 81 }
67 82 },
68 83 computed: {
... ... @@ -74,22 +89,37 @@ import {
74 89  
75 90 },
76 91 mounted() {
  92 + try {
  93 + if (this.$store.state.user.userInfo.UserType == 0) this.isAdmin = true;
  94 + } catch { }
  95 + this.init();
77 96 this.GetTotalHeadler();
78 97 },
79 98 methods: {
  99 + init() {
  100 + var _this = this;
  101 + GetInfo(1).then(res => {
  102 + var d = res.data;
  103 + if (d && d.data) {
  104 + if (d.data.home_images) {
  105 + _this.imageUrl = _this.BASE_URL + d.data.home_images;
  106 + }
  107 + }
  108 + });
  109 + },
80 110 GetTotalHeadler() {
81 111 GetQuestionTotal().then(res => {
82 112 this.total.questiontotal = res.data.data;
83 113 });
84   - GetTestPaperTotal().then(res=>{
  114 + GetTestPaperTotal().then(res => {
85 115 this.total.testpapertotal = res.data.data;
86 116 });
87   - OrderGetPriceNumber().then(res=>{
88   - this.total.PriceNumber = res.data.data;
89   - })
90   - GetUserList(this.query).then(res => {
91   - this.total.Count = res.data.data.total
92   - })
  117 + OrderGetPriceNumber().then(res => {
  118 + this.total.PriceNumber = res.data.data;
  119 + })
  120 + GetUserList(this.query).then(res => {
  121 + this.total.Count = res.data.data.total
  122 + })
93 123 }
94 124 }
95 125 }
... ... @@ -100,48 +130,59 @@ import {
100 130 &-container {
101 131 margin: 30px;
102 132 }
  133 +
103 134 &-text {
104 135 font-size: 30px;
105 136 line-height: 46px;
106 137 }
107 138 }
  139 +
108 140 .el-row {
109 141 margin-bottom: 20px;
110 142 margin-top: 20px;
  143 +
111 144 &:last-child {
112 145 margin-bottom: 0;
113 146 }
114 147 }
  148 +
115 149 .el-col {
116 150 border-radius: 5px;
117 151 }
  152 +
118 153 .bg-purple-dark {
119 154 background: #99a9bf;
120 155 }
  156 +
121 157 .bg-purple {
122 158 background: #d3dce6;
123 159 box-shadow: 0 0 10px #cdcdcd;
124 160 }
  161 +
125 162 .bg-purple-light {
126 163 background: #e5e9f2;
127 164 }
  165 +
128 166 .grid-content {
129 167 border-radius: 5px;
130 168 min-height: 36px;
131 169 text-align: center;
132 170 padding-top: 20px;
133 171 padding-bottom: 20px;
  172 +
134 173 .grid-content-number {
135 174 font-size: 40px;
136 175 color: red;
137 176 }
  177 +
138 178 div {
139 179 font-size: 20px;
140 180 margin-top: 10px;
141 181 }
142 182 }
  183 +
143 184 .row-bg {
144 185 padding: 10px 0;
145 186 background-color: #f9fafc;
146 187 }
147 188 -</style>
  189 +</style>
148 190 \ No newline at end of file
... ...
src/views/login/index.vue
... ... @@ -88,8 +88,8 @@
88 88 $route: {
89 89 handler: function (route) {
90 90 this.redirect = route.query && route.query.redirect
91   - if (this.redirect.indexOf('404') != -1)
92   - this.redirect = this.redirect.replace('404', 'dashboard')
  91 + // if (this.redirect.indexOf('404') != -1)
  92 + // this.redirect = this.redirect.replace('404', 'dashboard')
93 93 },
94 94 immediate: true
95 95 }
... ... @@ -109,12 +109,11 @@
109 109 },
110 110 handleLogin() {
111 111 this.$refs.loginForm.validate(valid => {
112   -
113 112 if (valid) {
114 113 this.loading = true
115 114 this.$store.dispatch('user/login', this.loginForm).then(() => {
116 115 this.$router.push({
117   - path: '/'
  116 + path: this.redirect || '/'
118 117 })
119 118 this.loading = false
120 119 }).catch((ret) => {
... ...
src/views/settings/index.vue 0 → 100644
  1 +<template>
  2 + <div class="app-container">
  3 + <el-form ref="form" :model="form" label-width="180px" style="width:50%">
  4 + <el-form-item label="系统名称">
  5 + <el-input v-model="form.name"></el-input>
  6 + </el-form-item>
  7 +
  8 +
  9 + <el-form-item label="首页广告图">
  10 + <el-upload :headers="{Authorization:token}"
  11 + class="avatar-uploader"
  12 + :action="BASE_URL + '/api/upload/single'"
  13 + :show-file-list="false"
  14 + :on-success="handleAvatarSuccess"
  15 + >
  16 + <img v-if="imageUrl" :src="imageUrl" class="avatar">
  17 + <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  18 + </el-upload>
  19 +
  20 + </el-form-item>
  21 +
  22 +
  23 +
  24 + <!-- <el-form-item label="活动区域">
  25 + <el-select v-model="form.region" placeholder="请选择活动区域">
  26 + <el-option label="区域一" value="shanghai"></el-option>
  27 + <el-option label="区域二" value="beijing"></el-option>
  28 + </el-select>
  29 + </el-form-item>
  30 + <el-form-item label="活动时间">
  31 + <el-col :span="11">
  32 + <el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker>
  33 + </el-col>
  34 + <el-col class="line" :span="2">-</el-col>
  35 + <el-col :span="11">
  36 + <el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
  37 + </el-col>
  38 + </el-form-item>
  39 + <el-form-item label="即时配送">
  40 + <el-switch v-model="form.delivery"></el-switch>
  41 + </el-form-item>
  42 + <el-form-item label="活动性质">
  43 + <el-checkbox-group v-model="form.type">
  44 + <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
  45 + <el-checkbox label="地推活动" name="type"></el-checkbox>
  46 + <el-checkbox label="线下主题活动" name="type"></el-checkbox>
  47 + <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
  48 + </el-checkbox-group>
  49 + </el-form-item>
  50 + <el-form-item label="特殊资源">
  51 + <el-radio-group v-model="form.resource">
  52 + <el-radio label="线上品牌商赞助"></el-radio>
  53 + <el-radio label="线下场地免费"></el-radio>
  54 + </el-radio-group>
  55 + </el-form-item>
  56 + <el-form-item label="活动形式">
  57 + <el-input type="textarea" v-model="form.desc"></el-input>
  58 + </el-form-item> -->
  59 + <el-form-item>
  60 + <el-button type="primary" @click="submitForm">保存</el-button>
  61 +
  62 + </el-form-item>
  63 + </el-form>
  64 + </div>
  65 +</template>
  66 +
  67 +<script>
  68 +
  69 +
  70 +import {
  71 + getToken
  72 + } from '@/utils/auth'
  73 +
  74 +
  75 +
  76 + import {
  77 + GetInfo,
  78 + Update
  79 + } from '@/api/setting'
  80 + export default {
  81 + data() {
  82 +
  83 + return {
  84 + token:getToken(),
  85 + imageUrl:'',
  86 + form: {
  87 + pass: '',
  88 + checkPass: '',
  89 + },
  90 + rules: {
  91 + }
  92 + };
  93 + },
  94 + created(){
  95 + var _this = this;
  96 + GetInfo(1).then(res=>{
  97 + _this.form = res.data.data;
  98 + if(_this.form.home_images){
  99 + _this.imageUrl = _this.BASE_URL+_this.form.home_images;
  100 + }
  101 + });
  102 + },
  103 +
  104 + methods: {
  105 + handleAvatarSuccess(res, file) {
  106 + this.imageUrl = URL.createObjectURL(file.raw);
  107 + this.form.home_images = res.data.data.src || '';
  108 + },
  109 +
  110 + submitForm(formName) {
  111 + Update(this.form).then(res=>{
  112 + if (res.data.code==200) {
  113 + this.$notify({
  114 + title: '提示',
  115 + message: '保存成功',
  116 + type: 'success',
  117 + duration: 1000
  118 + })
  119 +
  120 + }
  121 + })
  122 + },
  123 + resetForm(formName) {
  124 + this.$refs[formName].resetFields();
  125 + }
  126 + }
  127 + }
  128 +</script>
  129 +
  130 +<style>
  131 +</style>
  132 +<style scoped>
  133 + .avatar-uploader .el-upload {
  134 + border: 1px dashed #d9d9d9;
  135 + border-radius: 6px;
  136 + cursor: pointer;
  137 + position: relative;
  138 + overflow: hidden;
  139 + }
  140 + .avatar-uploader .el-upload:hover {
  141 + border-color: #409EFF;
  142 + }
  143 + .avatar-uploader-icon {
  144 + font-size: 28px;
  145 + color: #8c939d;
  146 + width: 178px;
  147 + height: 178px;
  148 + line-height: 178px;
  149 + text-align: center;
  150 + }
  151 + .avatar {
  152 + width: 178px;
  153 + height: 178px;
  154 + display: block;
  155 + }
  156 +</style>
0 157 \ No newline at end of file
... ...
src/views/user/loglist.vue 0 → 100644
  1 +<template>
  2 + <div style="padding: 10px">
  3 + <div class="seetingsDiv" style="">
  4 + <div class="flex" style="margin-top: 10px">
  5 + <el-form :inline="true" class="demo-form-inline">
  6 + <el-form-item label="关键字">
  7 + <el-input placeholder="输入关键字搜索" v-model="queryModel.keyword"></el-input>
  8 + </el-form-item>
  9 + <el-form-item label="用户">
  10 + <el-input placeholder="用户" v-model="queryModel.username"></el-input>
  11 + </el-form-item>
  12 + <el-form-item label="日志类型">
  13 + <el-select v-model="queryModel.type" placeholder="日志类型">
  14 + <el-option label="全部" value=""></el-option>
  15 + <el-option label="用户操作" value="1"></el-option>
  16 + <el-option label="系统操作" value="2"></el-option>
  17 + <el-option label="系统信息" value="3"></el-option>
  18 + <el-option label="底层信息" value="4"></el-option>
  19 + </el-select>
  20 + </el-form-item>
  21 +
  22 + </el-form>
  23 + <el-button type="success" @click="search">搜索</el-button>
  24 + </div>
  25 + <div class="flex align-center" style="margin-top: 10px">
  26 +
  27 +
  28 + </div>
  29 + </div>
  30 + <div class="main-box">
  31 + <el-table ref="mytable" :data="table_data" style="width: 100%;height:calc(100vh - 260px)" border
  32 + @selection-change="handleSelectionChange">
  33 + <el-table-column v-if="radio" type="index" width="50"></el-table-column>
  34 + <el-table-column v-if="selection" type="selection" width="55"></el-table-column>
  35 +
  36 +
  37 + <el-table-column align="center" width="120" label="类型">
  38 + <template slot-scope="scope">
  39 +
  40 + <div>
  41 + <span v-if="scope.row.TypeEnum == 1">用户操作</span>
  42 + <span v-else-if="scope.row.TypeEnum == 2">系统操作</span>
  43 + <span v-else-if="scope.row.TypeEnum == 3">系统信息</span>
  44 + <span v-else-if="scope.row.TypeEnum == 4">底层信息</span>
  45 + <span v-else >系统</span>
  46 + </div>
  47 + </template>
  48 + </el-table-column>
  49 + <el-table-column align="center" v-for="(item, index, key) in table_columns" :width="item.width"
  50 + :item="item" :key="key" :index="index" :label="item.label">
  51 + <template slot-scope="scope">
  52 + <el-input v-if="scope.row.edit" size="small" v-model="scope.row[item.prop]"
  53 + :placeholder="'请输入' + item.label">
  54 + </el-input>
  55 + <span v-if="!scope.row.edit">{{ scope.row[item.prop] }}</span>
  56 + </template>
  57 + </el-table-column>
  58 +
  59 + </el-table>
  60 +
  61 + </div>
  62 +
  63 + <div class="page-box">
  64 + <el-pagination background layout="prev, pager, next" :total="queryResult.totalCount"
  65 + @current-change="currentchange">
  66 + </el-pagination>
  67 + </div>
  68 + </div>
  69 +</template>
  70 +
  71 +<script>
  72 + import {
  73 + GetList,
  74 + } from "@/api/log";
  75 + import { formatTime } from '@/utils/util'
  76 + export default {
  77 + data() {
  78 + return {
  79 + currentFilePath: "",
  80 + queryResult: {},
  81 + queryModel: {
  82 + pageIndex: 1,
  83 + pageSize: 20,
  84 + },
  85 + query: {},
  86 + new_date_json: {}, //数据结构
  87 + multipleSelection: [], //复选框,数据
  88 + is_edit: true, //是否可编辑
  89 + is_delete: true, //是否可删除
  90 + selection: true, //是否需要复选框
  91 + radio: false, //单选变色
  92 + space_color: true, //隔行变色
  93 + //表头信息
  94 + table_columns: [{
  95 + prop: "OperationTitle",
  96 + label: "内容",
  97 + width: "350",
  98 + },
  99 + {
  100 + prop: "OperationIp",
  101 + label: "操作IP地址",
  102 + width: "180",
  103 + },
  104 + {
  105 + prop: "OperationTime",
  106 + label: "操作时间",
  107 + width: "180",
  108 + },
  109 + {
  110 + prop: "UserName",
  111 + label: "操作用户",
  112 + width: "120",
  113 + },
  114 + {
  115 + prop: "Describe",
  116 + label: "详细内容",
  117 + },
  118 + ],
  119 + //表格数据
  120 + table_data: [],
  121 + dialogVisible: false,
  122 + form: {},
  123 + };
  124 + },
  125 + methods: {
  126 +
  127 + search() {
  128 + this.queryModel.pageIndex = 1;
  129 + this.getList();
  130 + },
  131 + getList() {
  132 + GetList(this.queryModel).then((res) => {
  133 + this.queryResult = res.data;
  134 +
  135 + this.table_data = res.data.data.map(t => {
  136 + t.OperationTime = formatTime(t.OperationTime, 'yyyy-MM-dd');
  137 + return t;
  138 + });
  139 + });
  140 + },
  141 + //隔行变色
  142 + tableRowClassName() {
  143 + //选取DOM节点
  144 + var trs = this.$refs.mytable.$el
  145 + .getElementsByTagName("tbody")[0]
  146 + .getElementsByTagName("tr");
  147 + for (var i in trs) {
  148 + if (i % 2 == 0) {
  149 + //当隔行变色未true时改变颜色
  150 + if (this.space_color) {
  151 + trs[i].style.backgroundColor = "#f0f9eb";
  152 + } else {
  153 + trs[i].style.backgroundColor = "";
  154 + }
  155 + }
  156 + }
  157 + },
  158 +
  159 + //多选框
  160 + handleSelectionChange(val) {
  161 + this.multipleSelection = val;
  162 + console.log("selection:", this.multipleSelection);
  163 + },
  164 +
  165 +
  166 + //删除
  167 + handleDelete(index, row) {
  168 + console.log(index, row);
  169 +
  170 + this.table_data.splice(index, 1);
  171 + UserInfo_Delete(row.id);
  172 + this.$message({
  173 + message: "删除成功!",
  174 + type: "success",
  175 + });
  176 + },
  177 +
  178 + currentchange(page) {
  179 + this.queryModel.pageIndex = page;
  180 + this.getList();
  181 + },
  182 + },
  183 + created() {
  184 + this.getList();
  185 + },
  186 + mounted: function () {
  187 + //确保方法在页面渲染后调用
  188 + this.$nextTick(function () {
  189 + /////方法
  190 + this.tableRowClassName();
  191 + });
  192 + },
  193 + watch: {
  194 + space_color: function () {
  195 + //监听数据变化
  196 + this.$nextTick(function () {
  197 + /////方法
  198 + this.tableRowClassName();
  199 + });
  200 + },
  201 + table_data: function () {
  202 + //监听数据变化f
  203 + this.$nextTick(function () {
  204 + /////方法
  205 + this.tableRowClassName();
  206 + });
  207 + },
  208 + },
  209 + };
  210 +</script>
  211 +<style scoped>
  212 + /deep/.el-table__body-wrapper {
  213 + height: 92% !important;
  214 + }
  215 +</style>
  216 +<style lang="scss" scoped>
  217 + .main-box {
  218 + display: flex;
  219 + }
  220 +
  221 + .doc-view {
  222 + margin-left: 10px;
  223 + width: 100%;
  224 + flex: 1;
  225 + overflow: hidden;
  226 + }
  227 +
  228 + .el-table__expanded-cell {
  229 + padding: 10px;
  230 + }
  231 +
  232 + .demo-table-expand {
  233 + display: flex;
  234 + justify-content: space-between;
  235 + flex-wrap: wrap;
  236 + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
  237 + padding: 20px;
  238 + border-radius: 10px;
  239 + }
  240 +
  241 + .demo-table-expand .el-form-item {
  242 + margin-bottom: 10px !important;
  243 + min-width: 20%;
  244 + max-width: 50%;
  245 + }
  246 +
  247 + .demo-form-inline {
  248 + display: flex;
  249 + align-items: center;
  250 + }
  251 +
  252 + .el-form--inline .el-form-item {
  253 + display: flex;
  254 + align-items: center;
  255 + margin-bottom: 0;
  256 + }
  257 +
  258 + .aligin-center {
  259 + align-items: center;
  260 + }
  261 +
  262 + .seetingsDiv {
  263 + display: flex;
  264 + align-items: center;
  265 + width: 100%;
  266 + height: auto;
  267 + padding: 30px;
  268 + background: #efefef;
  269 + /* line-height: 60px; */
  270 + border-radius: 5px;
  271 + box-shadow: 0 0 5px #cdcdcd;
  272 + justify-content: space-between;
  273 + flex-wrap: wrap;
  274 + margin-bottom: 20px;
  275 + }
  276 +
  277 + .seetingsDiv button {
  278 + height: 40px;
  279 + background-color: #304156;
  280 + border: 0px;
  281 + margin-left: 10px;
  282 + box-shadow: 0 0 5px #cdcdcd;
  283 + float: none;
  284 + margin-right: 10px;
  285 + margin-top: 0;
  286 + }
  287 +</style>
0 288 \ No newline at end of file
... ...
src/views/user/rolelist.vue 0 → 100644
  1 +<template>
  2 + <div class="app-container">
  3 + <div class="seetingsDiv" style="">
  4 + <el-button type="primary" @click="dialogClassIVIsible=true">添加
  5 + </el-button>
  6 + </div>
  7 + <el-table :data="userList" id="QuestionTable" border
  8 + style="width: 100%;border-radius: 5px;box-shadow: 0 0 10px #efefef;margin-top: 10px;" :stripe='true'>
  9 + <el-table-column type="index" prop="date" width="50" align="center"></el-table-column>
  10 + <el-table-column prop="date" label="角色名称">
  11 + <template slot-scope="scope">
  12 + <span>{{ scope.row.name }}</span>
  13 + </template>
  14 + </el-table-column>
  15 +
  16 +
  17 +
  18 + <el-table-column fixed="right" label="操作" width="150">
  19 + <template slot-scope="scope">
  20 + <el-dropdown @command="(e)=>{handleCommand(e,scope.row)}">
  21 + <span class="el-dropdown-link">
  22 + 操作<i class="el-icon-arrow-down el-icon--right"></i>
  23 + </span>
  24 + <template #dropdown>
  25 + <el-dropdown-menu>
  26 + <el-dropdown-item command="update">编辑</el-dropdown-item>
  27 + <el-dropdown-item command="del" v-if="scope.row.username!='admin'">删除</el-dropdown-item>
  28 + </el-dropdown-menu>
  29 + </template>
  30 + </el-dropdown>
  31 + </template>
  32 + </el-table-column>
  33 + </el-table>
  34 + <el-pagination background @current-change="currentchange"
  35 + style="position:static;bottom: 3px;text-align: center;margin-top: 5px;" :page-size="this.query.PageSize"
  36 + layout="total,prev, pager, next" :total="Count">
  37 + </el-pagination>
  38 + <el-dialog :title="title" :visible.sync="dialogClassIVIsible" @close="closeClassDialog" width="450"
  39 + :close-on-click-modal="false">
  40 + <el-form ref="adminUserInfo" :rules="rules" :model="adminUserInfo" label-width="90px" style="margin-left: 40px;">
  41 + <el-form-item label="名称" prop="name">
  42 + <el-input v-model="adminUserInfo.name " placeholder="名称" style="width: 40%;"></el-input>
  43 + </el-form-item>
  44 + <el-form-item label="角色人员">
  45 + <el-transfer v-model="value" filterable :titles="['待选人员', '已选人员']" :data="data"></el-transfer>
  46 + </el-form-item>
  47 + <el-form-item label="权限" style="margin-top: 40px;">
  48 + <el-tree ref="tree" :check-strictly="true" :data="data1" show-checkbox node-key="id" default-expand-all :props="defaultProps">
  49 + </el-tree>
  50 + </el-form-item>
  51 +
  52 + <el-form-item style="text-align: right;">
  53 + <el-button @click="dialogClassIVIsible=false">取消</el-button>
  54 + <el-button type="primary" @click="submitForm('adminUserInfo')">{{buttonText}}</el-button>
  55 + </el-form-item>
  56 + </el-form>
  57 +
  58 + <div style="clear: both;"></div>
  59 + </el-dialog>
  60 +
  61 +
  62 + <el-dialog title="修改密码" :visible.sync="dialogClassIVIsibleT" @close="closeClassDialogT" width="450"
  63 + :close-on-click-modal="false">
  64 + <el-form :model="ruleForm" status-icon :rules="rulesT" ref="ruleForm" label-width="100px" class="demo-ruleForm"
  65 + style="width: 320px;">
  66 + <el-form-item label="密码" prop="Password">
  67 + <el-input type="password" v-model="ruleForm.Password" autocomplete="off"></el-input>
  68 + </el-form-item>
  69 + <el-form-item label="确认密码" prop="checkPass">
  70 + <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
  71 + </el-form-item>
  72 +
  73 + <el-form-item>
  74 + <el-button type="primary" @click="submitFormT('ruleForm')">提交</el-button>
  75 + <el-button @click="resetForm('ruleForm')">重置</el-button>
  76 + </el-form-item>
  77 + </el-form>
  78 +
  79 + <div style="clear: both;"></div>
  80 + </el-dialog>
  81 +
  82 + </div>
  83 +</template>
  84 +
  85 +<script>
  86 + import {
  87 + GetInfo,
  88 + GetUserList,
  89 + UsersCreate,
  90 + UsersUpdate,
  91 + UsersDelete,
  92 + GetMenue
  93 + } from '@/api/role'
  94 + import { GetUserListByAdminSimple } from '@/api/user'
  95 +
  96 + import {
  97 + formatTime
  98 + } from '@/utils/util.js'
  99 + export default {
  100 + data() {
  101 + var checkPhone = (rule, value, callback) => {
  102 + const phoneReg = /^1[3|4|5|7|8][0-9]{9}$/
  103 + if (!value) {
  104 + return callback(new Error('电话号码不能为空'))
  105 + }
  106 + setTimeout(() => {
  107 + if (!Number.isInteger(+value)) {
  108 + callback(new Error('请输入数字值'))
  109 + } else {
  110 + if (phoneReg.test(value)) {
  111 + callback()
  112 + } else {
  113 + callback(new Error('电话号码格式不正确'))
  114 + }
  115 + }
  116 + }, 100)
  117 + }
  118 +
  119 +
  120 + var validatePass = (rule, value, callback) => {
  121 + if (value === '') {
  122 + callback(new Error('请输入密码'));
  123 + } else {
  124 + if (this.ruleForm.checkPass !== '') {
  125 + this.$refs.ruleForm.validateField('checkPass');
  126 + }
  127 + callback();
  128 + }
  129 + };
  130 + var validatePass2 = (rule, value, callback) => {
  131 + if (value === '') {
  132 + callback(new Error('请再次输入密码'));
  133 + } else if (value !== this.ruleForm.Password) {
  134 + callback(new Error('两次输入密码不一致!'));
  135 + } else {
  136 + callback();
  137 + }
  138 + };
  139 +
  140 +
  141 + return {
  142 + data1: [],
  143 + data: [],
  144 + value: [],
  145 +
  146 + defaultProps: {
  147 + children: 'children',
  148 + label: 'label'
  149 + },
  150 +
  151 + title: '添加',
  152 + buttonText: '立即创建',
  153 + userList: [],
  154 + dialogClassIVIsible: false,
  155 + dialogClassIVIsibleT: false,
  156 + adminUserInfo: {
  157 + username: "",
  158 + password: "",
  159 + // type: 4,
  160 + fullName: "",
  161 + // remark: "",
  162 + phone: "",
  163 + // sex: "",
  164 + // card: "",
  165 + // address: "",
  166 + // birthday: "",
  167 + status: 1,
  168 + },
  169 +
  170 + ruleForm: {
  171 + UserId: 0,
  172 + Password: '',
  173 + checkPass: '',
  174 + },
  175 + rulesT: {
  176 + Password: [
  177 + { validator: validatePass, trigger: 'blur' }
  178 + ],
  179 + checkPass: [
  180 + { validator: validatePass2, trigger: 'blur' }
  181 + ],
  182 + },
  183 + Count: 0,
  184 + query: {
  185 + UserTypeEnum: 5, //0:管理员,1普通用户
  186 + PageIndex: 1,
  187 + PageSize: 10,
  188 +
  189 + },
  190 + rules: {
  191 + name: [{
  192 + required: true,
  193 + message: '请输入管理员名称',
  194 + trigger: 'blur'
  195 + }],
  196 + phone: [{
  197 + required: true,
  198 + message: '请输入联系方式',
  199 + trigger: 'blur'
  200 + }],
  201 + username: [{
  202 + required: true,
  203 + message: '请输入登录账号',
  204 + trigger: 'blur'
  205 + }],
  206 + phone: [{
  207 + required: true,
  208 + trigger: 'blur',
  209 + validator: checkPhone
  210 + }],
  211 + password: [{
  212 + required: true,
  213 + message: '请输入密码',
  214 + trigger: 'blur'
  215 + }],
  216 + type: [{
  217 + required: true,
  218 + message: '请输选择用户类型',
  219 + trigger: 'blur'
  220 + }]
  221 + }
  222 + }
  223 + },
  224 + created() {
  225 + this.GetUser()
  226 + this.getadmin()
  227 + this.getmenue()
  228 + },
  229 + methods: {
  230 + getmenue() {
  231 + GetMenue().then(res => {
  232 + this.data1 = res.data || [];
  233 + });
  234 + },
  235 + getadmin() {
  236 + GetUserListByAdminSimple({ PageSize: 9999999, PageIndex: 1, Sort: [{ Field: 'id', Type: 0 }] }).then(res => {
  237 + var data = res.data || [];
  238 + data = data.map(o => {
  239 + return {
  240 + key: o.id,
  241 + label: o.fullName
  242 + }
  243 + });
  244 + this.data = data;
  245 + });
  246 +
  247 + },
  248 + closeClassDialog() {
  249 + this.title = '添加'
  250 + this.buttonText = '立即创建'
  251 + this.GetUser();
  252 + },
  253 + submitForm(formName) {
  254 + var _this = this;
  255 + this.$refs[formName].validate((valid) => {
  256 + if (valid) {
  257 + _this.adminUserInfo.users = _this.value || [];
  258 + _this.adminUserInfo.menues = _this.$refs.tree.getCheckedKeys() || [];
  259 + if (_this.title == '添加') {
  260 + _this.adminUserInfo.addTime = formatTime(new Date(), 'yyyy-MM-dd HH:mm:ss')
  261 + UsersCreate(this.adminUserInfo).then(res => {
  262 + this.$notify({
  263 + title: '成功',
  264 + message: res.data.message,
  265 + type: 'success'
  266 + });
  267 + // this.$confirm(res.data.message, '消息')
  268 + _this.dialogClassIVIsible = false
  269 + })
  270 + } else {
  271 + _this.adminUserInfo.updateTime = formatTime(new Date(), 'yyyy-MM-dd HH:mm:ss')
  272 + _this.adminUserInfo.status = 1
  273 + UsersUpdate(this.adminUserInfo).then(res => {
  274 + _this.$notify({
  275 + title: '成功',
  276 + message: res.data.message,
  277 + type: 'success'
  278 + });
  279 + // this.$confirm(res.data.message, '消息')
  280 + _this.dialogClassIVIsible = false
  281 + })
  282 + }
  283 +
  284 + } else {
  285 + return false;
  286 + }
  287 + });
  288 + },
  289 +
  290 + GetUser() {
  291 + GetUserList(this.query).then(res => {
  292 + this.userList = res.data.data
  293 + this.Count = res.data.total
  294 + })
  295 + },
  296 + currentchange(page) {
  297 + this.query.PageIndex = page;
  298 + this.GetUser();
  299 + },
  300 + closeClassDialogT() {
  301 + this.dialogClassIVIsibleT = false
  302 + },
  303 +
  304 +
  305 + submitFormT(formName) {
  306 + this.$refs[formName].validate((valid) => {
  307 + if (valid) {
  308 + var postdata = Object.assign({}, this.ruleForm);
  309 + if (this.ruleForm.id) {
  310 + UsersUpdate(postdata).then(res => {
  311 + if (res.data.code == 200) {
  312 + this.$notify({
  313 + title: 'Success',
  314 + message: res.data.message,
  315 + type: 'success',
  316 + duration: 1000
  317 + })
  318 + this.dialogClassIVIsibleT = false
  319 +
  320 + }
  321 + })
  322 + }
  323 + else {
  324 + UsersCreate(postdata).then(res => {
  325 + if (res.data.code == 200) {
  326 + this.$notify({
  327 + title: 'Success',
  328 + message: res.data.message,
  329 + type: 'success',
  330 + duration: 1000
  331 + })
  332 + this.dialogClassIVIsibleT = false
  333 +
  334 + }
  335 + })
  336 + }
  337 +
  338 + } else {
  339 + console.log('error submit!!');
  340 + return false;
  341 + }
  342 + });
  343 + },
  344 + resetForm(formName) {
  345 + this.$refs[formName].resetFields();
  346 + },
  347 + handleCommand(value, val) {
  348 + let that = this;
  349 + if (value == "update") {
  350 + GetInfo(val.id).then(res => {
  351 + that.dialogClassIVIsible = true;
  352 + that.$nextTick(function () {
  353 +
  354 + that.adminUserInfo = res.data.data
  355 + if (res.data.data.users) {
  356 + that.value = res.data.data.users;
  357 + }
  358 + if (res.data.data.menues) {
  359 + that.$refs.tree.setCheckedKeys(res.data.data.menues);
  360 + }
  361 + that.title = '编辑信息'
  362 + that.buttonText = '保存'
  363 +
  364 + });
  365 +
  366 + });
  367 + }
  368 + if (value == 'updatePassword') {
  369 + that.ruleForm.UserId = val.id
  370 + ththatis.dialogClassIVIsibleT = true
  371 + }
  372 + if (value == "del") {
  373 + that.$confirm('确定删除该管理员?', '消息', {
  374 + confirmButtonText: '确认',
  375 + cancelButtonText: '取消',
  376 + callback: (action) => {
  377 + if (action == "confirm") {
  378 + UsersDelete({
  379 + ids: val.id
  380 + }).then(res => {
  381 + if (res.data.code == 200) {
  382 + that.$notify({
  383 + title: '成功',
  384 + message: res.data.message,
  385 + type: 'success'
  386 + });
  387 + that.GetUser();
  388 + }
  389 + });
  390 + }
  391 + },
  392 + })
  393 +
  394 + }
  395 + },
  396 + }
  397 + }
  398 +</script>
  399 +
  400 +<style scoped>
  401 + .seetingsDiv {
  402 + width: 100%;
  403 + height: 60px;
  404 + background: #efefef;
  405 + border-radius: 5px;
  406 + box-shadow: 0 0 5px #cdcdcd;
  407 + }
  408 +
  409 + .seetingsDiv button {
  410 + background-color: #304156;
  411 + border: 0px;
  412 + margin-left: 10px;
  413 + box-shadow: 0 0 5px #cdcdcd;
  414 + float: left;
  415 + margin-top: 12px;
  416 + margin-right: 10px;
  417 + }
  418 +</style>
0 419 \ No newline at end of file
... ...
vue.config.js
... ... @@ -47,8 +47,8 @@ module.exports = {
47 47 }
48 48 },
49 49 '/api': {
50   - target: `http://inteview.t1j2.com/`, //后台服务地址
51   - // target: 'http://localhost:8877',
  50 + // target: `http://inteview.t1j2.com/`, //后台服务地址
  51 + target: 'http://localhost:8877',
52 52 changeOrigin: true,
53 53 pathRewrite: {}
54 54 }
... ...